forked from mirrors/linux
		
	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. Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> Signed-off-by: Jiri Pirko <jiri@nvidia.com> Link: https://patch.msgid.link/20250505114513.53370-3-jiri@resnulli.us Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									37006af675
								
							
						
					
					
						commit
						429ac62114
					
				
					 5 changed files with 97 additions and 18 deletions
				
			
		|  | @ -202,6 +202,28 @@ definitions: | ||||||
|         name: exception |         name: exception | ||||||
|       - |       - | ||||||
|         name: control |         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: | attribute-sets: | ||||||
|   - |   - | ||||||
|  | @ -498,6 +520,7 @@ attribute-sets: | ||||||
|       - |       - | ||||||
|         name: param-type |         name: param-type | ||||||
|         type: u8 |         type: u8 | ||||||
|  |         enum: var-attr-type | ||||||
| 
 | 
 | ||||||
|       # TODO: fill in the attributes in between |       # TODO: fill in the attributes in between | ||||||
| 
 | 
 | ||||||
|  | @ -592,6 +615,7 @@ attribute-sets: | ||||||
|       - |       - | ||||||
|         name: fmsg-obj-value-type |         name: fmsg-obj-value-type | ||||||
|         type: u8 |         type: u8 | ||||||
|  |         enum: var-attr-type | ||||||
| 
 | 
 | ||||||
|       # TODO: fill in the attributes in between |       # TODO: fill in the attributes in between | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -385,6 +385,21 @@ enum devlink_linecard_state { | ||||||
| 	DEVLINK_LINECARD_STATE_MAX = __DEVLINK_LINECARD_STATE_MAX - 1 | 	DEVLINK_LINECARD_STATE_MAX = __DEVLINK_LINECARD_STATE_MAX - 1 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /* 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 { | enum devlink_attr { | ||||||
| 	/* don't change the order or add anything between, this is ABI! */ | 	/* don't change the order or add anything between, this is ABI! */ | ||||||
| 	DEVLINK_ATTR_UNSPEC, | 	DEVLINK_ATTR_UNSPEC, | ||||||
|  |  | ||||||
|  | @ -930,18 +930,31 @@ EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put); | ||||||
| static int | static int | ||||||
| devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb) | 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) { | 	switch (msg->nla_type) { | ||||||
| 	case NLA_FLAG: | 	case NLA_FLAG: | ||||||
|  | 		var_attr_type = DEVLINK_VAR_ATTR_TYPE_FLAG; | ||||||
|  | 		break; | ||||||
| 	case NLA_U8: | 	case NLA_U8: | ||||||
|  | 		var_attr_type = DEVLINK_VAR_ATTR_TYPE_U8; | ||||||
|  | 		break; | ||||||
| 	case NLA_U32: | 	case NLA_U32: | ||||||
|  | 		var_attr_type = DEVLINK_VAR_ATTR_TYPE_U32; | ||||||
|  | 		break; | ||||||
| 	case NLA_U64: | 	case NLA_U64: | ||||||
|  | 		var_attr_type = DEVLINK_VAR_ATTR_TYPE_U64; | ||||||
|  | 		break; | ||||||
| 	case NLA_NUL_STRING: | 	case NLA_NUL_STRING: | ||||||
|  | 		var_attr_type = DEVLINK_VAR_ATTR_TYPE_NUL_STRING; | ||||||
|  | 		break; | ||||||
| 	case NLA_BINARY: | 	case NLA_BINARY: | ||||||
| 		return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, | 		var_attr_type = DEVLINK_VAR_ATTR_TYPE_BINARY; | ||||||
| 				  msg->nla_type); | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 	} | 	} | ||||||
|  | 	return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, var_attr_type); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int | static int | ||||||
|  |  | ||||||
|  | @ -10,6 +10,33 @@ | ||||||
| 
 | 
 | ||||||
| #include <uapi/linux/devlink.h> | #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: | ||||||
|  | 		fallthrough; | ||||||
|  | 	case DEVLINK_VAR_ATTR_TYPE_U16: | ||||||
|  | 		fallthrough; | ||||||
|  | 	case DEVLINK_VAR_ATTR_TYPE_U32: | ||||||
|  | 		fallthrough; | ||||||
|  | 	case DEVLINK_VAR_ATTR_TYPE_U64: | ||||||
|  | 		fallthrough; | ||||||
|  | 	case DEVLINK_VAR_ATTR_TYPE_STRING: | ||||||
|  | 		fallthrough; | ||||||
|  | 	case DEVLINK_VAR_ATTR_TYPE_FLAG: | ||||||
|  | 		fallthrough; | ||||||
|  | 	case DEVLINK_VAR_ATTR_TYPE_NUL_STRING: | ||||||
|  | 		fallthrough; | ||||||
|  | 	case DEVLINK_VAR_ATTR_TYPE_BINARY: | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 	NL_SET_ERR_MSG_ATTR(extack, attr, "invalid enum value"); | ||||||
|  | 	return -EINVAL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Common nested types */ | /* Common nested types */ | ||||||
| const struct nla_policy devlink_dl_port_function_nl_policy[DEVLINK_PORT_FN_ATTR_CAPS + 1] = { | 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, }, | 	[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 | ||||||
| 	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, }, | 	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, }, | ||||||
| 	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, }, | 	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, }, | ||||||
| 	[DEVLINK_ATTR_PARAM_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), | 	[DEVLINK_ATTR_PARAM_VALUE_CMODE] = NLA_POLICY_MAX(NLA_U8, 2), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -167,19 +167,19 @@ static int devlink_param_set(struct devlink *devlink, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int | 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) { | 	switch (param_type) { | ||||||
| 	case DEVLINK_PARAM_TYPE_U8: | 	case DEVLINK_PARAM_TYPE_U8: | ||||||
| 		return NLA_U8; | 		return DEVLINK_VAR_ATTR_TYPE_U8; | ||||||
| 	case DEVLINK_PARAM_TYPE_U16: | 	case DEVLINK_PARAM_TYPE_U16: | ||||||
| 		return NLA_U16; | 		return DEVLINK_VAR_ATTR_TYPE_U16; | ||||||
| 	case DEVLINK_PARAM_TYPE_U32: | 	case DEVLINK_PARAM_TYPE_U32: | ||||||
| 		return NLA_U32; | 		return DEVLINK_VAR_ATTR_TYPE_U32; | ||||||
| 	case DEVLINK_PARAM_TYPE_STRING: | 	case DEVLINK_PARAM_TYPE_STRING: | ||||||
| 		return NLA_STRING; | 		return DEVLINK_VAR_ATTR_TYPE_STRING; | ||||||
| 	case DEVLINK_PARAM_TYPE_BOOL: | 	case DEVLINK_PARAM_TYPE_BOOL: | ||||||
| 		return NLA_FLAG; | 		return DEVLINK_VAR_ATTR_TYPE_FLAG; | ||||||
| 	default: | 	default: | ||||||
| 		return -EINVAL; | 		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 devlink_param_gset_ctx ctx; | ||||||
| 	struct nlattr *param_values_list; | 	struct nlattr *param_values_list; | ||||||
| 	struct nlattr *param_attr; | 	struct nlattr *param_attr; | ||||||
| 	int nla_type; | 	int var_attr_type; | ||||||
| 	void *hdr; | 	void *hdr; | ||||||
| 	int err; | 	int err; | ||||||
| 	int i; | 	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)) | 	if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC)) | ||||||
| 		goto param_nest_cancel; | 		goto param_nest_cancel; | ||||||
| 
 | 
 | ||||||
| 	nla_type = devlink_param_type_to_nla_type(param->type); | 	var_attr_type = devlink_param_type_to_var_attr_type(param->type); | ||||||
| 	if (nla_type < 0) | 	if (var_attr_type < 0) | ||||||
| 		goto param_nest_cancel; | 		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; | 		goto param_nest_cancel; | ||||||
| 
 | 
 | ||||||
| 	param_values_list = nla_nest_start_noflag(msg, | 	param_values_list = nla_nest_start_noflag(msg, | ||||||
|  | @ -420,19 +420,19 @@ devlink_param_type_get_from_info(struct genl_info *info, | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 
 | 
 | ||||||
| 	switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) { | 	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; | 		*param_type = DEVLINK_PARAM_TYPE_U8; | ||||||
| 		break; | 		break; | ||||||
| 	case NLA_U16: | 	case DEVLINK_VAR_ATTR_TYPE_U16: | ||||||
| 		*param_type = DEVLINK_PARAM_TYPE_U16; | 		*param_type = DEVLINK_PARAM_TYPE_U16; | ||||||
| 		break; | 		break; | ||||||
| 	case NLA_U32: | 	case DEVLINK_VAR_ATTR_TYPE_U32: | ||||||
| 		*param_type = DEVLINK_PARAM_TYPE_U32; | 		*param_type = DEVLINK_PARAM_TYPE_U32; | ||||||
| 		break; | 		break; | ||||||
| 	case NLA_STRING: | 	case DEVLINK_VAR_ATTR_TYPE_STRING: | ||||||
| 		*param_type = DEVLINK_PARAM_TYPE_STRING; | 		*param_type = DEVLINK_PARAM_TYPE_STRING; | ||||||
| 		break; | 		break; | ||||||
| 	case NLA_FLAG: | 	case DEVLINK_VAR_ATTR_TYPE_FLAG: | ||||||
| 		*param_type = DEVLINK_PARAM_TYPE_BOOL; | 		*param_type = DEVLINK_PARAM_TYPE_BOOL; | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jiri Pirko
						Jiri Pirko