tools: ynl-gen: support code gen for events
authorJakub Kicinski <kuba@kernel.org>
Thu, 8 Jun 2023 21:11:58 +0000 (14:11 -0700)
committerJakub Kicinski <kuba@kernel.org>
Fri, 9 Jun 2023 21:40:31 +0000 (14:40 -0700)
Netlink specs support both events and notifications (former can
define their own message contents). Plug in missing code to
generate types, parsers and include events into notification
tables.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tools/net/ynl/lib/nlspec.py
tools/net/ynl/ynl-gen-c.py

index 623c570..c5d4a6d 100644 (file)
@@ -423,7 +423,7 @@ class SpecFamily(SpecElement):
         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:
+            if 'notify' in elem or 'event' in elem:
                 if 'value' in elem:
                     rsp_val = elem['value']
                 req_val_next = req_val
index a230598..ccd73f1 100755 (executable)
@@ -828,7 +828,7 @@ class Family(SpecFamily):
                 }
 
     def _load_root_sets(self):
-        for op_name, op in self.ops.items():
+        for op_name, op in self.msgs.items():
             if 'attribute-set' not in op:
                 continue
 
@@ -839,6 +839,8 @@ class Family(SpecFamily):
                     req_attrs.update(set(op[op_mode]['request']['attributes']))
                 if op_mode in op and 'reply' in op[op_mode]:
                     rsp_attrs.update(set(op[op_mode]['reply']['attributes']))
+            if 'event' in op:
+                rsp_attrs.update(set(op['event']['attributes']))
 
             if op['attribute-set'] not in self.root_sets:
                 self.root_sets[op['attribute-set']] = {'request': req_attrs, 'reply': rsp_attrs}
@@ -2193,10 +2195,13 @@ def render_user_family(family, cw, prototype):
     if family.ntfs:
         cw.block_start(line=f"static const struct ynl_ntf_info {family['name']}_ntf_info[] = ")
         for ntf_op_name, ntf_op in family.ntfs.items():
-            if 'notify' not in ntf_op:
-                continue
-            op = family.ops[ntf_op['notify']]
-            ri = RenderInfo(cw, family, "user", op, op.name, "notify")
+            if 'notify' in ntf_op:
+                op = family.ops[ntf_op['notify']]
+                ri = RenderInfo(cw, family, "user", op, op.name, "notify")
+            elif 'event' in ntf_op:
+                ri = RenderInfo(cw, family, "user", ntf_op, ntf_op_name, "event")
+            else:
+                raise Exception('Invalid notification ' + ntf_op_name)
             _render_user_ntf_entry(ri, ntf_op)
         for op_name, op in family.ops.items():
             if 'event' not in op:
@@ -2424,6 +2429,7 @@ def main():
                         raise Exception(f'Only notifications with consistent types supported ({op.name})')
                     print_wrapped_type(ri)
 
+            for op_name, op in parsed.ntfs.items():
                 if 'event' in op:
                     ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'event')
                     cw.p(f"/* {op.enum_name} - event */")
@@ -2485,6 +2491,7 @@ def main():
                         raise Exception(f'Only notifications with consistent types supported ({op.name})')
                     print_ntf_type_free(ri)
 
+            for op_name, op in parsed.ntfs.items():
                 if 'event' in op:
                     cw.p(f"/* {op.enum_name} - event */")