diff --git a/include/bpf_util.h b/include/bpf_util.h index 6582ec8c..e818221d 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 201225f7..97971450 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -1146,7 +1146,7 @@ int print_linkinfo(const struct sockaddr_nl *who, "mtu", "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]) print_string(PRINT_ANY, "qdisc", @@ -1306,7 +1306,6 @@ int print_linkinfo(const struct sockaddr_nl *who, } } - if ((do_link || show_details) && tb[IFLA_IFALIAS]) { print_string(PRINT_FP, NULL, "%s ", _SL_); print_string(PRINT_ANY, @@ -1315,6 +1314,9 @@ int print_linkinfo(const struct sockaddr_nl *who, 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) { print_string(PRINT_FP, NULL, "%s", _SL_); __print_link_stats(fp, tb); diff --git a/ip/iplink_xdp.c b/ip/iplink_xdp.c index 3a61076e..71f77982 100644 --- a/ip/iplink_xdp.c +++ b/ip/iplink_xdp.c @@ -82,9 +82,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); @@ -98,6 +99,8 @@ void xdp_dump(FILE *fp, struct rtattr *xdp) } 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) @@ -106,11 +109,19 @@ void xdp_dump(FILE *fp, struct rtattr *xdp) 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 (tb[IFLA_XDP_PROG_ID]) - print_uint(PRINT_ANY, "prog_id", "/id:%u", - rta_getattr_u32(tb[IFLA_XDP_PROG_ID])); - - print_string(PRINT_FP, NULL, "%c", " "); } diff --git a/ip/xdp.h b/ip/xdp.h index ba897a29..1efd591b 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 c180934a..cfa1f79a 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, @@ -208,8 +214,9 @@ static int bpf_parse_string(char *arg, bool from_file, __u16 *bpf_len, if (from_file) { size_t tmp_len, op_len = sizeof("65535 255 255 4294967295,"); - char *tmp_string, *pos, c, c_prev = ' '; + char *tmp_string, *pos, c_prev = ' '; FILE *fp; + int c; tmp_len = sizeof("4096,") + BPF_MAXINSNS * op_len; tmp_string = pos = calloc(1, tmp_len); @@ -228,18 +235,20 @@ static int bpf_parse_string(char *arg, bool from_file, __u16 *bpf_len, case '\n': if (c_prev != ',') *(pos++) = ','; + c_prev = ','; break; case ' ': case '\t': if (c_prev != ' ') *(pos++) = c; + c_prev = ' '; break; default: *(pos++) = c; + c_prev = c; } if (pos - tmp_string == tmp_len) break; - c_prev = c; } if (!feof(fp)) { @@ -566,9 +575,9 @@ int bpf_trace_pipe(void) "/trace", 0, }; + int fd_in, fd_out = STDERR_FILENO; char tpipe[PATH_MAX]; const char *mnt; - int fd; mnt = bpf_find_mntpt("tracefs", TRACEFS_MAGIC, tracefs_mnt, sizeof(tracefs_mnt), tracefs_known_mnts); @@ -579,8 +588,8 @@ int bpf_trace_pipe(void) snprintf(tpipe, sizeof(tpipe), "%s/trace_pipe", mnt); - fd = open(tpipe, O_RDONLY); - if (fd < 0) + fd_in = open(tpipe, O_RDONLY); + if (fd_in < 0) return -1; fprintf(stderr, "Running! Hang up with ^C!\n\n"); @@ -588,15 +597,14 @@ int bpf_trace_pipe(void) static char buff[4096]; ssize_t ret; - ret = read(fd, buff, sizeof(buff) - 1); - if (ret > 0) { - if (write(STDERR_FILENO, buff, ret) != ret) - return -1; - fflush(stderr); - } + ret = read(fd_in, buff, sizeof(buff)); + if (ret > 0 && write(fd_out, buff, ret) == ret) + continue; + break; } - return 0; + close(fd_in); + return -1; } static int bpf_gen_global(const char *bpf_sub_dir) diff --git a/tc/f_bpf.c b/tc/f_bpf.c index c1154094..3f619d0d 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_action.c b/tc/m_action.c index 50d16b41..402228bb 100644 --- a/tc/m_action.c +++ b/tc/m_action.c @@ -242,7 +242,7 @@ done0: invarg("cookie must be a hex string\n", *argv); - act_ck_len = slen; + act_ck_len = slen / 2; argc--; argv++; } @@ -307,7 +307,7 @@ static int tc_print_one_action(FILE *f, struct rtattr *arg) print_tcstats2_attr(f, tb[TCA_ACT_STATS], "\t", NULL); if (tb[TCA_ACT_COOKIE]) { int strsz = RTA_PAYLOAD(tb[TCA_ACT_COOKIE]); - char b1[strsz+1]; + char b1[strsz * 2 + 1]; fprintf(f, "\n\tcookie len %d %s ", strsz, hexstring_n2a(RTA_DATA(tb[TCA_ACT_COOKIE]), diff --git a/tc/m_bpf.c b/tc/m_bpf.c index df559bcc..e3d0a2b1 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);