* [patch net-next v4] tools: ynl: introduce option to process unknown attributes or types
@ 2023-10-27 9:25 Jiri Pirko
2023-10-27 21:54 ` Jakub Kicinski
2023-10-27 22:00 ` patchwork-bot+netdevbpf
0 siblings, 2 replies; 4+ messages in thread
From: Jiri Pirko @ 2023-10-27 9:25 UTC (permalink / raw)
To: netdev; +Cc: kuba, pabeni, davem, edumazet
From: Jiri Pirko <jiri@nvidia.com>
In case the kernel sends message back containing attribute not defined
in family spec, following exception is raised to the user:
$ sudo ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/devlink.yaml --do trap-get --json '{"bus-name": "netdevsim", "dev-name": "netdevsim1", "trap-name": "source_mac_is_multicast"}'
Traceback (most recent call last):
File "/home/jiri/work/linux/tools/net/ynl/lib/ynl.py", line 521, in _decode
attr_spec = attr_space.attrs_by_val[attr.type]
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
KeyError: 132
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/jiri/work/linux/./tools/net/ynl/cli.py", line 61, in <module>
main()
File "/home/jiri/work/linux/./tools/net/ynl/cli.py", line 49, in main
reply = ynl.do(args.do, attrs, args.flags)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jiri/work/linux/tools/net/ynl/lib/ynl.py", line 731, in do
return self._op(method, vals, flags)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jiri/work/linux/tools/net/ynl/lib/ynl.py", line 719, in _op
rsp_msg = self._decode(decoded.raw_attrs, op.attr_set.name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jiri/work/linux/tools/net/ynl/lib/ynl.py", line 525, in _decode
raise Exception(f"Space '{space}' has no attribute with value '{attr.type}'")
Exception: Space 'devlink' has no attribute with value '132'
Introduce a command line option "process-unknown" and pass it down to
YnlFamily class constructor to allow user to process unknown
attributes and types and print them as binaries.
$ sudo ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/devlink.yaml --do trap-get --json '{"bus-name": "netdevsim", "dev-name": "netdevsim1", "trap-name": "source_mac_is_multicast"}' --process-unknown
{'UnknownAttr(129)': {'UnknownAttr(0)': b'\x00\x00\x00\x00\x00\x00\x00\x00',
'UnknownAttr(1)': b'\x00\x00\x00\x00\x00\x00\x00\x00',
'UnknownAttr(2)': b'\x0e\x00\x00\x00\x00\x00\x00\x00'},
'UnknownAttr(132)': b'\x00',
'UnknownAttr(133)': b'',
'UnknownAttr(134)': {'UnknownAttr(0)': b''},
'bus-name': 'netdevsim',
'dev-name': 'netdevsim1',
'trap-action': 'drop',
'trap-group-name': 'l2_drops',
'trap-name': 'source_mac_is_multicast'}
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v3->v4:
- changed unknown attr key to f"UnknownAttr({attr.type})"
v2->v3:
- rebased on top of previous patchset and recent net-next
- removed fake attr spec class
- introduced "attr.is_nest" and using it instead of direct access
to "attr._type"
- pushed out rsp value addition into separate helper and sanitize
the unknown attr is possibly multi-value there
- pushed out unknown attr decode into separate helper
v1->v2:
- changed to process unknown attributes and type instead of ignoring them
---
tools/net/ynl/cli.py | 3 ++-
tools/net/ynl/lib/ynl.py | 48 +++++++++++++++++++++++++++++++---------
2 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/tools/net/ynl/cli.py b/tools/net/ynl/cli.py
index 564ecf07cd2c..2ad9ec0f5545 100755
--- a/tools/net/ynl/cli.py
+++ b/tools/net/ynl/cli.py
@@ -27,6 +27,7 @@ def main():
const=Netlink.NLM_F_CREATE)
parser.add_argument('--append', dest='flags', action='append_const',
const=Netlink.NLM_F_APPEND)
+ parser.add_argument('--process-unknown', action=argparse.BooleanOptionalAction)
args = parser.parse_args()
if args.no_schema:
@@ -36,7 +37,7 @@ def main():
if args.json_text:
attrs = json.loads(args.json_text)
- ynl = YnlFamily(args.spec, args.schema)
+ ynl = YnlFamily(args.spec, args.schema, args.process_unknown)
if args.ntf:
ynl.ntf_subscribe(args.ntf)
diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py
index b1da4aea9336..92995bca14e1 100644
--- a/tools/net/ynl/lib/ynl.py
+++ b/tools/net/ynl/lib/ynl.py
@@ -100,6 +100,7 @@ class NlAttr:
def __init__(self, raw, offset):
self._len, self._type = struct.unpack("HH", raw[offset:offset + 4])
self.type = self._type & ~Netlink.NLA_TYPE_MASK
+ self.is_nest = self._type & Netlink.NLA_F_NESTED
self.payload_len = self._len
self.full_len = (self.payload_len + 3) & ~3
self.raw = raw[offset + 4:offset + self.payload_len]
@@ -411,10 +412,11 @@ class GenlProtocol(NetlinkProtocol):
class YnlFamily(SpecFamily):
- def __init__(self, def_path, schema=None):
+ def __init__(self, def_path, schema=None, process_unknown=False):
super().__init__(def_path, schema)
self.include_raw = False
+ self.process_unknown = process_unknown
try:
if self.proto == "netlink-raw":
@@ -526,14 +528,41 @@ class YnlFamily(SpecFamily):
decoded.append({ item.type: subattrs })
return decoded
+ def _decode_unknown(self, attr):
+ if attr.is_nest:
+ return self._decode(NlAttrs(attr.raw), None)
+ else:
+ return attr.as_bin()
+
+ def _rsp_add(self, rsp, name, is_multi, decoded):
+ if is_multi == None:
+ if name in rsp and type(rsp[name]) is not list:
+ rsp[name] = [rsp[name]]
+ is_multi = True
+ else:
+ is_multi = False
+
+ if not is_multi:
+ rsp[name] = decoded
+ elif name in rsp:
+ rsp[name].append(decoded)
+ else:
+ rsp[name] = [decoded]
+
def _decode(self, attrs, space):
- attr_space = self.attr_sets[space]
+ if space:
+ attr_space = self.attr_sets[space]
rsp = dict()
for attr in attrs:
try:
attr_spec = attr_space.attrs_by_val[attr.type]
- except KeyError:
- raise Exception(f"Space '{space}' has no attribute with value '{attr.type}'")
+ except (KeyError, UnboundLocalError):
+ if not self.process_unknown:
+ raise Exception(f"Space '{space}' has no attribute with value '{attr.type}'")
+ attr_name = f"UnknownAttr({attr.type})"
+ self._rsp_add(rsp, attr_name, None, self._decode_unknown(attr))
+ continue
+
if attr_spec["type"] == 'nest':
subdict = self._decode(NlAttrs(attr.raw), attr_spec['nested-attributes'])
decoded = subdict
@@ -558,14 +587,11 @@ class YnlFamily(SpecFamily):
selector = self._decode_enum(selector, attr_spec)
decoded = {"value": value, "selector": selector}
else:
- raise Exception(f'Unknown {attr_spec["type"]} with name {attr_spec["name"]}')
+ if not self.process_unknown:
+ raise Exception(f'Unknown {attr_spec["type"]} with name {attr_spec["name"]}')
+ decoded = self._decode_unknown(attr)
- if not attr_spec.is_multi:
- rsp[attr_spec['name']] = decoded
- elif attr_spec.name in rsp:
- rsp[attr_spec.name].append(decoded)
- else:
- rsp[attr_spec.name] = [decoded]
+ self._rsp_add(rsp, attr_spec["name"], attr_spec.is_multi, decoded)
return rsp
--
2.41.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [patch net-next v4] tools: ynl: introduce option to process unknown attributes or types
2023-10-27 9:25 [patch net-next v4] tools: ynl: introduce option to process unknown attributes or types Jiri Pirko
@ 2023-10-27 21:54 ` Jakub Kicinski
2023-10-28 8:24 ` Jiri Pirko
2023-10-27 22:00 ` patchwork-bot+netdevbpf
1 sibling, 1 reply; 4+ messages in thread
From: Jakub Kicinski @ 2023-10-27 21:54 UTC (permalink / raw)
To: Jiri Pirko; +Cc: netdev, pabeni, davem, edumazet
On Fri, 27 Oct 2023 11:25:25 +0200 Jiri Pirko wrote:
> - changed unknown attr key to f"UnknownAttr({attr.type})"
Not what I wanted but okay. Let's move on.. :)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [patch net-next v4] tools: ynl: introduce option to process unknown attributes or types
2023-10-27 9:25 [patch net-next v4] tools: ynl: introduce option to process unknown attributes or types Jiri Pirko
2023-10-27 21:54 ` Jakub Kicinski
@ 2023-10-27 22:00 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-10-27 22:00 UTC (permalink / raw)
To: Jiri Pirko; +Cc: netdev, kuba, pabeni, davem, edumazet
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Fri, 27 Oct 2023 11:25:25 +0200 you wrote:
> From: Jiri Pirko <jiri@nvidia.com>
>
> In case the kernel sends message back containing attribute not defined
> in family spec, following exception is raised to the user:
>
> $ sudo ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/devlink.yaml --do trap-get --json '{"bus-name": "netdevsim", "dev-name": "netdevsim1", "trap-name": "source_mac_is_multicast"}'
> Traceback (most recent call last):
> File "/home/jiri/work/linux/tools/net/ynl/lib/ynl.py", line 521, in _decode
> attr_spec = attr_space.attrs_by_val[attr.type]
> ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
> KeyError: 132
>
> [...]
Here is the summary with links:
- [net-next,v4] tools: ynl: introduce option to process unknown attributes or types
https://git.kernel.org/netdev/net-next/c/d96e48a3d55d
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [patch net-next v4] tools: ynl: introduce option to process unknown attributes or types
2023-10-27 21:54 ` Jakub Kicinski
@ 2023-10-28 8:24 ` Jiri Pirko
0 siblings, 0 replies; 4+ messages in thread
From: Jiri Pirko @ 2023-10-28 8:24 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: netdev, pabeni, davem, edumazet
Fri, Oct 27, 2023 at 11:54:19PM CEST, kuba@kernel.org wrote:
>On Fri, 27 Oct 2023 11:25:25 +0200 Jiri Pirko wrote:
>> - changed unknown attr key to f"UnknownAttr({attr.type})"
>
>Not what I wanted but okay. Let's move on.. :)
Feel free to patch the way you wanted. But I don't see any nicer way
now. What you suggest with the class does not make sense to me.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-10-28 8:24 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-27 9:25 [patch net-next v4] tools: ynl: introduce option to process unknown attributes or types Jiri Pirko
2023-10-27 21:54 ` Jakub Kicinski
2023-10-28 8:24 ` Jiri Pirko
2023-10-27 22:00 ` patchwork-bot+netdevbpf
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).