Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools/net/ynl: add support for --family and --list-families

Add a --family option to ynl to specify the spec by family name instead
of file path, with support for searching in-tree and system install
location and a --list-families option to show the available families.

./tools/net/ynl/pyynl/cli.py --family rt_addr --dump getaddr

Signed-off-by: Donald Hunter <donald.hunter@gmail.com>
Link: https://patch.msgid.link/20250111154803.7496-1-donald.hunter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Donald Hunter and committed by
Jakub Kicinski
2ff80cef 7c125d5b

+43 -2
+43 -2
tools/net/ynl/pyynl/cli.py
··· 3 3 4 4 import argparse 5 5 import json 6 + import os 6 7 import pathlib 7 8 import pprint 8 9 import sys 9 10 10 11 sys.path.append(pathlib.Path(__file__).resolve().parent.as_posix()) 11 12 from lib import YnlFamily, Netlink, NlError 13 + 14 + sys_schema_dir='/usr/share/ynl' 15 + relative_schema_dir='../../../../Documentation/netlink' 16 + 17 + def schema_dir(): 18 + script_dir = os.path.dirname(os.path.abspath(__file__)) 19 + schema_dir = os.path.abspath(f"{script_dir}/{relative_schema_dir}") 20 + if not os.path.isdir(schema_dir): 21 + schema_dir = sys_schema_dir 22 + if not os.path.isdir(schema_dir): 23 + raise Exception(f"Schema directory {schema_dir} does not exist") 24 + return schema_dir 25 + 26 + def spec_dir(): 27 + spec_dir = schema_dir() + '/specs' 28 + if not os.path.isdir(spec_dir): 29 + raise Exception(f"Spec directory {spec_dir} does not exist") 30 + return spec_dir 12 31 13 32 14 33 class YnlEncoder(json.JSONEncoder): ··· 51 32 52 33 parser = argparse.ArgumentParser(description=description, 53 34 epilog=epilog) 54 - parser.add_argument('--spec', dest='spec', type=str, required=True) 35 + spec_group = parser.add_mutually_exclusive_group(required=True) 36 + spec_group.add_argument('--family', dest='family', type=str, 37 + help='name of the netlink FAMILY') 38 + spec_group.add_argument('--list-families', action='store_true', 39 + help='list all netlink families supported by YNL (has spec)') 40 + spec_group.add_argument('--spec', dest='spec', type=str, 41 + help='choose the family by SPEC file path') 42 + 55 43 parser.add_argument('--schema', dest='schema', type=str) 56 44 parser.add_argument('--no-schema', action='store_true') 57 45 parser.add_argument('--json', dest='json_text', type=str) ··· 96 70 else: 97 71 pprint.PrettyPrinter().pprint(msg) 98 72 73 + if args.list_families: 74 + for filename in sorted(os.listdir(spec_dir())): 75 + if filename.endswith('.yaml'): 76 + print(filename.removesuffix('.yaml')) 77 + return 78 + 99 79 if args.no_schema: 100 80 args.schema = '' 101 81 ··· 109 77 if args.json_text: 110 78 attrs = json.loads(args.json_text) 111 79 112 - ynl = YnlFamily(args.spec, args.schema, args.process_unknown, 80 + if args.family: 81 + spec = f"{spec_dir()}/{args.family}.yaml" 82 + if args.schema is None and spec.startswith(sys_schema_dir): 83 + args.schema = '' # disable schema validation when installed 84 + else: 85 + spec = args.spec 86 + if not os.path.isfile(spec): 87 + raise Exception(f"Spec file {spec} does not exist") 88 + 89 + ynl = YnlFamily(spec, args.schema, args.process_unknown, 113 90 recv_size=args.dbg_small_recv) 114 91 if args.dbg_small_recv: 115 92 ynl.set_recv_dbg(True)