* [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).