summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorDonald Hunter <donald.hunter@gmail.com>2024-01-30 01:34:55 +0300
committerJakub Kicinski <kuba@kernel.org>2024-02-01 08:19:19 +0300
commitbf08f32c8cedb12a23efcdc2c9584601d7030e16 (patch)
tree11b33fc945ef2162ff027898c241437ab065f795 /tools
parent971c3eeaf668ed312d032d12becb106982d2b2bd (diff)
downloadlinux-bf08f32c8cedb12a23efcdc2c9584601d7030e16.tar.xz
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>
Diffstat (limited to 'tools')
-rw-r--r--tools/net/ynl/lib/nlspec.py2
-rw-r--r--tools/net/ynl/lib/ynl.py26
2 files changed, 22 insertions, 6 deletions
diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/lib/nlspec.py
index 44f13e383e8a..5d197a12ab8d 100644
--- a/tools/net/ynl/lib/nlspec.py
+++ b/tools/net/ynl/lib/nlspec.py
@@ -248,6 +248,7 @@ class SpecStructMember(SpecElement):
len integer, optional byte length of binary types
display_hint string, hint to help choose format specifier
when displaying the value
+ struct string, name of nested struct type
"""
def __init__(self, family, yaml):
super().__init__(family, yaml)
@@ -256,6 +257,7 @@ class SpecStructMember(SpecElement):
self.enum = yaml.get('enum')
self.len = yaml.get('len')
self.display_hint = yaml.get('display-hint')
+ self.struct = yaml.get('struct')
class SpecStruct(SpecElement):
diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py
index 2b0ca61deaf8..0f4193cc2e3b 100644
--- a/tools/net/ynl/lib/ynl.py
+++ b/tools/net/ynl/lib/ynl.py
@@ -674,7 +674,10 @@ class YnlFamily(SpecFamily):
size = 0
for m in members:
if m.type in ['pad', 'binary']:
- size += m.len
+ if m.struct:
+ size += self._struct_size(m.struct)
+ else:
+ size += m.len
else:
format = NlAttr.get_format(m.type, m.byte_order)
size += format.size
@@ -691,8 +694,14 @@ class YnlFamily(SpecFamily):
if m.type == 'pad':
offset += m.len
elif m.type == 'binary':
- value = data[offset : offset + m.len]
- offset += m.len
+ if m.struct:
+ 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:
format = NlAttr.get_format(m.type, m.byte_order)
[ value ] = format.unpack_from(data, offset)
@@ -713,10 +722,15 @@ class YnlFamily(SpecFamily):
if m.type == 'pad':
attr_payload += bytearray(m.len)
elif m.type == 'binary':
- if value is None:
- attr_payload += bytearray(m.len)
+ if m.struct:
+ if value is None:
+ value = dict()
+ attr_payload += self._encode_struct(m.struct, value)
else:
- attr_payload += bytes.fromhex(value)
+ if value is None:
+ attr_payload += bytearray(m.len)
+ else:
+ attr_payload += bytes.fromhex(value)
else:
if value is None:
value = 0