tools: ynl: Add struct attr decoding to ynl
Add support for decoding attributes that contain C structs. Signed-off-by: Donald Hunter <donald.hunter@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
b423c3c863
commit
2607191395
|
@ -218,6 +218,11 @@ properties:
|
|||
description: Max length for a string or a binary attribute.
|
||||
$ref: '#/$defs/len-or-define'
|
||||
sub-type: *attr-type
|
||||
# Start genetlink-legacy
|
||||
struct:
|
||||
description: Name of the struct type used for the attribute.
|
||||
type: string
|
||||
# End genetlink-legacy
|
||||
|
||||
# Make sure name-prefix does not appear in subsets (subsets inherit naming)
|
||||
dependencies:
|
||||
|
|
|
@ -152,6 +152,7 @@ class SpecAttr(SpecElement):
|
|||
value numerical ID when serialized
|
||||
attr_set Attribute Set containing this attr
|
||||
is_multi bool, attr may repeat multiple times
|
||||
struct_name string, name of struct definition
|
||||
sub_type string, name of sub type
|
||||
"""
|
||||
def __init__(self, family, attr_set, yaml, value):
|
||||
|
@ -160,6 +161,7 @@ class SpecAttr(SpecElement):
|
|||
self.value = value
|
||||
self.attr_set = attr_set
|
||||
self.is_multi = yaml.get('multi-attr', False)
|
||||
self.struct_name = yaml.get('struct')
|
||||
self.sub_type = yaml.get('sub-type')
|
||||
|
||||
|
||||
|
|
|
@ -102,6 +102,17 @@ class NlAttr:
|
|||
format, _ = self.type_formats[type]
|
||||
return list({ x[0] for x in struct.iter_unpack(format, self.raw) })
|
||||
|
||||
def as_struct(self, members):
|
||||
value = dict()
|
||||
offset = 0
|
||||
for m in members:
|
||||
# TODO: handle non-scalar members
|
||||
format, size = self.type_formats[m.type]
|
||||
decoded = struct.unpack_from(format, self.raw, offset)
|
||||
offset += size
|
||||
value[m.name] = decoded[0]
|
||||
return value
|
||||
|
||||
def __repr__(self):
|
||||
return f"[type:{self.type} len:{self._len}] {self.raw}"
|
||||
|
||||
|
@ -377,7 +388,9 @@ class YnlFamily(SpecFamily):
|
|||
rsp[attr_spec['name']] = value
|
||||
|
||||
def _decode_binary(self, attr, attr_spec):
|
||||
if attr_spec.sub_type:
|
||||
if attr_spec.struct_name:
|
||||
decoded = attr.as_struct(self.consts[attr_spec.struct_name])
|
||||
elif attr_spec.sub_type:
|
||||
decoded = attr.as_c_array(attr_spec.sub_type)
|
||||
else:
|
||||
decoded = attr.as_bin()
|
||||
|
|
Loading…
Reference in New Issue