netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch net-next v4 0/7] expose devlink instances relationships
@ 2023-10-27 10:13 Jiri Pirko
  2023-10-27 10:13 ` [patch net-next v4 1/7] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c Jiri Pirko
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Jiri Pirko @ 2023-10-27 10:13 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern, daniel.machon

From: Jiri Pirko <jiri@nvidia.com>

Print out recently added attributes that expose relationships between
devlink instances. This patchset extends the outputs by
"nested_devlink" attributes.

Examples:
$ devlink dev
pci/0000:08:00.0:
  nested_devlink:
    auxiliary/mlx5_core.eth.0
auxiliary/mlx5_core.eth.0
pci/0000:08:00.1:
  nested_devlink:
    auxiliary/mlx5_core.eth.1
auxiliary/mlx5_core.eth.1

$ devlink dev -j -p
{
    "dev": {
        "pci/0000:08:00.0": {
            "nested_devlink": {
                "auxiliary/mlx5_core.eth.0": {}
            }
        },
        "auxiliary/mlx5_core.eth.0": {},
        "pci/0000:08:00.1": {
            "nested_devlink": {
                "auxiliary/mlx5_core.eth.1": {}
            }
        },
        "auxiliary/mlx5_core.eth.1": {}
    }
}

$ devlink port add pci/0000:08:00.0 flavour pcisf pfnum 0 sfnum 106
pci/0000:08:00.0/32768: type eth netdev eth2 flavour pcisf controller 0 pfnum 0 sfnum 106 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state inactive opstate detached roce enable
$ devlink port function set pci/0000:08:00.0/32768 state active
$ devlink port show pci/0000:08:00.0/32768
pci/0000:08:00.0/32768: type eth netdev eth2 flavour pcisf controller 0 pfnum 0 sfnum 106 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state active opstate attached roce enable
      nested_devlink:
        auxiliary/mlx5_core.sf.2
$ devlink port show pci/0000:08:00.0/32768 -j -p
{
    "port": {
        "pci/0000:08:00.0/32768": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 0,
            "sfnum": 106,
            "splittable": false,
            "function": {
                "hw_addr": "00:00:00:00:00:00",
                "state": "active",
                "opstate": "attached",
                "roce": "enable",
                "nested_devlink": {
                    "auxiliary/mlx5_core.sf.2": {}
                }
            }
        }
    }
}

$ devlink dev reload auxiliary/mlx5_core.sf.2 netns ns1
$ devlink port show pci/0000:08:00.0/32768
pci/0000:08:00.0/32768: type eth netdev eth2 flavour pcisf controller 0 pfnum 0 sfnum 106 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state active opstate attached roce enable
      nested_devlink:
        auxiliary/mlx5_core.sf.2: netns ns1
$ devlink port show pci/0000:08:00.0/32768 -j -p
{
    "port": {
        "pci/0000:08:00.0/32768": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 0,
            "sfnum": 106,
            "splittable": false,
            "function": {
                "hw_addr": "00:00:00:00:00:00",
                "state": "active",
                "opstate": "attached",
                "roce": "enable",
                "nested_devlink": {
                    "auxiliary/mlx5_core.sf.2": {
                        "netns": "ns1"
                    }
                }
            }
        }
    }
}

---
v3->v4
- removed namespace.h include from patch #1
- added patch #2
v2->v3:
- the output format is changed to treat the nested handle in a similar
  way as the dev_handle/port_handle allowing to contain attrs, like
  netns. See examples
- couple of details
- see individual patches for more details
v1->v2:
- patch #2 was added
- patch #3 uses new helper added by patch #2, typo is fixed

Jiri Pirko (7):
  ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c
  devlink: use snprintf instead of sprintf
  devlink: do conditional new line print in pr_out_port_handle_end()
  devlink: extend pr_out_nested_handle() to print object
  devlink: introduce support for netns id for nested handle
  devlink: print nested handle for port function
  devlink: print nested devlink handle for devlink dev

 devlink/devlink.c   | 140 ++++++++++++++++++++++++++++++++++----------
 include/namespace.h |   3 +
 ip/ipnetns.c        |  45 +-------------
 lib/namespace.c     |  83 ++++++++++++++++++++++++++
 4 files changed, 196 insertions(+), 75 deletions(-)

-- 
2.41.0


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

* [patch net-next v4 1/7] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c
  2023-10-27 10:13 [patch net-next v4 0/7] expose devlink instances relationships Jiri Pirko
@ 2023-10-27 10:13 ` Jiri Pirko
  2023-11-06 17:11   ` David Ahern
  2023-10-27 10:13 ` [patch net-next v4 2/7] devlink: use snprintf instead of sprintf Jiri Pirko
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Jiri Pirko @ 2023-10-27 10:13 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern, daniel.machon

From: Jiri Pirko <jiri@nvidia.com>

In order to be able to reuse get_netnsid_from_name() function outside of
ip code, move the internals to lib/namespace.c to a new function called
netns_id_from_name().

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v3->v4:
- removed namespace.h include
v2->v3:
- s/netns_netnsid_from_name/netns_id_from_name/
v1->v2:
- new patch
---
 include/namespace.h |  2 ++
 ip/ipnetns.c        | 45 +----------------------------------------
 lib/namespace.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 52 insertions(+), 44 deletions(-)

diff --git a/include/namespace.h b/include/namespace.h
index e47f9b5d49d1..6483630b8082 100644
--- a/include/namespace.h
+++ b/include/namespace.h
@@ -58,4 +58,6 @@ struct netns_func {
 	void *arg;
 };
 
+int netns_id_from_name(struct rtnl_handle *rtnl, const char *name);
+
 #endif /* __NAMESPACE_H__ */
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 9d996832aef8..0ae46a874a0c 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -105,52 +105,9 @@ static int ipnetns_have_nsid(void)
 
 int get_netnsid_from_name(const char *name)
 {
-	struct {
-		struct nlmsghdr n;
-		struct rtgenmsg g;
-		char            buf[1024];
-	} req = {
-		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
-		.n.nlmsg_flags = NLM_F_REQUEST,
-		.n.nlmsg_type = RTM_GETNSID,
-		.g.rtgen_family = AF_UNSPEC,
-	};
-	struct nlmsghdr *answer;
-	struct rtattr *tb[NETNSA_MAX + 1];
-	struct rtgenmsg *rthdr;
-	int len, fd, ret = -1;
-
 	netns_nsid_socket_init();
 
-	fd = netns_get_fd(name);
-	if (fd < 0)
-		return fd;
-
-	addattr32(&req.n, 1024, NETNSA_FD, fd);
-	if (rtnl_talk(&rtnsh, &req.n, &answer) < 0) {
-		close(fd);
-		return -2;
-	}
-	close(fd);
-
-	/* Validate message and parse attributes */
-	if (answer->nlmsg_type == NLMSG_ERROR)
-		goto out;
-
-	rthdr = NLMSG_DATA(answer);
-	len = answer->nlmsg_len - NLMSG_SPACE(sizeof(*rthdr));
-	if (len < 0)
-		goto out;
-
-	parse_rtattr(tb, NETNSA_MAX, NETNS_RTA(rthdr), len);
-
-	if (tb[NETNSA_NSID]) {
-		ret = rta_getattr_s32(tb[NETNSA_NSID]);
-	}
-
-out:
-	free(answer);
-	return ret;
+	return netns_id_from_name(&rtnsh, name);
 }
 
 struct nsid_cache {
diff --git a/lib/namespace.c b/lib/namespace.c
index 1202fa85f97d..f03f4bbabceb 100644
--- a/lib/namespace.c
+++ b/lib/namespace.c
@@ -7,9 +7,11 @@
 #include <fcntl.h>
 #include <dirent.h>
 #include <limits.h>
+#include <linux/net_namespace.h>
 
 #include "utils.h"
 #include "namespace.h"
+#include "libnetlink.h"
 
 static void bind_etc(const char *name)
 {
@@ -139,3 +141,50 @@ int netns_foreach(int (*func)(char *nsname, void *arg), void *arg)
 	closedir(dir);
 	return 0;
 }
+
+int netns_id_from_name(struct rtnl_handle *rtnl, const char *name)
+{
+	struct {
+		struct nlmsghdr n;
+		struct rtgenmsg g;
+		char            buf[1024];
+	} req = {
+		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+		.n.nlmsg_flags = NLM_F_REQUEST,
+		.n.nlmsg_type = RTM_GETNSID,
+		.g.rtgen_family = AF_UNSPEC,
+	};
+	struct nlmsghdr *answer;
+	struct rtattr *tb[NETNSA_MAX + 1];
+	struct rtgenmsg *rthdr;
+	int len, fd, ret = -1;
+
+	fd = netns_get_fd(name);
+	if (fd < 0)
+		return fd;
+
+	addattr32(&req.n, 1024, NETNSA_FD, fd);
+	if (rtnl_talk(rtnl, &req.n, &answer) < 0) {
+		close(fd);
+		return -2;
+	}
+	close(fd);
+
+	/* Validate message and parse attributes */
+	if (answer->nlmsg_type == NLMSG_ERROR)
+		goto out;
+
+	rthdr = NLMSG_DATA(answer);
+	len = answer->nlmsg_len - NLMSG_SPACE(sizeof(*rthdr));
+	if (len < 0)
+		goto out;
+
+	parse_rtattr(tb, NETNSA_MAX, NETNS_RTA(rthdr), len);
+
+	if (tb[NETNSA_NSID])
+		ret = rta_getattr_s32(tb[NETNSA_NSID]);
+
+out:
+	free(answer);
+	return ret;
+}
-- 
2.41.0


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

* [patch net-next v4 2/7] devlink: use snprintf instead of sprintf
  2023-10-27 10:13 [patch net-next v4 0/7] expose devlink instances relationships Jiri Pirko
  2023-10-27 10:13 ` [patch net-next v4 1/7] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c Jiri Pirko
@ 2023-10-27 10:13 ` Jiri Pirko
  2023-10-27 10:13 ` [patch net-next v4 3/7] devlink: do conditional new line print in pr_out_port_handle_end() Jiri Pirko
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Jiri Pirko @ 2023-10-27 10:13 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern, daniel.machon

From: Jiri Pirko <jiri@nvidia.com>

Use snprintf instead of sprintf to ensure only valid memory is printed
to and the output string is properly terminated.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v3->v4:
- new patch
---
 devlink/devlink.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 3baad355759e..b711e92caaba 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2761,8 +2761,9 @@ static void pr_out_nested_handle(struct nlattr *nla_nested_dl)
 	    !tb[DEVLINK_ATTR_DEV_NAME])
 		return;
 
-	sprintf(buf, "%s/%s", mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]),
-		mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]));
+	snprintf(buf, sizeof(buf), "%s/%s",
+		 mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]),
+		 mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]));
 	print_string(PRINT_ANY, "nested_devlink", " nested_devlink %s", buf);
 }
 
@@ -2773,7 +2774,7 @@ static void __pr_out_handle_start(struct dl *dl, struct nlattr **tb,
 	const char *dev_name = mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]);
 	char buf[64];
 
-	sprintf(buf, "%s/%s", bus_name, dev_name);
+	snprintf(buf, sizeof(buf), "%s/%s", bus_name, dev_name);
 
 	if (dl->json_output) {
 		if (array) {
@@ -2832,7 +2833,7 @@ static void pr_out_selftests_handle_start(struct dl *dl, struct nlattr **tb)
 	const char *dev_name = mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]);
 	char buf[64];
 
-	sprintf(buf, "%s/%s", bus_name, dev_name);
+	snprintf(buf, sizeof(buf), "%s/%s", bus_name, dev_name);
 
 	if (dl->json_output) {
 		if (should_arr_last_handle_end(dl, bus_name, dev_name))
@@ -2902,9 +2903,10 @@ static void __pr_out_port_handle_start(struct dl *dl, const char *bus_name,
 	if (dl->no_nice_names || !try_nice ||
 	    ifname_map_rev_lookup(dl, bus_name, dev_name,
 				  port_index, &ifname) != 0)
-		sprintf(buf, "%s/%s/%d", bus_name, dev_name, port_index);
+		snprintf(buf, sizeof(buf), "%s/%s/%d",
+			 bus_name, dev_name, port_index);
 	else
-		sprintf(buf, "%s", ifname);
+		snprintf(buf, sizeof(buf), "%s", ifname);
 
 	if (dl->json_output) {
 		if (array) {
@@ -5230,7 +5232,7 @@ pr_out_port_rate_handle_start(struct dl *dl, struct nlattr **tb, bool try_nice)
 	bus_name = mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]);
 	dev_name = mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]);
 	node_name = mnl_attr_get_str(tb[DEVLINK_ATTR_RATE_NODE_NAME]);
-	sprintf(buf, "%s/%s/%s", bus_name, dev_name, node_name);
+	snprintf(buf, sizeof(buf), "%s/%s/%s", bus_name, dev_name, node_name);
 	if (dl->json_output)
 		open_json_object(buf);
 	else
@@ -6305,7 +6307,7 @@ static void pr_out_json_occ_show_item_list(struct dl *dl, const char *label,
 
 	open_json_object(label);
 	list_for_each_entry(occ_item, list, list) {
-		sprintf(buf, "%u", occ_item->index);
+		snprintf(buf, sizeof(buf), "%u", occ_item->index);
 		open_json_object(buf);
 		if (bound_pool)
 			print_uint(PRINT_JSON, "bound_pool", NULL,
@@ -8674,7 +8676,7 @@ static void pr_out_region_handle_start(struct dl *dl, struct nlattr **tb)
 	const char *region_name = mnl_attr_get_str(tb[DEVLINK_ATTR_REGION_NAME]);
 	char buf[256];
 
-	sprintf(buf, "%s/%s/%s", bus_name, dev_name, region_name);
+	snprintf(buf, sizeof(buf), "%s/%s/%s", bus_name, dev_name, region_name);
 	if (dl->json_output)
 		open_json_object(buf);
 	else
-- 
2.41.0


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

* [patch net-next v4 3/7] devlink: do conditional new line print in pr_out_port_handle_end()
  2023-10-27 10:13 [patch net-next v4 0/7] expose devlink instances relationships Jiri Pirko
  2023-10-27 10:13 ` [patch net-next v4 1/7] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c Jiri Pirko
  2023-10-27 10:13 ` [patch net-next v4 2/7] devlink: use snprintf instead of sprintf Jiri Pirko
@ 2023-10-27 10:13 ` Jiri Pirko
  2023-10-27 10:14 ` [patch net-next v4 4/7] devlink: extend pr_out_nested_handle() to print object Jiri Pirko
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Jiri Pirko @ 2023-10-27 10:13 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern, daniel.machon

From: Jiri Pirko <jiri@nvidia.com>

Instead of printing out new line unconditionally, use __pr_out_newline()
to print it only when needed avoiding double prints.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- new patch
---
 devlink/devlink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index b711e92caaba..90f6f8ff90e2 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2976,7 +2976,7 @@ static void pr_out_port_handle_end(struct dl *dl)
 	if (dl->json_output)
 		close_json_object();
 	else
-		pr_out("\n");
+		__pr_out_newline();
 }
 
 static void pr_out_region_chunk_start(struct dl *dl, uint64_t addr)
-- 
2.41.0


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

* [patch net-next v4 4/7] devlink: extend pr_out_nested_handle() to print object
  2023-10-27 10:13 [patch net-next v4 0/7] expose devlink instances relationships Jiri Pirko
                   ` (2 preceding siblings ...)
  2023-10-27 10:13 ` [patch net-next v4 3/7] devlink: do conditional new line print in pr_out_port_handle_end() Jiri Pirko
@ 2023-10-27 10:14 ` Jiri Pirko
  2023-10-27 10:14 ` [patch net-next v4 5/7] devlink: introduce support for netns id for nested handle Jiri Pirko
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Jiri Pirko @ 2023-10-27 10:14 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern, daniel.machon

From: Jiri Pirko <jiri@nvidia.com>

For existing pr_out_nested_handle() user (line card), the output stays
the same. For the new users, introduce __pr_out_nested_handle()
to allow to print devlink instance as object allowing to carry
attributes in it (like netns).

Note that as __pr_out_handle_start() and pr_out_handle_end() are newly
used, the function is moved below the definitions.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v3->v4:
- rebased on top of snprintf patch
v2->v3:
- new patch
---
 devlink/devlink.c | 53 +++++++++++++++++++++++++++++------------------
 1 file changed, 33 insertions(+), 20 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 90f6f8ff90e2..f06f3069e80a 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2747,26 +2747,6 @@ static bool should_arr_last_handle_end(struct dl *dl, const char *bus_name,
 	       !cmp_arr_last_handle(dl, bus_name, dev_name);
 }
 
-static void pr_out_nested_handle(struct nlattr *nla_nested_dl)
-{
-	struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
-	char buf[64];
-	int err;
-
-	err = mnl_attr_parse_nested(nla_nested_dl, attr_cb, tb);
-	if (err != MNL_CB_OK)
-		return;
-
-	if (!tb[DEVLINK_ATTR_BUS_NAME] ||
-	    !tb[DEVLINK_ATTR_DEV_NAME])
-		return;
-
-	snprintf(buf, sizeof(buf), "%s/%s",
-		 mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]),
-		 mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]));
-	print_string(PRINT_ANY, "nested_devlink", " nested_devlink %s", buf);
-}
-
 static void __pr_out_handle_start(struct dl *dl, struct nlattr **tb,
 				  bool content, bool array)
 {
@@ -2862,6 +2842,39 @@ static void pr_out_selftests_handle_end(struct dl *dl)
 		__pr_out_newline();
 }
 
+static void __pr_out_nested_handle(struct dl *dl, struct nlattr *nla_nested_dl,
+				   bool is_object)
+{
+	struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
+	int err;
+
+	err = mnl_attr_parse_nested(nla_nested_dl, attr_cb, tb);
+	if (err != MNL_CB_OK)
+		return;
+
+	if (!tb[DEVLINK_ATTR_BUS_NAME] ||
+	    !tb[DEVLINK_ATTR_DEV_NAME])
+		return;
+
+	if (!is_object) {
+		char buf[64];
+
+		snprintf(buf, sizeof(buf), "%s/%s",
+			 mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]),
+			 mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]));
+		print_string(PRINT_ANY, "nested_devlink", " nested_devlink %s", buf);
+		return;
+	}
+
+	__pr_out_handle_start(dl, tb, false, false);
+	pr_out_handle_end(dl);
+}
+
+static void pr_out_nested_handle(struct nlattr *nla_nested_dl)
+{
+	__pr_out_nested_handle(NULL, nla_nested_dl, false);
+}
+
 static bool cmp_arr_last_port_handle(struct dl *dl, const char *bus_name,
 				     const char *dev_name, uint32_t port_index)
 {
-- 
2.41.0


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

* [patch net-next v4 5/7] devlink: introduce support for netns id for nested handle
  2023-10-27 10:13 [patch net-next v4 0/7] expose devlink instances relationships Jiri Pirko
                   ` (3 preceding siblings ...)
  2023-10-27 10:14 ` [patch net-next v4 4/7] devlink: extend pr_out_nested_handle() to print object Jiri Pirko
@ 2023-10-27 10:14 ` Jiri Pirko
  2023-10-27 10:14 ` [patch net-next v4 6/7] devlink: print nested handle for port function Jiri Pirko
  2023-10-27 10:14 ` [patch net-next v4 7/7] devlink: print nested devlink handle for devlink dev Jiri Pirko
  6 siblings, 0 replies; 10+ messages in thread
From: Jiri Pirko @ 2023-10-27 10:14 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern, daniel.machon

From: Jiri Pirko <jiri@nvidia.com>

Nested handle may contain DEVLINK_ATTR_NETNS_ID attribute that indicates
the network namespace where the nested devlink instance resides. Process
this converting to netns name if possible and print to user.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- moved netns_name_by_id() into lib/namespace.c
- s/netns_name_by_id/netns_name_from_id/
- rebased on top of new patch "devlink: extend pr_out_nested_handle() to
  print object"
v1->v2:
- use previously introduced netns_netnsid_from_name() instead of code
  duplication for the same function.
- s/nesns_name_by_id_func/netns_name_by_id_func/
---
 devlink/devlink.c   | 23 ++++++++++++++++++++++-
 include/namespace.h |  1 +
 lib/namespace.c     | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index f06f3069e80a..f276026b9ba7 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -24,6 +24,7 @@
 #include <linux/genetlink.h>
 #include <linux/devlink.h>
 #include <linux/netlink.h>
+#include <linux/net_namespace.h>
 #include <libmnl/libmnl.h>
 #include <netinet/ether.h>
 #include <sys/select.h>
@@ -722,6 +723,7 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
 	[DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES] = MNL_TYPE_NESTED,
 	[DEVLINK_ATTR_NESTED_DEVLINK] = MNL_TYPE_NESTED,
 	[DEVLINK_ATTR_SELFTESTS] = MNL_TYPE_NESTED,
+	[DEVLINK_ATTR_NETNS_ID] = MNL_TYPE_U32,
 };
 
 static const enum mnl_attr_data_type
@@ -2866,7 +2868,26 @@ static void __pr_out_nested_handle(struct dl *dl, struct nlattr *nla_nested_dl,
 		return;
 	}
 
-	__pr_out_handle_start(dl, tb, false, false);
+	__pr_out_handle_start(dl, tb, tb[DEVLINK_ATTR_NETNS_ID], false);
+	if (tb[DEVLINK_ATTR_NETNS_ID]) {
+		int32_t id = mnl_attr_get_u32(tb[DEVLINK_ATTR_NETNS_ID]);
+
+		if (id >= 0) {
+			char *name = netns_name_from_id(id);
+
+			if (name) {
+				print_string(PRINT_ANY, "netns",
+					     " netns %s", name);
+				free(name);
+			} else {
+				print_int(PRINT_ANY, "netnsid",
+					  " netnsid %d", id);
+			}
+		} else {
+			print_string(PRINT_FP, NULL, " netnsid %s", "unknown");
+			print_int(PRINT_JSON, "netnsid", NULL, id);
+		}
+	}
 	pr_out_handle_end(dl);
 }
 
diff --git a/include/namespace.h b/include/namespace.h
index 6483630b8082..4ae294749962 100644
--- a/include/namespace.h
+++ b/include/namespace.h
@@ -59,5 +59,6 @@ struct netns_func {
 };
 
 int netns_id_from_name(struct rtnl_handle *rtnl, const char *name);
+char *netns_name_from_id(int32_t id);
 
 #endif /* __NAMESPACE_H__ */
diff --git a/lib/namespace.c b/lib/namespace.c
index f03f4bbabceb..d3aeb9658e73 100644
--- a/lib/namespace.c
+++ b/lib/namespace.c
@@ -188,3 +188,37 @@ out:
 	free(answer);
 	return ret;
 }
+
+struct netns_name_from_id_ctx {
+	int32_t id;
+	char *name;
+	struct rtnl_handle *rth;
+};
+
+static int netns_name_from_id_func(char *nsname, void *arg)
+{
+	struct netns_name_from_id_ctx *ctx = arg;
+	int32_t ret;
+
+	ret = netns_id_from_name(ctx->rth, nsname);
+	if (ret < 0 || ret != ctx->id)
+		return 0;
+	ctx->name = strdup(nsname);
+	return 1;
+}
+
+char *netns_name_from_id(int32_t id)
+{
+	struct rtnl_handle rth;
+	struct netns_name_from_id_ctx ctx = {
+		.id = id,
+		.rth = &rth,
+	};
+
+	if (rtnl_open(&rth, 0) < 0)
+		return NULL;
+	netns_foreach(netns_name_from_id_func, &ctx);
+	rtnl_close(&rth);
+
+	return ctx.name;
+}
-- 
2.41.0


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

* [patch net-next v4 6/7] devlink: print nested handle for port function
  2023-10-27 10:13 [patch net-next v4 0/7] expose devlink instances relationships Jiri Pirko
                   ` (4 preceding siblings ...)
  2023-10-27 10:14 ` [patch net-next v4 5/7] devlink: introduce support for netns id for nested handle Jiri Pirko
@ 2023-10-27 10:14 ` Jiri Pirko
  2023-10-27 10:14 ` [patch net-next v4 7/7] devlink: print nested devlink handle for devlink dev Jiri Pirko
  6 siblings, 0 replies; 10+ messages in thread
From: Jiri Pirko @ 2023-10-27 10:14 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern, daniel.machon

From: Jiri Pirko <jiri@nvidia.com>

If port function contains nested handle attribute, print it.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- rebased on top of new patch "devlink: extend pr_out_nested_handle() to
  print object"
---
 devlink/devlink.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index f276026b9ba7..ae31e7cf34e3 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -772,6 +772,7 @@ static const enum mnl_attr_data_type
 devlink_function_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
 	[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR ] = MNL_TYPE_BINARY,
 	[DEVLINK_PORT_FN_ATTR_STATE] = MNL_TYPE_U8,
+	[DEVLINK_PORT_FN_ATTR_DEVLINK] = MNL_TYPE_NESTED,
 };
 
 static int function_attr_cb(const struct nlattr *attr, void *data)
@@ -2896,6 +2897,22 @@ static void pr_out_nested_handle(struct nlattr *nla_nested_dl)
 	__pr_out_nested_handle(NULL, nla_nested_dl, false);
 }
 
+static void pr_out_nested_handle_obj(struct dl *dl,
+				     struct nlattr *nla_nested_dl,
+				     bool obj_start, bool obj_end)
+{
+	if (obj_start) {
+		pr_out_object_start(dl, "nested_devlink");
+		check_indent_newline(dl);
+	}
+	__pr_out_nested_handle(dl, nla_nested_dl, true);
+	if (obj_end) {
+		if (!dl->json_output)
+			__pr_out_indent_dec();
+		pr_out_object_end(dl);
+	}
+}
+
 static bool cmp_arr_last_port_handle(struct dl *dl, const char *bus_name,
 				     const char *dev_name, uint32_t port_index)
 {
@@ -4839,6 +4856,9 @@ static void pr_out_port_function(struct dl *dl, struct nlattr **tb_port)
 				     port_fn_caps->value & DEVLINK_PORT_FN_CAP_IPSEC_PACKET ?
 				     "enable" : "disable");
 	}
+	if (tb[DEVLINK_PORT_FN_ATTR_DEVLINK])
+		pr_out_nested_handle_obj(dl, tb[DEVLINK_PORT_FN_ATTR_DEVLINK],
+					 true, true);
 
 	if (!dl->json_output)
 		__pr_out_indent_dec();
-- 
2.41.0


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

* [patch net-next v4 7/7] devlink: print nested devlink handle for devlink dev
  2023-10-27 10:13 [patch net-next v4 0/7] expose devlink instances relationships Jiri Pirko
                   ` (5 preceding siblings ...)
  2023-10-27 10:14 ` [patch net-next v4 6/7] devlink: print nested handle for port function Jiri Pirko
@ 2023-10-27 10:14 ` Jiri Pirko
  6 siblings, 0 replies; 10+ messages in thread
From: Jiri Pirko @ 2023-10-27 10:14 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern, daniel.machon

From: Jiri Pirko <jiri@nvidia.com>

Devlink dev may contain one or more nested devlink instances.
Print them using previously introduced pr_out_nested_handle_obj()
helper.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- rebased on top of new patch "devlink: extend pr_out_nested_handle() to
  print object" and previous patch to use pr_out_nested_handle_obj()
---
 devlink/devlink.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index ae31e7cf34e3..f999e5940c63 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -3860,13 +3860,35 @@ static void pr_out_reload_data(struct dl *dl, struct nlattr **tb)
 	pr_out_object_end(dl);
 }
 
+static void pr_out_dev_nested(struct dl *dl, const struct nlmsghdr *nlh)
+{
+	int i = 0, count = 0;
+	struct nlattr *attr;
+
+	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+		if (mnl_attr_get_type(attr) == DEVLINK_ATTR_NESTED_DEVLINK)
+			count++;
+	}
+	if (!count)
+		return;
+
+	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+		if (mnl_attr_get_type(attr) != DEVLINK_ATTR_NESTED_DEVLINK)
+			continue;
+		pr_out_nested_handle_obj(dl, attr, i == 0, i == count - 1);
+		i++;
+	}
+}
 
-static void pr_out_dev(struct dl *dl, struct nlattr **tb)
+static void pr_out_dev(struct dl *dl, const struct nlmsghdr *nlh,
+		       struct nlattr **tb)
 {
 	if ((tb[DEVLINK_ATTR_RELOAD_FAILED] && mnl_attr_get_u8(tb[DEVLINK_ATTR_RELOAD_FAILED])) ||
-	    (tb[DEVLINK_ATTR_DEV_STATS] && dl->stats)) {
+	    (tb[DEVLINK_ATTR_DEV_STATS] && dl->stats) ||
+	     tb[DEVLINK_ATTR_NESTED_DEVLINK]) {
 		__pr_out_handle_start(dl, tb, true, false);
 		pr_out_reload_data(dl, tb);
+		pr_out_dev_nested(dl, nlh);
 		pr_out_handle_end(dl);
 	} else {
 		pr_out_handle(dl, tb);
@@ -3883,7 +3905,7 @@ static int cmd_dev_show_cb(const struct nlmsghdr *nlh, void *data)
 	if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME])
 		return MNL_CB_ERROR;
 
-	pr_out_dev(dl, tb);
+	pr_out_dev(dl, nlh, tb);
 	return MNL_CB_OK;
 }
 
@@ -6810,7 +6832,7 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
 			return MNL_CB_ERROR;
 		pr_out_mon_header(genl->cmd);
 		dl->stats = true;
-		pr_out_dev(dl, tb);
+		pr_out_dev(dl, nlh, tb);
 		pr_out_mon_footer();
 		break;
 	case DEVLINK_CMD_PORT_GET: /* fall through */
-- 
2.41.0


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

* Re: [patch net-next v4 1/7] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c
  2023-10-27 10:13 ` [patch net-next v4 1/7] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c Jiri Pirko
@ 2023-11-06 17:11   ` David Ahern
  2023-11-07  7:24     ` Jiri Pirko
  0 siblings, 1 reply; 10+ messages in thread
From: David Ahern @ 2023-11-06 17:11 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: stephen, daniel.machon

On 10/27/23 4:13 AM, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@nvidia.com>
> 
> In order to be able to reuse get_netnsid_from_name() function outside of
> ip code, move the internals to lib/namespace.c to a new function called
> netns_id_from_name().
> 
> Signed-off-by: Jiri Pirko <jiri@nvidia.com>
> ---
> v3->v4:
> - removed namespace.h include
> v2->v3:
> - s/netns_netnsid_from_name/netns_id_from_name/
> v1->v2:
> - new patch
> ---
>  include/namespace.h |  2 ++
>  ip/ipnetns.c        | 45 +----------------------------------------
>  lib/namespace.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 52 insertions(+), 44 deletions(-)
> 


dcb
    CC       dcb.o
In file included from dcb.c:11:
../include/namespace.h:61:31: warning: ‘struct rtnl_handle’ declared
inside parameter list will not be visible outside of this definition or
declaration
   61 | int netns_id_from_name(struct rtnl_handle *rtnl, const char *name);
      |                               ^~~~~~~~~~~

--
pw-bot: cr

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

* Re: [patch net-next v4 1/7] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c
  2023-11-06 17:11   ` David Ahern
@ 2023-11-07  7:24     ` Jiri Pirko
  0 siblings, 0 replies; 10+ messages in thread
From: Jiri Pirko @ 2023-11-07  7:24 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev, stephen, daniel.machon

Mon, Nov 06, 2023 at 06:11:29PM CET, dsahern@gmail.com wrote:
>On 10/27/23 4:13 AM, Jiri Pirko wrote:
>> From: Jiri Pirko <jiri@nvidia.com>
>> 
>> In order to be able to reuse get_netnsid_from_name() function outside of
>> ip code, move the internals to lib/namespace.c to a new function called
>> netns_id_from_name().
>> 
>> Signed-off-by: Jiri Pirko <jiri@nvidia.com>
>> ---
>> v3->v4:
>> - removed namespace.h include
>> v2->v3:
>> - s/netns_netnsid_from_name/netns_id_from_name/
>> v1->v2:
>> - new patch
>> ---
>>  include/namespace.h |  2 ++
>>  ip/ipnetns.c        | 45 +----------------------------------------
>>  lib/namespace.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 52 insertions(+), 44 deletions(-)
>> 
>
>
>dcb
>    CC       dcb.o
>In file included from dcb.c:11:
>../include/namespace.h:61:31: warning: ‘struct rtnl_handle’ declared
>inside parameter list will not be visible outside of this definition or
>declaration
>   61 | int netns_id_from_name(struct rtnl_handle *rtnl, const char *name);
>      |                               ^~~~~~~~~~~

Ah, I wonder why I didn't hit it. Will fix, thanks!

>
>--
>pw-bot: cr

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

end of thread, other threads:[~2023-11-07  7:25 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-27 10:13 [patch net-next v4 0/7] expose devlink instances relationships Jiri Pirko
2023-10-27 10:13 ` [patch net-next v4 1/7] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c Jiri Pirko
2023-11-06 17:11   ` David Ahern
2023-11-07  7:24     ` Jiri Pirko
2023-10-27 10:13 ` [patch net-next v4 2/7] devlink: use snprintf instead of sprintf Jiri Pirko
2023-10-27 10:13 ` [patch net-next v4 3/7] devlink: do conditional new line print in pr_out_port_handle_end() Jiri Pirko
2023-10-27 10:14 ` [patch net-next v4 4/7] devlink: extend pr_out_nested_handle() to print object Jiri Pirko
2023-10-27 10:14 ` [patch net-next v4 5/7] devlink: introduce support for netns id for nested handle Jiri Pirko
2023-10-27 10:14 ` [patch net-next v4 6/7] devlink: print nested handle for port function Jiri Pirko
2023-10-27 10:14 ` [patch net-next v4 7/7] devlink: print nested devlink handle for devlink dev Jiri Pirko

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 NNTP newsgroup(s).