diff --git a/configure b/configure index 174bf459..70fdfdf7 100755 --- a/configure +++ b/configure @@ -210,6 +210,7 @@ check_libbpf_functions() check_libbpf_function "bpf_program__insn_cnt" "(NULL)" "$LIBBPF_CFLAGS" "$LIBBPF_LDLIBS" check_libbpf_function "bpf_map_create" "(0, NULL, 0, 0, 0, NULL)" "$LIBBPF_CFLAGS" "$LIBBPF_LDLIBS" check_libbpf_function "perf_buffer__new_raw" "(0, 0, NULL, NULL, NULL, NULL)" "$LIBBPF_CFLAGS" "$LIBBPF_LDLIBS" + check_libbpf_function "bpf_xdp_attach" "(0, 0, 0, NULL)" "$LIBBPF_CFLAGS" "$LIBBPF_LDLIBS" } get_libbpf_version() diff --git a/lib/libxdp/libxdp.c b/lib/libxdp/libxdp.c index 14ca3125..1a1e0b07 100644 --- a/lib/libxdp/libxdp.c +++ b/lib/libxdp/libxdp.c @@ -411,18 +411,30 @@ static int xdp_lock_release(int lock_fd) return err; } +static int do_xdp_attach(int ifindex, int prog_fd, int old_fd, __u32 xdp_flags) +{ +#ifdef HAVE_LIBBPF_BPF_XDP_ATTACH + LIBBPF_OPTS(bpf_xdp_attach_opts, opts, + .old_prog_fd = old_fd); + return bpf_xdp_attach(ifindex, prog_fd, xdp_flags, &opts); +#else + DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, opts, .old_fd = old_fd); + return bpf_set_link_xdp_fd_opts(ifindex, prog_fd, xdp_flags, old_fd ? &opts : NULL); +#endif +} + static int xdp_attach_fd(int prog_fd, int old_fd, int ifindex, enum xdp_attach_mode mode) { - DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, opts, .old_fd = old_fd); - struct bpf_xdp_set_link_opts *setopts = &opts; int err = 0, xdp_flags = 0; pr_debug("Replacing XDP fd %d with %d on ifindex %d\n", old_fd, prog_fd, ifindex); - if (old_fd == -1) + if (old_fd == -1) { xdp_flags |= XDP_FLAGS_UPDATE_IF_NOEXIST; + old_fd = 0; + } switch (mode) { case XDP_MODE_SKB: @@ -438,11 +450,11 @@ static int xdp_attach_fd(int prog_fd, int old_fd, int ifindex, break; } again: - err = bpf_set_link_xdp_fd_opts(ifindex, prog_fd, xdp_flags, setopts); + err = do_xdp_attach(ifindex, prog_fd, old_fd, xdp_flags); if (err < 0) { - if (err == -EINVAL && setopts) { + if (err == -EINVAL && old_fd) { pr_debug("Got 'invalid argument', trying again without old_fd\n"); - setopts = NULL; + old_fd = 0; goto again; } pr_info("Error attaching XDP program to ifindex %d: %s\n", @@ -1989,43 +2001,84 @@ static struct xdp_multiprog *xdp_multiprog__from_id(__u32 id, __u32 hw_id, return ERR_PTR(err); } +static int xdp_get_ifindex_prog_id(int ifindex, __u32 *prog_id, + __u32 *hw_prog_id, enum xdp_attach_mode *mode) +{ + __u32 _prog_id, _drv_prog_id, _hw_prog_id, _skb_prog_id; + enum xdp_attach_mode _mode; + __u8 _attach_mode; + + if (!hw_prog_id) + hw_prog_id = &_prog_id; + if (!mode) + mode = &_mode; + int err; +#ifdef HAVE_LIBBPF_BPF_XDP_ATTACH + LIBBPF_OPTS(bpf_xdp_query_opts, opts); + err = bpf_xdp_query(ifindex, 0, &opts); + if (err) + return err; + + _drv_prog_id = opts.drv_prog_id; + _skb_prog_id = opts.skb_prog_id; + _hw_prog_id = opts.hw_prog_id; + _attach_mode = opts.attach_mode; +#else + struct xdp_link_info xinfo = {}; + err = bpf_get_link_xdp_info(ifindex, &xinfo, sizeof(xinfo), 0); + if (err) + return err; + + _drv_prog_id = xdp_info.drv_prog_id; + _skb_prog_id = xdp_info.skb_prog_id; + _hw_prog_id = xdp_info.hw_prog_id; + _attach_mode = xdp_info.attach_mode; +#endif + switch (_attach_mode) { + case XDP_ATTACHED_SKB: + *prog_id = _skb_prog_id; + *mode = XDP_MODE_SKB; + break; + case XDP_ATTACHED_DRV: + *prog_id = _drv_prog_id; + *mode = XDP_MODE_NATIVE; + break; + case XDP_ATTACHED_MULTI: + if (_drv_prog_id) { + *prog_id = _drv_prog_id; + *mode = XDP_MODE_NATIVE; + } else if (_skb_prog_id) { + *prog_id = _skb_prog_id; + *mode = XDP_MODE_SKB; + } + *hw_prog_id = _hw_prog_id; + break; + case XDP_ATTACHED_HW: + *hw_prog_id = _hw_prog_id; + *mode = XDP_MODE_UNSPEC; + break; + case XDP_ATTACHED_NONE: + default: + *mode = XDP_MODE_UNSPEC; + break; + } + return 0; +} struct xdp_multiprog *xdp_multiprog__get_from_ifindex(int ifindex) { enum xdp_attach_mode mode = XDP_MODE_UNSPEC; - struct xdp_link_info xinfo = {}; struct xdp_multiprog *mp; __u32 hw_prog_id = 0; __u32 prog_id = 0; int err; - err = bpf_get_link_xdp_info(ifindex, &xinfo, sizeof(xinfo), 0); + err = xdp_get_ifindex_prog_id(ifindex, &prog_id, &hw_prog_id, &mode); if (err) return ERR_PTR(err); - if (xinfo.attach_mode == XDP_ATTACHED_SKB) { - prog_id = xinfo.skb_prog_id; - mode = XDP_MODE_SKB; - } else if (xinfo.attach_mode == XDP_ATTACHED_DRV) { - prog_id = xinfo.drv_prog_id; - mode = XDP_MODE_NATIVE; - } else if (xinfo.attach_mode == XDP_ATTACHED_HW) { - hw_prog_id = xinfo.hw_prog_id; - mode = XDP_MODE_UNSPEC; - } else if (xinfo.attach_mode == XDP_ATTACHED_MULTI) { - if (xinfo.drv_prog_id) { - prog_id = xinfo.drv_prog_id; - mode = XDP_MODE_NATIVE; - } else if (xinfo.skb_prog_id) { - prog_id = xinfo.skb_prog_id; - mode = XDP_MODE_SKB; - } - hw_prog_id = xinfo.hw_prog_id; - } - - if (!prog_id && !hw_prog_id) { + if (!prog_id && !hw_prog_id) return ERR_PTR(-ENOENT); - } mp = xdp_multiprog__from_id(prog_id, hw_prog_id, ifindex); if (!IS_ERR_OR_NULL(mp)) @@ -2725,30 +2778,6 @@ int xdp_multiprog__program_count(const struct xdp_multiprog *mp) return mp->num_links; } -static __u32 xdp_get_ifindex_prog_id(int ifindex) -{ - struct xdp_link_info xinfo = {}; - __u32 prog_id = 0; - - if (!bpf_get_link_xdp_info(ifindex, &xinfo, sizeof(xinfo), 0)) { - switch (xinfo.attach_mode) { - case XDP_ATTACHED_SKB: - prog_id = xinfo.skb_prog_id; - break; - case XDP_ATTACHED_DRV: - prog_id = xinfo.drv_prog_id; - break; - case XDP_ATTACHED_MULTI: - prog_id = xinfo.drv_prog_id ?: xinfo.skb_prog_id; - break; - case XDP_ATTACHED_NONE: - case XDP_ATTACHED_HW: - default:; - } - } - return prog_id; -} - static int remove_pin_dir(const char *subdir) { char prog_path[PATH_MAX], pin_path[PATH_MAX]; @@ -2802,7 +2831,7 @@ static int remove_pin_dir(const char *subdir) int libxdp_clean_references(int ifindex) { int err = 0, lock_fd, path_ifindex; - __u32 dir_prog_id, prog_id; + __u32 dir_prog_id, prog_id = 0; DIR *d; const char *dir = get_bpffs_dir(); @@ -2833,7 +2862,7 @@ int libxdp_clean_references(int ifindex) if (ifindex && path_ifindex != ifindex) continue; - prog_id = xdp_get_ifindex_prog_id(path_ifindex); + xdp_get_ifindex_prog_id(path_ifindex, &prog_id, NULL, NULL); if (!prog_id || prog_id != dir_prog_id) { pr_info("Prog id %"PRIu32" no longer attached on ifindex %d, removing pin directory %s\n", dir_prog_id, path_ifindex, dent->d_name); diff --git a/lib/libxdp/xsk.c b/lib/libxdp/xsk.c index 42c9eb67..e8406a0e 100644 --- a/lib/libxdp/xsk.c +++ b/lib/libxdp/xsk.c @@ -483,7 +483,7 @@ static int xsk_size_map(struct xdp_program *xdp_prog, char *ifname) if (!map) return -ENOENT; - err = bpf_map__resize(map, max_queues); + err = bpf_map__set_max_entries(map, max_queues); if (err) return err; diff --git a/lib/testing/test-tool.c b/lib/testing/test-tool.c index 06ef8343..54d73502 100644 --- a/lib/testing/test-tool.c +++ b/lib/testing/test-tool.c @@ -67,6 +67,17 @@ static struct bpf_object *open_bpf_obj(const char *filename, return obj; } +static int do_xdp_attach(int ifindex, int prog_fd, int old_fd, __u32 xdp_flags) +{ +#ifdef HAVE_LIBBPF_BPF_XDP_ATTACH + LIBBPF_OPTS(bpf_xdp_attach_opts, opts, + .old_prog_fd = old_fd); + return bpf_xdp_attach(ifindex, prog_fd, xdp_flags, &opts); +#else + DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, opts, .old_fd = old_fd); + return bpf_set_link_xdp_fd_opts(ifindex, prog_fd, xdp_flags, old_fd ? &opts : NULL); +#endif +} int do_load(const void *cfg, __unused const char *pin_root_path) { @@ -138,8 +149,7 @@ int do_load(const void *cfg, __unused const char *pin_root_path) case XDP_MODE_UNSPEC: break; } - err = bpf_set_link_xdp_fd_opts(opt->iface.ifindex, prog_fd, xdp_flags, - NULL); + err = do_xdp_attach(opt->iface.ifindex, prog_fd, 0, xdp_flags); if (err < 0) { pr_info("ERROR: Failed attaching XDP program to ifindex %d: %s\n", opt->iface.ifindex, strerror(-err)); diff --git a/xdp-dump/xdpdump.c b/xdp-dump/xdpdump.c index 9e7d671b..b60707ec 100644 --- a/xdp-dump/xdpdump.c +++ b/xdp-dump/xdpdump.c @@ -1311,7 +1311,6 @@ static bool load_and_attach_trace(struct dumpopt *cfg, struct bpf_link *trace_link_fexit = NULL; struct bpf_map *perf_map; struct bpf_map *data_map; - const struct bpf_map_def *data_map_def; struct trace_configuration trace_cfg; if (idx >= progs->nr_of_progs || progs->nr_of_progs == 0) { @@ -1347,9 +1346,7 @@ static bool load_and_attach_trace(struct dumpopt *cfg, goto error_exit; } - data_map_def = bpf_map__def(data_map); - if (!data_map_def || - data_map_def->value_size != sizeof(trace_cfg)) { + if (bpf_map__value_size(data_map) != sizeof(trace_cfg)) { pr_warn("ERROR: Can't find the correct sized .data MAP in the " "trace program!\n"); goto error_exit; @@ -1525,7 +1522,6 @@ static bool load_xdp_trace_program(struct dumpopt *cfg, struct xdp_program *prog; struct bpf_map *perf_map; struct bpf_map *data_map; - const struct bpf_map_def *data_map_def; struct trace_configuration trace_cfg; if (!cfg || !progs) @@ -1559,9 +1555,7 @@ static bool load_xdp_trace_program(struct dumpopt *cfg, goto error_exit; } - data_map_def = bpf_map__def(data_map); - if (!data_map_def || - data_map_def->value_size != sizeof(trace_cfg)) { + if (bpf_map__value_size(data_map) != sizeof(trace_cfg)) { pr_warn("ERROR: Can't find the correct sized .data MAP in the xdp program!\n"); goto error_exit; }