From bf08f32c8cedb12a23efcdc2c9584601d7030e16 Mon Sep 17 00:00:00 2001 From: Donald Hunter Date: Mon, 29 Jan 2024 22:34:55 +0000 Subject: tools/net/ynl: Add support for nested structs Make it possible for struct definitions to reference other struct definitions ofr binary members. For example, the tbf qdisc uses this struct definition for its parms attribute: - name: tc-tbf-qopt type: struct members: - name: rate type: binary struct: tc-ratespec - name: peakrate type: binary struct: tc-ratespec - name: limit type: u32 - name: buffer type: u32 - name: mtu type: u32 This adds the necessary schema changes and adds nested struct encoding and decoding to ynl. Signed-off-by: Donald Hunter Reviewed-by: Jiri Pirko Link: https://lore.kernel.org/r/20240129223458.52046-11-donald.hunter@gmail.com Signed-off-by: Jakub Kicinski --- tools/net/ynl/lib/nlspec.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/net/ynl/lib/nlspec.py') diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/lib/nlspec.py index 44f13e383e8a..5d197a12ab8d 100644 --- a/tools/net/ynl/lib/nlspec.py +++ b/tools/net/ynl/lib/nlspec.py @@ -248,6 +248,7 @@ class SpecStructMember(SpecElement): len integer, optional byte length of binary types display_hint string, hint to help choose format specifier when displaying the value + struct string, name of nested struct type """ def __init__(self, family, yaml): super().__init__(family, yaml) @@ -256,6 +257,7 @@ class SpecStructMember(SpecElement): self.enum = yaml.get('enum') self.len = yaml.get('len') self.display_hint = yaml.get('display-hint') + self.struct = yaml.get('struct') class SpecStruct(SpecElement): -- cgit v1.2.3 From 7b4434a8face07aa1a9737637e58de028a5972d8 Mon Sep 17 00:00:00 2001 From: Alessandro Marcolini Date: Sat, 3 Feb 2024 14:16:51 +0100 Subject: tools: ynl: correct typo and docstring Correct typo in SpecAttr docstring. Changed SpecSubMessageFormat docstring. Signed-off-by: Alessandro Marcolini Reviewed-by: Donald Hunter Reviewed-by: Jakub Kicinski Link: https://lore.kernel.org/r/6ab1dea7fb1f635c0d8b237f03a49eaa448c2bf4.1706962013.git.alessandromarcolini99@gmail.com Signed-off-by: Jakub Kicinski --- tools/net/ynl/lib/nlspec.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'tools/net/ynl/lib/nlspec.py') diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/lib/nlspec.py index 5d197a12ab8d..fbce52395b3b 100644 --- a/tools/net/ynl/lib/nlspec.py +++ b/tools/net/ynl/lib/nlspec.py @@ -144,7 +144,7 @@ class SpecEnumSet(SpecElement): class SpecAttr(SpecElement): - """ Single Netlink atttribute type + """ Single Netlink attribute type Represents a single attribute type within an attr space. @@ -308,10 +308,9 @@ class SpecSubMessage(SpecElement): class SpecSubMessageFormat(SpecElement): - """ Netlink sub-message definition + """ Netlink sub-message format definition - Represents a set of sub-message formats for polymorphic nlattrs - that contain type-specific sub messages. + Represents a single format for a sub-message. Attributes: value attribute value to match against type selector -- cgit v1.2.3 From ba980f8dff548ec4558ca9c5f20ac6545920debb Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 8 Mar 2024 11:03:19 -0800 Subject: netlink: specs: support generating code for genl socket priv The family struct is auto-generated for new families, support use of the sock_priv_* mechanism added in commit a731132424ad ("genetlink: introduce per-sock family private storage"). For example if the family wants to use struct sk_buff as its private struct (unrealistic but just for illustration), it would add to its spec: kernel-family: headers: [ "linux/skbuff.h" ] sock-priv: struct sk_buff ynl-gen-c will declare the appropriate priv size and hook in function prototypes to be implemented by the family. Link: https://lore.kernel.org/r/20240308190319.2523704-1-kuba@kernel.org Signed-off-by: Jakub Kicinski --- Documentation/netlink/genetlink-c.yaml | 19 +++++++++++++++++++ Documentation/netlink/genetlink-legacy.yaml | 19 +++++++++++++++++++ Documentation/netlink/genetlink.yaml | 19 +++++++++++++++++++ tools/net/ynl/lib/nlspec.py | 2 ++ tools/net/ynl/ynl-gen-c.py | 10 ++++++++++ 5 files changed, 69 insertions(+) (limited to 'tools/net/ynl/lib/nlspec.py') diff --git a/Documentation/netlink/genetlink-c.yaml b/Documentation/netlink/genetlink-c.yaml index de786e2d35bf..4dfd899a1661 100644 --- a/Documentation/netlink/genetlink-c.yaml +++ b/Documentation/netlink/genetlink-c.yaml @@ -378,3 +378,22 @@ properties: type: string # End genetlink-c flags: *cmd_flags + + kernel-family: + description: Additional global attributes used for kernel C code generation. + type: object + additionalProperties: False + properties: + headers: + description: | + List of extra headers which should be included in the source + of the generated code. + type: array + items: + type: string + sock-priv: + description: | + Literal name of the type which is used within the kernel + to store the socket state. The type / structure is internal + to the kernel, and is not defined in the spec. + type: string diff --git a/Documentation/netlink/genetlink-legacy.yaml b/Documentation/netlink/genetlink-legacy.yaml index c69de46b189b..b48ad3b1cc32 100644 --- a/Documentation/netlink/genetlink-legacy.yaml +++ b/Documentation/netlink/genetlink-legacy.yaml @@ -439,3 +439,22 @@ properties: type: string # End genetlink-c flags: *cmd_flags + + kernel-family: + description: Additional global attributes used for kernel C code generation. + type: object + additionalProperties: False + properties: + headers: + description: | + List of extra headers which should be included in the source + of the generated code. + type: array + items: + type: string + sock-priv: + description: | + Literal name of the type which is used within the kernel + to store the socket state. The type / structure is internal + to the kernel, and is not defined in the spec. + type: string diff --git a/Documentation/netlink/genetlink.yaml b/Documentation/netlink/genetlink.yaml index d7edb8855563..ebd6ee743fcc 100644 --- a/Documentation/netlink/genetlink.yaml +++ b/Documentation/netlink/genetlink.yaml @@ -328,3 +328,22 @@ properties: The name for the group, used to form the define and the value of the define. type: string flags: *cmd_flags + + kernel-family: + description: Additional global attributes used for kernel C code generation. + type: object + additionalProperties: False + properties: + headers: + description: | + List of extra headers which should be included in the source + of the generated code. + type: array + items: + type: string + sock-priv: + description: | + Literal name of the type which is used within the kernel + to store the socket state. The type / structure is internal + to the kernel, and is not defined in the spec. + type: string diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/lib/nlspec.py index fbce52395b3b..6d08ab9e213f 100644 --- a/tools/net/ynl/lib/nlspec.py +++ b/tools/net/ynl/lib/nlspec.py @@ -418,6 +418,7 @@ class SpecFamily(SpecElement): consts dict of all constants/enums fixed_header string, optional name of family default fixed header struct mcast_groups dict of all multicast groups (index by name) + kernel_family dict of kernel family attributes """ def __init__(self, spec_path, schema_path=None, exclude_ops=None): with open(spec_path, "r") as stream: @@ -461,6 +462,7 @@ class SpecFamily(SpecElement): self.ntfs = collections.OrderedDict() self.consts = collections.OrderedDict() self.mcast_groups = collections.OrderedDict() + self.kernel_family = collections.OrderedDict(self.yaml.get('kernel-family', {})) last_exception = None while len(self._resolution_list) > 0: diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index 5bb7ca01fe51..6b7eb2d2aaf1 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -2342,6 +2342,10 @@ def print_kernel_family_struct_hdr(family, cw): cw.p(f"extern struct genl_family {family.c_name}_nl_family;") cw.nl() + if 'sock-priv' in family.kernel_family: + cw.p(f'void {family.c_name}_nl_sock_priv_init({family.kernel_family["sock-priv"]} *priv);') + cw.p(f'void {family.c_name}_nl_sock_priv_destroy({family.kernel_family["sock-priv"]} *priv);') + cw.nl() def print_kernel_family_struct_src(family, cw): @@ -2363,6 +2367,11 @@ def print_kernel_family_struct_src(family, cw): if family.mcgrps['list']: cw.p(f'.mcgrps\t\t= {family.c_name}_nl_mcgrps,') cw.p(f'.n_mcgrps\t= ARRAY_SIZE({family.c_name}_nl_mcgrps),') + if 'sock-priv' in family.kernel_family: + cw.p(f'.sock_priv_size\t= sizeof({family.kernel_family["sock-priv"]}),') + # Force cast here, actual helpers take pointer to the real type. + cw.p(f'.sock_priv_init\t= (void *){family.c_name}_nl_sock_priv_init,') + cw.p(f'.sock_priv_destroy = (void *){family.c_name}_nl_sock_priv_destroy,') cw.block_end(';') @@ -2659,6 +2668,7 @@ def main(): cw.p(f'#include "{os.path.basename(args.out_file[:-2])}.h"') cw.nl() headers = ['uapi/' + parsed.uapi_header] + headers += parsed.kernel_family.get('headers', []) else: cw.p('#include ') cw.p('#include ') -- cgit v1.2.3