From: Jakub Kicinski <kuba@kernel.org>
To: Jiri Pirko <jiri@resnulli.us>
Cc: netdev@vger.kernel.org, davem@davemloft.net, edumazet@google.com,
pabeni@redhat.com, saeedm@nvidia.com, horms@kernel.org,
donald.hunter@gmail.com
Subject: Re: [PATCH net-next 2/5] tools: ynl-gen: allow noncontiguous enums
Date: Fri, 2 May 2025 18:43:47 -0700 [thread overview]
Message-ID: <20250502184347.68488470@kernel.org> (raw)
In-Reply-To: <20250502113821.889-3-jiri@resnulli.us>
On Fri, 2 May 2025 13:38:18 +0200 Jiri Pirko wrote:
> From: Jiri Pirko <jiri@nvidia.com>
>
> In case the enum has holes, instead of hard stop, generate a validation
> callback to check valid enum values.
>
> Signed-off-by: Jiri Pirko <jiri@nvidia.com>
> ---
> Saeed's v3->v1:
> - add validation callback generation
> ---
> tools/net/ynl/pyynl/ynl_gen_c.py | 45 +++++++++++++++++++++++++++++---
> 1 file changed, 42 insertions(+), 3 deletions(-)
>
> diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py
> index b4889974f645..c37551473923 100755
> --- a/tools/net/ynl/pyynl/ynl_gen_c.py
> +++ b/tools/net/ynl/pyynl/ynl_gen_c.py
> @@ -358,11 +358,13 @@ class TypeScalar(Type):
> if 'enum' in self.attr:
> enum = self.family.consts[self.attr['enum']]
> low, high = enum.value_range()
> - if 'min' not in self.checks:
> + if low and 'min' not in self.checks:
> if low != 0 or self.type[0] == 's':
> self.checks['min'] = low
> - if 'max' not in self.checks:
> + if high and 'max' not in self.checks:
> self.checks['max'] = high
> + if not low and not high:
> + self.checks['sparse'] = True
you should probably explicitly check for None, 0 is a valid low / high
> if 'min' in self.checks and 'max' in self.checks:
> if self.get_limit('min') > self.get_limit('max'):
> +def print_kernel_policy_sparse_enum_validates(family, cw):
> + first = True
> + for _, attr_set in family.attr_sets.items():
> + if attr_set.subset_of:
> + continue
> +
> + for _, attr in attr_set.items():
> + if not attr.request:
> + continue
> + if not attr.enum_name:
> + continue
> + if 'sparse' not in attr.checks:
> + continue
> +
> + if first:
> + cw.p('/* Sparse enums validation callbacks */')
> + first = False
> +
> + sign = '' if attr.type[0] == 'u' else '_signed'
> + suffix = 'ULL' if attr.type[0] == 'u' else 'LL'
> + cw.write_func_prot('static int', f'{c_lower(attr.enum_name)}_validate',
> + ['const struct nlattr *attr', 'struct netlink_ext_ack *extack'])
> + cw.block_start()
> + cw.block_start(line=f'switch (nla_get_{attr["type"]}(attr))', noind=True)
> + enum = family.consts[attr['enum']]
> + for entry in enum.entries.values():
> + cw.p(f'case {entry.c_name}: return 0;')
All the cases end in "return 0;"
remove this, and add the return 0; before the block end.
The code should look something like:
switch (nla_get_...) {
case VAL1:
case VAL2:
case VAL3:
return 0;
}
> + cw.block_end(noind=True)
> + cw.p('NL_SET_ERR_MSG_ATTR(extack, attr, "invalid enum value");')
> + cw.p('return -EINVAL;')
> + cw.block_end()
> + cw.nl()
> +
> +
> def print_kernel_op_table_fwd(family, cw, terminate):
> exported = not kernel_can_gen_family_struct(family)
>
> @@ -2965,6 +3003,7 @@ def main():
> print_kernel_family_struct_hdr(parsed, cw)
> else:
> print_kernel_policy_ranges(parsed, cw)
> + print_kernel_policy_sparse_enum_validates(parsed, cw)
>
> for _, struct in sorted(parsed.pure_nested_structs.items()):
> if struct.request:
next prev parent reply other threads:[~2025-05-03 1:43 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-02 11:38 [PATCH net-next 0/5] devlink: sanitize variable typed attributes Jiri Pirko
2025-05-02 11:38 ` [PATCH net-next 1/5] tools: ynl-gen: extend block_start/end by noind arg Jiri Pirko
2025-05-03 1:37 ` Jakub Kicinski
2025-05-04 18:25 ` Jiri Pirko
2025-05-02 11:38 ` [PATCH net-next 2/5] tools: ynl-gen: allow noncontiguous enums Jiri Pirko
2025-05-03 1:43 ` Jakub Kicinski [this message]
2025-05-04 18:25 ` Jiri Pirko
2025-05-02 11:38 ` [PATCH net-next 3/5] devlink: define enum for attr types of dynamic attributes Jiri Pirko
2025-05-03 1:46 ` Jakub Kicinski
2025-05-04 18:25 ` Jiri Pirko
2025-05-02 11:38 ` [PATCH net-next 4/5] devlink: avoid param type value translations Jiri Pirko
2025-05-02 11:38 ` [PATCH net-next 5/5] devlink: use DEVLINK_VAR_ATTR_TYPE_* instead of NLA_* in fmsg Jiri Pirko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250502184347.68488470@kernel.org \
--to=kuba@kernel.org \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jiri@resnulli.us \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=saeedm@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.