diff options
author | Moshe Shemesh <moshe@mellanox.com> | 2018-07-04 07:30:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-07-05 06:58:35 -0400 |
commit | e3b7ca18ad7b2f47ebd3b6e6ce58a42c6ec24746 (patch) | |
tree | c7c71c7baef0f531561d190862a1cd2f9be68c42 /net | |
parent | 45f05def5c44c806f094709f1c9b03dcecdd54f0 (diff) |
devlink: Add param set command
Add param set command to set value for a parameter.
Value can be set to any of the supported configuration modes.
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/devlink.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/net/core/devlink.c b/net/core/devlink.c index b22d41275f0b..0cd7a42dcec2 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c | |||
@@ -2661,6 +2661,15 @@ static int devlink_param_get(struct devlink *devlink, | |||
2661 | return param->get(devlink, param->id, ctx); | 2661 | return param->get(devlink, param->id, ctx); |
2662 | } | 2662 | } |
2663 | 2663 | ||
2664 | static int devlink_param_set(struct devlink *devlink, | ||
2665 | const struct devlink_param *param, | ||
2666 | struct devlink_param_gset_ctx *ctx) | ||
2667 | { | ||
2668 | if (!param->set) | ||
2669 | return -EOPNOTSUPP; | ||
2670 | return param->set(devlink, param->id, ctx); | ||
2671 | } | ||
2672 | |||
2664 | static int | 2673 | static int |
2665 | devlink_param_type_to_nla_type(enum devlink_param_type param_type) | 2674 | devlink_param_type_to_nla_type(enum devlink_param_type param_type) |
2666 | { | 2675 | { |
@@ -2847,6 +2856,69 @@ out: | |||
2847 | return msg->len; | 2856 | return msg->len; |
2848 | } | 2857 | } |
2849 | 2858 | ||
2859 | static int | ||
2860 | devlink_param_type_get_from_info(struct genl_info *info, | ||
2861 | enum devlink_param_type *param_type) | ||
2862 | { | ||
2863 | if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE]) | ||
2864 | return -EINVAL; | ||
2865 | |||
2866 | switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) { | ||
2867 | case NLA_U8: | ||
2868 | *param_type = DEVLINK_PARAM_TYPE_U8; | ||
2869 | break; | ||
2870 | case NLA_U16: | ||
2871 | *param_type = DEVLINK_PARAM_TYPE_U16; | ||
2872 | break; | ||
2873 | case NLA_U32: | ||
2874 | *param_type = DEVLINK_PARAM_TYPE_U32; | ||
2875 | break; | ||
2876 | case NLA_STRING: | ||
2877 | *param_type = DEVLINK_PARAM_TYPE_STRING; | ||
2878 | break; | ||
2879 | case NLA_FLAG: | ||
2880 | *param_type = DEVLINK_PARAM_TYPE_BOOL; | ||
2881 | break; | ||
2882 | default: | ||
2883 | return -EINVAL; | ||
2884 | } | ||
2885 | |||
2886 | return 0; | ||
2887 | } | ||
2888 | |||
2889 | static int | ||
2890 | devlink_param_value_get_from_info(const struct devlink_param *param, | ||
2891 | struct genl_info *info, | ||
2892 | union devlink_param_value *value) | ||
2893 | { | ||
2894 | if (param->type != DEVLINK_PARAM_TYPE_BOOL && | ||
2895 | !info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) | ||
2896 | return -EINVAL; | ||
2897 | |||
2898 | switch (param->type) { | ||
2899 | case DEVLINK_PARAM_TYPE_U8: | ||
2900 | value->vu8 = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); | ||
2901 | break; | ||
2902 | case DEVLINK_PARAM_TYPE_U16: | ||
2903 | value->vu16 = nla_get_u16(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); | ||
2904 | break; | ||
2905 | case DEVLINK_PARAM_TYPE_U32: | ||
2906 | value->vu32 = nla_get_u32(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); | ||
2907 | break; | ||
2908 | case DEVLINK_PARAM_TYPE_STRING: | ||
2909 | if (nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) > | ||
2910 | DEVLINK_PARAM_MAX_STRING_VALUE) | ||
2911 | return -EINVAL; | ||
2912 | value->vstr = nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); | ||
2913 | break; | ||
2914 | case DEVLINK_PARAM_TYPE_BOOL: | ||
2915 | value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ? | ||
2916 | true : false; | ||
2917 | break; | ||
2918 | } | ||
2919 | return 0; | ||
2920 | } | ||
2921 | |||
2850 | static struct devlink_param_item * | 2922 | static struct devlink_param_item * |
2851 | devlink_param_get_from_info(struct devlink *devlink, | 2923 | devlink_param_get_from_info(struct devlink *devlink, |
2852 | struct genl_info *info) | 2924 | struct genl_info *info) |
@@ -2887,6 +2959,58 @@ static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb, | |||
2887 | return genlmsg_reply(msg, info); | 2959 | return genlmsg_reply(msg, info); |
2888 | } | 2960 | } |
2889 | 2961 | ||
2962 | static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb, | ||
2963 | struct genl_info *info) | ||
2964 | { | ||
2965 | struct devlink *devlink = info->user_ptr[0]; | ||
2966 | enum devlink_param_type param_type; | ||
2967 | struct devlink_param_gset_ctx ctx; | ||
2968 | enum devlink_param_cmode cmode; | ||
2969 | struct devlink_param_item *param_item; | ||
2970 | const struct devlink_param *param; | ||
2971 | union devlink_param_value value; | ||
2972 | int err = 0; | ||
2973 | |||
2974 | param_item = devlink_param_get_from_info(devlink, info); | ||
2975 | if (!param_item) | ||
2976 | return -EINVAL; | ||
2977 | param = param_item->param; | ||
2978 | err = devlink_param_type_get_from_info(info, ¶m_type); | ||
2979 | if (err) | ||
2980 | return err; | ||
2981 | if (param_type != param->type) | ||
2982 | return -EINVAL; | ||
2983 | err = devlink_param_value_get_from_info(param, info, &value); | ||
2984 | if (err) | ||
2985 | return err; | ||
2986 | if (param->validate) { | ||
2987 | err = param->validate(devlink, param->id, value, info->extack); | ||
2988 | if (err) | ||
2989 | return err; | ||
2990 | } | ||
2991 | |||
2992 | if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]) | ||
2993 | return -EINVAL; | ||
2994 | cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]); | ||
2995 | if (!devlink_param_cmode_is_supported(param, cmode)) | ||
2996 | return -EOPNOTSUPP; | ||
2997 | |||
2998 | if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { | ||
2999 | param_item->driverinit_value = value; | ||
3000 | param_item->driverinit_value_valid = true; | ||
3001 | } else { | ||
3002 | if (!param->set) | ||
3003 | return -EOPNOTSUPP; | ||
3004 | ctx.val = value; | ||
3005 | ctx.cmode = cmode; | ||
3006 | err = devlink_param_set(devlink, param, &ctx); | ||
3007 | if (err) | ||
3008 | return err; | ||
3009 | } | ||
3010 | |||
3011 | return 0; | ||
3012 | } | ||
3013 | |||
2890 | static int devlink_param_register_one(struct devlink *devlink, | 3014 | static int devlink_param_register_one(struct devlink *devlink, |
2891 | const struct devlink_param *param) | 3015 | const struct devlink_param *param) |
2892 | { | 3016 | { |
@@ -2942,6 +3066,9 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { | |||
2942 | [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, | 3066 | [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, |
2943 | [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64}, | 3067 | [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64}, |
2944 | [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64}, | 3068 | [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64}, |
3069 | [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING }, | ||
3070 | [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 }, | ||
3071 | [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 }, | ||
2945 | }; | 3072 | }; |
2946 | 3073 | ||
2947 | static const struct genl_ops devlink_nl_ops[] = { | 3074 | static const struct genl_ops devlink_nl_ops[] = { |
@@ -3133,6 +3260,13 @@ static const struct genl_ops devlink_nl_ops[] = { | |||
3133 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, | 3260 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, |
3134 | /* can be retrieved by unprivileged users */ | 3261 | /* can be retrieved by unprivileged users */ |
3135 | }, | 3262 | }, |
3263 | { | ||
3264 | .cmd = DEVLINK_CMD_PARAM_SET, | ||
3265 | .doit = devlink_nl_cmd_param_set_doit, | ||
3266 | .policy = devlink_nl_policy, | ||
3267 | .flags = GENL_ADMIN_PERM, | ||
3268 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, | ||
3269 | }, | ||
3136 | }; | 3270 | }; |
3137 | 3271 | ||
3138 | static struct genl_family devlink_nl_family __ro_after_init = { | 3272 | static struct genl_family devlink_nl_family __ro_after_init = { |