netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/5] devlink: sanitize variable typed attributes
@ 2025-05-02 11:38 Jiri Pirko
  2025-05-02 11:38 ` [PATCH net-next 1/5] tools: ynl-gen: extend block_start/end by noind arg Jiri Pirko
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Jiri Pirko @ 2025-05-02 11:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, kuba, pabeni, saeedm, horms, donald.hunter

From: Jiri Pirko <jiri@nvidia.com>

This is continuation based on first two patches
of https://lore.kernel.org/netdev/20250425214808.507732-1-saeed@kernel.org/

Better to take it as a separate patchset, as the rest of the original
patchset is probably settled.

This patchset is taking care of incorrect usage of internal NLA_* values
in uapi, introduces new enum (in patch #3) that shadows NLA_* values and
makes that part of UAPI.

The last two patches removes unnecessary translations with maintaining
clear devlink param driver api. I hope this might be acceptable.

Please check and merge to get this over with :)

Jiri Pirko (5):
  tools: ynl-gen: extend block_start/end by noind arg
  tools: ynl-gen: allow noncontiguous enums
  devlink: define enum for attr types of dynamic attributes
  devlink: avoid param type value translations
  devlink: use DEVLINK_VAR_ATTR_TYPE_* instead of NLA_* in fmsg

 Documentation/netlink/specs/devlink.yaml | 24 +++++++++++
 include/net/devlink.h                    | 10 ++---
 include/uapi/linux/devlink.h             | 17 ++++++++
 net/devlink/health.c                     | 52 +++++++++-------------
 net/devlink/netlink_gen.c                | 21 ++++++++-
 net/devlink/param.c                      | 46 +-------------------
 tools/net/ynl/pyynl/ynl_gen_c.py         | 55 +++++++++++++++++++++---
 7 files changed, 137 insertions(+), 88 deletions(-)

-- 
2.49.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH net-next 1/5] tools: ynl-gen: extend block_start/end by noind arg
  2025-05-02 11:38 [PATCH net-next 0/5] devlink: sanitize variable typed attributes Jiri Pirko
@ 2025-05-02 11:38 ` Jiri Pirko
  2025-05-03  1:37   ` Jakub Kicinski
  2025-05-02 11:38 ` [PATCH net-next 2/5] tools: ynl-gen: allow noncontiguous enums Jiri Pirko
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Jiri Pirko @ 2025-05-02 11:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, kuba, pabeni, saeedm, horms, donald.hunter

From: Jiri Pirko <jiri@nvidia.com>

In order to allow block with no indentation, like switch-case, extend
block_start/end by "noind" arg allowing caller to instruct writer to
do no indentation.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 tools/net/ynl/pyynl/ynl_gen_c.py | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py
index 9613a6135003..b4889974f645 100755
--- a/tools/net/ynl/pyynl/ynl_gen_c.py
+++ b/tools/net/ynl/pyynl/ynl_gen_c.py
@@ -1345,16 +1345,18 @@ class CodeWriter:
     def nl(self):
         self._nl = True
 
-    def block_start(self, line=''):
+    def block_start(self, line='', noind=False):
         if line:
             line = line + ' '
         self.p(line + '{')
-        self._ind += 1
+        if not noind:
+            self._ind += 1
 
-    def block_end(self, line=''):
+    def block_end(self, line='', noind=False):
         if line and line[0] not in {';', ','}:
             line = ' ' + line
-        self._ind -= 1
+        if not noind:
+            self._ind -= 1
         self._nl = False
         if not line:
             # Delay printing closing bracket in case "else" comes next
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 2/5] tools: ynl-gen: allow noncontiguous enums
  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-02 11:38 ` Jiri Pirko
  2025-05-03  1:43   ` Jakub Kicinski
  2025-05-02 11:38 ` [PATCH net-next 3/5] devlink: define enum for attr types of dynamic attributes Jiri Pirko
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Jiri Pirko @ 2025-05-02 11:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, kuba, pabeni, saeedm, horms, donald.hunter

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
 
         if 'min' in self.checks and 'max' in self.checks:
             if self.get_limit('min') > self.get_limit('max'):
@@ -417,6 +419,8 @@ class TypeScalar(Type):
             return f"NLA_POLICY_MIN({policy}, {self.get_limit_str('min')})"
         elif 'max' in self.checks:
             return f"NLA_POLICY_MAX({policy}, {self.get_limit_str('max')})"
+        elif 'sparse' in self.checks:
+            return f"NLA_POLICY_VALIDATE_FN({policy}, &{c_lower(self.enum_name)}_validate)"
         return super()._attr_policy(policy)
 
     def _attr_typol(self):
@@ -862,7 +866,7 @@ class EnumSet(SpecEnumSet):
         high = max([x.value for x in self.entries.values()])
 
         if high - low + 1 != len(self.entries):
-            raise Exception("Can't get value range for a noncontiguous enum")
+            return None, None
 
         return low, high
 
@@ -2299,6 +2303,40 @@ def print_kernel_policy_ranges(family, cw):
             cw.nl()
 
 
+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;')
+            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:
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 3/5] devlink: define enum for attr types of dynamic attributes
  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-02 11:38 ` [PATCH net-next 2/5] tools: ynl-gen: allow noncontiguous enums Jiri Pirko
@ 2025-05-02 11:38 ` Jiri Pirko
  2025-05-03  1:46   ` Jakub Kicinski
  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
  4 siblings, 1 reply; 12+ messages in thread
From: Jiri Pirko @ 2025-05-02 11:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, kuba, pabeni, saeedm, horms, donald.hunter

From: Jiri Pirko <jiri@nvidia.com>

Devlink param and health reporter fmsg use attributes with dynamic type
which is determined according to a different type. Currently used values
are NLA_*. The problem is, they are not part of UAPI. They may change
which would cause a break.

To make this future safe, introduce a enum that shadows NLA_* values in
it and is part of UAPI.

Also, this allows to possibly carry types that are unrelated to NLA_*
values.

Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
Saeed's v3->v1:
- s/Dynamic/Variable/ in comment
- re-generated netlink_gen.c according to changes in previous patch
---
 Documentation/netlink/specs/devlink.yaml | 24 +++++++++++++++++++
 include/uapi/linux/devlink.h             | 17 ++++++++++++++
 net/devlink/health.c                     | 17 ++++++++++++--
 net/devlink/netlink_gen.c                | 21 ++++++++++++++++-
 net/devlink/param.c                      | 30 ++++++++++++------------
 5 files changed, 91 insertions(+), 18 deletions(-)

diff --git a/Documentation/netlink/specs/devlink.yaml b/Documentation/netlink/specs/devlink.yaml
index bd9726269b4f..05fee1b7fe19 100644
--- a/Documentation/netlink/specs/devlink.yaml
+++ b/Documentation/netlink/specs/devlink.yaml
@@ -202,6 +202,28 @@ definitions:
         name: exception
       -
         name: control
+  -
+    type: enum
+    name: var-attr-type
+    entries:
+      -
+        name: u8
+        value: 1
+      -
+        name: u16
+      -
+        name: u32
+      -
+        name: u64
+      -
+        name: string
+      -
+        name: flag
+      -
+        name: nul_string
+        value: 10
+      -
+        name: binary
 
 attribute-sets:
   -
@@ -498,6 +520,7 @@ attribute-sets:
       -
         name: param-type
         type: u8
+        enum: var-attr-type
 
       # TODO: fill in the attributes in between
 
@@ -592,6 +615,7 @@ attribute-sets:
       -
         name: fmsg-obj-value-type
         type: u8
+        enum: var-attr-type
 
       # TODO: fill in the attributes in between
 
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 9401aa343673..39a1216d15fe 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -385,6 +385,23 @@ enum devlink_linecard_state {
 	DEVLINK_LINECARD_STATE_MAX = __DEVLINK_LINECARD_STATE_MAX - 1
 };
 
+/**
+ * enum devlink_var_attr_type - Variable attribute type.
+ */
+enum devlink_var_attr_type {
+	/* Following values relate to the internal NLA_* values */
+	DEVLINK_VAR_ATTR_TYPE_U8 = 1,
+	DEVLINK_VAR_ATTR_TYPE_U16,
+	DEVLINK_VAR_ATTR_TYPE_U32,
+	DEVLINK_VAR_ATTR_TYPE_U64,
+	DEVLINK_VAR_ATTR_TYPE_STRING,
+	DEVLINK_VAR_ATTR_TYPE_FLAG,
+	DEVLINK_VAR_ATTR_TYPE_NUL_STRING = 10,
+	DEVLINK_VAR_ATTR_TYPE_BINARY,
+	__DEVLINK_VAR_ATTR_TYPE_CUSTOM_BASE = 0x80,
+	/* Any possible custom types, unrelated to NLA_* values go below */
+};
+
 enum devlink_attr {
 	/* don't change the order or add anything between, this is ABI! */
 	DEVLINK_ATTR_UNSPEC,
diff --git a/net/devlink/health.c b/net/devlink/health.c
index 57db6799722a..95a7a62d85a2 100644
--- a/net/devlink/health.c
+++ b/net/devlink/health.c
@@ -930,18 +930,31 @@ EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
 static int
 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
 {
+	enum devlink_var_attr_type var_attr_type;
+
 	switch (msg->nla_type) {
 	case NLA_FLAG:
+		var_attr_type = DEVLINK_VAR_ATTR_TYPE_FLAG;
+		break;
 	case NLA_U8:
+		var_attr_type = DEVLINK_VAR_ATTR_TYPE_U8;
+		break;
 	case NLA_U32:
+		var_attr_type = DEVLINK_VAR_ATTR_TYPE_U32;
+		break;
 	case NLA_U64:
+		var_attr_type = DEVLINK_VAR_ATTR_TYPE_U64;
+		break;
 	case NLA_NUL_STRING:
+		var_attr_type = DEVLINK_VAR_ATTR_TYPE_NUL_STRING;
+		break;
 	case NLA_BINARY:
-		return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
-				  msg->nla_type);
+		var_attr_type = DEVLINK_VAR_ATTR_TYPE_BINARY;
+		break;
 	default:
 		return -EINVAL;
 	}
+	return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, var_attr_type);
 }
 
 static int
diff --git a/net/devlink/netlink_gen.c b/net/devlink/netlink_gen.c
index f9786d51f68f..4b4122140ce4 100644
--- a/net/devlink/netlink_gen.c
+++ b/net/devlink/netlink_gen.c
@@ -10,6 +10,25 @@
 
 #include <uapi/linux/devlink.h>
 
+/* Sparse enums validation callbacks */
+static int
+devlink_attr_param_type_validate(const struct nlattr *attr,
+				 struct netlink_ext_ack *extack)
+{
+	switch (nla_get_u8(attr)) {
+	case DEVLINK_VAR_ATTR_TYPE_U8: return 0;
+	case DEVLINK_VAR_ATTR_TYPE_U16: return 0;
+	case DEVLINK_VAR_ATTR_TYPE_U32: return 0;
+	case DEVLINK_VAR_ATTR_TYPE_U64: return 0;
+	case DEVLINK_VAR_ATTR_TYPE_STRING: return 0;
+	case DEVLINK_VAR_ATTR_TYPE_FLAG: return 0;
+	case DEVLINK_VAR_ATTR_TYPE_NUL_STRING: return 0;
+	case DEVLINK_VAR_ATTR_TYPE_BINARY: return 0;
+	}
+	NL_SET_ERR_MSG_ATTR(extack, attr, "invalid enum value");
+	return -EINVAL;
+}
+
 /* Common nested types */
 const struct nla_policy devlink_dl_port_function_nl_policy[DEVLINK_PORT_FN_ATTR_CAPS + 1] = {
 	[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY, },
@@ -273,7 +292,7 @@ static const struct nla_policy devlink_param_set_nl_policy[DEVLINK_ATTR_PARAM_VA
 	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
 	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
 	[DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING, },
-	[DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8, },
+	[DEVLINK_ATTR_PARAM_TYPE] = NLA_POLICY_VALIDATE_FN(NLA_U8, &devlink_attr_param_type_validate),
 	[DEVLINK_ATTR_PARAM_VALUE_CMODE] = NLA_POLICY_MAX(NLA_U8, 2),
 };
 
diff --git a/net/devlink/param.c b/net/devlink/param.c
index dcf0d1ccebba..d0fb7c88bdb8 100644
--- a/net/devlink/param.c
+++ b/net/devlink/param.c
@@ -167,19 +167,19 @@ static int devlink_param_set(struct devlink *devlink,
 }
 
 static int
-devlink_param_type_to_nla_type(enum devlink_param_type param_type)
+devlink_param_type_to_var_attr_type(enum devlink_param_type param_type)
 {
 	switch (param_type) {
 	case DEVLINK_PARAM_TYPE_U8:
-		return NLA_U8;
+		return DEVLINK_VAR_ATTR_TYPE_U8;
 	case DEVLINK_PARAM_TYPE_U16:
-		return NLA_U16;
+		return DEVLINK_VAR_ATTR_TYPE_U16;
 	case DEVLINK_PARAM_TYPE_U32:
-		return NLA_U32;
+		return DEVLINK_VAR_ATTR_TYPE_U32;
 	case DEVLINK_PARAM_TYPE_STRING:
-		return NLA_STRING;
+		return DEVLINK_VAR_ATTR_TYPE_STRING;
 	case DEVLINK_PARAM_TYPE_BOOL:
-		return NLA_FLAG;
+		return DEVLINK_VAR_ATTR_TYPE_FLAG;
 	default:
 		return -EINVAL;
 	}
@@ -247,7 +247,7 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
 	struct devlink_param_gset_ctx ctx;
 	struct nlattr *param_values_list;
 	struct nlattr *param_attr;
-	int nla_type;
+	int var_attr_type;
 	void *hdr;
 	int err;
 	int i;
@@ -294,10 +294,10 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
 	if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
 		goto param_nest_cancel;
 
-	nla_type = devlink_param_type_to_nla_type(param->type);
-	if (nla_type < 0)
+	var_attr_type = devlink_param_type_to_var_attr_type(param->type);
+	if (var_attr_type < 0)
 		goto param_nest_cancel;
-	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
+	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, var_attr_type))
 		goto param_nest_cancel;
 
 	param_values_list = nla_nest_start_noflag(msg,
@@ -420,19 +420,19 @@ devlink_param_type_get_from_info(struct genl_info *info,
 		return -EINVAL;
 
 	switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
-	case NLA_U8:
+	case DEVLINK_VAR_ATTR_TYPE_U8:
 		*param_type = DEVLINK_PARAM_TYPE_U8;
 		break;
-	case NLA_U16:
+	case DEVLINK_VAR_ATTR_TYPE_U16:
 		*param_type = DEVLINK_PARAM_TYPE_U16;
 		break;
-	case NLA_U32:
+	case DEVLINK_VAR_ATTR_TYPE_U32:
 		*param_type = DEVLINK_PARAM_TYPE_U32;
 		break;
-	case NLA_STRING:
+	case DEVLINK_VAR_ATTR_TYPE_STRING:
 		*param_type = DEVLINK_PARAM_TYPE_STRING;
 		break;
-	case NLA_FLAG:
+	case DEVLINK_VAR_ATTR_TYPE_FLAG:
 		*param_type = DEVLINK_PARAM_TYPE_BOOL;
 		break;
 	default:
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 4/5] devlink: avoid param type value translations
  2025-05-02 11:38 [PATCH net-next 0/5] devlink: sanitize variable typed attributes Jiri Pirko
                   ` (2 preceding siblings ...)
  2025-05-02 11:38 ` [PATCH net-next 3/5] devlink: define enum for attr types of dynamic attributes Jiri Pirko
@ 2025-05-02 11:38 ` 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
  4 siblings, 0 replies; 12+ messages in thread
From: Jiri Pirko @ 2025-05-02 11:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, kuba, pabeni, saeedm, horms, donald.hunter

From: Jiri Pirko <jiri@nvidia.com>

Assign DEVLINK_PARAM_TYPE_* enum values to DEVLINK_VAR_ATTR_TYPE_* to
ensure the same values are used internally and in UAPI. Benefit from
that by removing the value translations.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 include/net/devlink.h | 10 +++++-----
 net/devlink/param.c   | 46 ++-----------------------------------------
 2 files changed, 7 insertions(+), 49 deletions(-)

diff --git a/include/net/devlink.h b/include/net/devlink.h
index b8783126c1ed..0091f23a40f7 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -420,11 +420,11 @@ typedef u64 devlink_resource_occ_get_t(void *priv);
 
 #define __DEVLINK_PARAM_MAX_STRING_VALUE 32
 enum devlink_param_type {
-	DEVLINK_PARAM_TYPE_U8,
-	DEVLINK_PARAM_TYPE_U16,
-	DEVLINK_PARAM_TYPE_U32,
-	DEVLINK_PARAM_TYPE_STRING,
-	DEVLINK_PARAM_TYPE_BOOL,
+	DEVLINK_PARAM_TYPE_U8 = DEVLINK_VAR_ATTR_TYPE_U8,
+	DEVLINK_PARAM_TYPE_U16 = DEVLINK_VAR_ATTR_TYPE_U16,
+	DEVLINK_PARAM_TYPE_U32 = DEVLINK_VAR_ATTR_TYPE_U32,
+	DEVLINK_PARAM_TYPE_STRING = DEVLINK_VAR_ATTR_TYPE_STRING,
+	DEVLINK_PARAM_TYPE_BOOL = DEVLINK_VAR_ATTR_TYPE_FLAG,
 };
 
 union devlink_param_value {
diff --git a/net/devlink/param.c b/net/devlink/param.c
index d0fb7c88bdb8..b29abf8d3ed4 100644
--- a/net/devlink/param.c
+++ b/net/devlink/param.c
@@ -166,25 +166,6 @@ static int devlink_param_set(struct devlink *devlink,
 	return param->set(devlink, param->id, ctx, extack);
 }
 
-static int
-devlink_param_type_to_var_attr_type(enum devlink_param_type param_type)
-{
-	switch (param_type) {
-	case DEVLINK_PARAM_TYPE_U8:
-		return DEVLINK_VAR_ATTR_TYPE_U8;
-	case DEVLINK_PARAM_TYPE_U16:
-		return DEVLINK_VAR_ATTR_TYPE_U16;
-	case DEVLINK_PARAM_TYPE_U32:
-		return DEVLINK_VAR_ATTR_TYPE_U32;
-	case DEVLINK_PARAM_TYPE_STRING:
-		return DEVLINK_VAR_ATTR_TYPE_STRING;
-	case DEVLINK_PARAM_TYPE_BOOL:
-		return DEVLINK_VAR_ATTR_TYPE_FLAG;
-	default:
-		return -EINVAL;
-	}
-}
-
 static int
 devlink_nl_param_value_fill_one(struct sk_buff *msg,
 				enum devlink_param_type type,
@@ -247,7 +228,6 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
 	struct devlink_param_gset_ctx ctx;
 	struct nlattr *param_values_list;
 	struct nlattr *param_attr;
-	int var_attr_type;
 	void *hdr;
 	int err;
 	int i;
@@ -293,11 +273,7 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
 		goto param_nest_cancel;
 	if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
 		goto param_nest_cancel;
-
-	var_attr_type = devlink_param_type_to_var_attr_type(param->type);
-	if (var_attr_type < 0)
-		goto param_nest_cancel;
-	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, var_attr_type))
+	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, param->type))
 		goto param_nest_cancel;
 
 	param_values_list = nla_nest_start_noflag(msg,
@@ -419,25 +395,7 @@ devlink_param_type_get_from_info(struct genl_info *info,
 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE))
 		return -EINVAL;
 
-	switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
-	case DEVLINK_VAR_ATTR_TYPE_U8:
-		*param_type = DEVLINK_PARAM_TYPE_U8;
-		break;
-	case DEVLINK_VAR_ATTR_TYPE_U16:
-		*param_type = DEVLINK_PARAM_TYPE_U16;
-		break;
-	case DEVLINK_VAR_ATTR_TYPE_U32:
-		*param_type = DEVLINK_PARAM_TYPE_U32;
-		break;
-	case DEVLINK_VAR_ATTR_TYPE_STRING:
-		*param_type = DEVLINK_PARAM_TYPE_STRING;
-		break;
-	case DEVLINK_VAR_ATTR_TYPE_FLAG:
-		*param_type = DEVLINK_PARAM_TYPE_BOOL;
-		break;
-	default:
-		return -EINVAL;
-	}
+	*param_type = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE]);
 
 	return 0;
 }
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 5/5] devlink: use DEVLINK_VAR_ATTR_TYPE_* instead of NLA_* in fmsg
  2025-05-02 11:38 [PATCH net-next 0/5] devlink: sanitize variable typed attributes Jiri Pirko
                   ` (3 preceding siblings ...)
  2025-05-02 11:38 ` [PATCH net-next 4/5] devlink: avoid param type value translations Jiri Pirko
@ 2025-05-02 11:38 ` Jiri Pirko
  4 siblings, 0 replies; 12+ messages in thread
From: Jiri Pirko @ 2025-05-02 11:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, kuba, pabeni, saeedm, horms, donald.hunter

From: Jiri Pirko <jiri@nvidia.com>

Use newly introduced DEVLINK_VAR_ATTR_TYPE_* enum values instead of
internal NLA_* in fmsg health reporter code.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 net/devlink/health.c | 65 ++++++++++++++------------------------------
 1 file changed, 21 insertions(+), 44 deletions(-)

diff --git a/net/devlink/health.c b/net/devlink/health.c
index 95a7a62d85a2..b3ce8ecbb7fb 100644
--- a/net/devlink/health.c
+++ b/net/devlink/health.c
@@ -735,7 +735,7 @@ static void devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
 		return;
 	}
 
-	item->nla_type = NLA_NUL_STRING;
+	item->nla_type = DEVLINK_VAR_ATTR_TYPE_NUL_STRING;
 	item->len = strlen(name) + 1;
 	item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
 	memcpy(&item->value, name, item->len);
@@ -822,32 +822,37 @@ static void devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
 static void devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
 {
 	devlink_fmsg_err_if_binary(fmsg);
-	devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
+	devlink_fmsg_put_value(fmsg, &value, sizeof(value),
+			       DEVLINK_VAR_ATTR_TYPE_FLAG);
 }
 
 static void devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
 {
 	devlink_fmsg_err_if_binary(fmsg);
-	devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
+	devlink_fmsg_put_value(fmsg, &value, sizeof(value),
+			       DEVLINK_VAR_ATTR_TYPE_U8);
 }
 
 void devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
 {
 	devlink_fmsg_err_if_binary(fmsg);
-	devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
+	devlink_fmsg_put_value(fmsg, &value, sizeof(value),
+			       DEVLINK_VAR_ATTR_TYPE_U32);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
 
 static void devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
 {
 	devlink_fmsg_err_if_binary(fmsg);
-	devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
+	devlink_fmsg_put_value(fmsg, &value, sizeof(value),
+			       DEVLINK_VAR_ATTR_TYPE_U64);
 }
 
 void devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
 {
 	devlink_fmsg_err_if_binary(fmsg);
-	devlink_fmsg_put_value(fmsg, value, strlen(value) + 1, NLA_NUL_STRING);
+	devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
+			       DEVLINK_VAR_ATTR_TYPE_NUL_STRING);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
 
@@ -857,7 +862,8 @@ void devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
 	if (!fmsg->err && !fmsg->putting_binary)
 		fmsg->err = -EINVAL;
 
-	devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
+	devlink_fmsg_put_value(fmsg, value, value_len,
+			       DEVLINK_VAR_ATTR_TYPE_BINARY);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
 
@@ -927,36 +933,6 @@ void devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
 
-static int
-devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
-{
-	enum devlink_var_attr_type var_attr_type;
-
-	switch (msg->nla_type) {
-	case NLA_FLAG:
-		var_attr_type = DEVLINK_VAR_ATTR_TYPE_FLAG;
-		break;
-	case NLA_U8:
-		var_attr_type = DEVLINK_VAR_ATTR_TYPE_U8;
-		break;
-	case NLA_U32:
-		var_attr_type = DEVLINK_VAR_ATTR_TYPE_U32;
-		break;
-	case NLA_U64:
-		var_attr_type = DEVLINK_VAR_ATTR_TYPE_U64;
-		break;
-	case NLA_NUL_STRING:
-		var_attr_type = DEVLINK_VAR_ATTR_TYPE_NUL_STRING;
-		break;
-	case NLA_BINARY:
-		var_attr_type = DEVLINK_VAR_ATTR_TYPE_BINARY;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, var_attr_type);
-}
-
 static int
 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
 {
@@ -964,20 +940,20 @@ devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
 	u8 tmp;
 
 	switch (msg->nla_type) {
-	case NLA_FLAG:
+	case DEVLINK_VAR_ATTR_TYPE_FLAG:
 		/* Always provide flag data, regardless of its value */
 		tmp = *(bool *)msg->value;
 
 		return nla_put_u8(skb, attrtype, tmp);
-	case NLA_U8:
+	case DEVLINK_VAR_ATTR_TYPE_U8:
 		return nla_put_u8(skb, attrtype, *(u8 *)msg->value);
-	case NLA_U32:
+	case DEVLINK_VAR_ATTR_TYPE_U32:
 		return nla_put_u32(skb, attrtype, *(u32 *)msg->value);
-	case NLA_U64:
+	case DEVLINK_VAR_ATTR_TYPE_U64:
 		return devlink_nl_put_u64(skb, attrtype, *(u64 *)msg->value);
-	case NLA_NUL_STRING:
+	case DEVLINK_VAR_ATTR_TYPE_NUL_STRING:
 		return nla_put_string(skb, attrtype, (char *)&msg->value);
-	case NLA_BINARY:
+	case DEVLINK_VAR_ATTR_TYPE_BINARY:
 		return nla_put(skb, attrtype, msg->len, (void *)&msg->value);
 	default:
 		return -EINVAL;
@@ -1011,7 +987,8 @@ devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
 			err = nla_put_flag(skb, item->attrtype);
 			break;
 		case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
-			err = devlink_fmsg_item_fill_type(item, skb);
+			err = nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
+					 item->nla_type);
 			if (err)
 				break;
 			err = devlink_fmsg_item_fill_data(item, skb);
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 1/5] tools: ynl-gen: extend block_start/end by noind arg
  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
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Kicinski @ 2025-05-03  1:37 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: netdev, davem, edumazet, pabeni, saeedm, horms, donald.hunter

On Fri,  2 May 2025 13:38:17 +0200 Jiri Pirko wrote:
> -    def block_start(self, line=''):
> +    def block_start(self, line='', noind=False):
>          if line:
>              line = line + ' '
>          self.p(line + '{')
> -        self._ind += 1
> +        if not noind:
> +            self._ind += 1
>  
> -    def block_end(self, line=''):
> +    def block_end(self, line='', noind=False):
>          if line and line[0] not in {';', ','}:
>              line = ' ' + line
> -        self._ind -= 1
> +        if not noind:
> +            self._ind -= 1

Should not be necessary, CodeWriter already automatically "unindents"
lines which end with : as all switch cases should.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 2/5] tools: ynl-gen: allow noncontiguous enums
  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
  2025-05-04 18:25     ` Jiri Pirko
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Kicinski @ 2025-05-03  1:43 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: netdev, davem, edumazet, pabeni, saeedm, horms, donald.hunter

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:


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 3/5] devlink: define enum for attr types of dynamic attributes
  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
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Kicinski @ 2025-05-03  1:46 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: netdev, davem, edumazet, pabeni, saeedm, horms, donald.hunter

On Fri,  2 May 2025 13:38:19 +0200 Jiri Pirko wrote:
> +/**
> + * enum devlink_var_attr_type - Variable attribute type.
> + */

If we want this to be a kdoc it needs to document all values.
Same as a struct kdoc needs to document all values.
Not sure if there's much to say here for each value, so a non-kdoc
comment is probably better?

I think I already mentioned this generates a build warning..

> +enum devlink_var_attr_type {
> +	/* Following values relate to the internal NLA_* values */
> +	DEVLINK_VAR_ATTR_TYPE_U8 = 1,
> +	DEVLINK_VAR_ATTR_TYPE_U16,
> +	DEVLINK_VAR_ATTR_TYPE_U32,
> +	DEVLINK_VAR_ATTR_TYPE_U64,
> +	DEVLINK_VAR_ATTR_TYPE_STRING,
> +	DEVLINK_VAR_ATTR_TYPE_FLAG,
> +	DEVLINK_VAR_ATTR_TYPE_NUL_STRING = 10,
> +	DEVLINK_VAR_ATTR_TYPE_BINARY,
> +	__DEVLINK_VAR_ATTR_TYPE_CUSTOM_BASE = 0x80,
> +	/* Any possible custom types, unrelated to NLA_* values go below */
> +};

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 3/5] devlink: define enum for attr types of dynamic attributes
  2025-05-03  1:46   ` Jakub Kicinski
@ 2025-05-04 18:25     ` Jiri Pirko
  0 siblings, 0 replies; 12+ messages in thread
From: Jiri Pirko @ 2025-05-04 18:25 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: netdev, davem, edumazet, pabeni, saeedm, horms, donald.hunter

Sat, May 03, 2025 at 03:46:04AM +0200, kuba@kernel.org wrote:
>On Fri,  2 May 2025 13:38:19 +0200 Jiri Pirko wrote:
>> +/**
>> + * enum devlink_var_attr_type - Variable attribute type.
>> + */
>
>If we want this to be a kdoc it needs to document all values.
>Same as a struct kdoc needs to document all values.
>Not sure if there's much to say here for each value, so a non-kdoc
>comment is probably better?

Okay.

>
>I think I already mentioned this generates a build warning..

Did not see. Any. Will check.

>
>> +enum devlink_var_attr_type {
>> +	/* Following values relate to the internal NLA_* values */
>> +	DEVLINK_VAR_ATTR_TYPE_U8 = 1,
>> +	DEVLINK_VAR_ATTR_TYPE_U16,
>> +	DEVLINK_VAR_ATTR_TYPE_U32,
>> +	DEVLINK_VAR_ATTR_TYPE_U64,
>> +	DEVLINK_VAR_ATTR_TYPE_STRING,
>> +	DEVLINK_VAR_ATTR_TYPE_FLAG,
>> +	DEVLINK_VAR_ATTR_TYPE_NUL_STRING = 10,
>> +	DEVLINK_VAR_ATTR_TYPE_BINARY,
>> +	__DEVLINK_VAR_ATTR_TYPE_CUSTOM_BASE = 0x80,
>> +	/* Any possible custom types, unrelated to NLA_* values go below */
>> +};

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 2/5] tools: ynl-gen: allow noncontiguous enums
  2025-05-03  1:43   ` Jakub Kicinski
@ 2025-05-04 18:25     ` Jiri Pirko
  0 siblings, 0 replies; 12+ messages in thread
From: Jiri Pirko @ 2025-05-04 18:25 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: netdev, davem, edumazet, pabeni, saeedm, horms, donald.hunter

Sat, May 03, 2025 at 03:43:47AM +0200, kuba@kernel.org wrote:
>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

Okay.


>  
>>          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;
>	}

Sure.

Thanks!

>
>> +            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:
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 1/5] tools: ynl-gen: extend block_start/end by noind arg
  2025-05-03  1:37   ` Jakub Kicinski
@ 2025-05-04 18:25     ` Jiri Pirko
  0 siblings, 0 replies; 12+ messages in thread
From: Jiri Pirko @ 2025-05-04 18:25 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: netdev, davem, edumazet, pabeni, saeedm, horms, donald.hunter

Sat, May 03, 2025 at 03:37:20AM +0200, kuba@kernel.org wrote:
>On Fri,  2 May 2025 13:38:17 +0200 Jiri Pirko wrote:
>> -    def block_start(self, line=''):
>> +    def block_start(self, line='', noind=False):
>>          if line:
>>              line = line + ' '
>>          self.p(line + '{')
>> -        self._ind += 1
>> +        if not noind:
>> +            self._ind += 1
>>  
>> -    def block_end(self, line=''):
>> +    def block_end(self, line='', noind=False):
>>          if line and line[0] not in {';', ','}:
>>              line = ' ' + line
>> -        self._ind -= 1
>> +        if not noind:
>> +            self._ind -= 1
>
>Should not be necessary, CodeWriter already automatically "unindents"
>lines which end with : as all switch cases should.

Got it. Will try. Thanks!

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-05-04 18:26 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).