Consolidate dump of prog info to use bpf_dump_prog_info() when possible. Moving forward, we want to have a consistent output for BPF progs when being dumped. E.g. in cls/act case we used to dump tag as a separate netlink attribute before we had BPF_OBJ_GET_INFO_BY_FD bpf(2) command.
Move dumping tag into bpf_dump_prog_info() as well, and only dump the netlink attribute for older kernels. Also, reuse bpf_dump_prog_info() for XDP case, so we can dump tag and whether program was jited, which we currently don't show. Signed-off-by: Daniel Borkmann <dan...@iogearbox.net> --- include/bpf_util.h | 2 +- ip/ipaddress.c | 6 ++++-- ip/iplink_xdp.c | 19 +++++++++++++++---- ip/xdp.h | 2 +- lib/bpf.c | 12 +++++++++--- tc/f_bpf.c | 8 ++++---- tc/m_bpf.c | 8 ++++---- 7 files changed, 38 insertions(+), 19 deletions(-) diff --git a/include/bpf_util.h b/include/bpf_util.h index 6582ec8..e818221 100644 --- a/include/bpf_util.h +++ b/include/bpf_util.h @@ -261,7 +261,7 @@ int bpf_prog_load(enum bpf_prog_type type, const struct bpf_insn *insns, int bpf_prog_attach_fd(int prog_fd, int target_fd, enum bpf_attach_type type); int bpf_prog_detach_fd(int target_fd, enum bpf_attach_type type); -void bpf_dump_prog_info(FILE *f, uint32_t id); +int bpf_dump_prog_info(FILE *f, uint32_t id); #ifdef HAVE_ELF int bpf_send_map_fds(const char *path, const char *obj); diff --git a/ip/ipaddress.c b/ip/ipaddress.c index c9312f0..dbdd839 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -837,7 +837,7 @@ int print_linkinfo(const struct sockaddr_nl *who, if (tb[IFLA_MTU]) fprintf(fp, "mtu %u ", rta_getattr_u32(tb[IFLA_MTU])); if (tb[IFLA_XDP]) - xdp_dump(fp, tb[IFLA_XDP]); + xdp_dump(fp, tb[IFLA_XDP], do_link, false); if (tb[IFLA_QDISC]) fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC])); if (tb[IFLA_MASTER]) { @@ -951,12 +951,14 @@ int print_linkinfo(const struct sockaddr_nl *who, } } - if ((do_link || show_details) && tb[IFLA_IFALIAS]) { fprintf(fp, "%s alias %s", _SL_, rta_getattr_str(tb[IFLA_IFALIAS])); } + if ((do_link || show_details) && tb[IFLA_XDP]) + xdp_dump(fp, tb[IFLA_XDP], true, true); + if (do_link && show_stats) { fprintf(fp, "%s", _SL_); __print_link_stats(fp, tb); diff --git a/ip/iplink_xdp.c b/ip/iplink_xdp.c index 9ae9ee5..5aa66fe 100644 --- a/ip/iplink_xdp.c +++ b/ip/iplink_xdp.c @@ -81,9 +81,10 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic, return 0; } -void xdp_dump(FILE *fp, struct rtattr *xdp) +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); @@ -94,6 +95,8 @@ void xdp_dump(FILE *fp, struct rtattr *xdp) mode = rta_getattr_u8(tb[IFLA_XDP_ATTACHED]); 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) @@ -104,8 +107,16 @@ void xdp_dump(FILE *fp, struct rtattr *xdp) fprintf(fp, "xdp[%u]", mode); if (tb[IFLA_XDP_PROG_ID]) - fprintf(fp, "/id:%u", - rta_getattr_u32(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; + } - fprintf(fp, " "); + if (prog_id) { + fprintf(fp, " "); + bpf_dump_prog_info(fp, prog_id); + } } diff --git a/ip/xdp.h b/ip/xdp.h index ba897a2..1efd591 100644 --- a/ip/xdp.h +++ b/ip/xdp.h @@ -5,6 +5,6 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic, bool drv, bool offload); -void xdp_dump(FILE *fp, struct rtattr *tb); +void xdp_dump(FILE *fp, struct rtattr *tb, bool link, bool details); #endif /* __XDP__ */ diff --git a/lib/bpf.c b/lib/bpf.c index 7463fdc..cfa1f79 100644 --- a/lib/bpf.c +++ b/lib/bpf.c @@ -179,25 +179,31 @@ static int bpf_prog_info_by_fd(int fd, struct bpf_prog_info *info, return ret; } -void bpf_dump_prog_info(FILE *f, uint32_t id) +int bpf_dump_prog_info(FILE *f, uint32_t id) { struct bpf_prog_info info = {}; uint32_t len = sizeof(info); - int fd, ret; + int fd, ret, dump_ok = 0; + SPRINT_BUF(tmp); fprintf(f, "id %u ", id); fd = bpf_prog_fd_by_id(id); if (fd < 0) - return; + return dump_ok; 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) fprintf(f, "jited "); + dump_ok = 1; } close(fd); + return dump_ok; } static int bpf_parse_string(char *arg, bool from_file, __u16 *bpf_len, diff --git a/tc/f_bpf.c b/tc/f_bpf.c index 2f8d12a..4fb9209 100644 --- a/tc/f_bpf.c +++ b/tc/f_bpf.c @@ -177,6 +177,7 @@ static int bpf_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle) { struct rtattr *tb[TCA_BPF_MAX + 1]; + int dump_ok = 0; if (opt == NULL) return 0; @@ -221,7 +222,9 @@ static int bpf_print_opt(struct filter_util *qu, FILE *f, bpf_print_ops(f, tb[TCA_BPF_OPS], rta_getattr_u16(tb[TCA_BPF_OPS_LEN])); - if (tb[TCA_BPF_TAG]) { + if (tb[TCA_BPF_ID]) + dump_ok = bpf_dump_prog_info(f, rta_getattr_u32(tb[TCA_BPF_ID])); + if (!dump_ok && tb[TCA_BPF_TAG]) { SPRINT_BUF(b); fprintf(f, "tag %s ", @@ -230,9 +233,6 @@ static int bpf_print_opt(struct filter_util *qu, FILE *f, b, sizeof(b))); } - if (tb[TCA_BPF_ID]) - bpf_dump_prog_info(f, rta_getattr_u32(tb[TCA_BPF_ID])); - if (tb[TCA_BPF_POLICE]) { fprintf(f, "\n"); tc_print_police(f, tb[TCA_BPF_POLICE]); diff --git a/tc/m_bpf.c b/tc/m_bpf.c index df559bc..e3d0a2b 100644 --- a/tc/m_bpf.c +++ b/tc/m_bpf.c @@ -154,6 +154,7 @@ static int bpf_print_opt(struct action_util *au, FILE *f, struct rtattr *arg) { struct rtattr *tb[TCA_ACT_BPF_MAX + 1]; struct tc_act_bpf *parm; + int dump_ok = 0; if (arg == NULL) return -1; @@ -177,7 +178,9 @@ static int bpf_print_opt(struct action_util *au, FILE *f, struct rtattr *arg) fprintf(f, " "); } - if (tb[TCA_ACT_BPF_TAG]) { + if (tb[TCA_ACT_BPF_ID]) + dump_ok = bpf_dump_prog_info(f, rta_getattr_u32(tb[TCA_ACT_BPF_ID])); + if (!dump_ok && tb[TCA_ACT_BPF_TAG]) { SPRINT_BUF(b); fprintf(f, "tag %s ", @@ -186,9 +189,6 @@ static int bpf_print_opt(struct action_util *au, FILE *f, struct rtattr *arg) b, sizeof(b))); } - if (tb[TCA_ACT_BPF_ID]) - bpf_dump_prog_info(f, rta_getattr_u32(tb[TCA_ACT_BPF_ID])); - print_action_control(f, "default-action ", parm->action, "\n"); fprintf(f, "\tindex %u ref %d bind %d", parm->index, parm->refcnt, parm->bindcnt); -- 1.9.3