211 lines
6.3 KiB
Diff
211 lines
6.3 KiB
Diff
From 907e2adbcb6e02453972d5ada93de7bbaefedb2a Mon Sep 17 00:00:00 2001
|
|
From: Andrea Claudi <aclaudi@redhat.com>
|
|
Date: Thu, 13 Jun 2019 14:37:56 +0200
|
|
Subject: [PATCH] iplink: add support for reporting multiple XDP programs
|
|
|
|
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
|
|
Upstream Status: iproute2.git commit da083b5a483bf
|
|
|
|
commit da083b5a483bfd52dfe72912f62a3bc16d775b87
|
|
Author: Jakub Kicinski <jakub.kicinski@netronome.com>
|
|
Date: Fri Jul 13 15:54:51 2018 -0700
|
|
|
|
iplink: add support for reporting multiple XDP programs
|
|
|
|
Kernel now supports attaching XDP programs in the driver
|
|
and hardware at the same time. Print that information
|
|
correctly.
|
|
|
|
In case there are multiple programs attached kernel will
|
|
not provide IFLA_XDP_PROG_ID, so don't expect it to be
|
|
there (this also improves the printing for very old kernels
|
|
slightly, as it avoids unnecessary "prog/xdp" line).
|
|
|
|
In short mode preserve the current outputs but don't print
|
|
IDs if there are multiple.
|
|
|
|
6: netdevsim0: <BROADCAST,NOARP> mtu 1500 xdpoffload/id:11 qdisc [...]
|
|
|
|
and:
|
|
|
|
6: netdevsim0: <BROADCAST,NOARP> mtu 1500 xdpmulti qdisc [...]
|
|
|
|
ip link output will keep using prog/xdp prefix if only one program
|
|
is attached, but can also print multiple program lines:
|
|
|
|
prog/xdp id 8 tag fc7a51d1a693a99e jited
|
|
|
|
vs:
|
|
|
|
prog/xdpdrv id 8 tag fc7a51d1a693a99e jited
|
|
prog/xdpoffload id 9 tag fc7a51d1a693a99e
|
|
|
|
JSON output gains a new array called "attached" which will
|
|
contain the full list of attached programs along with their
|
|
attachment modes:
|
|
|
|
"xdp": {
|
|
"mode": 3,
|
|
"prog": {
|
|
"id": 11,
|
|
"tag": "fc7a51d1a693a99e",
|
|
"jited": 0
|
|
},
|
|
"attached": [ {
|
|
"mode": 3,
|
|
"prog": {
|
|
"id": 11,
|
|
"tag": "fc7a51d1a693a99e",
|
|
"jited": 0
|
|
}
|
|
} ]
|
|
},
|
|
|
|
In case there are multiple programs attached the general "xdp"
|
|
section will not contain program information:
|
|
|
|
"xdp": {
|
|
"mode": 4,
|
|
"attached": [ {
|
|
"mode": 1,
|
|
"prog": {
|
|
"id": 10,
|
|
"tag": "fc7a51d1a693a99e",
|
|
"jited": 1
|
|
}
|
|
},{
|
|
"mode": 3,
|
|
"prog": {
|
|
"id": 11,
|
|
"tag": "fc7a51d1a693a99e",
|
|
"jited": 0
|
|
}
|
|
} ]
|
|
},
|
|
|
|
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
|
|
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
|
|
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
Signed-off-by: David Ahern <dsahern@gmail.com>
|
|
---
|
|
ip/iplink_xdp.c | 73 +++++++++++++++++++++++++++++++++++++++++--------
|
|
1 file changed, 61 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/ip/iplink_xdp.c b/ip/iplink_xdp.c
|
|
index dd4fd1fd3a3b1..4a490bc8fb66c 100644
|
|
--- a/ip/iplink_xdp.c
|
|
+++ b/ip/iplink_xdp.c
|
|
@@ -91,6 +91,18 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req,
|
|
return 0;
|
|
}
|
|
|
|
+static void xdp_dump_json_one(struct rtattr *tb[IFLA_XDP_MAX + 1], __u32 attr,
|
|
+ __u8 mode)
|
|
+{
|
|
+ if (!tb[attr])
|
|
+ return;
|
|
+
|
|
+ open_json_object(NULL);
|
|
+ print_uint(PRINT_JSON, "mode", NULL, mode);
|
|
+ bpf_dump_prog_info(NULL, rta_getattr_u32(tb[attr]));
|
|
+ close_json_object();
|
|
+}
|
|
+
|
|
static void xdp_dump_json(struct rtattr *tb[IFLA_XDP_MAX + 1])
|
|
{
|
|
__u32 prog_id = 0;
|
|
@@ -104,13 +116,48 @@ static void xdp_dump_json(struct rtattr *tb[IFLA_XDP_MAX + 1])
|
|
print_uint(PRINT_JSON, "mode", NULL, mode);
|
|
if (prog_id)
|
|
bpf_dump_prog_info(NULL, prog_id);
|
|
+
|
|
+ open_json_array(PRINT_JSON, "attached");
|
|
+ if (tb[IFLA_XDP_SKB_PROG_ID] ||
|
|
+ tb[IFLA_XDP_DRV_PROG_ID] ||
|
|
+ tb[IFLA_XDP_HW_PROG_ID]) {
|
|
+ xdp_dump_json_one(tb, IFLA_XDP_SKB_PROG_ID, XDP_ATTACHED_SKB);
|
|
+ xdp_dump_json_one(tb, IFLA_XDP_DRV_PROG_ID, XDP_ATTACHED_DRV);
|
|
+ xdp_dump_json_one(tb, IFLA_XDP_HW_PROG_ID, XDP_ATTACHED_HW);
|
|
+ } else if (tb[IFLA_XDP_PROG_ID]) {
|
|
+ /* Older kernel - use IFLA_XDP_PROG_ID */
|
|
+ xdp_dump_json_one(tb, IFLA_XDP_PROG_ID, mode);
|
|
+ }
|
|
+ close_json_array(PRINT_JSON, NULL);
|
|
+
|
|
close_json_object();
|
|
}
|
|
|
|
+static void xdp_dump_prog_one(FILE *fp, struct rtattr *tb[IFLA_XDP_MAX + 1],
|
|
+ __u32 attr, bool link, bool details,
|
|
+ const char *pfx)
|
|
+{
|
|
+ __u32 prog_id;
|
|
+
|
|
+ if (!tb[attr])
|
|
+ return;
|
|
+
|
|
+ prog_id = rta_getattr_u32(tb[attr]);
|
|
+ if (!details) {
|
|
+ if (prog_id && !link && attr == IFLA_XDP_PROG_ID)
|
|
+ fprintf(fp, "/id:%u", prog_id);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (prog_id) {
|
|
+ fprintf(fp, "%s prog/xdp%s ", _SL_, pfx);
|
|
+ bpf_dump_prog_info(fp, prog_id);
|
|
+ }
|
|
+}
|
|
+
|
|
void xdp_dump(FILE *fp, struct rtattr *xdp, bool link, bool details)
|
|
{
|
|
struct rtattr *tb[IFLA_XDP_MAX + 1];
|
|
- __u32 prog_id = 0;
|
|
__u8 mode;
|
|
|
|
parse_rtattr_nested(tb, IFLA_XDP_MAX, xdp);
|
|
@@ -124,27 +171,29 @@ void xdp_dump(FILE *fp, struct rtattr *xdp, bool link, bool details)
|
|
else if (is_json_context())
|
|
return details ? (void)0 : xdp_dump_json(tb);
|
|
else if (details && link)
|
|
- fprintf(fp, "%s prog/xdp", _SL_);
|
|
+ /* don't print mode */;
|
|
else if (mode == XDP_ATTACHED_DRV)
|
|
fprintf(fp, "xdp");
|
|
else if (mode == XDP_ATTACHED_SKB)
|
|
fprintf(fp, "xdpgeneric");
|
|
else if (mode == XDP_ATTACHED_HW)
|
|
fprintf(fp, "xdpoffload");
|
|
+ else if (mode == XDP_ATTACHED_MULTI)
|
|
+ fprintf(fp, "xdpmulti");
|
|
else
|
|
fprintf(fp, "xdp[%u]", mode);
|
|
|
|
- if (tb[IFLA_XDP_PROG_ID])
|
|
- prog_id = rta_getattr_u32(tb[IFLA_XDP_PROG_ID]);
|
|
- if (!details) {
|
|
- if (prog_id && !link)
|
|
- fprintf(fp, "/id:%u", prog_id);
|
|
- fprintf(fp, " ");
|
|
- return;
|
|
+ xdp_dump_prog_one(fp, tb, IFLA_XDP_PROG_ID, link, details, "");
|
|
+
|
|
+ if (mode == XDP_ATTACHED_MULTI) {
|
|
+ xdp_dump_prog_one(fp, tb, IFLA_XDP_SKB_PROG_ID, link, details,
|
|
+ "generic");
|
|
+ xdp_dump_prog_one(fp, tb, IFLA_XDP_DRV_PROG_ID, link, details,
|
|
+ "drv");
|
|
+ xdp_dump_prog_one(fp, tb, IFLA_XDP_HW_PROG_ID, link, details,
|
|
+ "offload");
|
|
}
|
|
|
|
- if (prog_id) {
|
|
+ if (!details || !link)
|
|
fprintf(fp, " ");
|
|
- bpf_dump_prog_info(fp, prog_id);
|
|
- }
|
|
}
|
|
--
|
|
2.20.1
|
|
|