Thread (6 messages) 6 messages, 2 authors, 2025-11-29
STALE200d

[PATCH net-next v1 1/4] tools: ynl: add schema checking

From: Donald Hunter <donald.hunter@gmail.com>
Date: 2025-11-27 12:35:27
Subsystem: networking [general], the rest, yaml netlink (ynl) · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Donald Hunter

Add a --validate flag to pyynl for explicit schema check with error
reporting and add a schema_check make target to check all YNL specs.

make -C tools/net/ynl schema_check
make: Entering directory '/home/donaldh/net-next/tools/net/ynl'
ok 1 binder.yaml schema validation
not ok 2 conntrack.yaml schema validation
'labels mask' does not match '^[0-9a-z-]+$'

Failed validating 'pattern' in schema['properties']['attribute-sets']['items']['properties']['attributes']['items']['properties']['name']:
    {'type': 'string', 'pattern': '^[0-9a-z-]+$'}

On instance['attribute-sets'][14]['attributes'][22]['name']:
    'labels mask'

ok 3 devlink.yaml schema validation
[...]

Signed-off-by: Donald Hunter <donald.hunter@gmail.com>
---
 tools/net/ynl/Makefile     | 20 +++++++++++++++++++-
 tools/net/ynl/pyynl/cli.py | 21 ++++++++++++++++-----
 2 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/tools/net/ynl/Makefile b/tools/net/ynl/Makefile
index a40591e513b7..b23083b2dfb2 100644
--- a/tools/net/ynl/Makefile
+++ b/tools/net/ynl/Makefile
@@ -12,6 +12,8 @@ endif
 libdir  ?= $(prefix)/$(libdir_relative)
 includedir ?= $(prefix)/include
 
+SPECDIR=../../../Documentation/netlink/specs
+
 SUBDIRS = lib generated samples ynltool tests
 
 all: $(SUBDIRS) libynl.a
@@ -54,4 +56,20 @@ install: libynl.a lib/*.h
 run_tests:
 	@$(MAKE) -C tests run_tests
 
-.PHONY: all clean distclean install run_tests $(SUBDIRS)
+
+schema_check:
+	@N=1; \
+	for spec in $(SPECDIR)/*.yaml ; do \
+		NAME=$$(basename $$spec) ; \
+		OUTPUT=$$(./pyynl/cli.py --spec $$spec --validate) ; \
+		if [ $$? -eq 0 ] ; then \
+			echo "ok $$N $$NAME schema validation" ; \
+		else \
+			echo "not ok $$N $$NAME schema validation" ; \
+			echo "$$OUTPUT" ; \
+			echo ; \
+		fi ; \
+		N=$$((N+1)) ; \
+	done
+
+.PHONY: all clean distclean install run_tests schema_check $(SUBDIRS)
diff --git a/tools/net/ynl/pyynl/cli.py b/tools/net/ynl/pyynl/cli.py
index ff81ff083764..af02a5b7e5a2 100755
--- a/tools/net/ynl/pyynl/cli.py
+++ b/tools/net/ynl/pyynl/cli.py
@@ -10,7 +10,7 @@ import sys
 import textwrap
 
 sys.path.append(pathlib.Path(__file__).resolve().parent.as_posix())
-from lib import YnlFamily, Netlink, NlError
+from lib import YnlFamily, Netlink, NlError, SpecFamily
 
 sys_schema_dir='/usr/share/ynl'
 relative_schema_dir='../../../../Documentation/netlink'
@@ -127,6 +127,7 @@ def main():
     group.add_argument('--list-msgs', action='store_true')
     group.add_argument('--list-attrs', dest='list_attrs', metavar='OPERATION', type=str,
                        help='List attributes for an operation')
+    group.add_argument('--validate', action='store_true')
 
     parser.add_argument('--duration', dest='duration', type=int,
                         help='when subscribed, watch for DURATION seconds')
@@ -168,15 +169,25 @@ def main():
 
     if args.family:
         spec = f"{spec_dir()}/{args.family}.yaml"
-        if args.schema is None and spec.startswith(sys_schema_dir):
-            args.schema = '' # disable schema validation when installed
-        if args.process_unknown is None:
-            args.process_unknown = True
     else:
         spec = args.spec
     if not os.path.isfile(spec):
         raise Exception(f"Spec file {spec} does not exist")
 
+    if args.validate:
+        try:
+            SpecFamily(spec, args.schema)
+        except Exception as error:
+            print(error)
+            exit(1)
+        return
+
+    if args.family: # set behaviour when using installed specs
+        if args.schema is None and spec.startswith(sys_schema_dir):
+            args.schema = '' # disable schema validation when installed
+        if args.process_unknown is None:
+            args.process_unknown = True
+
     ynl = YnlFamily(spec, args.schema, args.process_unknown,
                     recv_size=args.dbg_small_recv)
     if args.dbg_small_recv:
-- 
2.51.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help