From: Donald Hunter <donald.hunter@gmail.com>
To: netdev@vger.kernel.org, Jakub Kicinski <kuba@kernel.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>, Jonathan Corbet <corbet@lwn.net>,
linux-doc@vger.kernel.org
Cc: donald.hunter@redhat.com, Donald Hunter <donald.hunter@gmail.com>
Subject: [RFC PATCH net-next v1 3/6] tools/net/ynl: Add dynamic attribute decoding to ynl
Date: Wed, 29 Nov 2023 10:11:56 +0000 [thread overview]
Message-ID: <20231129101159.99197-4-donald.hunter@gmail.com> (raw)
In-Reply-To: <20231129101159.99197-1-donald.hunter@gmail.com>
Implement dynamic attribute space selection and decoding to
the ynl library.
Encode support is not yet implemented. Support for dynamic selectors
at a different nest level from the key attribute is not yet supported.
Signed-off-by: Donald Hunter <donald.hunter@gmail.com>
---
tools/net/ynl/lib/nlspec.py | 27 +++++++++++++++++++++++++++
tools/net/ynl/lib/ynl.py | 32 ++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/lib/nlspec.py
index 92889298b197..c32c85ddf8fb 100644
--- a/tools/net/ynl/lib/nlspec.py
+++ b/tools/net/ynl/lib/nlspec.py
@@ -142,6 +142,29 @@ class SpecEnumSet(SpecElement):
mask += e.user_value(as_flags)
return mask
+class SpecDynAttr(SpecElement):
+ """ Single Dynamic Netlink atttribute type
+
+ Represents a choice of dynamic attribute type within an attr space.
+
+ Attributes:
+ value attribute value to match against dynamic type selector
+ struct_name string, name of struct definition
+ sub_type string, name of sub type
+ len integer, optional byte length of binary types
+ display_hint string, hint to help choose format specifier
+ when displaying the value
+ """
+ def __init__(self, family, parent, yaml):
+ super().__init__(family, yaml)
+
+ self.value = yaml.get('value')
+ self.struct_name = yaml.get('struct')
+ self.sub_type = yaml.get('sub-type')
+ self.byte_order = yaml.get('byte-order')
+ self.len = yaml.get('len')
+ self.display_hint = yaml.get('display-hint')
+
class SpecAttr(SpecElement):
""" Single Netlink atttribute type
@@ -173,9 +196,13 @@ class SpecAttr(SpecElement):
self.byte_order = yaml.get('byte-order')
self.len = yaml.get('len')
self.display_hint = yaml.get('display-hint')
+ self.dynamic_types = {}
self.is_auto_scalar = self.type == "sint" or self.type == "uint"
+ if 'selector' in yaml:
+ for item in yaml.get('selector').get('list', []):
+ self.dynamic_types[item['value']] = SpecDynAttr(family, self, item)
class SpecAttrSet(SpecElement):
""" Netlink Attribute Set class.
diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py
index 92995bca14e1..5ce01ce37573 100644
--- a/tools/net/ynl/lib/ynl.py
+++ b/tools/net/ynl/lib/ynl.py
@@ -549,6 +549,36 @@ class YnlFamily(SpecFamily):
else:
rsp[name] = [decoded]
+ def _resolve_selector(self, attr_spec, vals):
+ if 'selector' in attr_spec:
+ selector = attr_spec['selector']
+ key = selector['attribute']
+ if key in vals:
+ value = vals[key]
+ if value in attr_spec.dynamic_types:
+ spec = attr_spec.dynamic_types[value]
+ return spec
+ else:
+ raise Exception(f"No entry for {key}={value} in selector for '{attr_spec['name']}'")
+ else:
+ raise Exception(f"There is no value for {key} to use in selector for '{attr_spec['name']}'")
+ else:
+ raise Exception("type=dynamic requires a selector in '{attr_spec['name']}'")
+
+ def _decode_dynamic(self, attr, attr_spec, rsp):
+ dyn_spec = self._resolve_selector(attr_spec, rsp)
+ if dyn_spec['type'] == 'binary':
+ decoded = self._decode_binary(attr, dyn_spec)
+ elif dyn_spec['type'] == 'nest':
+ attr_space = dyn_spec['nested-attributes']
+ if attr_space in self.attr_sets:
+ decoded = self._decode(NlAttrs(attr.raw), attr_space)
+ else:
+ raise Exception(f"Unknown attribute-set '{attr_space}'")
+ else:
+ raise Exception(f"Unknown type '{spec['type']}' for value '{value}'")
+ return decoded
+
def _decode(self, attrs, space):
if space:
attr_space = self.attr_sets[space]
@@ -586,6 +616,8 @@ class YnlFamily(SpecFamily):
value = self._decode_enum(value, attr_spec)
selector = self._decode_enum(selector, attr_spec)
decoded = {"value": value, "selector": selector}
+ elif attr_spec["type"] == 'dynamic':
+ decoded = self._decode_dynamic(attr, attr_spec, rsp)
else:
if not self.process_unknown:
raise Exception(f'Unknown {attr_spec["type"]} with name {attr_spec["name"]}')
--
2.42.0
next prev parent reply other threads:[~2023-11-29 10:12 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-29 10:11 [RFC PATCH net-next v1 0/6] tools/net/ynl: Add dynamic selector for options attrs Donald Hunter
2023-11-29 10:11 ` [RFC PATCH net-next v1 1/6] doc/netlink: Add bitfield32, s8, s16 to the netlink-raw schema Donald Hunter
2023-11-29 10:11 ` [RFC PATCH net-next v1 2/6] doc/netlink: Add a nest selector to " Donald Hunter
2023-11-29 10:11 ` Donald Hunter [this message]
2023-11-29 10:11 ` [RFC PATCH net-next v1 4/6] doc/netlink/specs: add dynamic nest selector for rt_link data Donald Hunter
2023-11-29 10:11 ` [RFC PATCH net-next v1 5/6] doc/netlink/specs: Add a spec for tc Donald Hunter
2023-11-29 10:11 ` [RFC PATCH net-next v1 6/6] tools/net/ynl: Add optional fixed-header to dynamic nests Donald Hunter
2023-11-29 16:09 ` [RFC PATCH net-next v1 0/6] tools/net/ynl: Add dynamic selector for options attrs Jakub Kicinski
2023-11-29 16:58 ` Donald Hunter
2023-11-29 17:49 ` Jakub Kicinski
2023-11-30 8:48 ` Donald Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231129101159.99197-4-donald.hunter@gmail.com \
--to=donald.hunter@gmail.com \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=donald.hunter@redhat.com \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).