naccyde / rpms / iproute

Forked from rpms/iproute 5 months ago
Clone

Blame SOURCES/0055-iplink-add-support-for-reporting-multiple-XDP-progra.patch

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