netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jiri Pirko <jiri@resnulli.us>
To: netdev@vger.kernel.org
Cc: kuba@kernel.org, pabeni@redhat.com, davem@davemloft.net,
	edumazet@google.com, jacob.e.keller@intel.com,
	swarupkotikalapudi@gmail.com, donald.hunter@gmail.com,
	sdf@google.com, lorenzo@kernel.org,
	alessandromarcolini99@gmail.com
Subject: [patch net-next 06/13] tools: ynl: introduce attribute-replace for sub-message
Date: Mon, 19 Feb 2024 18:25:22 +0100	[thread overview]
Message-ID: <20240219172525.71406-7-jiri@resnulli.us> (raw)
In-Reply-To: <20240219172525.71406-1-jiri@resnulli.us>

From: Jiri Pirko <jiri@nvidia.com>

For devlink param, param-value-data attr is used by kernel to fill
different attribute type according to param-type attribute value.

Currently the sub-message feature allows spec to embed custom message
selected by another attribute. The sub-message is then nested inside the
attr of sub-message type.

Benefit from the sub-message feature and extend it. Introduce
attribute-replace spec flag by which the spec indicates that ynl should
consider sub-message as not nested in the original attribute, but rather
to consider the original attribute as the sub-message right away.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 Documentation/netlink/genetlink-legacy.yaml   |  4 +++
 Documentation/netlink/netlink-raw.yaml        |  4 +++
 .../netlink/genetlink-legacy.rst              | 25 ++++++++++++++++++
 tools/net/ynl/lib/nlspec.py                   |  6 +++++
 tools/net/ynl/lib/ynl.py                      | 26 ++++++++++++++-----
 5 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/Documentation/netlink/genetlink-legacy.yaml b/Documentation/netlink/genetlink-legacy.yaml
index 6cb50e2cc021..77d89f81c71f 100644
--- a/Documentation/netlink/genetlink-legacy.yaml
+++ b/Documentation/netlink/genetlink-legacy.yaml
@@ -328,6 +328,10 @@ properties:
                   Name of the attribute space from which to resolve attributes
                   in the sub message.
                 type: string
+              attribute-replace:
+                description: |
+                  Replace the parent nested attribute with attribute set
+                type: boolean
 
   operations:
     description: Operations supported by the protocol.
diff --git a/Documentation/netlink/netlink-raw.yaml b/Documentation/netlink/netlink-raw.yaml
index cc38b026c451..e32660fbe6c3 100644
--- a/Documentation/netlink/netlink-raw.yaml
+++ b/Documentation/netlink/netlink-raw.yaml
@@ -346,6 +346,10 @@ properties:
                   Name of the attribute space from which to resolve attributes
                   in the sub message.
                 type: string
+              attribute-replace:
+                description: |
+                  Replace the parent nested attribute with attribute set
+                type: boolean
 
   operations:
     description: Operations supported by the protocol.
diff --git a/Documentation/userspace-api/netlink/genetlink-legacy.rst b/Documentation/userspace-api/netlink/genetlink-legacy.rst
index 7126b650090e..a9ccbfbb4a8d 100644
--- a/Documentation/userspace-api/netlink/genetlink-legacy.rst
+++ b/Documentation/userspace-api/netlink/genetlink-legacy.rst
@@ -381,3 +381,28 @@ alongside a sub-message selector and also in a top level ``attribute-set``, then
 the selector will be resolved using the value 'closest' to the selector. If the
 value is not present in the message at the same level as defined in the spec
 then this is an error.
+
+Some users, like devlink param, fill different attribute type according to
+selector attribute value. ``replace-attribute`` set to ``true`` indicates,
+that sub-message is not nested inside the attribute, but rather replacing
+the attribute. This allows to treat the attribute type differently according
+to the selector:
+
+.. code-block:: yaml
+
+  sub-messages:
+    -
+      name: dl-param-value-data-msg
+      formats:
+        -
+          value: u32
+          attribute-set: dl-param-value-data-u32-attrs
+          attribute-replace: true
+        -
+          value: string
+          attribute-set: dl-param-value-data-string-attrs
+          attribute-replace: true
+        -
+          value: bool
+          attribute-set: dl-param-value-data-bool-attrs
+          attribute-replace: true
diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/lib/nlspec.py
index 5e48ee0fb8b4..280d50e9079c 100644
--- a/tools/net/ynl/lib/nlspec.py
+++ b/tools/net/ynl/lib/nlspec.py
@@ -237,6 +237,9 @@ class SpecAttrSet(SpecElement):
     def items(self):
         return self.attrs.items()
 
+    def keys(self):
+        return self.attrs.keys()
+
 
 class SpecStructMember(SpecElement):
     """Struct member attribute
@@ -318,6 +321,8 @@ class SpecSubMessageFormat(SpecElement):
         value         attribute value to match against type selector
         fixed_header  string, name of fixed header, or None
         attr_set      string, name of attribute set, or None
+        attr_replace  bool, indicates replacement of parent attribute with
+                      attr_set decode, or None
     """
     def __init__(self, family, yaml):
         super().__init__(family, yaml)
@@ -325,6 +330,7 @@ class SpecSubMessageFormat(SpecElement):
         self.value = yaml.get('value')
         self.fixed_header = yaml.get('fixed-header')
         self.attr_set = yaml.get('attribute-set')
+        self.attr_replace = yaml.get('attribute-replace')
 
 
 class SpecOperation(SpecElement):
diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py
index d2ea1571d00c..8591e6bfe40b 100644
--- a/tools/net/ynl/lib/ynl.py
+++ b/tools/net/ynl/lib/ynl.py
@@ -507,11 +507,16 @@ class YnlFamily(SpecFamily):
                 attr_payload += self._encode_struct(msg_format.fixed_header, value)
             if msg_format.attr_set:
                 if msg_format.attr_set in self.attr_sets:
-                    nl_type |= Netlink.NLA_F_NESTED
-                    sub_attrs = SpaceAttrs(msg_format.attr_set, value, search_attrs)
-                    for subname, subvalue in value.items():
-                        attr_payload += self._add_attr(msg_format.attr_set,
-                                                       subname, subvalue, sub_attrs)
+                    if msg_format.attr_replace:
+                        first_attr_name = list(self.attr_sets[msg_format.attr_set].keys())[0]
+                        return self._add_attr(msg_format.attr_set, first_attr_name,
+                                              value, search_attrs)
+                    else:
+                        nl_type |= Netlink.NLA_F_NESTED
+                        sub_attrs = SpaceAttrs(msg_format.attr_set, value, search_attrs)
+                        for subname, subvalue in value.items():
+                            attr_payload += self._add_attr(msg_format.attr_set,
+                                                           subname, subvalue, sub_attrs)
                 else:
                     raise Exception(f"Unknown attribute-set '{msg_format.attr_set}'")
         else:
@@ -600,8 +605,17 @@ class YnlFamily(SpecFamily):
             offset = self._struct_size(msg_format.fixed_header)
         if msg_format.attr_set:
             if msg_format.attr_set in self.attr_sets:
-                subdict = self._decode(NlAttrs(attr.raw, offset), msg_format.attr_set)
+                if msg_format.attr_replace:
+                    attrs = [attr]
+                else:
+                    attrs = NlAttrs(attr.raw, offset);
+                subdict = self._decode(attrs, msg_format.attr_set)
                 decoded.update(subdict)
+                if msg_format.attr_replace:
+                    try:
+                        decoded = decoded[attr_spec.name]
+                    except KeyError:
+                        raise Exception(f"Attribute-set '{attr_space}' does not contain '{attr_spec.name}'")
             else:
                 raise Exception(f"Unknown attribute-set '{attr_space}' when decoding '{attr_spec.name}'")
         return decoded
-- 
2.43.2


  parent reply	other threads:[~2024-02-19 17:25 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-19 17:25 [patch net-next 00/13] netlink: specs: devlink: add the rest of missing attribute definitions Jiri Pirko
2024-02-19 17:25 ` [patch net-next 01/13] tools: ynl: allow user to specify flag attr with bool values Jiri Pirko
2024-02-19 20:42   ` Jakub Kicinski
2024-02-20  7:24     ` Jiri Pirko
2024-02-19 17:25 ` [patch net-next 02/13] tools: ynl: process all scalar types encoding in single elif statement Jiri Pirko
2024-02-19 17:25 ` [patch net-next 03/13] tools: ynl: allow user to pass enum string instead of scalar value Jiri Pirko
2024-02-19 20:49   ` Jakub Kicinski
2024-02-20  7:25     ` Jiri Pirko
2024-02-21  1:55       ` Jakub Kicinski
2024-02-21 14:31         ` Jiri Pirko
2024-02-19 20:51   ` Jakub Kicinski
2024-02-20  7:27     ` Jiri Pirko
2024-02-21  1:59       ` Jakub Kicinski
2024-02-21 11:40         ` Donald Hunter
2024-02-19 17:25 ` [patch net-next 04/13] netlink: specs: allow sub-messages in genetlink-legacy Jiri Pirko
2024-02-19 20:51   ` Jakub Kicinski
2024-02-20  7:28     ` Jiri Pirko
2024-02-19 17:25 ` [patch net-next 05/13] tools: ynl: allow attr in a subset to be of a different type Jiri Pirko
2024-02-19 17:25 ` Jiri Pirko [this message]
2024-02-19 22:52   ` [patch net-next 06/13] tools: ynl: introduce attribute-replace for sub-message Jakub Kicinski
2024-02-20  7:31     ` Jiri Pirko
2024-02-21  2:10       ` Jakub Kicinski
2024-02-21 12:48         ` Jiri Pirko
2024-02-21 18:45           ` Jakub Kicinski
2024-02-22 13:20             ` Jiri Pirko
2024-02-19 17:25 ` [patch net-next 07/13] tools: ynl: add support for list in nested attribute Jiri Pirko
2024-02-19 17:25 ` [patch net-next 08/13] netlink: specs: devlink: add enum for param-type attribute values Jiri Pirko
2024-02-19 17:25 ` [patch net-next 09/13] netlink: specs: devlink: add missing param attribute definitions Jiri Pirko
2024-02-19 17:26 ` [patch net-next 10/13] netlink: specs: devlink: treat dl-fmsg attribute as list Jiri Pirko
2024-02-19 17:26   ` [patch net-next 11/13] netlink: specs: devlink: add enum for fmsg-obj-value-type attribute values Jiri Pirko
2024-02-19 17:26   ` [patch net-next 12/13] netlink: specs: devlink: add missing fmsg-obj-value-data attribute definitions Jiri Pirko
2024-02-19 17:26   ` [patch net-next 13/13] netlink: specs: devlink: add missing nested devlink definitions Jiri Pirko

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=20240219172525.71406-7-jiri@resnulli.us \
    --to=jiri@resnulli.us \
    --cc=alessandromarcolini99@gmail.com \
    --cc=davem@davemloft.net \
    --cc=donald.hunter@gmail.com \
    --cc=edumazet@google.com \
    --cc=jacob.e.keller@intel.com \
    --cc=kuba@kernel.org \
    --cc=lorenzo@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sdf@google.com \
    --cc=swarupkotikalapudi@gmail.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).