2024-03-26 13:48:32 +00:00
|
|
|
#!/usr/bin/env python3
|
2024-03-26 13:48:42 +00:00
|
|
|
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
2024-03-26 13:48:15 +00:00
|
|
|
|
|
|
|
import argparse
|
|
|
|
import json
|
|
|
|
import pprint
|
|
|
|
import time
|
|
|
|
|
tools/net/ynl: Report netlink errors without stacktrace
JIRA: https://issues.redhat.com/browse/RHEL-57764
commit 771b7012e5f3a49739dab4be60b87517a249a1df
Author: Donald Hunter <donald.hunter@gmail.com>
Date: Wed Mar 6 23:10:42 2024 +0000
tools/net/ynl: Report netlink errors without stacktrace
ynl does not handle NlError exceptions so they get reported like program
failures. Handle the NlError exceptions and report the netlink errors
more cleanly.
Example now:
Netlink error: No such file or directory
nl_len = 44 (28) nl_flags = 0x300 nl_type = 2
error: -2 extack: {'bad-attr': '.op'}
Example before:
Traceback (most recent call last):
File "/home/donaldh/net-next/./tools/net/ynl/cli.py", line 81, in <module>
main()
File "/home/donaldh/net-next/./tools/net/ynl/cli.py", line 69, in main
reply = ynl.dump(args.dump, attrs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/donaldh/net-next/tools/net/ynl/lib/ynl.py", line 906, in dump
return self._op(method, vals, [], dump=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/donaldh/net-next/tools/net/ynl/lib/ynl.py", line 872, in _op
raise NlError(nl_msg)
lib.ynl.NlError: Netlink error: No such file or directory
nl_len = 44 (28) nl_flags = 0x300 nl_type = 2
error: -2 extack: {'bad-attr': '.op'}
Signed-off-by: Donald Hunter <donald.hunter@gmail.com>
Link: https://lore.kernel.org/r/20240306231046.97158-3-donald.hunter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-10-07 09:26:23 +00:00
|
|
|
from lib import YnlFamily, Netlink, NlError
|
2024-03-26 13:48:15 +00:00
|
|
|
|
|
|
|
|
2024-10-07 09:26:22 +00:00
|
|
|
class YnlEncoder(json.JSONEncoder):
|
|
|
|
def default(self, obj):
|
|
|
|
if isinstance(obj, bytes):
|
|
|
|
return bytes.hex(obj)
|
|
|
|
if isinstance(obj, set):
|
|
|
|
return list(obj)
|
|
|
|
return json.JSONEncoder.default(self, obj)
|
|
|
|
|
|
|
|
|
2024-03-26 13:48:15 +00:00
|
|
|
def main():
|
|
|
|
parser = argparse.ArgumentParser(description='YNL CLI sample')
|
|
|
|
parser.add_argument('--spec', dest='spec', type=str, required=True)
|
|
|
|
parser.add_argument('--schema', dest='schema', type=str)
|
2024-03-26 13:48:30 +00:00
|
|
|
parser.add_argument('--no-schema', action='store_true')
|
2024-03-26 13:48:15 +00:00
|
|
|
parser.add_argument('--json', dest='json_text', type=str)
|
|
|
|
parser.add_argument('--do', dest='do', type=str)
|
|
|
|
parser.add_argument('--dump', dest='dump', type=str)
|
|
|
|
parser.add_argument('--sleep', dest='sleep', type=int)
|
|
|
|
parser.add_argument('--subscribe', dest='ntf', type=str)
|
2024-03-28 15:00:10 +00:00
|
|
|
parser.add_argument('--replace', dest='flags', action='append_const',
|
|
|
|
const=Netlink.NLM_F_REPLACE)
|
|
|
|
parser.add_argument('--excl', dest='flags', action='append_const',
|
|
|
|
const=Netlink.NLM_F_EXCL)
|
|
|
|
parser.add_argument('--create', dest='flags', action='append_const',
|
|
|
|
const=Netlink.NLM_F_CREATE)
|
|
|
|
parser.add_argument('--append', dest='flags', action='append_const',
|
|
|
|
const=Netlink.NLM_F_APPEND)
|
tools: ynl: introduce option to process unknown attributes or types
JIRA: https://issues.redhat.com/browse/RHEL-30145
Upstream commit(s):
commit d96e48a3d55db7ee62e607ad2d89eee1a8585028
Author: Jiri Pirko <jiri@nvidia.com>
Date: Fri Oct 27 11:25:25 2023 +0200
tools: ynl: introduce option to process unknown attributes or types
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>
Link: https://lore.kernel.org/r/20231027092525.956172-1-jiri@resnulli.us
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Petr Oros <poros@redhat.com>
2024-04-08 09:27:51 +00:00
|
|
|
parser.add_argument('--process-unknown', action=argparse.BooleanOptionalAction)
|
2024-10-07 09:26:22 +00:00
|
|
|
parser.add_argument('--output-json', action='store_true')
|
2024-03-26 13:48:15 +00:00
|
|
|
args = parser.parse_args()
|
|
|
|
|
2024-10-07 09:26:22 +00:00
|
|
|
def output(msg):
|
|
|
|
if args.output_json:
|
|
|
|
print(json.dumps(msg, cls=YnlEncoder))
|
|
|
|
else:
|
|
|
|
pprint.PrettyPrinter().pprint(msg)
|
|
|
|
|
2024-03-26 13:48:30 +00:00
|
|
|
if args.no_schema:
|
|
|
|
args.schema = ''
|
|
|
|
|
2024-03-26 13:48:15 +00:00
|
|
|
attrs = {}
|
|
|
|
if args.json_text:
|
|
|
|
attrs = json.loads(args.json_text)
|
|
|
|
|
tools: ynl: introduce option to process unknown attributes or types
JIRA: https://issues.redhat.com/browse/RHEL-30145
Upstream commit(s):
commit d96e48a3d55db7ee62e607ad2d89eee1a8585028
Author: Jiri Pirko <jiri@nvidia.com>
Date: Fri Oct 27 11:25:25 2023 +0200
tools: ynl: introduce option to process unknown attributes or types
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>
Link: https://lore.kernel.org/r/20231027092525.956172-1-jiri@resnulli.us
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Petr Oros <poros@redhat.com>
2024-04-08 09:27:51 +00:00
|
|
|
ynl = YnlFamily(args.spec, args.schema, args.process_unknown)
|
2024-03-26 13:48:15 +00:00
|
|
|
|
|
|
|
if args.ntf:
|
|
|
|
ynl.ntf_subscribe(args.ntf)
|
|
|
|
|
|
|
|
if args.sleep:
|
|
|
|
time.sleep(args.sleep)
|
|
|
|
|
tools/net/ynl: Report netlink errors without stacktrace
JIRA: https://issues.redhat.com/browse/RHEL-57764
commit 771b7012e5f3a49739dab4be60b87517a249a1df
Author: Donald Hunter <donald.hunter@gmail.com>
Date: Wed Mar 6 23:10:42 2024 +0000
tools/net/ynl: Report netlink errors without stacktrace
ynl does not handle NlError exceptions so they get reported like program
failures. Handle the NlError exceptions and report the netlink errors
more cleanly.
Example now:
Netlink error: No such file or directory
nl_len = 44 (28) nl_flags = 0x300 nl_type = 2
error: -2 extack: {'bad-attr': '.op'}
Example before:
Traceback (most recent call last):
File "/home/donaldh/net-next/./tools/net/ynl/cli.py", line 81, in <module>
main()
File "/home/donaldh/net-next/./tools/net/ynl/cli.py", line 69, in main
reply = ynl.dump(args.dump, attrs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/donaldh/net-next/tools/net/ynl/lib/ynl.py", line 906, in dump
return self._op(method, vals, [], dump=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/donaldh/net-next/tools/net/ynl/lib/ynl.py", line 872, in _op
raise NlError(nl_msg)
lib.ynl.NlError: Netlink error: No such file or directory
nl_len = 44 (28) nl_flags = 0x300 nl_type = 2
error: -2 extack: {'bad-attr': '.op'}
Signed-off-by: Donald Hunter <donald.hunter@gmail.com>
Link: https://lore.kernel.org/r/20240306231046.97158-3-donald.hunter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-10-07 09:26:23 +00:00
|
|
|
try:
|
|
|
|
if args.do:
|
|
|
|
reply = ynl.do(args.do, attrs, args.flags)
|
|
|
|
output(reply)
|
|
|
|
if args.dump:
|
|
|
|
reply = ynl.dump(args.dump, attrs)
|
|
|
|
output(reply)
|
|
|
|
except NlError as e:
|
|
|
|
print(e)
|
|
|
|
exit(1)
|
2024-03-26 13:48:15 +00:00
|
|
|
|
|
|
|
if args.ntf:
|
|
|
|
ynl.check_ntf()
|
2024-10-07 09:26:22 +00:00
|
|
|
output(ynl.async_msg_queue)
|
2024-03-26 13:48:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|