Netdev Archive mirror
 help / color / mirror / Atom feed
* [patch iproute2-next v2 0/6] devlink: implement dump selector for devlink objects show commands
@ 2023-09-06 11:11 Jiri Pirko
  2023-09-06 11:11 ` [patch iproute2-next v2 1/6] devlink: move DL_OPT_SB into required options Jiri Pirko
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Jiri Pirko @ 2023-09-06 11:11 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern

From: Jiri Pirko <jiri@nvidia.com>

First 5 patches are preparations for the last one.

Motivation:

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.

Solution:

Allow user to pass devlink handle (and possibly other attributes)
alongside the dump command and dump only objects which are matching
the selection.

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

Jiri Pirko (6):
  devlink: move DL_OPT_SB into required options
  devlink: make parsing of handle non-destructive to argv
  devlink: implement command line args dry parsing
  devlink: return -ENOENT if argument is missing
  mnl_utils: introduce a helper to check if dump policy exists for
    command
  devlink: implement dump selector for devlink objects show commands

 devlink/devlink.c   | 382 ++++++++++++++++++++++++++------------------
 include/mnl_utils.h |   1 +
 lib/mnl_utils.c     | 121 +++++++++++++-
 3 files changed, 345 insertions(+), 159 deletions(-)

-- 
2.41.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [patch iproute2-next v2 1/6] devlink: move DL_OPT_SB into required options
  2023-09-06 11:11 [patch iproute2-next v2 0/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
@ 2023-09-06 11:11 ` Jiri Pirko
  2023-09-06 11:11 ` [patch iproute2-next v2 2/6] devlink: make parsing of handle non-destructive to argv Jiri Pirko
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jiri Pirko @ 2023-09-06 11:11 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern

From: Jiri Pirko <jiri@nvidia.com>

This is basically a cosmetic change. The SB index is not required to be
passed by user and implicitly index 0 is used. This is ensured by
special treating at the end of dl_argv_parse(). Move this option from
optional to required options.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v1->v2:
- fixed o_found bit set
---
 devlink/devlink.c | 41 ++++++++++++++++++++---------------------
 1 file changed, 20 insertions(+), 21 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 616720a9051f..6643f659a8bd 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2269,13 +2269,13 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
 		}
 	}
 
-	opts->present = o_found;
-
-	if ((o_optional & DL_OPT_SB) && !(o_found & DL_OPT_SB)) {
+	if ((o_required & DL_OPT_SB) && !(o_found & DL_OPT_SB)) {
 		opts->sb_index = 0;
-		opts->present |= DL_OPT_SB;
+		o_found |= DL_OPT_SB;
 	}
 
+	opts->present = o_found;
+
 	return dl_args_finding_required_validate(o_required, o_found);
 }
 
@@ -5721,7 +5721,7 @@ static int cmd_sb_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_SB);
+		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB, 0);
 		if (err)
 			return err;
 	}
@@ -5800,8 +5800,8 @@ static int cmd_sb_pool_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB_POOL,
-				    DL_OPT_SB);
+		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB |
+				    DL_OPT_SB_POOL, 0);
 		if (err)
 			return err;
 	}
@@ -5821,8 +5821,8 @@ static int cmd_sb_pool_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB_POOL |
-			    DL_OPT_SB_SIZE | DL_OPT_SB_THTYPE, DL_OPT_SB);
+	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB | DL_OPT_SB_POOL |
+			    DL_OPT_SB_SIZE | DL_OPT_SB_THTYPE, 0);
 	if (err)
 		return err;
 
@@ -5889,8 +5889,8 @@ static int cmd_sb_port_pool_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB_POOL,
-				    DL_OPT_SB);
+		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB |
+				    DL_OPT_SB_POOL, 0);
 		if (err)
 			return err;
 	}
@@ -5910,8 +5910,8 @@ static int cmd_sb_port_pool_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB_POOL | DL_OPT_SB_TH,
-			    DL_OPT_SB);
+	err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB | DL_OPT_SB_POOL |
+			    DL_OPT_SB_TH, 0);
 	if (err)
 		return err;
 
@@ -5996,8 +5996,8 @@ static int cmd_sb_tc_bind_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB_TC |
-				    DL_OPT_SB_TYPE, DL_OPT_SB);
+		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB | DL_OPT_SB_TC |
+				    DL_OPT_SB_TYPE, 0);
 		if (err)
 			return err;
 	}
@@ -6017,9 +6017,8 @@ static int cmd_sb_tc_bind_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB_TC |
-			    DL_OPT_SB_TYPE | DL_OPT_SB_POOL | DL_OPT_SB_TH,
-			    DL_OPT_SB);
+	err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB | DL_OPT_SB_TC |
+			    DL_OPT_SB_TYPE | DL_OPT_SB_POOL | DL_OPT_SB_TH, 0);
 	if (err)
 		return err;
 
@@ -6338,7 +6337,7 @@ static int cmd_sb_occ_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HANDLEP, DL_OPT_SB);
+	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_SB, 0);
 	if (err)
 		return err;
 
@@ -6374,7 +6373,7 @@ static int cmd_sb_occ_snapshot(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_SB);
+	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB, 0);
 	if (err)
 		return err;
 
@@ -6391,7 +6390,7 @@ static int cmd_sb_occ_clearmax(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_SB);
+	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB, 0);
 	if (err)
 		return err;
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [patch iproute2-next v2 2/6] devlink: make parsing of handle non-destructive to argv
  2023-09-06 11:11 [patch iproute2-next v2 0/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
  2023-09-06 11:11 ` [patch iproute2-next v2 1/6] devlink: move DL_OPT_SB into required options Jiri Pirko
@ 2023-09-06 11:11 ` Jiri Pirko
  2023-09-06 11:11 ` [patch iproute2-next v2 3/6] devlink: implement command line args dry parsing Jiri Pirko
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jiri Pirko @ 2023-09-06 11:11 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern

From: Jiri Pirko <jiri@nvidia.com>

Currently, handle parsing is destructive as the "\0" string ends are
being put in certain positions during parsing. That prevents it from
being used repeatedly. This is problematic with the follow-up patch
implementing dry-parsing. Fix by making a copy of handle argv during
parsing.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 devlink/devlink.c | 46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 6643f659a8bd..f383028ec560 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -378,6 +378,7 @@ struct dl {
 	struct list_head ifname_map_list;
 	int argc;
 	char **argv;
+	char *handle_argv;
 	bool no_nice_names;
 	struct dl_opts opts;
 	bool json_output;
@@ -1066,9 +1067,8 @@ static int __dl_argv_handle(char *str, char **p_bus_name, char **p_dev_name)
 	return 0;
 }
 
-static int dl_argv_handle(struct dl *dl, char **p_bus_name, char **p_dev_name)
+static int dl_argv_handle(char *str, char **p_bus_name, char **p_dev_name)
 {
-	char *str = dl_argv_next(dl);
 	int err;
 
 	err = ident_str_validate(str, 1);
@@ -1121,10 +1121,9 @@ static int __dl_argv_handle_port_ifname(struct dl *dl, char *str,
 	return 0;
 }
 
-static int dl_argv_handle_port(struct dl *dl, char **p_bus_name,
+static int dl_argv_handle_port(struct dl *dl, char *str, char **p_bus_name,
 			       char **p_dev_name, uint32_t *p_port_index)
 {
-	char *str = dl_argv_next(dl);
 	unsigned int slash_count;
 
 	if (!str) {
@@ -1146,11 +1145,10 @@ static int dl_argv_handle_port(struct dl *dl, char **p_bus_name,
 	}
 }
 
-static int dl_argv_handle_both(struct dl *dl, char **p_bus_name,
+static int dl_argv_handle_both(struct dl *dl, char *str, char **p_bus_name,
 			       char **p_dev_name, uint32_t *p_port_index,
 			       uint64_t *p_handle_bit)
 {
-	char *str = dl_argv_next(dl);
 	unsigned int slash_count;
 	int err;
 
@@ -1199,10 +1197,9 @@ static int __dl_argv_handle_name(char *str, char **p_bus_name,
 	return str_split_by_char(handlestr, p_bus_name, p_dev_name, '/');
 }
 
-static int dl_argv_handle_region(struct dl *dl, char **p_bus_name,
+static int dl_argv_handle_region(char *str, char **p_bus_name,
 				 char **p_dev_name, char **p_region)
 {
-	char *str = dl_argv_next(dl);
 	int err;
 
 	err = ident_str_validate(str, 2);
@@ -1218,10 +1215,9 @@ static int dl_argv_handle_region(struct dl *dl, char **p_bus_name,
 }
 
 
-static int dl_argv_handle_rate_node(struct dl *dl, char **p_bus_name,
+static int dl_argv_handle_rate_node(char *str, char **p_bus_name,
 				    char **p_dev_name, char **p_node)
 {
-	char *str = dl_argv_next(dl);
 	int err;
 
 	err = ident_str_validate(str, 2);
@@ -1244,11 +1240,10 @@ static int dl_argv_handle_rate_node(struct dl *dl, char **p_bus_name,
 	return err;
 }
 
-static int dl_argv_handle_rate(struct dl *dl, char **p_bus_name,
+static int dl_argv_handle_rate(char *str, char **p_bus_name,
 			       char **p_dev_name, uint32_t *p_port_index,
 			       char **p_node_name, uint64_t *p_handle_bit)
 {
-	char *str = dl_argv_next(dl);
 	char *identifier;
 	int err;
 
@@ -1698,14 +1693,24 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
 {
 	struct dl_opts *opts = &dl->opts;
 	uint64_t o_all = o_required | o_optional;
+	char *str = dl_argv_next(dl);
 	uint64_t o_found = 0;
 	int err;
 
+	if (str) {
+		str = strdup(str);
+		if (!str)
+			return -ENOMEM;
+		free(dl->handle_argv);
+		dl->handle_argv = str;
+	}
+
 	if (o_required & DL_OPT_HANDLE && o_required & DL_OPT_HANDLEP) {
 		uint64_t handle_bit;
 
-		err = dl_argv_handle_both(dl, &opts->bus_name, &opts->dev_name,
-					  &opts->port_index, &handle_bit);
+		err = dl_argv_handle_both(dl, str, &opts->bus_name,
+					  &opts->dev_name, &opts->port_index,
+					  &handle_bit);
 		if (err)
 			return err;
 		o_required &= ~(DL_OPT_HANDLE | DL_OPT_HANDLEP) | handle_bit;
@@ -1714,7 +1719,7 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
 		   o_required & DL_OPT_PORT_FN_RATE_NODE_NAME) {
 		uint64_t handle_bit;
 
-		err = dl_argv_handle_rate(dl, &opts->bus_name, &opts->dev_name,
+		err = dl_argv_handle_rate(str, &opts->bus_name, &opts->dev_name,
 					  &opts->port_index,
 					  &opts->rate_node_name,
 					  &handle_bit);
@@ -1724,25 +1729,25 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
 			handle_bit;
 		o_found |= handle_bit;
 	} else if (o_required & DL_OPT_HANDLE) {
-		err = dl_argv_handle(dl, &opts->bus_name, &opts->dev_name);
+		err = dl_argv_handle(str, &opts->bus_name, &opts->dev_name);
 		if (err)
 			return err;
 		o_found |= DL_OPT_HANDLE;
 	} else if (o_required & DL_OPT_HANDLEP) {
-		err = dl_argv_handle_port(dl, &opts->bus_name, &opts->dev_name,
-					  &opts->port_index);
+		err = dl_argv_handle_port(dl, str, &opts->bus_name,
+					  &opts->dev_name, &opts->port_index);
 		if (err)
 			return err;
 		o_found |= DL_OPT_HANDLEP;
 	} else if (o_required & DL_OPT_HANDLE_REGION) {
-		err = dl_argv_handle_region(dl, &opts->bus_name,
+		err = dl_argv_handle_region(str, &opts->bus_name,
 					    &opts->dev_name,
 					    &opts->region_name);
 		if (err)
 			return err;
 		o_found |= DL_OPT_HANDLE_REGION;
 	} else if (o_required & DL_OPT_PORT_FN_RATE_NODE_NAME) {
-		err = dl_argv_handle_rate_node(dl, &opts->bus_name,
+		err = dl_argv_handle_rate_node(str, &opts->bus_name,
 					       &opts->dev_name,
 					       &opts->rate_node_name);
 		if (err)
@@ -9902,6 +9907,7 @@ static struct dl *dl_alloc(void)
 
 static void dl_free(struct dl *dl)
 {
+	free(dl->handle_argv);
 	free(dl);
 }
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [patch iproute2-next v2 3/6] devlink: implement command line args dry parsing
  2023-09-06 11:11 [patch iproute2-next v2 0/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
  2023-09-06 11:11 ` [patch iproute2-next v2 1/6] devlink: move DL_OPT_SB into required options Jiri Pirko
  2023-09-06 11:11 ` [patch iproute2-next v2 2/6] devlink: make parsing of handle non-destructive to argv Jiri Pirko
@ 2023-09-06 11:11 ` Jiri Pirko
  2023-09-06 11:11 ` [patch iproute2-next v2 4/6] devlink: return -ENOENT if argument is missing Jiri Pirko
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jiri Pirko @ 2023-09-06 11:11 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern

From: Jiri Pirko <jiri@nvidia.com>

In preparation to the follow-up dump selector patch, introduce function
dl_argv_dry_parse() which allows to do dry parsing of command line
arguments without printing out any error messages to the user.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 devlink/devlink.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index f383028ec560..083a30d7536c 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -64,6 +64,7 @@
 static int g_new_line_count;
 static int g_indent_level;
 static bool g_indent_newline;
+static bool g_err_suspended;
 
 #define INDENT_STR_STEP 2
 #define INDENT_STR_MAXLEN 32
@@ -74,6 +75,8 @@ pr_err(const char *fmt, ...)
 {
 	va_list ap;
 
+	if (g_err_suspended)
+		return;
 	va_start(ap, fmt);
 	vfprintf(stderr, fmt, ap);
 	va_end(ap);
@@ -2284,6 +2287,21 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
 	return dl_args_finding_required_validate(o_required, o_found);
 }
 
+static int dl_argv_dry_parse(struct dl *dl, uint64_t o_required,
+			     uint64_t o_optional)
+{
+	char **argv = dl->argv;
+	int argc = dl->argc;
+	int err;
+
+	g_err_suspended = true;
+	err = dl_argv_parse(dl, o_required, o_optional);
+	g_err_suspended = false;
+	dl->argv = argv;
+	dl->argc = argc;
+	return err;
+}
+
 static void
 dl_function_attr_put(struct nlmsghdr *nlh, const struct dl_opts *opts)
 {
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [patch iproute2-next v2 4/6] devlink: return -ENOENT if argument is missing
  2023-09-06 11:11 [patch iproute2-next v2 0/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
                   ` (2 preceding siblings ...)
  2023-09-06 11:11 ` [patch iproute2-next v2 3/6] devlink: implement command line args dry parsing Jiri Pirko
@ 2023-09-06 11:11 ` Jiri Pirko
  2023-09-06 11:11 ` [patch iproute2-next v2 5/6] mnl_utils: introduce a helper to check if dump policy exists for command Jiri Pirko
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jiri Pirko @ 2023-09-06 11:11 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern

From: Jiri Pirko <jiri@nvidia.com>

In preparation to the follow-up dump selector patch, make sure that the
command line arguments parsing function returns -ENOENT in case the
option is missing so the caller can distinguish.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 devlink/devlink.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 083a30d7536c..7888173fb4bc 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -1048,7 +1048,7 @@ static int strtobool(const char *str, bool *p_val)
 static int ident_str_validate(char *str, unsigned int expected)
 {
 	if (!str)
-		return -EINVAL;
+		return -ENOENT;
 
 	if (get_str_char_count(str, '/') != expected) {
 		pr_err("Wrong identification string format.\n");
@@ -1131,7 +1131,7 @@ static int dl_argv_handle_port(struct dl *dl, char *str, char **p_bus_name,
 
 	if (!str) {
 		pr_err("Port identification (\"bus_name/dev_name/port_index\" or \"netdev ifname\") expected.\n");
-		return -EINVAL;
+		return -ENOENT;
 	}
 	slash_count = get_str_char_count(str, '/');
 	switch (slash_count) {
@@ -1159,7 +1159,7 @@ static int dl_argv_handle_both(struct dl *dl, char *str, char **p_bus_name,
 		pr_err("One of following identifications expected:\n"
 		       "Devlink identification (\"bus_name/dev_name\")\n"
 		       "Port identification (\"bus_name/dev_name/port_index\" or \"netdev ifname\")\n");
-		return -EINVAL;
+		return -ENOENT;
 	}
 	slash_count = get_str_char_count(str, '/');
 	if (slash_count == 1) {
@@ -1681,7 +1681,7 @@ static int dl_args_finding_required_validate(uint64_t o_required,
 		o_flag = dl_args_required[i].o_flag;
 		if ((o_required & o_flag) && !(o_found & o_flag)) {
 			pr_err("%s\n", dl_args_required[i].err_msg);
-			return -EINVAL;
+			return -ENOENT;
 		}
 	}
 	if (o_required & ~o_found) {
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [patch iproute2-next v2 5/6] mnl_utils: introduce a helper to check if dump policy exists for command
  2023-09-06 11:11 [patch iproute2-next v2 0/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
                   ` (3 preceding siblings ...)
  2023-09-06 11:11 ` [patch iproute2-next v2 4/6] devlink: return -ENOENT if argument is missing Jiri Pirko
@ 2023-09-06 11:11 ` Jiri Pirko
  2023-09-06 11:11 ` [patch iproute2-next v2 6/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
  2023-09-11 15:50 ` [patch iproute2-next v2 0/6] " patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: Jiri Pirko @ 2023-09-06 11:11 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern

From: Jiri Pirko <jiri@nvidia.com>

Benefit from GET_POLICY command of ctrl netlink and introduce a helper
that dumps policies and finds out, if there is a separate policy
specified for dump op of specified command.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 include/mnl_utils.h |   1 +
 lib/mnl_utils.c     | 121 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/include/mnl_utils.h b/include/mnl_utils.h
index 2193934849e1..76fe1dfec938 100644
--- a/include/mnl_utils.h
+++ b/include/mnl_utils.h
@@ -30,5 +30,6 @@ int mnlu_socket_recv_run(struct mnl_socket *nl, unsigned int seq, void *buf, siz
 			 mnl_cb_t cb, void *data);
 int mnlu_gen_socket_recv_run(struct mnlu_gen_socket *nlg, mnl_cb_t cb,
 			     void *data);
+int mnlu_gen_cmd_dump_policy(struct mnlu_gen_socket *nlg, uint8_t cmd);
 
 #endif /* __MNL_UTILS_H__ */
diff --git a/lib/mnl_utils.c b/lib/mnl_utils.c
index f8e07d2f467f..1c78222828ff 100644
--- a/lib/mnl_utils.c
+++ b/lib/mnl_utils.c
@@ -110,7 +110,7 @@ int mnlu_socket_recv_run(struct mnl_socket *nl, unsigned int seq, void *buf, siz
 	return err;
 }
 
-static int get_family_attrs_cb(const struct nlattr *attr, void *data)
+static int ctrl_attrs_cb(const struct nlattr *attr, void *data)
 {
 	int type = mnl_attr_get_type(attr);
 	const struct nlattr **tb = data;
@@ -124,6 +124,12 @@ static int get_family_attrs_cb(const struct nlattr *attr, void *data)
 	if (type == CTRL_ATTR_MAXATTR &&
 	    mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
 		return MNL_CB_ERROR;
+	if (type == CTRL_ATTR_POLICY &&
+	    mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
+		return MNL_CB_ERROR;
+	if (type == CTRL_ATTR_OP_POLICY &&
+	    mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
+		return MNL_CB_ERROR;
 	tb[type] = attr;
 	return MNL_CB_OK;
 }
@@ -134,7 +140,7 @@ static int get_family_cb(const struct nlmsghdr *nlh, void *data)
 	struct nlattr *tb[CTRL_ATTR_MAX + 1] = {};
 	struct mnlu_gen_socket *nlg = data;
 
-	mnl_attr_parse(nlh, sizeof(*genl), get_family_attrs_cb, tb);
+	mnl_attr_parse(nlh, sizeof(*genl), ctrl_attrs_cb, tb);
 	if (!tb[CTRL_ATTR_FAMILY_ID])
 		return MNL_CB_ERROR;
 	if (!tb[CTRL_ATTR_MAXATTR])
@@ -252,3 +258,114 @@ int mnlu_gen_socket_recv_run(struct mnlu_gen_socket *nlg, mnl_cb_t cb,
 				    MNL_SOCKET_BUFFER_SIZE,
 				    cb, data);
 }
+
+static int ctrl_policy_attrs_cb(const struct nlattr *attr, void *data)
+{
+	int type = mnl_attr_get_type(attr);
+	const struct nlattr **tb = data;
+
+	if (mnl_attr_type_valid(attr, CTRL_ATTR_POLICY_DUMP_MAX) < 0)
+		return MNL_CB_ERROR;
+
+	if (type == CTRL_ATTR_POLICY_DO &&
+	    mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+		return MNL_CB_ERROR;
+	if (type == CTRL_ATTR_POLICY_DUMP &&
+	    mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+		return MNL_CB_ERROR;
+
+	tb[type] = attr;
+	return MNL_CB_OK;
+}
+
+struct cmd_dump_policy_ctx {
+	uint8_t cmd;
+	uint8_t do_policy_idx_found:1,
+		dump_policy_idx_found:1;
+	uint32_t do_policy_idx;
+	uint32_t dump_policy_idx;
+	uint32_t dump_policy_attr_count;
+};
+
+static void process_dump_op_policy_nest(const struct nlattr *op_policy_nest,
+					struct cmd_dump_policy_ctx *ctx)
+{
+	struct nlattr *tb[CTRL_ATTR_POLICY_DUMP_MAX + 1] = {};
+	const struct nlattr *attr;
+	int err;
+
+	mnl_attr_for_each_nested(attr, op_policy_nest) {
+		if (ctx->cmd != (attr->nla_type & ~NLA_F_NESTED))
+			continue;
+		err = mnl_attr_parse_nested(attr, ctrl_policy_attrs_cb, tb);
+		if (err != MNL_CB_OK)
+			continue;
+		if (tb[CTRL_ATTR_POLICY_DO]) {
+			ctx->do_policy_idx = mnl_attr_get_u32(tb[CTRL_ATTR_POLICY_DO]);
+			ctx->do_policy_idx_found = true;
+		}
+		if (tb[CTRL_ATTR_POLICY_DUMP]) {
+			ctx->dump_policy_idx = mnl_attr_get_u32(tb[CTRL_ATTR_POLICY_DUMP]);
+			ctx->dump_policy_idx_found = true;
+		}
+		break;
+	}
+}
+
+static void process_dump_policy_nest(const struct nlattr *policy_nest,
+				     struct cmd_dump_policy_ctx *ctx)
+{
+	const struct nlattr *attr;
+
+	if (!ctx->dump_policy_idx_found)
+		return;
+
+	mnl_attr_for_each_nested(attr, policy_nest)
+		if (ctx->dump_policy_idx == (attr->nla_type & ~NLA_F_NESTED))
+			ctx->dump_policy_attr_count++;
+}
+
+static int cmd_dump_policy_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+	struct nlattr *tb[CTRL_ATTR_MAX + 1] = {};
+	struct cmd_dump_policy_ctx *ctx = data;
+
+	mnl_attr_parse(nlh, sizeof(*genl), ctrl_attrs_cb, tb);
+	if (!tb[CTRL_ATTR_FAMILY_ID])
+		return MNL_CB_OK;
+
+	if (tb[CTRL_ATTR_OP_POLICY])
+		process_dump_op_policy_nest(tb[CTRL_ATTR_OP_POLICY], ctx);
+
+	if (tb[CTRL_ATTR_POLICY])
+		process_dump_policy_nest(tb[CTRL_ATTR_POLICY], ctx);
+
+	return MNL_CB_OK;
+}
+
+int mnlu_gen_cmd_dump_policy(struct mnlu_gen_socket *nlg, uint8_t cmd)
+{
+	struct cmd_dump_policy_ctx ctx = {
+		.cmd = cmd,
+	};
+	struct nlmsghdr *nlh;
+	int err;
+
+	nlh = _mnlu_gen_socket_cmd_prepare(nlg, CTRL_CMD_GETPOLICY,
+					   NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP,
+					   GENL_ID_CTRL, 1);
+
+	mnl_attr_put_u16(nlh, CTRL_ATTR_FAMILY_ID, nlg->family);
+
+	err = mnlu_gen_socket_sndrcv(nlg, nlh, cmd_dump_policy_cb, &ctx);
+	if (err)
+		return err;
+
+	if (!ctx.dump_policy_idx_found || !ctx.do_policy_idx_found ||
+	    ctx.do_policy_idx == ctx.dump_policy_idx ||
+	    !ctx.dump_policy_attr_count)
+		return -ENOTSUP;
+
+	return 0;
+}
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [patch iproute2-next v2 6/6] devlink: implement dump selector for devlink objects show commands
  2023-09-06 11:11 [patch iproute2-next v2 0/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
                   ` (4 preceding siblings ...)
  2023-09-06 11:11 ` [patch iproute2-next v2 5/6] mnl_utils: introduce a helper to check if dump policy exists for command Jiri Pirko
@ 2023-09-06 11:11 ` Jiri Pirko
  2023-09-11 15:50 ` [patch iproute2-next v2 0/6] " patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: Jiri Pirko @ 2023-09-06 11:11 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern

From: Jiri Pirko <jiri@nvidia.com>

Introduce a new helper dl_argv_parse_with_selector() to be used
by show() functions instead of dl_argv().

Implement it to check if all needed options got get commands are
specified. In case they are not, ask kernel for dump passing only
the options (attributes) that are present, creating sort of partial
key to instruct kernel to do partial dump.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 devlink/devlink.c | 283 +++++++++++++++++++++++++++-------------------
 1 file changed, 164 insertions(+), 119 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 7888173fb4bc..d1795f616ca0 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2302,6 +2302,88 @@ static int dl_argv_dry_parse(struct dl *dl, uint64_t o_required,
 	return err;
 }
 
+/* List of extented handles with two slashes. */
+static const uint64_t dl_opt_extended_handle[] = {
+	DL_OPT_HANDLEP,
+	DL_OPT_HANDLE_REGION,
+	DL_OPT_PORT_FN_RATE_NODE_NAME,
+};
+
+static int dl_argv_parse_with_selector(struct dl *dl, uint16_t *flags,
+				       uint8_t cmd,
+				       uint64_t o_required,
+				       uint64_t o_optional,
+				       uint64_t o_dump_required,
+				       uint64_t o_dump_optional)
+{
+	int err;
+	int i;
+
+	if (dl_no_arg(dl))
+		goto flag_set;
+
+	/* In case the handle suggests it, do dry parsing first
+	 * to see if all required options are there. Proceed with
+	 * dump selector in case there are missing options on the
+	 * command line. That means user provided partial
+	 * object identification.
+	 */
+
+	if ((o_required & (DL_OPT_HANDLE | DL_OPT_HANDLEP)) ==
+	    (DL_OPT_HANDLE | DL_OPT_HANDLEP)) {
+		/* Handle case when both devlink handle and port handle
+		 * are allowed. Try both alone, if parsing of either
+		 * is successful, we have a do parse case.
+		 */
+		err = dl_argv_dry_parse(dl, o_required & ~DL_OPT_HANDLEP,
+					o_optional);
+		if (err == -ENOENT)
+			goto dump_parse;
+		else if (!err)
+			goto do_parse;
+		err = dl_argv_dry_parse(dl, o_required & ~DL_OPT_HANDLE,
+					o_optional);
+		if (err == -ENOENT)
+			goto dump_parse;
+		goto do_parse;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(dl_opt_extended_handle); i++) {
+		uint64_t handle = dl_opt_extended_handle[i];
+
+		if ((o_required & handle) == handle) {
+			err = dl_argv_dry_parse(dl, (o_required & ~handle) |
+						DL_OPT_HANDLE,
+						o_optional);
+			if (err == -ENOENT || !err)
+				goto dump_parse;
+			goto do_parse;
+		}
+	}
+
+	err = dl_argv_dry_parse(dl, o_required, o_optional);
+	if (err == -ENOENT)
+		goto dump_parse;
+
+do_parse:
+	return dl_argv_parse(dl, o_required, o_optional);
+
+dump_parse:
+	err = mnlu_gen_cmd_dump_policy(&dl->nlg, cmd);
+	if (err) {
+		pr_err("Dump selectors are not supported by kernel for this command\n");
+		return -ENOTSUP;
+	}
+
+	err = dl_argv_parse(dl, o_dump_required, o_dump_optional);
+	if (err)
+		return err;
+
+flag_set:
+	*flags |= NLM_F_DUMP;
+	return 0;
+}
+
 static void
 dl_function_attr_put(struct nlmsghdr *nlh, const struct dl_opts *opts)
 {
@@ -3580,13 +3662,11 @@ static int cmd_dev_param_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	} else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_PARAM_NAME, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_PARAM_GET,
+					  DL_OPT_HANDLE | DL_OPT_PARAM_NAME, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_PARAM_GET, flags);
 
@@ -4784,14 +4864,11 @@ static int cmd_port_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_PORT_GET,
+					  DL_OPT_HANDLEP, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_PORT_GET, flags);
 
@@ -4860,14 +4937,12 @@ static int cmd_port_param_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_PARAM_NAME, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_PORT_PARAM_GET,
+					  DL_OPT_HANDLE | DL_OPT_PARAM_NAME, 0,
+					  DL_OPT_HANDLE | DL_OPT_HANDLEP, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_PORT_PARAM_GET,
 					  flags);
@@ -5234,16 +5309,9 @@ static int cmd_port_fn_rate_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLEP | DL_OPT_PORT_FN_RATE_NODE_NAME,
-				    0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_RATE_GET,
+					  DL_OPT_HANDLEP | DL_OPT_PORT_FN_RATE_NODE_NAME,
+					  0, DL_OPT_HANDLE, 0);
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_RATE_GET, flags);
 
@@ -5622,14 +5690,11 @@ static int cmd_linecard_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_LINECARD);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_LINECARD_GET,
+					  DL_OPT_HANDLE | DL_OPT_LINECARD, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_LINECARD_GET,
 					  flags);
@@ -5740,14 +5805,11 @@ static int cmd_sb_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_SB_GET,
+					  DL_OPT_HANDLE | DL_OPT_SB, 0,
+					  DL_OPT_HANDLE, DL_OPT_SB);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_SB_GET, flags);
 
@@ -5819,15 +5881,12 @@ static int cmd_sb_pool_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB |
-				    DL_OPT_SB_POOL, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_SB_POOL_GET,
+					  DL_OPT_HANDLE | DL_OPT_SB |
+					  DL_OPT_SB_POOL, 0,
+					  DL_OPT_HANDLE, DL_OPT_SB);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_SB_POOL_GET, flags);
 
@@ -5908,15 +5967,13 @@ static int cmd_sb_port_pool_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB |
-				    DL_OPT_SB_POOL, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_SB_PORT_POOL_GET,
+					  DL_OPT_HANDLEP | DL_OPT_SB |
+					  DL_OPT_SB_POOL, 0,
+					  DL_OPT_HANDLE | DL_OPT_HANDLEP, DL_OPT_SB);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_SB_PORT_POOL_GET, flags);
 
@@ -6015,15 +6072,14 @@ static int cmd_sb_tc_bind_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB | DL_OPT_SB_TC |
-				    DL_OPT_SB_TYPE, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_SB_TC_POOL_BIND_GET,
+					  DL_OPT_HANDLEP | DL_OPT_SB |
+					  DL_OPT_SB_TC | DL_OPT_SB_TYPE, 0,
+					  DL_OPT_HANDLE | DL_OPT_HANDLEP,
+					  DL_OPT_SB);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_SB_TC_POOL_BIND_GET, flags);
 
@@ -8697,14 +8753,11 @@ static int cmd_region_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE_REGION, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_REGION_GET,
+					  DL_OPT_HANDLE_REGION, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_REGION_GET, flags);
 
@@ -9388,19 +9441,20 @@ static int __cmd_health_show(struct dl *dl, bool show_device, bool show_port)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	} else {
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_HEALTH_REPORTER_GET,
+					  DL_OPT_HANDLE | DL_OPT_HANDLEP |
+					  DL_OPT_HEALTH_REPORTER_NAME, 0,
+					  DL_OPT_HANDLE | DL_OPT_HANDLEP, 0);
+	if (err)
+		return err;
+
+	if (!(flags & NLM_F_DUMP))
 		ctx.show_port = true;
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLE | DL_OPT_HANDLEP |
-				    DL_OPT_HEALTH_REPORTER_NAME, 0);
-		if (err)
-			return err;
-	}
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_HEALTH_REPORTER_GET,
 			       flags);
+
 	dl_opts_put(nlh, dl);
 
 	pr_out_section_start(dl, "health");
@@ -9582,14 +9636,11 @@ static int cmd_trap_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_TRAP_NAME, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_TRAP_GET,
+					  DL_OPT_HANDLE | DL_OPT_TRAP_NAME, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_TRAP_GET, flags);
 
@@ -9660,15 +9711,12 @@ static int cmd_trap_group_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLE | DL_OPT_TRAP_GROUP_NAME, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_TRAP_GROUP_GET,
+					  DL_OPT_HANDLE | DL_OPT_TRAP_GROUP_NAME, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_TRAP_GROUP_GET, flags);
 
@@ -9759,15 +9807,12 @@ static int cmd_trap_policer_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLE | DL_OPT_TRAP_POLICER_ID, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_TRAP_POLICER_GET,
+					  DL_OPT_HANDLE | DL_OPT_TRAP_POLICER_ID, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_TRAP_POLICER_GET, flags);
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [patch iproute2-next v2 0/6] devlink: implement dump selector for devlink objects show commands
  2023-09-06 11:11 [patch iproute2-next v2 0/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
                   ` (5 preceding siblings ...)
  2023-09-06 11:11 ` [patch iproute2-next v2 6/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
@ 2023-09-11 15:50 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-09-11 15:50 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: netdev, stephen, dsahern

Hello:

This series was applied to iproute2/iproute2-next.git (main)
by David Ahern <dsahern@kernel.org>:

On Wed,  6 Sep 2023 13:11:07 +0200 you wrote:
> From: Jiri Pirko <jiri@nvidia.com>
> 
> First 5 patches are preparations for the last one.
> 
> Motivation:
> 
> 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.
> 
> [...]

Here is the summary with links:
  - [iproute2-next,v2,1/6] devlink: move DL_OPT_SB into required options
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=158215c53677
  - [iproute2-next,v2,2/6] devlink: make parsing of handle non-destructive to argv
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=5d9f42124ccd
  - [iproute2-next,v2,3/6] devlink: implement command line args dry parsing
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=8eb894eda67d
  - [iproute2-next,v2,4/6] devlink: return -ENOENT if argument is missing
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=fd1c2af8cbaa
  - [iproute2-next,v2,5/6] mnl_utils: introduce a helper to check if dump policy exists for command
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=20b299a3ec35
  - [iproute2-next,v2,6/6] devlink: implement dump selector for devlink objects show commands
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=70faecdca8f5

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-09-11 15:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-06 11:11 [patch iproute2-next v2 0/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
2023-09-06 11:11 ` [patch iproute2-next v2 1/6] devlink: move DL_OPT_SB into required options Jiri Pirko
2023-09-06 11:11 ` [patch iproute2-next v2 2/6] devlink: make parsing of handle non-destructive to argv Jiri Pirko
2023-09-06 11:11 ` [patch iproute2-next v2 3/6] devlink: implement command line args dry parsing Jiri Pirko
2023-09-06 11:11 ` [patch iproute2-next v2 4/6] devlink: return -ENOENT if argument is missing Jiri Pirko
2023-09-06 11:11 ` [patch iproute2-next v2 5/6] mnl_utils: introduce a helper to check if dump policy exists for command Jiri Pirko
2023-09-06 11:11 ` [patch iproute2-next v2 6/6] devlink: implement dump selector for devlink objects show commands Jiri Pirko
2023-09-11 15:50 ` [patch iproute2-next v2 0/6] " patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).