Commit ba980f8d authored by Jakub Kicinski's avatar Jakub Kicinski

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 a7311324
("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.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a0d94296
...@@ -378,3 +378,22 @@ properties: ...@@ -378,3 +378,22 @@ properties:
type: string type: string
# End genetlink-c # End genetlink-c
flags: *cmd_flags 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
...@@ -439,3 +439,22 @@ properties: ...@@ -439,3 +439,22 @@ properties:
type: string type: string
# End genetlink-c # End genetlink-c
flags: *cmd_flags 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
...@@ -328,3 +328,22 @@ properties: ...@@ -328,3 +328,22 @@ properties:
The name for the group, used to form the define and the value of the define. The name for the group, used to form the define and the value of the define.
type: string type: string
flags: *cmd_flags 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
...@@ -418,6 +418,7 @@ class SpecFamily(SpecElement): ...@@ -418,6 +418,7 @@ class SpecFamily(SpecElement):
consts dict of all constants/enums consts dict of all constants/enums
fixed_header string, optional name of family default fixed header struct fixed_header string, optional name of family default fixed header struct
mcast_groups dict of all multicast groups (index by name) 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): def __init__(self, spec_path, schema_path=None, exclude_ops=None):
with open(spec_path, "r") as stream: with open(spec_path, "r") as stream:
...@@ -461,6 +462,7 @@ class SpecFamily(SpecElement): ...@@ -461,6 +462,7 @@ class SpecFamily(SpecElement):
self.ntfs = collections.OrderedDict() self.ntfs = collections.OrderedDict()
self.consts = collections.OrderedDict() self.consts = collections.OrderedDict()
self.mcast_groups = collections.OrderedDict() self.mcast_groups = collections.OrderedDict()
self.kernel_family = collections.OrderedDict(self.yaml.get('kernel-family', {}))
last_exception = None last_exception = None
while len(self._resolution_list) > 0: while len(self._resolution_list) > 0:
......
...@@ -2342,6 +2342,10 @@ def print_kernel_family_struct_hdr(family, cw): ...@@ -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.p(f"extern struct genl_family {family.c_name}_nl_family;")
cw.nl() 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): def print_kernel_family_struct_src(family, cw):
...@@ -2363,6 +2367,11 @@ def print_kernel_family_struct_src(family, cw): ...@@ -2363,6 +2367,11 @@ def print_kernel_family_struct_src(family, cw):
if family.mcgrps['list']: if family.mcgrps['list']:
cw.p(f'.mcgrps\t\t= {family.c_name}_nl_mcgrps,') cw.p(f'.mcgrps\t\t= {family.c_name}_nl_mcgrps,')
cw.p(f'.n_mcgrps\t= ARRAY_SIZE({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(';') cw.block_end(';')
...@@ -2659,6 +2668,7 @@ def main(): ...@@ -2659,6 +2668,7 @@ def main():
cw.p(f'#include "{os.path.basename(args.out_file[:-2])}.h"') cw.p(f'#include "{os.path.basename(args.out_file[:-2])}.h"')
cw.nl() cw.nl()
headers = ['uapi/' + parsed.uapi_header] headers = ['uapi/' + parsed.uapi_header]
headers += parsed.kernel_family.get('headers', [])
else: else:
cw.p('#include <stdlib.h>') cw.p('#include <stdlib.h>')
cw.p('#include <string.h>') cw.p('#include <string.h>')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment