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
202 name: exception202 name: exception
203 -203 -
204 name: control204 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
205 227
206attribute-sets:228attribute-sets:
207 -229 -
@@ -498,6 +520,7 @@ attribute-sets: · 290 unmodified lines
498 -520 -
499 name: param-type521 name: param-type
500 type: u8522 type: u8
523 enum: var-attr-type
501 524
502 # TODO: fill in the attributes in between525 # TODO: fill in the attributes in between
503 526
@@ -592,6 +615,7 @@ attribute-sets: · 88 unmodified lines
592 -615 -
593 name: fmsg-obj-value-type616 name: fmsg-obj-value-type
594 type: u8617 type: u8
618 enum: var-attr-type
595 619
596 # TODO: fill in the attributes in between620 # TODO: fill in the attributes in between
597 621
include/uapi/linux/devlink.h+15−0
@@ -385,6 +385,21 @@ enum devlink_linecard_state { · 384 unmodified lines
385 DEVLINK_LINECARD_STATE_MAX = __DEVLINK_LINECARD_STATE_MAX - 1385 DEVLINK_LINECARD_STATE_MAX = __DEVLINK_LINECARD_STATE_MAX - 1
386};386};
387 387
388/* Variable attribute type. */
389enum 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
388enum devlink_attr {403enum devlink_attr {
389 /* don't change the order or add anything between, this is ABI! */404 /* don't change the order or add anything between, this is ABI! */
390 DEVLINK_ATTR_UNSPEC,405 DEVLINK_ATTR_UNSPEC,
net/devlink/health.c+15−2
@@ -930,18 +930,31 @@ EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put); · 929 unmodified lines
930static int930static int
931devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)931devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
932{932{
933 enum devlink_var_attr_type var_attr_type;
934
933 switch (msg->nla_type) {935 switch (msg->nla_type) {
934 case NLA_FLAG:936 case NLA_FLAG:
937 var_attr_type = DEVLINK_VAR_ATTR_TYPE_FLAG;
938 break;
935 case NLA_U8:939 case NLA_U8:
940 var_attr_type = DEVLINK_VAR_ATTR_TYPE_U8;
941 break;
936 case NLA_U32:942 case NLA_U32:
943 var_attr_type = DEVLINK_VAR_ATTR_TYPE_U32;
944 break;
937 case NLA_U64:945 case NLA_U64:
946 var_attr_type = DEVLINK_VAR_ATTR_TYPE_U64;
947 break;
938 case NLA_NUL_STRING:948 case NLA_NUL_STRING:
949 var_attr_type = DEVLINK_VAR_ATTR_TYPE_NUL_STRING;
950 break;
939 case NLA_BINARY:951 case NLA_BINARY:
940 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,952 var_attr_type = DEVLINK_VAR_ATTR_TYPE_BINARY;
941 msg->nla_type);953 break;
942 default:954 default:
943 return -EINVAL;955 return -EINVAL;
944 }956 }
957 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, var_attr_type);
945}958}
946 959
947static int960static int
net/devlink/netlink_gen.c+28−1
@@ -10,6 +10,33 @@ · 9 unmodified lines
10 10
11#include <uapi/linux/devlink.h>11#include <uapi/linux/devlink.h>
12 12
13/* Sparse enums validation callbacks */
14static int
15devlink_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
13/* Common nested types */40/* Common nested types */
14const struct nla_policy devlink_dl_port_function_nl_policy[DEVLINK_PORT_FN_ATTR_CAPS + 1] = {41const struct nla_policy devlink_dl_port_function_nl_policy[DEVLINK_PORT_FN_ATTR_CAPS + 1] = {
15 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY, },42 [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
273 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },300 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
274 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },301 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
275 [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING, },302 [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),
277 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = NLA_POLICY_MAX(NLA_U8, 2),304 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = NLA_POLICY_MAX(NLA_U8, 2),
278};305};
279 306
net/devlink/param.c+15−15
@@ -167,19 +167,19 @@ static int devlink_param_set(struct devlink *devlink, · 166 unmodified lines
167}167}
168 168
169static int169static int
170devlink_param_type_to_nla_type(enum devlink_param_type param_type)170devlink_param_type_to_var_attr_type(enum devlink_param_type param_type)
171{171{
172 switch (param_type) {172 switch (param_type) {
173 case DEVLINK_PARAM_TYPE_U8:173 case DEVLINK_PARAM_TYPE_U8:
174 return NLA_U8;174 return DEVLINK_VAR_ATTR_TYPE_U8;
175 case DEVLINK_PARAM_TYPE_U16:175 case DEVLINK_PARAM_TYPE_U16:
176 return NLA_U16;176 return DEVLINK_VAR_ATTR_TYPE_U16;
177 case DEVLINK_PARAM_TYPE_U32:177 case DEVLINK_PARAM_TYPE_U32:
178 return NLA_U32;178 return DEVLINK_VAR_ATTR_TYPE_U32;
179 case DEVLINK_PARAM_TYPE_STRING:179 case DEVLINK_PARAM_TYPE_STRING:
180 return NLA_STRING;180 return DEVLINK_VAR_ATTR_TYPE_STRING;
181 case DEVLINK_PARAM_TYPE_BOOL:181 case DEVLINK_PARAM_TYPE_BOOL:
182 return NLA_FLAG;182 return DEVLINK_VAR_ATTR_TYPE_FLAG;
183 default:183 default:
184 return -EINVAL;184 return -EINVAL;
185 }185 }
@@ -247,7 +247,7 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, · 61 unmodified lines
247 struct devlink_param_gset_ctx ctx;247 struct devlink_param_gset_ctx ctx;
248 struct nlattr *param_values_list;248 struct nlattr *param_values_list;
249 struct nlattr *param_attr;249 struct nlattr *param_attr;
250 int nla_type;250 int var_attr_type;
251 void *hdr;251 void *hdr;
252 int err;252 int err;
253 int i;253 int i;
@@ -294,10 +294,10 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, · 40 unmodified lines
294 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))294 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
295 goto param_nest_cancel;295 goto param_nest_cancel;
296 296
297 nla_type = devlink_param_type_to_nla_type(param->type);297 var_attr_type = devlink_param_type_to_var_attr_type(param->type);
298 if (nla_type < 0)298 if (var_attr_type < 0)
299 goto param_nest_cancel;299 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))
301 goto param_nest_cancel;301 goto param_nest_cancel;
302 302
303 param_values_list = nla_nest_start_noflag(msg,303 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
420 return -EINVAL;420 return -EINVAL;
421 421
422 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {422 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
423 case NLA_U8:423 case DEVLINK_VAR_ATTR_TYPE_U8:
424 *param_type = DEVLINK_PARAM_TYPE_U8;424 *param_type = DEVLINK_PARAM_TYPE_U8;
425 break;425 break;
426 case NLA_U16:426 case DEVLINK_VAR_ATTR_TYPE_U16:
427 *param_type = DEVLINK_PARAM_TYPE_U16;427 *param_type = DEVLINK_PARAM_TYPE_U16;
428 break;428 break;
429 case NLA_U32:429 case DEVLINK_VAR_ATTR_TYPE_U32:
430 *param_type = DEVLINK_PARAM_TYPE_U32;430 *param_type = DEVLINK_PARAM_TYPE_U32;
431 break;431 break;
432 case NLA_STRING:432 case DEVLINK_VAR_ATTR_TYPE_STRING:
433 *param_type = DEVLINK_PARAM_TYPE_STRING;433 *param_type = DEVLINK_PARAM_TYPE_STRING;
434 break;434 break;
435 case NLA_FLAG:435 case DEVLINK_VAR_ATTR_TYPE_FLAG:
436 *param_type = DEVLINK_PARAM_TYPE_BOOL;436 *param_type = DEVLINK_PARAM_TYPE_BOOL;
437 break;437 break;
438 default:438 default: