X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ip%2Fiplink_xdp.c;h=4a490bc8fb66c65448ba860355d8837be2eec3c0;hb=2e320d8b7e74d667628ede35d2ec0340347cd2af;hp=9ae9ee5d06650cee5bb4f4ce607a7d3e0247eb06;hpb=1b5e809466376df1be0e9e7e5460605c974ad42b;p=mirror_iproute2.git diff --git a/ip/iplink_xdp.c b/ip/iplink_xdp.c index 9ae9ee5d..4a490bc8 100644 --- a/ip/iplink_xdp.c +++ b/ip/iplink_xdp.c @@ -14,8 +14,9 @@ #include -#include "xdp.h" #include "bpf_util.h" +#include "utils.h" +#include "ip_common.h" extern int force; @@ -47,10 +48,11 @@ static int xdp_delete(struct xdp_req *xdp) return 0; } -int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic, - bool drv, bool offload) +int xdp_parse(int *argc, char ***argv, struct iplink_req *req, + const char *ifname, bool generic, bool drv, bool offload) { struct bpf_cfg_in cfg = { + .type = BPF_PROG_TYPE_XDP, .argc = *argc, .argv = *argv, }; @@ -58,6 +60,14 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic, .req = req, }; + if (offload) { + int ifindex = ll_name_to_index(ifname); + + if (!ifindex) + incomplete_command(); + cfg.ifindex = ifindex; + } + if (!force) xdp.flags |= XDP_FLAGS_UPDATE_IF_NOEXIST; if (generic) @@ -73,7 +83,7 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic, return xdp_delete(&xdp); } - if (bpf_parse_common(BPF_PROG_TYPE_XDP, &cfg, &bpf_cb_ops, &xdp)) + if (bpf_parse_and_load_common(&cfg, &bpf_cb_ops, &xdp)) return -1; *argc = cfg.argc; @@ -81,7 +91,71 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic, return 0; } -void xdp_dump(FILE *fp, struct rtattr *xdp) +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; + __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); + + 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]; __u8 mode; @@ -94,18 +168,32 @@ void xdp_dump(FILE *fp, struct rtattr *xdp) mode = rta_getattr_u8(tb[IFLA_XDP_ATTACHED]); if (mode == XDP_ATTACHED_NONE) return; + else if (is_json_context()) + return details ? (void)0 : xdp_dump_json(tb); + else if (details && link) + /* 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]) - fprintf(fp, "/id:%u", - rta_getattr_u32(tb[IFLA_XDP_PROG_ID])); + 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"); + } - fprintf(fp, " "); + if (!details || !link) + fprintf(fp, " "); }