* [patch iproute2-next v3 0/6] expose devlink instances relationships
@ 2023-10-24 10:03 Jiri Pirko
2023-10-24 10:03 ` [patch iproute2-next v3 1/6] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c Jiri Pirko
` (5 more replies)
0 siblings, 6 replies; 16+ messages in thread
From: Jiri Pirko @ 2023-10-24 10:03 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"
}
}
}
}
}
}
---
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 (6):
ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c
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 | 124 +++++++++++++++++++++++++++++++++++---------
include/namespace.h | 5 ++
ip/ipnetns.c | 45 +---------------
lib/namespace.c | 83 +++++++++++++++++++++++++++++
4 files changed, 189 insertions(+), 68 deletions(-)
--
2.41.0
^ permalink raw reply [flat|nested] 16+ messages in thread
* [patch iproute2-next v3 1/6] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c
2023-10-24 10:03 [patch iproute2-next v3 0/6] expose devlink instances relationships Jiri Pirko
@ 2023-10-24 10:03 ` Jiri Pirko
2023-10-26 16:56 ` David Ahern
2023-10-24 10:03 ` [patch iproute2-next v3 2/6] devlink: do conditional new line print in pr_out_port_handle_end() Jiri Pirko
` (4 subsequent siblings)
5 siblings, 1 reply; 16+ messages in thread
From: Jiri Pirko @ 2023-10-24 10:03 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>
---
v2->v3:
- s/netns_netnsid_from_name/netns_id_from_name/
v1->v2:
- new patch
---
include/namespace.h | 4 ++++
ip/ipnetns.c | 45 +----------------------------------------
lib/namespace.c | 49 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+), 44 deletions(-)
diff --git a/include/namespace.h b/include/namespace.h
index e47f9b5d49d1..e860a4b8ee5b 100644
--- a/include/namespace.h
+++ b/include/namespace.h
@@ -8,6 +8,8 @@
#include <sys/syscall.h>
#include <errno.h>
+#include "namespace.h"
+
#ifndef NETNS_RUN_DIR
#define NETNS_RUN_DIR "/var/run/netns"
#endif
@@ -58,4 +60,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] 16+ messages in thread
* [patch iproute2-next v3 2/6] devlink: do conditional new line print in pr_out_port_handle_end()
2023-10-24 10:03 [patch iproute2-next v3 0/6] expose devlink instances relationships Jiri Pirko
2023-10-24 10:03 ` [patch iproute2-next v3 1/6] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c Jiri Pirko
@ 2023-10-24 10:03 ` Jiri Pirko
2023-10-24 10:04 ` [patch iproute2-next v3 3/6] devlink: extend pr_out_nested_handle() to print object Jiri Pirko
` (3 subsequent siblings)
5 siblings, 0 replies; 16+ messages in thread
From: Jiri Pirko @ 2023-10-24 10:03 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 3baad355759e..c18a4a4fbc5a 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2974,7 +2974,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] 16+ messages in thread
* [patch iproute2-next v3 3/6] devlink: extend pr_out_nested_handle() to print object
2023-10-24 10:03 [patch iproute2-next v3 0/6] expose devlink instances relationships Jiri Pirko
2023-10-24 10:03 ` [patch iproute2-next v3 1/6] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c Jiri Pirko
2023-10-24 10:03 ` [patch iproute2-next v3 2/6] devlink: do conditional new line print in pr_out_port_handle_end() Jiri Pirko
@ 2023-10-24 10:04 ` Jiri Pirko
2023-10-26 17:03 ` David Ahern
2023-10-24 10:04 ` [patch iproute2-next v3 4/6] devlink: introduce support for netns id for nested handle Jiri Pirko
` (2 subsequent siblings)
5 siblings, 1 reply; 16+ messages in thread
From: Jiri Pirko @ 2023-10-24 10:04 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>
---
v2->v3:
- new patch
---
devlink/devlink.c | 51 +++++++++++++++++++++++++++++------------------
1 file changed, 32 insertions(+), 19 deletions(-)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index c18a4a4fbc5a..f7325477f271 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2747,25 +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;
-
- sprintf(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)
{
@@ -2861,6 +2842,38 @@ 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];
+
+ sprintf(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] 16+ messages in thread
* [patch iproute2-next v3 4/6] devlink: introduce support for netns id for nested handle
2023-10-24 10:03 [patch iproute2-next v3 0/6] expose devlink instances relationships Jiri Pirko
` (2 preceding siblings ...)
2023-10-24 10:04 ` [patch iproute2-next v3 3/6] devlink: extend pr_out_nested_handle() to print object Jiri Pirko
@ 2023-10-24 10:04 ` Jiri Pirko
2023-10-26 17:08 ` David Ahern
2023-10-24 10:04 ` [patch iproute2-next v3 5/6] devlink: print nested handle for port function Jiri Pirko
2023-10-24 10:04 ` [patch iproute2-next v3 6/6] devlink: print nested devlink handle for devlink dev Jiri Pirko
5 siblings, 1 reply; 16+ messages in thread
From: Jiri Pirko @ 2023-10-24 10:04 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 f7325477f271..7ba2d0dcac72 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
@@ -2865,7 +2867,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 e860a4b8ee5b..fbdfbc9a1c3b 100644
--- a/include/namespace.h
+++ b/include/namespace.h
@@ -61,5 +61,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] 16+ messages in thread
* [patch iproute2-next v3 5/6] devlink: print nested handle for port function
2023-10-24 10:03 [patch iproute2-next v3 0/6] expose devlink instances relationships Jiri Pirko
` (3 preceding siblings ...)
2023-10-24 10:04 ` [patch iproute2-next v3 4/6] devlink: introduce support for netns id for nested handle Jiri Pirko
@ 2023-10-24 10:04 ` Jiri Pirko
2023-10-24 10:04 ` [patch iproute2-next v3 6/6] devlink: print nested devlink handle for devlink dev Jiri Pirko
5 siblings, 0 replies; 16+ messages in thread
From: Jiri Pirko @ 2023-10-24 10:04 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 7ba2d0dcac72..90e8872b07ef 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)
@@ -2895,6 +2896,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)
{
@@ -4837,6 +4854,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] 16+ messages in thread
* [patch iproute2-next v3 6/6] devlink: print nested devlink handle for devlink dev
2023-10-24 10:03 [patch iproute2-next v3 0/6] expose devlink instances relationships Jiri Pirko
` (4 preceding siblings ...)
2023-10-24 10:04 ` [patch iproute2-next v3 5/6] devlink: print nested handle for port function Jiri Pirko
@ 2023-10-24 10:04 ` Jiri Pirko
5 siblings, 0 replies; 16+ messages in thread
From: Jiri Pirko @ 2023-10-24 10:04 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 90e8872b07ef..09ac347051f4 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -3858,13 +3858,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);
@@ -3881,7 +3903,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;
}
@@ -6808,7 +6830,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] 16+ messages in thread
* Re: [patch iproute2-next v3 1/6] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c
2023-10-24 10:03 ` [patch iproute2-next v3 1/6] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c Jiri Pirko
@ 2023-10-26 16:56 ` David Ahern
2023-10-27 8:25 ` Jiri Pirko
0 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2023-10-26 16:56 UTC (permalink / raw)
To: Jiri Pirko, netdev; +Cc: stephen, daniel.machon
On 10/24/23 4:03 AM, Jiri Pirko wrote:
> diff --git a/include/namespace.h b/include/namespace.h
> index e47f9b5d49d1..e860a4b8ee5b 100644
> --- a/include/namespace.h
> +++ b/include/namespace.h
> @@ -8,6 +8,8 @@
> #include <sys/syscall.h>
> #include <errno.h>
>
> +#include "namespace.h"
??? including this file into itself?
> +
> #ifndef NETNS_RUN_DIR
> #define NETNS_RUN_DIR "/var/run/netns"
> #endif
> @@ -58,4 +60,6 @@ struct netns_func {
> void *arg;
> };
>
> +int netns_id_from_name(struct rtnl_handle *rtnl, const char *name);
> +
> #endif /* __NAMESPACE_H__ */
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [patch iproute2-next v3 3/6] devlink: extend pr_out_nested_handle() to print object
2023-10-24 10:04 ` [patch iproute2-next v3 3/6] devlink: extend pr_out_nested_handle() to print object Jiri Pirko
@ 2023-10-26 17:03 ` David Ahern
2023-10-27 8:26 ` Jiri Pirko
2023-10-27 13:12 ` Petr Machata
0 siblings, 2 replies; 16+ messages in thread
From: David Ahern @ 2023-10-26 17:03 UTC (permalink / raw)
To: Jiri Pirko, netdev; +Cc: stephen, daniel.machon
On 10/24/23 4:04 AM, Jiri Pirko wrote:
> @@ -2861,6 +2842,38 @@ 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];
> +
> + sprintf(buf, "%s/%s", mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]),
> + mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]));
buf[64] - 1 for null terminator - 16 for IFNAMSIZ leaves 47. I do not
see limits on bus name length, so how can you guarantee it is always <
47 characters?
Make this snprintf, check the return and make sure buf is null terminated.
> + 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)
> {
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [patch iproute2-next v3 4/6] devlink: introduce support for netns id for nested handle
2023-10-24 10:04 ` [patch iproute2-next v3 4/6] devlink: introduce support for netns id for nested handle Jiri Pirko
@ 2023-10-26 17:08 ` David Ahern
2023-10-27 8:29 ` Jiri Pirko
0 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2023-10-26 17:08 UTC (permalink / raw)
To: Jiri Pirko, netdev; +Cc: stephen, daniel.machon
On 10/24/23 4:04 AM, Jiri Pirko wrote:
> 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 f7325477f271..7ba2d0dcac72 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
> @@ -2865,7 +2867,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) {
why does the kernel side even add DEVLINK_ATTR_NETNS_ID if
peernet2id_alloc fails?
> + 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);
ie., how is -1 useful to userspace?
> + }
> + }
> pr_out_handle_end(dl);
> }
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [patch iproute2-next v3 1/6] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c
2023-10-26 16:56 ` David Ahern
@ 2023-10-27 8:25 ` Jiri Pirko
0 siblings, 0 replies; 16+ messages in thread
From: Jiri Pirko @ 2023-10-27 8:25 UTC (permalink / raw)
To: David Ahern; +Cc: netdev, stephen, daniel.machon
Thu, Oct 26, 2023 at 06:56:20PM CEST, dsahern@gmail.com wrote:
>On 10/24/23 4:03 AM, Jiri Pirko wrote:
>> diff --git a/include/namespace.h b/include/namespace.h
>> index e47f9b5d49d1..e860a4b8ee5b 100644
>> --- a/include/namespace.h
>> +++ b/include/namespace.h
>> @@ -8,6 +8,8 @@
>> #include <sys/syscall.h>
>> #include <errno.h>
>>
>> +#include "namespace.h"
>
>??? including this file into itself?
Interesting. Must have been done during code move. Will fix.
>
>> +
>> #ifndef NETNS_RUN_DIR
>> #define NETNS_RUN_DIR "/var/run/netns"
>> #endif
>> @@ -58,4 +60,6 @@ struct netns_func {
>> void *arg;
>> };
>>
>> +int netns_id_from_name(struct rtnl_handle *rtnl, const char *name);
>> +
>> #endif /* __NAMESPACE_H__ */
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [patch iproute2-next v3 3/6] devlink: extend pr_out_nested_handle() to print object
2023-10-26 17:03 ` David Ahern
@ 2023-10-27 8:26 ` Jiri Pirko
2023-10-27 13:12 ` Petr Machata
1 sibling, 0 replies; 16+ messages in thread
From: Jiri Pirko @ 2023-10-27 8:26 UTC (permalink / raw)
To: David Ahern; +Cc: netdev, stephen, daniel.machon
Thu, Oct 26, 2023 at 07:03:30PM CEST, dsahern@gmail.com wrote:
>On 10/24/23 4:04 AM, Jiri Pirko wrote:
>> @@ -2861,6 +2842,38 @@ 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];
>> +
>> + sprintf(buf, "%s/%s", mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]),
>> + mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]));
>
>buf[64] - 1 for null terminator - 16 for IFNAMSIZ leaves 47. I do not
IFNAMSIZ is irrelevant here.
>see limits on bus name length, so how can you guarantee it is always <
>47 characters?
>
>Make this snprintf, check the return and make sure buf is null terminated.
I will fix it in separate patch, as this is just copied here.
>
>> + 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)
>> {
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [patch iproute2-next v3 4/6] devlink: introduce support for netns id for nested handle
2023-10-26 17:08 ` David Ahern
@ 2023-10-27 8:29 ` Jiri Pirko
0 siblings, 0 replies; 16+ messages in thread
From: Jiri Pirko @ 2023-10-27 8:29 UTC (permalink / raw)
To: David Ahern; +Cc: netdev, stephen, daniel.machon
Thu, Oct 26, 2023 at 07:08:04PM CEST, dsahern@gmail.com wrote:
>On 10/24/23 4:04 AM, Jiri Pirko wrote:
>> 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 f7325477f271..7ba2d0dcac72 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
>> @@ -2865,7 +2867,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) {
>
>why does the kernel side even add DEVLINK_ATTR_NETNS_ID if
>peernet2id_alloc fails?
Yep. So the user knows that this is in a different namespace. This
logic is copied from iplink
>
>
>> + 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);
>
>ie., how is -1 useful to userspace?
The userspace knows that this device is in a different netnamespace, but
it is unknown as peernet2id_alloc failed. Should be really a rare
corner case when system is under memory pressure.
>
>
>> + }
>> + }
>> pr_out_handle_end(dl);
>> }
>>
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [patch iproute2-next v3 3/6] devlink: extend pr_out_nested_handle() to print object
2023-10-26 17:03 ` David Ahern
2023-10-27 8:26 ` Jiri Pirko
@ 2023-10-27 13:12 ` Petr Machata
2023-10-27 17:16 ` David Ahern
1 sibling, 1 reply; 16+ messages in thread
From: Petr Machata @ 2023-10-27 13:12 UTC (permalink / raw)
To: David Ahern; +Cc: Jiri Pirko, netdev, stephen, daniel.machon
David Ahern <dsahern@gmail.com> writes:
> On 10/24/23 4:04 AM, Jiri Pirko wrote:
>> @@ -2861,6 +2842,38 @@ 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];
>> +
>> + sprintf(buf, "%s/%s", mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]),
>> + mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]));
>
> buf[64] - 1 for null terminator - 16 for IFNAMSIZ leaves 47. I do not
> see limits on bus name length, so how can you guarantee it is always <
> 47 characters?
>
> Make this snprintf, check the return and make sure buf is null terminated.
I was wondering whether somehing like this might make sense in the
iproute2 library:
#define alloca_sprintf(FMT, ...) ({ \
int xasprintf_n = snprintf(NULL, 0, (FMT), __VA_ARGS__); \
char *xasprintf_buf = alloca(xasprintf_n); \
sprintf(xasprintf_buf, (FMT), __VA_ARGS__); \
xasprintf_buf; \
})
void foo() {
const char *buf = alloca_sprintf("%x %y %z", etc.);
printf(... buf ...);
}
I'm not really happy with it -- because of alloca vs. array, and because
of the double evaluation. But all those SPRINT_BUF's peppered everywhere
make me uneasy every time I read or write them.
Or maybe roll something custom asprintf-like that can reuse and/or
realloc a passed-in buffer?
The sprintf story is pretty bad in iproute2 right now, IMHO.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [patch iproute2-next v3 3/6] devlink: extend pr_out_nested_handle() to print object
2023-10-27 13:12 ` Petr Machata
@ 2023-10-27 17:16 ` David Ahern
2023-10-30 11:03 ` Petr Machata
0 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2023-10-27 17:16 UTC (permalink / raw)
To: Petr Machata; +Cc: Jiri Pirko, netdev, stephen, daniel.machon
On 10/27/23 7:12 AM, Petr Machata wrote:
> I was wondering whether somehing like this might make sense in the
> iproute2 library:
>
> #define alloca_sprintf(FMT, ...) ({ \
> int xasprintf_n = snprintf(NULL, 0, (FMT), __VA_ARGS__); \
> char *xasprintf_buf = alloca(xasprintf_n); \
> sprintf(xasprintf_buf, (FMT), __VA_ARGS__); \
> xasprintf_buf; \
> })
>
> void foo() {
> const char *buf = alloca_sprintf("%x %y %z", etc.);
> printf(... buf ...);
> }
>
> I'm not really happy with it -- because of alloca vs. array, and because
> of the double evaluation. But all those SPRINT_BUF's peppered everywhere
> make me uneasy every time I read or write them.
agreed.
>
> Or maybe roll something custom asprintf-like that can reuse and/or
> realloc a passed-in buffer?
>
> The sprintf story is pretty bad in iproute2 right now, IMHO.
It is a bit of a mess. If you have a few cycles, want to send an RFC?
Just pick 1 or 2 to convert to show intent with a new design.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [patch iproute2-next v3 3/6] devlink: extend pr_out_nested_handle() to print object
2023-10-27 17:16 ` David Ahern
@ 2023-10-30 11:03 ` Petr Machata
0 siblings, 0 replies; 16+ messages in thread
From: Petr Machata @ 2023-10-30 11:03 UTC (permalink / raw)
To: David Ahern; +Cc: Petr Machata, Jiri Pirko, netdev, stephen, daniel.machon
David Ahern <dsahern@gmail.com> writes:
> On 10/27/23 7:12 AM, Petr Machata wrote:
>> I was wondering whether somehing like this might make sense in the
>> iproute2 library:
>>
>> #define alloca_sprintf(FMT, ...) ({ \
>> int xasprintf_n = snprintf(NULL, 0, (FMT), __VA_ARGS__); \
>> char *xasprintf_buf = alloca(xasprintf_n); \
>> sprintf(xasprintf_buf, (FMT), __VA_ARGS__); \
>> xasprintf_buf; \
>> })
>>
>> void foo() {
>> const char *buf = alloca_sprintf("%x %y %z", etc.);
>> printf(... buf ...);
>> }
>>
>> I'm not really happy with it -- because of alloca vs. array, and because
>> of the double evaluation. But all those SPRINT_BUF's peppered everywhere
>> make me uneasy every time I read or write them.
>
> agreed.
>
>>
>> Or maybe roll something custom asprintf-like that can reuse and/or
>> realloc a passed-in buffer?
>>
>> The sprintf story is pretty bad in iproute2 right now, IMHO.
>
> It is a bit of a mess. If you have a few cycles, want to send an RFC?
> Just pick 1 or 2 to convert to show intent with a new design.
I picked at it a bit over the weekend, but came up with nothing that I
find comfortable proposing. The static buffer approach has some major
advantages: nothing ever fails and nothing ever needs cleanups. This
keeps the client code tidy and compact. Anything dynamic adds points of
failure and cleanups, which in C means more client-side boilerplate.
Anyway, I'll pick at it some more and see I find anything.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2023-10-30 12:25 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-24 10:03 [patch iproute2-next v3 0/6] expose devlink instances relationships Jiri Pirko
2023-10-24 10:03 ` [patch iproute2-next v3 1/6] ip/ipnetns: move internals of get_netnsid_from_name() into namespace.c Jiri Pirko
2023-10-26 16:56 ` David Ahern
2023-10-27 8:25 ` Jiri Pirko
2023-10-24 10:03 ` [patch iproute2-next v3 2/6] devlink: do conditional new line print in pr_out_port_handle_end() Jiri Pirko
2023-10-24 10:04 ` [patch iproute2-next v3 3/6] devlink: extend pr_out_nested_handle() to print object Jiri Pirko
2023-10-26 17:03 ` David Ahern
2023-10-27 8:26 ` Jiri Pirko
2023-10-27 13:12 ` Petr Machata
2023-10-27 17:16 ` David Ahern
2023-10-30 11:03 ` Petr Machata
2023-10-24 10:04 ` [patch iproute2-next v3 4/6] devlink: introduce support for netns id for nested handle Jiri Pirko
2023-10-26 17:08 ` David Ahern
2023-10-27 8:29 ` Jiri Pirko
2023-10-24 10:04 ` [patch iproute2-next v3 5/6] devlink: print nested handle for port function Jiri Pirko
2023-10-24 10:04 ` [patch iproute2-next v3 6/6] devlink: print nested devlink handle for devlink dev Jiri Pirko
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.