[PATCH iproute2 master 2/2] bpf: properly output json for xdp
From: Daniel Borkmann <daniel@iogearbox.net>
Date: 2017-09-21 08:42:43
Subsystem:
library code, the rest · Maintainers:
Andrew Morton, Linus Torvalds
After merging net-next branch into master, Stephen asked
to fix up json dump for XDP. Thus, rework the json dump a
bit, such that 'ip -json l' looks as below.
[{
"ifindex": 1,
"ifname": "lo",
"flags": ["LOOPBACK","UP","LOWER_UP"],
"mtu": 65536,
"xdp": {
"mode": 2,
"prog": {
"id": 5,
"tag": "e1e9d0ec0f55d638",
"jited": 1
}
},
"qdisc": "noqueue",
"operstate": "UNKNOWN",
"linkmode": "DEFAULT",
"group": "default",
"txqlen": 1000,
"link_type": "loopback",
"address": "00:00:00:00:00:00",
"broadcast": "00:00:00:00:00:00"
},[...]
]
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
---
ip/iplink_xdp.c | 74 ++++++++++++++++++++++++++++++++++-----------------------
lib/bpf.c | 19 ++++++++++-----
2 files changed, 57 insertions(+), 36 deletions(-)
diff --git a/ip/iplink_xdp.c b/ip/iplink_xdp.c
index 71f7798..2d2953a 100644
--- a/ip/iplink_xdp.c
+++ b/ip/iplink_xdp.c@@ -14,9 +14,9 @@ #include <linux/bpf.h> +#include "json_print.h" #include "xdp.h" #include "bpf_util.h" -#include "ip_common.h" extern int force;
@@ -82,6 +82,22 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic, return 0; } +static void xdp_dump_json(struct rtattr *tb[IFLA_XDP_MAX + 1]) +{ + __u32 prog_id = 0; + __u8 mode; + + mode = rta_getattr_u8(tb[IFLA_XDP_ATTACHED]); + if (tb[IFLA_XDP_PROG_ID]) + prog_id = rta_getattr_u32(tb[IFLA_XDP_PROG_ID]); + + open_json_object("xdp"); + print_uint(PRINT_JSON, "mode", NULL, mode); + if (prog_id) + bpf_dump_prog_info(NULL, prog_id); + close_json_object(); +} + void xdp_dump(FILE *fp, struct rtattr *xdp, bool link, bool details) { struct rtattr *tb[IFLA_XDP_MAX + 1];
@@ -94,34 +110,32 @@ void xdp_dump(FILE *fp, struct rtattr *xdp, bool link, bool details) return; mode = rta_getattr_u8(tb[IFLA_XDP_ATTACHED]); - if (is_json_context()) { - print_uint(PRINT_JSON, "attached", NULL, mode); - } else { - if (mode == XDP_ATTACHED_NONE) - return; - else if (details && link) - fprintf(fp, "%s prog/xdp", _SL_); - 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 - 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; - } - - if (prog_id) { - fprintf(fp, " "); - bpf_dump_prog_info(fp, prog_id); - } + if (mode == XDP_ATTACHED_NONE) + return; + else if (is_json_context()) + return details ? (void)0 : xdp_dump_json(tb); + else if (details && link) + fprintf(fp, "%s prog/xdp", _SL_); + 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 + 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; + } + + if (prog_id) { + fprintf(fp, " "); + bpf_dump_prog_info(fp, prog_id); } }
diff --git a/lib/bpf.c b/lib/bpf.c
index cfa1f79..10ea23a 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c@@ -40,6 +40,7 @@ #include <arpa/inet.h> #include "utils.h" +#include "json_print.h" #include "bpf_util.h" #include "bpf_elf.h"
@@ -186,23 +187,29 @@ int bpf_dump_prog_info(FILE *f, uint32_t id) int fd, ret, dump_ok = 0; SPRINT_BUF(tmp); - fprintf(f, "id %u ", id); + open_json_object("prog"); + print_uint(PRINT_ANY, "id", "id %u ", id); fd = bpf_prog_fd_by_id(id); if (fd < 0) - return dump_ok; + goto out; ret = bpf_prog_info_by_fd(fd, &info, &len); if (!ret && len) { - fprintf(f, "tag %s ", - hexstring_n2a(info.tag, sizeof(info.tag), - tmp, sizeof(tmp))); - if (info.jited_prog_len) + int jited = !!info.jited_prog_len; + + print_string(PRINT_ANY, "tag", "tag %s ", + hexstring_n2a(info.tag, sizeof(info.tag), + tmp, sizeof(tmp))); + print_uint(PRINT_JSON, "jited", NULL, jited); + if (jited && !is_json_context()) fprintf(f, "jited "); dump_ok = 1; } close(fd); +out: + close_json_object(); return dump_ok; }
--
1.9.3