Skip to content

Commit

Permalink
devlink: Add port param get command
Browse files Browse the repository at this point in the history
Add port param get command which gets data per parameter.
It also has option to dump the parameters data per port.

v7->v8: Append "Acked-by: Jiri Pirko <jiri@mellanox.com>"

Cc: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Vasundhara Volam authored and David S. Miller committed Jan 30, 2019
1 parent 39e6160 commit f4601de
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 7 deletions.
2 changes: 2 additions & 0 deletions include/uapi/linux/devlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ enum devlink_command {
DEVLINK_CMD_REGION_DEL,
DEVLINK_CMD_REGION_READ,

DEVLINK_CMD_PORT_PARAM_GET, /* can dump */

/* add new commands above here */
__DEVLINK_CMD_MAX,
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
Expand Down
102 changes: 95 additions & 7 deletions net/core/devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -2843,6 +2843,7 @@ devlink_nl_param_value_fill_one(struct sk_buff *msg,
}

static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
unsigned int port_index,
struct devlink_param_item *param_item,
enum devlink_command cmd,
u32 portid, u32 seq, int flags)
Expand Down Expand Up @@ -2880,6 +2881,11 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,

if (devlink_nl_put_handle(msg, devlink))
goto genlmsg_cancel;

if (cmd == DEVLINK_CMD_PORT_PARAM_GET)
if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
goto genlmsg_cancel;

param_attr = nla_nest_start(msg, DEVLINK_ATTR_PARAM);
if (!param_attr)
goto genlmsg_cancel;
Expand Down Expand Up @@ -2933,7 +2939,7 @@ static void devlink_param_notify(struct devlink *devlink,
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return;
err = devlink_nl_param_fill(msg, devlink, param_item, cmd, 0, 0, 0);
err = devlink_nl_param_fill(msg, devlink, 0, param_item, cmd, 0, 0, 0);
if (err) {
nlmsg_free(msg);
return;
Expand Down Expand Up @@ -2962,7 +2968,7 @@ static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
idx++;
continue;
}
err = devlink_nl_param_fill(msg, devlink, param_item,
err = devlink_nl_param_fill(msg, devlink, 0, param_item,
DEVLINK_CMD_PARAM_GET,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
Expand Down Expand Up @@ -3051,7 +3057,7 @@ devlink_param_value_get_from_info(const struct devlink_param *param,
}

static struct devlink_param_item *
devlink_param_get_from_info(struct devlink *devlink,
devlink_param_get_from_info(struct list_head *param_list,
struct genl_info *info)
{
char *param_name;
Expand All @@ -3060,7 +3066,7 @@ devlink_param_get_from_info(struct devlink *devlink,
return NULL;

param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
return devlink_param_find_by_name(&devlink->param_list, param_name);
return devlink_param_find_by_name(param_list, param_name);
}

static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
Expand All @@ -3071,15 +3077,15 @@ static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
struct sk_buff *msg;
int err;

param_item = devlink_param_get_from_info(devlink, info);
param_item = devlink_param_get_from_info(&devlink->param_list, info);
if (!param_item)
return -EINVAL;

msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;

err = devlink_nl_param_fill(msg, devlink, param_item,
err = devlink_nl_param_fill(msg, devlink, 0, param_item,
DEVLINK_CMD_PARAM_GET,
info->snd_portid, info->snd_seq, 0);
if (err) {
Expand All @@ -3102,7 +3108,7 @@ static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
union devlink_param_value value;
int err = 0;

param_item = devlink_param_get_from_info(devlink, info);
param_item = devlink_param_get_from_info(&devlink->param_list, info);
if (!param_item)
return -EINVAL;
param = param_item->param;
Expand Down Expand Up @@ -3183,6 +3189,80 @@ static void devlink_param_unregister_one(struct devlink *devlink,
kfree(param_item);
}

static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
struct netlink_callback *cb)
{
struct devlink_param_item *param_item;
struct devlink_port *devlink_port;
struct devlink *devlink;
int start = cb->args[0];
int idx = 0;
int err;

mutex_lock(&devlink_mutex);
list_for_each_entry(devlink, &devlink_list, list) {
if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
continue;
mutex_lock(&devlink->lock);
list_for_each_entry(devlink_port, &devlink->port_list, list) {
list_for_each_entry(param_item,
&devlink_port->param_list, list) {
if (idx < start) {
idx++;
continue;
}
err = devlink_nl_param_fill(msg,
devlink_port->devlink,
devlink_port->index, param_item,
DEVLINK_CMD_PORT_PARAM_GET,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
NLM_F_MULTI);
if (err) {
mutex_unlock(&devlink->lock);
goto out;
}
idx++;
}
}
mutex_unlock(&devlink->lock);
}
out:
mutex_unlock(&devlink_mutex);

cb->args[0] = idx;
return msg->len;
}

static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
struct genl_info *info)
{
struct devlink_port *devlink_port = info->user_ptr[0];
struct devlink_param_item *param_item;
struct sk_buff *msg;
int err;

param_item = devlink_param_get_from_info(&devlink_port->param_list,
info);
if (!param_item)
return -EINVAL;

msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;

err = devlink_nl_param_fill(msg, devlink_port->devlink,
devlink_port->index, param_item,
DEVLINK_CMD_PORT_PARAM_GET,
info->snd_portid, info->snd_seq, 0);
if (err) {
nlmsg_free(msg);
return err;
}

return genlmsg_reply(msg, info);
}

static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
struct devlink *devlink,
struct devlink_snapshot *snapshot)
Expand Down Expand Up @@ -3820,6 +3900,14 @@ static const struct genl_ops devlink_nl_ops[] = {
.flags = GENL_ADMIN_PERM,
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
},
{
.cmd = DEVLINK_CMD_PORT_PARAM_GET,
.doit = devlink_nl_cmd_port_param_get_doit,
.dumpit = devlink_nl_cmd_port_param_get_dumpit,
.policy = devlink_nl_policy,
.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
/* can be retrieved by unprivileged users */
},
{
.cmd = DEVLINK_CMD_REGION_GET,
.doit = devlink_nl_cmd_region_get_doit,
Expand Down

0 comments on commit f4601de

Please sign in to comment.