mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
tools/net/ynl: Add support for nested structs
Make it possible for struct definitions to reference other struct definitions ofr binary members. For example, the tbf qdisc uses this struct definition for its parms attribute: - name: tc-tbf-qopt type: struct members: - name: rate type: binary struct: tc-ratespec - name: peakrate type: binary struct: tc-ratespec - name: limit type: u32 - name: buffer type: u32 - name: mtu type: u32 This adds the necessary schema changes and adds nested struct encoding and decoding to ynl. Signed-off-by: Donald Hunter <donald.hunter@gmail.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Link: https://lore.kernel.org/r/20240129223458.52046-11-donald.hunter@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
971c3eeaf6
commit
bf08f32c8c
@ -152,14 +152,23 @@ properties:
|
|||||||
the right formatting mechanism when displaying values of this
|
the right formatting mechanism when displaying values of this
|
||||||
type.
|
type.
|
||||||
enum: [ hex, mac, fddi, ipv4, ipv6, uuid ]
|
enum: [ hex, mac, fddi, ipv4, ipv6, uuid ]
|
||||||
|
struct:
|
||||||
|
description: Name of the nested struct type.
|
||||||
|
type: string
|
||||||
if:
|
if:
|
||||||
properties:
|
properties:
|
||||||
type:
|
type:
|
||||||
oneOf:
|
const: pad
|
||||||
- const: binary
|
|
||||||
- const: pad
|
|
||||||
then:
|
then:
|
||||||
required: [ len ]
|
required: [ len ]
|
||||||
|
if:
|
||||||
|
properties:
|
||||||
|
type:
|
||||||
|
const: binary
|
||||||
|
then:
|
||||||
|
oneOf:
|
||||||
|
- required: [ len ]
|
||||||
|
- required: [ struct ]
|
||||||
# End genetlink-legacy
|
# End genetlink-legacy
|
||||||
|
|
||||||
attribute-sets:
|
attribute-sets:
|
||||||
|
@ -248,6 +248,7 @@ class SpecStructMember(SpecElement):
|
|||||||
len integer, optional byte length of binary types
|
len integer, optional byte length of binary types
|
||||||
display_hint string, hint to help choose format specifier
|
display_hint string, hint to help choose format specifier
|
||||||
when displaying the value
|
when displaying the value
|
||||||
|
struct string, name of nested struct type
|
||||||
"""
|
"""
|
||||||
def __init__(self, family, yaml):
|
def __init__(self, family, yaml):
|
||||||
super().__init__(family, yaml)
|
super().__init__(family, yaml)
|
||||||
@ -256,6 +257,7 @@ class SpecStructMember(SpecElement):
|
|||||||
self.enum = yaml.get('enum')
|
self.enum = yaml.get('enum')
|
||||||
self.len = yaml.get('len')
|
self.len = yaml.get('len')
|
||||||
self.display_hint = yaml.get('display-hint')
|
self.display_hint = yaml.get('display-hint')
|
||||||
|
self.struct = yaml.get('struct')
|
||||||
|
|
||||||
|
|
||||||
class SpecStruct(SpecElement):
|
class SpecStruct(SpecElement):
|
||||||
|
@ -674,7 +674,10 @@ class YnlFamily(SpecFamily):
|
|||||||
size = 0
|
size = 0
|
||||||
for m in members:
|
for m in members:
|
||||||
if m.type in ['pad', 'binary']:
|
if m.type in ['pad', 'binary']:
|
||||||
size += m.len
|
if m.struct:
|
||||||
|
size += self._struct_size(m.struct)
|
||||||
|
else:
|
||||||
|
size += m.len
|
||||||
else:
|
else:
|
||||||
format = NlAttr.get_format(m.type, m.byte_order)
|
format = NlAttr.get_format(m.type, m.byte_order)
|
||||||
size += format.size
|
size += format.size
|
||||||
@ -691,8 +694,14 @@ class YnlFamily(SpecFamily):
|
|||||||
if m.type == 'pad':
|
if m.type == 'pad':
|
||||||
offset += m.len
|
offset += m.len
|
||||||
elif m.type == 'binary':
|
elif m.type == 'binary':
|
||||||
value = data[offset : offset + m.len]
|
if m.struct:
|
||||||
offset += m.len
|
len = self._struct_size(m.struct)
|
||||||
|
value = self._decode_struct(data[offset : offset + len],
|
||||||
|
m.struct)
|
||||||
|
offset += len
|
||||||
|
else:
|
||||||
|
value = data[offset : offset + m.len]
|
||||||
|
offset += m.len
|
||||||
else:
|
else:
|
||||||
format = NlAttr.get_format(m.type, m.byte_order)
|
format = NlAttr.get_format(m.type, m.byte_order)
|
||||||
[ value ] = format.unpack_from(data, offset)
|
[ value ] = format.unpack_from(data, offset)
|
||||||
@ -713,10 +722,15 @@ class YnlFamily(SpecFamily):
|
|||||||
if m.type == 'pad':
|
if m.type == 'pad':
|
||||||
attr_payload += bytearray(m.len)
|
attr_payload += bytearray(m.len)
|
||||||
elif m.type == 'binary':
|
elif m.type == 'binary':
|
||||||
if value is None:
|
if m.struct:
|
||||||
attr_payload += bytearray(m.len)
|
if value is None:
|
||||||
|
value = dict()
|
||||||
|
attr_payload += self._encode_struct(m.struct, value)
|
||||||
else:
|
else:
|
||||||
attr_payload += bytes.fromhex(value)
|
if value is None:
|
||||||
|
attr_payload += bytearray(m.len)
|
||||||
|
else:
|
||||||
|
attr_payload += bytes.fromhex(value)
|
||||||
else:
|
else:
|
||||||
if value is None:
|
if value is None:
|
||||||
value = 0
|
value = 0
|
||||||
|
Loading…
Reference in New Issue
Block a user