lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230720121829.566974-11-jiri@resnulli.us>
Date: Thu, 20 Jul 2023 14:18:28 +0200
From: Jiri Pirko <jiri@...nulli.us>
To: netdev@...r.kernel.org
Cc: kuba@...nel.org,
	pabeni@...hat.com,
	davem@...emloft.net,
	edumazet@...gle.com,
	moshe@...dia.com,
	saeedm@...dia.com,
	idosch@...dia.com,
	petrm@...dia.com
Subject: [patch net-next v2 10/11] devlink: introduce dump selector attr and use it for per-instance dumps

From: Jiri Pirko <jiri@...dia.com>

For SFs, one devlink instance per SF is created. There might be
thousands of these on a single host. When a user needs to know port
handle for specific SF, he needs to dump all devlink ports on the host
which does not scale good.

Allow user to pass devlink handle alongside the dump command
and dump only objects which are under selected devlink instance.

Introduce new attr DEVLINK_ATTR_DUMP_SELECTOR to nest the selection
attributes. This way the userspace can use maxattr to tell if dump
selector is supported by kernel or not.

Assemble netlink policy for selector attribute. If user passes attr
unknown to kernel, netlink validation errors out.

Example:
$ devlink port show
auxiliary/mlx5_core.eth.0/65535: type eth netdev eth2 flavour physical port 0 splittable false
auxiliary/mlx5_core.eth.1/131071: type eth netdev eth3 flavour physical port 1 splittable false

$ devlink port show auxiliary/mlx5_core.eth.0
auxiliary/mlx5_core.eth.0/65535: type eth netdev eth2 flavour physical port 0 splittable false

$ devlink port show auxiliary/mlx5_core.eth.1
auxiliary/mlx5_core.eth.1/131071: type eth netdev eth3 flavour physical port 1 splittable false

Signed-off-by: Jiri Pirko <jiri@...dia.com>
---
v1->v2:
- extended to patch that covers all dumpit commands
- used start() and done() callback to parse the selector attr
- changed the selector attr netlink policy to be created on fly
- changed patch description accordingly
---
 include/uapi/linux/devlink.h |  2 +
 net/devlink/devl_internal.h  |  1 +
 net/devlink/netlink.c        | 99 +++++++++++++++++++++++++++++++++++-
 3 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 3782d4219ac9..8b74686512ae 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -612,6 +612,8 @@ enum devlink_attr {
 
 	DEVLINK_ATTR_REGION_DIRECT,		/* flag */
 
+	DEVLINK_ATTR_DUMP_SELECTOR,		/* nested */
+
 	/* add new attributes above here, update the policy in devlink.c */
 
 	__DEVLINK_ATTR_MAX,
diff --git a/net/devlink/devl_internal.h b/net/devlink/devl_internal.h
index 79614b45e8ac..168d36dbc6f7 100644
--- a/net/devlink/devl_internal.h
+++ b/net/devlink/devl_internal.h
@@ -109,6 +109,7 @@ struct devlink_nl_dump_state {
 			u64 dump_ts;
 		};
 	};
+	struct nlattr **selector;
 };
 
 struct devlink_cmd {
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c
index 90497d0e1a7b..c2083398bd73 100644
--- a/net/devlink/netlink.c
+++ b/net/devlink/netlink.c
@@ -80,6 +80,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
 	[DEVLINK_ATTR_RATE_TX_PRIORITY] = { .type = NLA_U32 },
 	[DEVLINK_ATTR_RATE_TX_WEIGHT] = { .type = NLA_U32 },
 	[DEVLINK_ATTR_REGION_DIRECT] = { .type = NLA_FLAG },
+	[DEVLINK_ATTR_DUMP_SELECTOR] = { .type = NLA_NESTED },
 };
 
 struct devlink *
@@ -195,6 +196,30 @@ static const struct devlink_cmd *devl_cmds[] = {
 	[DEVLINK_CMD_SELFTESTS_GET]	= &devl_cmd_selftests_get,
 };
 
+static int devlink_nl_instance_single_dumpit(struct sk_buff *msg,
+					     struct netlink_callback *cb)
+{
+	struct devlink_nl_dump_state *state = devlink_dump_state(cb);
+	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
+	struct nlattr **selector = state->selector;
+	const struct devlink_cmd *cmd;
+	struct devlink *devlink;
+	int err;
+
+	cmd = devl_cmds[info->op.cmd];
+
+	devlink = devlink_get_from_attrs_lock(sock_net(msg->sk), selector);
+	if (IS_ERR(devlink))
+		return PTR_ERR(devlink);
+	err = cmd->dump_one(msg, devlink, cb);
+	devl_unlock(devlink);
+	devlink_put(devlink);
+
+	if (err != -EMSGSIZE)
+		return err;
+	return msg->len;
+}
+
 static int devlink_nl_instance_iter_dumpit(struct sk_buff *msg,
 					   struct netlink_callback *cb)
 {
@@ -232,6 +257,76 @@ static int devlink_nl_instance_iter_dumpit(struct sk_buff *msg,
 	return msg->len;
 }
 
+static void devlink_nl_policy_cpy(struct nla_policy *policy, unsigned int attr)
+{
+	memcpy(&policy[attr], &devlink_nl_policy[attr], sizeof(*policy));
+}
+
+static void devlink_nl_dump_selector_policy_init(const struct devlink_cmd *cmd,
+						 struct nla_policy *policy)
+{
+	devlink_nl_policy_cpy(policy, DEVLINK_ATTR_BUS_NAME);
+	devlink_nl_policy_cpy(policy, DEVLINK_ATTR_DEV_NAME);
+}
+
+static int devlink_nl_start(struct netlink_callback *cb)
+{
+	struct devlink_nl_dump_state *state = devlink_dump_state(cb);
+	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
+	struct nlattr **attrs = info->attrs;
+	const struct devlink_cmd *cmd;
+	struct nla_policy *policy;
+	struct nlattr **selector;
+	int err;
+
+	if (!attrs[DEVLINK_ATTR_DUMP_SELECTOR])
+		return 0;
+
+	selector = kzalloc(sizeof(*selector) * (DEVLINK_ATTR_MAX + 1),
+			   GFP_KERNEL);
+	if (!selector)
+		return -ENOMEM;
+	policy = kzalloc(sizeof(*policy) * (DEVLINK_ATTR_MAX + 1), GFP_KERNEL);
+	if (!policy) {
+		kfree(selector);
+		return -ENOMEM;
+	}
+
+	cmd = devl_cmds[info->op.cmd];
+	devlink_nl_dump_selector_policy_init(cmd, policy);
+	err = nla_parse_nested(selector, DEVLINK_ATTR_MAX,
+			       attrs[DEVLINK_ATTR_DUMP_SELECTOR],
+			       policy, cb->extack);
+	kfree(policy);
+	if (err) {
+		kfree(selector);
+		return err;
+	}
+
+	state->selector = selector;
+	return 0;
+}
+
+static int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
+{
+	struct devlink_nl_dump_state *state = devlink_dump_state(cb);
+	struct nlattr **selector = state->selector;
+
+	if (selector && selector[DEVLINK_ATTR_BUS_NAME] &&
+	    selector[DEVLINK_ATTR_DEV_NAME])
+		return devlink_nl_instance_single_dumpit(msg, cb);
+	else
+		return devlink_nl_instance_iter_dumpit(msg, cb);
+}
+
+static int devlink_nl_done(struct netlink_callback *cb)
+{
+	struct devlink_nl_dump_state *state = devlink_dump_state(cb);
+
+	kfree(state->selector);
+	return 0;
+}
+
 #define __DEVL_NL_OP_DO(cmd_subname, doit_subname, pre_doit_suffix, _validate,	\
 			_maxattr, _policy)					\
 	{									\
@@ -248,7 +343,9 @@ static int devlink_nl_instance_iter_dumpit(struct sk_buff *msg,
 #define __DEVL_NL_OP_DUMP(cmd_subname, _validate, _maxattr, _policy)		\
 	{									\
 		.cmd = DEVLINK_CMD_##cmd_subname,				\
-		.dumpit = devlink_nl_instance_iter_dumpit,			\
+		.start = devlink_nl_start,					\
+		.dumpit = devlink_nl_dumpit,					\
+		.done = devlink_nl_done,					\
 		.flags = GENL_CMD_CAP_DUMP,					\
 		.validate = _validate,						\
 		.maxattr = _maxattr,						\
-- 
2.41.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ