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: [PATCH net-next v5 4/7] tools: ynl: Add fixed-header support to ynl
Date: Mon, 27 Mar 2023 09:31:35 +0100 [thread overview]
Message-ID: <20230327083138.96044-5-donald.hunter@gmail.com> (raw)
In-Reply-To: <20230327083138.96044-1-donald.hunter@gmail.com>
Add support for netlink families that add an optional fixed header structure
after the genetlink header and before any attributes. The fixed-header can be
specified on a per op basis, or once for all operations, which serves as a
default value that can be overridden.
Signed-off-by: Donald Hunter <donald.hunter@gmail.com>
---
Documentation/netlink/genetlink-legacy.yaml | 11 ++++++++++
tools/net/ynl/lib/nlspec.py | 21 +++++++++++-------
tools/net/ynl/lib/ynl.py | 24 +++++++++++++++++----
3 files changed, 44 insertions(+), 12 deletions(-)
diff --git a/Documentation/netlink/genetlink-legacy.yaml b/Documentation/netlink/genetlink-legacy.yaml
index d50c78b9f42d..b33541a51d6b 100644
--- a/Documentation/netlink/genetlink-legacy.yaml
+++ b/Documentation/netlink/genetlink-legacy.yaml
@@ -261,6 +261,14 @@ properties:
async-enum:
description: Name for the enum type with notifications/events.
type: string
+ # Start genetlink-legacy
+ fixed-header: &fixed-header
+ description: |
+ Name of the structure defining the optional fixed-length protocol
+ header. This header is placed in a message after the netlink and
+ genetlink headers and before any attributes.
+ type: string
+ # End genetlink-legacy
list:
description: List of commands
type: array
@@ -293,6 +301,9 @@ properties:
type: array
items:
enum: [ strict, dump ]
+ # Start genetlink-legacy
+ fixed-header: *fixed-header
+ # End genetlink-legacy
do: &subop-type
description: Main command handler.
type: object
diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/lib/nlspec.py
index d1e5f60af580..06a906d74f0e 100644
--- a/tools/net/ynl/lib/nlspec.py
+++ b/tools/net/ynl/lib/nlspec.py
@@ -263,16 +263,17 @@ class SpecOperation(SpecElement):
Information about a single Netlink operation.
Attributes:
- value numerical ID when serialized, None if req/rsp values differ
+ value numerical ID when serialized, None if req/rsp values differ
- req_value numerical ID when serialized, user -> kernel
- rsp_value numerical ID when serialized, user <- kernel
- is_call bool, whether the operation is a call
- is_async bool, whether the operation is a notification
- is_resv bool, whether the operation does not exist (it's just a reserved ID)
- attr_set attribute set name
+ req_value numerical ID when serialized, user -> kernel
+ rsp_value numerical ID when serialized, user <- kernel
+ is_call bool, whether the operation is a call
+ is_async bool, whether the operation is a notification
+ is_resv bool, whether the operation does not exist (it's just a reserved ID)
+ attr_set attribute set name
+ fixed_header string, optional name of fixed header struct
- yaml raw spec as loaded from the spec file
+ yaml raw spec as loaded from the spec file
"""
def __init__(self, family, yaml, req_value, rsp_value):
super().__init__(family, yaml)
@@ -284,6 +285,7 @@ class SpecOperation(SpecElement):
self.is_call = 'do' in yaml or 'dump' in yaml
self.is_async = 'notify' in yaml or 'event' in yaml
self.is_resv = not self.is_async and not self.is_call
+ self.fixed_header = self.yaml.get('fixed-header', family.fixed_header)
# Added by resolve:
self.attr_set = None
@@ -324,6 +326,7 @@ class SpecFamily(SpecElement):
msgs_by_value dict of all messages (indexed by name)
ops dict of all valid requests / responses
consts dict of all constants/enums
+ fixed_header string, optional name of family default fixed header struct
"""
def __init__(self, spec_path, schema_path=None):
with open(spec_path, "r") as stream:
@@ -397,6 +400,7 @@ class SpecFamily(SpecElement):
self._resolution_list.append(elem)
def _dictify_ops_unified(self):
+ self.fixed_header = self.yaml['operations'].get('fixed-header')
val = 1
for elem in self.yaml['operations']['list']:
if 'value' in elem:
@@ -408,6 +412,7 @@ class SpecFamily(SpecElement):
self.msgs[op.name] = op
def _dictify_ops_directional(self):
+ self.fixed_header = self.yaml['operations'].get('fixed-header')
req_val = rsp_val = 1
for elem in self.yaml['operations']['list']:
if 'notify' in elem:
diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py
index 63af3bd9787d..ec40918152e1 100644
--- a/tools/net/ynl/lib/ynl.py
+++ b/tools/net/ynl/lib/ynl.py
@@ -278,14 +278,22 @@ def _genl_load_families():
class GenlMsg:
- def __init__(self, nl_msg):
+ def __init__(self, nl_msg, fixed_header_members=[]):
self.nl = nl_msg
self.hdr = nl_msg.raw[0:4]
- self.raw = nl_msg.raw[4:]
+ offset = 4
self.genl_cmd, self.genl_version, _ = struct.unpack("BBH", self.hdr)
+ self.fixed_header_attrs = dict()
+ for m in fixed_header_members:
+ format, size = NlAttr.type_formats[m.type]
+ decoded = struct.unpack_from(format, nl_msg.raw, offset)
+ offset += size
+ self.fixed_header_attrs[m.name] = decoded[0]
+
+ self.raw = nl_msg.raw[offset:]
self.raw_attrs = NlAttrs(self.raw)
def __repr__(self):
@@ -509,6 +517,13 @@ class YnlFamily(SpecFamily):
req_seq = random.randint(1024, 65535)
msg = _genl_msg(self.family.family_id, nl_flags, op.req_value, 1, req_seq)
+ fixed_header_members = []
+ if op.fixed_header:
+ fixed_header_members = self.consts[op.fixed_header].members
+ for m in fixed_header_members:
+ value = vals.pop(m.name)
+ format, _ = NlAttr.type_formats[m.type]
+ msg += struct.pack(format, value)
for name, value in vals.items():
msg += self._add_attr(op.attr_set.name, name, value)
msg = _genl_msg_finalize(msg)
@@ -535,7 +550,7 @@ class YnlFamily(SpecFamily):
done = True
break
- gm = GenlMsg(nl_msg)
+ gm = GenlMsg(nl_msg, fixed_header_members)
# Check if this is a reply to our request
if nl_msg.nl_seq != req_seq or gm.genl_cmd != op.rsp_value:
if gm.genl_cmd in self.async_msg_ids:
@@ -545,7 +560,8 @@ class YnlFamily(SpecFamily):
print('Unexpected message: ' + repr(gm))
continue
- rsp.append(self._decode(gm.raw_attrs, op.attr_set.name))
+ rsp.append(self._decode(gm.raw_attrs, op.attr_set.name)
+ | gm.fixed_header_attrs)
if not rsp:
return None
--
2.39.0
next prev parent reply other threads:[~2023-03-27 8:38 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-27 8:31 [PATCH net-next v5 0/7] ynl: add support for user headers and struct attrs Donald Hunter
2023-03-27 8:31 ` [PATCH net-next v5 1/7] tools: ynl: Add struct parsing to nlspec Donald Hunter
2023-03-27 8:31 ` [PATCH net-next v5 2/7] tools: ynl: Add C array attribute decoding to ynl Donald Hunter
2023-03-27 8:31 ` [PATCH net-next v5 3/7] tools: ynl: Add struct attr " Donald Hunter
2023-03-27 8:31 ` Donald Hunter [this message]
2023-03-27 8:31 ` [PATCH net-next v5 5/7] netlink: specs: add partial specification for openvswitch Donald Hunter
2023-03-27 8:31 ` [PATCH net-next v5 6/7] docs: netlink: document struct support for genetlink-legacy Donald Hunter
2023-03-27 12:44 ` Bagas Sanjaya
2023-03-27 14:39 ` Akira Yokosawa
2023-03-28 8:38 ` Bagas Sanjaya
2023-03-27 8:31 ` [PATCH net-next v5 7/7] docs: netlink: document the sub-type attribute property Donald Hunter
2023-03-27 12:45 ` Bagas Sanjaya
2023-03-29 7:00 ` [PATCH net-next v5 0/7] ynl: add support for user headers and struct attrs patchwork-bot+netdevbpf
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=20230327083138.96044-5-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.