History

devlink: define enum for attr types of dynamic attributes

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.

Jiri Pirko committed 1 year ago

Commit 429ac621 parent 37006af5 files · +97 −18Browse files

Unified · Split

5 files
  1. Documentation/netlink/specs/devlink.yaml +24 −0
  2. include/uapi/linux/devlink.h +15 −0
  3. net/devlink/health.c +15 −2
  4. net/devlink/netlink_gen.c +28 −1
  5. net/devlink/param.c +15 −15
Documentation/netlink/specs/devlink.yaml+24−0
@@ -202,6 +202,28 @@ definitions: · 201 unmodified lines
202202 name: exception
203203 -
204204 name: control
205+ -
206+ type: enum
207+ name: var-attr-type
208+ entries:
209+ -
210+ name: u8
211+ value: 1
212+ -
213+ name: u16
214+ -
215+ name: u32
216+ -
217+ name: u64
218+ -
219+ name: string
220+ -
221+ name: flag
222+ -
223+ name: nul_string
224+ value: 10
225+ -
226+ name: binary
205227
206228 attribute-sets:
207229 -
@@ -498,6 +520,7 @@ attribute-sets: · 290 unmodified lines
498520 -
499521 name: param-type
500522 type: u8
523+ enum: var-attr-type
501524
502525 # TODO: fill in the attributes in between
503526
@@ -592,6 +615,7 @@ attribute-sets: · 88 unmodified lines
592615 -
593616 name: fmsg-obj-value-type
594617 type: u8
618+ enum: var-attr-type
595619
596620 # TODO: fill in the attributes in between
597621
include/uapi/linux/devlink.h+15−0
@@ -385,6 +385,21 @@ enum devlink_linecard_state { · 384 unmodified lines
385385 DEVLINK_LINECARD_STATE_MAX = __DEVLINK_LINECARD_STATE_MAX - 1
386386 };
387387
388+/* Variable attribute type. */
389+enum devlink_var_attr_type {
390+ /* Following values relate to the internal NLA_* values */
391+ DEVLINK_VAR_ATTR_TYPE_U8 = 1,
392+ DEVLINK_VAR_ATTR_TYPE_U16,
393+ DEVLINK_VAR_ATTR_TYPE_U32,
394+ DEVLINK_VAR_ATTR_TYPE_U64,
395+ DEVLINK_VAR_ATTR_TYPE_STRING,
396+ DEVLINK_VAR_ATTR_TYPE_FLAG,
397+ DEVLINK_VAR_ATTR_TYPE_NUL_STRING = 10,
398+ DEVLINK_VAR_ATTR_TYPE_BINARY,
399+ __DEVLINK_VAR_ATTR_TYPE_CUSTOM_BASE = 0x80,
400+ /* Any possible custom types, unrelated to NLA_* values go below */
401+};
402+
388403 enum devlink_attr {
389404 /* don't change the order or add anything between, this is ABI! */
390405 DEVLINK_ATTR_UNSPEC,
net/devlink/health.c+15−2
@@ -930,18 +930,31 @@ EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put); · 929 unmodified lines
930930 static int
931931 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
932932 {
933+ enum devlink_var_attr_type var_attr_type;
934+
933935 switch (msg->nla_type) {
934936 case NLA_FLAG:
937+ var_attr_type = DEVLINK_VAR_ATTR_TYPE_FLAG;
938+ break;
935939 case NLA_U8:
940+ var_attr_type = DEVLINK_VAR_ATTR_TYPE_U8;
941+ break;
936942 case NLA_U32:
943+ var_attr_type = DEVLINK_VAR_ATTR_TYPE_U32;
944+ break;
937945 case NLA_U64:
946+ var_attr_type = DEVLINK_VAR_ATTR_TYPE_U64;
947+ break;
938948 case NLA_NUL_STRING:
949+ var_attr_type = DEVLINK_VAR_ATTR_TYPE_NUL_STRING;
950+ break;
939951 case NLA_BINARY:
940− return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
941− msg->nla_type);
952+ var_attr_type = DEVLINK_VAR_ATTR_TYPE_BINARY;
953+ break;
942954 default:
943955 return -EINVAL;
944956 }
957+ return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, var_attr_type);
945958 }
946959
947960 static int
net/devlink/netlink_gen.c+28−1
@@ -10,6 +10,33 @@ · 9 unmodified lines
1010
1111 #include <uapi/linux/devlink.h>
1212
13+/* Sparse enums validation callbacks */
14+static int
15+devlink_attr_param_type_validate(const struct nlattr *attr,
16+ struct netlink_ext_ack *extack)
17+{
18+ switch (nla_get_u8(attr)) {
19+ case DEVLINK_VAR_ATTR_TYPE_U8:
20+ fallthrough;
21+ case DEVLINK_VAR_ATTR_TYPE_U16:
22+ fallthrough;
23+ case DEVLINK_VAR_ATTR_TYPE_U32:
24+ fallthrough;
25+ case DEVLINK_VAR_ATTR_TYPE_U64:
26+ fallthrough;
27+ case DEVLINK_VAR_ATTR_TYPE_STRING:
28+ fallthrough;
29+ case DEVLINK_VAR_ATTR_TYPE_FLAG:
30+ fallthrough;
31+ case DEVLINK_VAR_ATTR_TYPE_NUL_STRING:
32+ fallthrough;
33+ case DEVLINK_VAR_ATTR_TYPE_BINARY:
34+ return 0;
35+ }
36+ NL_SET_ERR_MSG_ATTR(extack, attr, "invalid enum value");
37+ return -EINVAL;
38+}
39+
1340 /* Common nested types */
1441 const struct nla_policy devlink_dl_port_function_nl_policy[DEVLINK_PORT_FN_ATTR_CAPS + 1] = {
1542 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY, },
@@ -273,7 +300,7 @@ static const struct nla_policy devlink_param_set_nl_policy[DEVLINK_ATTR_PARAM_VA · 257 unmodified lines
273300 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
274301 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
275302 [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING, },
276− [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8, },
303+ [DEVLINK_ATTR_PARAM_TYPE] = NLA_POLICY_VALIDATE_FN(NLA_U8, &devlink_attr_param_type_validate),
277304 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = NLA_POLICY_MAX(NLA_U8, 2),
278305 };
279306
net/devlink/param.c+15−15
@@ -167,19 +167,19 @@ static int devlink_param_set(struct devlink *devlink, · 166 unmodified lines
167167 }
168168
169169 static int
170−devlink_param_type_to_nla_type(enum devlink_param_type param_type)
170+devlink_param_type_to_var_attr_type(enum devlink_param_type param_type)
171171 {
172172 switch (param_type) {
173173 case DEVLINK_PARAM_TYPE_U8:
174− return NLA_U8;
174+ return DEVLINK_VAR_ATTR_TYPE_U8;
175175 case DEVLINK_PARAM_TYPE_U16:
176− return NLA_U16;
176+ return DEVLINK_VAR_ATTR_TYPE_U16;
177177 case DEVLINK_PARAM_TYPE_U32:
178− return NLA_U32;
178+ return DEVLINK_VAR_ATTR_TYPE_U32;
179179 case DEVLINK_PARAM_TYPE_STRING:
180− return NLA_STRING;
180+ return DEVLINK_VAR_ATTR_TYPE_STRING;
181181 case DEVLINK_PARAM_TYPE_BOOL:
182− return NLA_FLAG;
182+ return DEVLINK_VAR_ATTR_TYPE_FLAG;
183183 default:
184184 return -EINVAL;
185185 }
@@ -247,7 +247,7 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, · 61 unmodified lines
247247 struct devlink_param_gset_ctx ctx;
248248 struct nlattr *param_values_list;
249249 struct nlattr *param_attr;
250− int nla_type;
250+ int var_attr_type;
251251 void *hdr;
252252 int err;
253253 int i;
@@ -294,10 +294,10 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, · 40 unmodified lines
294294 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
295295 goto param_nest_cancel;
296296
297− nla_type = devlink_param_type_to_nla_type(param->type);
298− if (nla_type < 0)
297+ var_attr_type = devlink_param_type_to_var_attr_type(param->type);
298+ if (var_attr_type < 0)
299299 goto param_nest_cancel;
300− if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
300+ if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, var_attr_type))
301301 goto param_nest_cancel;
302302
303303 param_values_list = nla_nest_start_noflag(msg,
@@ -420,19 +420,19 @@ devlink_param_type_get_from_info(struct genl_info *info, · 116 unmodified lines
420420 return -EINVAL;
421421
422422 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
423− case NLA_U8:
423+ case DEVLINK_VAR_ATTR_TYPE_U8:
424424 *param_type = DEVLINK_PARAM_TYPE_U8;
425425 break;
426− case NLA_U16:
426+ case DEVLINK_VAR_ATTR_TYPE_U16:
427427 *param_type = DEVLINK_PARAM_TYPE_U16;
428428 break;
429− case NLA_U32:
429+ case DEVLINK_VAR_ATTR_TYPE_U32:
430430 *param_type = DEVLINK_PARAM_TYPE_U32;
431431 break;
432− case NLA_STRING:
432+ case DEVLINK_VAR_ATTR_TYPE_STRING:
433433 *param_type = DEVLINK_PARAM_TYPE_STRING;
434434 break;
435− case NLA_FLAG:
435+ case DEVLINK_VAR_ATTR_TYPE_FLAG:
436436 *param_type = DEVLINK_PARAM_TYPE_BOOL;
437437 break;
438438 default: