Commit bc30bb88 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

netlink: specs: support conditional operations



Page pool code is compiled conditionally, but the operations
are part of the shared netlink family. We can handle this
by reporting empty list of pools or -EOPNOTSUPP / -ENOSYS
but the cleanest way seems to be removing the ops completely
at compilation time. That way user can see that the page
pool ops are not present using genetlink introspection.
Same way they'd check if the kernel is "new enough" to
support the ops.

Extend the specs with the ability to specify the config
condition under which op (and its policies, etc.) should
be hidden.

Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20231025162253.133159-1-kuba@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ea23fbd2
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -295,6 +295,11 @@ properties:
              type: array
              items:
                enum: [ strict, dump, dump-strict ]
            config-cond:
              description: |
                Name of the kernel config option gating the presence of
                the operation, without the 'CONFIG_' prefix.
              type: string
            do: &subop-type
              description: Main command handler.
              type: object
+5 −0
Original line number Diff line number Diff line
@@ -346,6 +346,11 @@ properties:
              type: array
              items:
                enum: [ strict, dump, dump-strict ]
            config-cond:
              description: |
                Name of the kernel config option gating the presence of
                the operation, without the 'CONFIG_' prefix.
              type: string
            # Start genetlink-legacy
            fixed-header: *fixed-header
            # End genetlink-legacy
+5 −0
Original line number Diff line number Diff line
@@ -264,6 +264,11 @@ properties:
              type: array
              items:
                enum: [ strict, dump, dump-strict ]
            config-cond:
              description: |
                Name of the kernel config option gating the presence of
                the operation, without the 'CONFIG_' prefix.
              type: string
            do: &subop-type
              description: Main command handler.
              type: object
+22 −0
Original line number Diff line number Diff line
@@ -1162,6 +1162,7 @@ class CodeWriter:
        self._block_end = False
        self._silent_block = False
        self._ind = 0
        self._ifdef_block = None
        if out_file is None:
            self._out = os.sys.stdout
        else:
@@ -1202,6 +1203,8 @@ class CodeWriter:
        if self._silent_block:
            ind += 1
        self._silent_block = line.endswith(')') and CodeWriter._is_cond(line)
        if line[0] == '#':
            ind = 0
        if add_ind:
            ind += add_ind
        self._out.write('\t' * ind + line + '\n')
@@ -1328,6 +1331,19 @@ class CodeWriter:
            line += '= ' + str(one[1]) + ','
            self.p(line)

    def ifdef_block(self, config):
        config_option = None
        if config:
            config_option = 'CONFIG_' + c_upper(config)
        if self._ifdef_block == config_option:
            return

        if self._ifdef_block:
            self.p('#endif /* ' + self._ifdef_block + ' */')
        if config_option:
            self.p('#ifdef ' + config_option)
        self._ifdef_block = config_option


scalars = {'u8', 'u16', 'u32', 'u64', 's32', 's64', 'uint', 'sint'}

@@ -2006,10 +2022,13 @@ def print_req_policy_fwd(cw, struct, ri=None, terminate=True):


def print_req_policy(cw, struct, ri=None):
    if ri and ri.op:
        cw.ifdef_block(ri.op.get('config-cond', None))
    print_req_policy_fwd(cw, struct, ri=ri, terminate=False)
    for _, arg in struct.member_list():
        arg.attr_policy(cw)
    cw.p("};")
    cw.ifdef_block(None)
    cw.nl()


@@ -2127,6 +2146,7 @@ def print_kernel_op_table(family, cw):
            if op.is_async:
                continue

            cw.ifdef_block(op.get('config-cond', None))
            cw.block_start()
            members = [('cmd', op.enum_name)]
            if 'dont-validate' in op:
@@ -2157,6 +2177,7 @@ def print_kernel_op_table(family, cw):
                if op.is_async or op_mode not in op:
                    continue

                cw.ifdef_block(op.get('config-cond', None))
                cw.block_start()
                members = [('cmd', op.enum_name)]
                if 'dont-validate' in op:
@@ -2192,6 +2213,7 @@ def print_kernel_op_table(family, cw):
                members.append(('flags', ' | '.join([c_upper('genl-' + x) for x in flags])))
                cw.write_struct_init(members)
                cw.block_end(line=',')
    cw.ifdef_block(None)

    cw.block_end(line=';')
    cw.nl()