@@ -240,7 +240,7 @@ $(OUTPUT)/flow_dissector_load: $(TESTING_HELPERS)
$(OUTPUT)/test_maps: $(TESTING_HELPERS)
$(OUTPUT)/test_verifier: $(TESTING_HELPERS) $(CAP_HELPERS)
$(OUTPUT)/xsk.o: $(BPFOBJ)
-$(OUTPUT)/xskxceiver: $(OUTPUT)/xsk.o
+$(OUTPUT)/xskxceiver: $(OUTPUT)/xsk.o $(OUTPUT)/xsk_def_prog.skel.h
BPFTOOL ?= $(DEFAULT_BPFTOOL)
$(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \
new file mode 100644
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2022 Intel */
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+struct {
+ __uint(type, BPF_MAP_TYPE_XSKMAP);
+ __uint(max_entries, 1);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(int));
+} xsk SEC(".maps");
+
+SEC("xdp") int xsk_def_prog(struct xdp_md *xdp)
+{
+ return bpf_redirect_map(&xsk, 0, XDP_DROP);
+}
+
+char _license[] SEC("license") = "GPL";
@@ -267,87 +267,37 @@ int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area,
return err;
}
-static int __xsk_load_xdp_prog(int xsk_map_fd)
+int xsk_attach_xdp_program(struct bpf_program *prog, int ifindex, u32 xdp_flags)
{
- static const int log_buf_size = 16 * 1024;
- char log_buf[log_buf_size];
int prog_fd;
- /* This is the post-5.3 kernel C-program:
- * SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx)
- * {
- * return bpf_redirect_map(&xsks_map, ctx->rx_queue_index, XDP_PASS);
- * }
- */
- struct bpf_insn prog[] = {
- /* r2 = *(u32 *)(r1 + 16) */
- BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 16),
- /* r1 = xskmap[] */
- BPF_LD_MAP_FD(BPF_REG_1, xsk_map_fd),
- /* r3 = XDP_PASS */
- BPF_MOV64_IMM(BPF_REG_3, 2),
- /* call bpf_redirect_map */
- BPF_EMIT_CALL(BPF_FUNC_redirect_map),
- BPF_EXIT_INSN(),
- };
- size_t insns_cnt = ARRAY_SIZE(prog);
- LIBBPF_OPTS(bpf_prog_load_opts, opts,
- .log_buf = log_buf,
- .log_size = log_buf_size,
- );
-
- prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, NULL, "LGPL-2.1 or BSD-2-Clause",
- prog, insns_cnt, &opts);
- if (prog_fd < 0)
- pr_warn("BPF log buffer:\n%s", log_buf);
-
- return prog_fd;
+ prog_fd = bpf_program__fd(prog);
+ return bpf_xdp_attach(ifindex, prog_fd, xdp_flags, NULL);
}
-int xsk_attach_xdp_program(int ifindex, int prog_fd, u32 xdp_flags)
+void xsk_detach_xdp_program(int ifindex, u32 xdp_flags)
{
- DECLARE_LIBBPF_OPTS(bpf_link_create_opts, opts);
- __u32 prog_id = 0;
- int link_fd;
- int err;
-
- err = bpf_xdp_query_id(ifindex, xdp_flags, &prog_id);
- if (err) {
- pr_warn("getting XDP prog id failed\n");
- return err;
- }
-
- /* If there's a netlink-based XDP prog loaded on interface, bail out
- * and ask user to do the removal by himself
- */
- if (prog_id) {
- pr_warn("Netlink-based XDP prog detected, please unload it in order to launch AF_XDP prog\n");
- return -EINVAL;
- }
-
- opts.flags = xdp_flags & ~(XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_REPLACE);
+ bpf_xdp_detach(ifindex, xdp_flags, NULL);
+}
- link_fd = bpf_link_create(prog_fd, ifindex, BPF_XDP, &opts);
- if (link_fd < 0)
- pr_warn("bpf_link_create failed: %s\n", strerror(errno));
+void xsk_clear_xskmap(struct bpf_map *map)
+{
+ u32 index = 0;
+ int map_fd;
- return link_fd;
+ map_fd = bpf_map__fd(map);
+ bpf_map_delete_elem(map_fd, &index);
}
-int xsk_load_xdp_program(int *xsk_map_fd, int *prog_fd)
+int xsk_update_xskmap(struct bpf_map *map, struct xsk_socket *xsk)
{
- *xsk_map_fd = bpf_map_create(BPF_MAP_TYPE_XSKMAP, "xsks_map", sizeof(int), sizeof(int),
- XSKMAP_SIZE, NULL);
- if (*xsk_map_fd < 0)
- return *xsk_map_fd;
-
- *prog_fd = __xsk_load_xdp_prog(*xsk_map_fd);
- if (*prog_fd < 0) {
- close(*xsk_map_fd);
- return *prog_fd;
- }
+ int map_fd, sock_fd;
+ u32 index = 0;
- return 0;
+ map_fd = bpf_map__fd(map);
+ sock_fd = xsk_socket__fd(xsk);
+
+ return bpf_map_update_elem(map_fd, &index, &sock_fd, 0);
}
static struct xsk_ctx *xsk_get_ctx(struct xsk_umem *umem, int ifindex,
@@ -197,8 +197,10 @@ struct xsk_umem_config {
__u32 flags;
};
-int xsk_load_xdp_program(int *xsk_map_fd, int *prog_fd);
-int xsk_attach_xdp_program(int ifindex, int prog_fd, u32 xdp_flags);
+int xsk_attach_xdp_program(struct bpf_program *prog, int ifindex, u32 xdp_flags);
+void xsk_detach_xdp_program(int ifindex, u32 xdp_flags);
+int xsk_update_xskmap(struct bpf_map *map, struct xsk_socket *xsk);
+void xsk_clear_xskmap(struct bpf_map *map);
struct xsk_socket_config {
__u32 rx_size;
@@ -1215,7 +1215,7 @@ static void thread_common_ops_tx(struct test_spec *test, struct ifobject *ifobje
{
xsk_configure_socket(test, ifobject, test->ifobj_rx->umem, true);
ifobject->xsk = &ifobject->xsk_arr[0];
- ifobject->xsk_map_fd = test->ifobj_rx->xsk_map_fd;
+ ifobject->xskmap = test->ifobj_rx->xskmap;
memcpy(ifobject->umem, test->ifobj_rx->umem, sizeof(struct xsk_umem_info));
}
@@ -1255,9 +1255,8 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
u64 umem_sz = ifobject->umem->num_frames * ifobject->umem->frame_size;
int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
LIBBPF_OPTS(bpf_xdp_query_opts, opts);
- u32 queue_id = 0;
- int ret, fd;
void *bufs;
+ int ret;
if (ifobject->umem->unaligned_mode)
mmap_flags |= MAP_HUGETLB;
@@ -1282,8 +1281,7 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
if (!ifobject->rx_on)
return;
- fd = xsk_socket__fd(ifobject->xsk->xsk);
- ret = bpf_map_update_elem(ifobject->xsk_map_fd, &queue_id, &fd, 0);
+ ret = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk->xsk);
if (ret)
exit_with_error(errno);
}
@@ -1317,18 +1315,17 @@ static void *worker_testapp_validate_rx(void *arg)
{
struct test_spec *test = (struct test_spec *)arg;
struct ifobject *ifobject = test->ifobj_rx;
- int id = 0, err, fd = xsk_socket__fd(ifobject->xsk->xsk);
struct pollfd fds = { };
- u32 queue_id = 0;
+ int err;
if (test->current_step == 1) {
thread_common_ops(test, ifobject);
} else {
- bpf_map_delete_elem(ifobject->xsk_map_fd, &id);
- err = bpf_map_update_elem(ifobject->xsk_map_fd, &queue_id, &fd, 0);
+ xsk_clear_xskmap(ifobject->xskmap);
+ err = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk->xsk);
if (err) {
- printf("Error: Failed to update xskmap, error %s\n", strerror(err));
- exit_with_error(err);
+ printf("Error: Failed to update xskmap, error %s\n", strerror(-err));
+ exit_with_error(-err);
}
}
@@ -1398,10 +1395,8 @@ static int testapp_validate_traffic_single_thread(struct test_spec *test, struct
pthread_join(t0, NULL);
if (test->total_steps == test->current_step || test->fail) {
- u32 queue_id = 0;
-
xsk_socket__delete(ifobj->xsk->xsk);
- bpf_map_delete_elem(ifobj->xsk_map_fd, &queue_id);
+ xsk_clear_xskmap(ifobj->xskmap);
testapp_clean_xsk_umem(ifobj);
}
@@ -1490,14 +1485,14 @@ static void testapp_bidi(struct test_spec *test)
static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj_rx)
{
- int ret, queue_id = 0, fd = xsk_socket__fd(ifobj_rx->xsk->xsk);
+ int ret;
xsk_socket__delete(ifobj_tx->xsk->xsk);
xsk_socket__delete(ifobj_rx->xsk->xsk);
ifobj_tx->xsk = &ifobj_tx->xsk_arr[1];
ifobj_rx->xsk = &ifobj_rx->xsk_arr[1];
- ret = bpf_map_update_elem(ifobj_rx->xsk_map_fd, &queue_id, &fd, 0);
+ ret = xsk_update_xskmap(ifobj_rx->xskmap, ifobj_rx->xsk->xsk);
if (ret)
exit_with_error(errno);
}
@@ -1659,12 +1654,26 @@ static void testapp_invalid_desc(struct test_spec *test)
pkt_stream_restore_default(test);
}
+static int xsk_load_xdp_program(struct ifobject *ifobj)
+{
+ ifobj->def_prog = xsk_def_prog__open_and_load();
+ if (libbpf_get_error(ifobj->def_prog))
+ return libbpf_get_error(ifobj->def_prog);
+
+ return 0;
+}
+
+static void xsk_unload_xdp_program(struct ifobject *ifobj)
+{
+ xsk_def_prog__destroy(ifobj->def_prog);
+}
+
static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *src_mac,
const char *dst_ip, const char *src_ip, const u16 dst_port,
const u16 src_port, thread_func_t func_ptr, bool load_xdp)
{
- int xsk_map_fd, prog_fd, err;
struct in_addr ip;
+ int err;
memcpy(ifobj->dst_mac, dst_mac, ETH_ALEN);
memcpy(ifobj->src_mac, src_mac, ETH_ALEN);
@@ -1683,20 +1692,20 @@ static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *
if (!load_xdp)
return;
- err = xsk_load_xdp_program(&xsk_map_fd, &prog_fd);
+ err = xsk_load_xdp_program(ifobj);
if (err) {
printf("Error loading XDP program\n");
exit_with_error(err);
}
- ifobj->xsk_map_fd = xsk_map_fd;
- ifobj->prog_fd = prog_fd;
ifobj->xdp_flags = mode_to_xdp_flags(TEST_MODE_SKB);
- ifobj->link_fd = xsk_attach_xdp_program(ifobj->ifindex, prog_fd, ifobj->xdp_flags);
- if (ifobj->link_fd < 0) {
+ err = xsk_attach_xdp_program(ifobj->def_prog->progs.xsk_def_prog, ifobj->ifindex,
+ ifobj->xdp_flags);
+ if (err) {
printf("Error attaching XDP program\n");
- exit_with_error(ifobj->link_fd);
+ exit_with_error(-err);
}
+ ifobj->xskmap = ifobj->def_prog->maps.xsk;
}
static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_type type)
@@ -1831,9 +1840,6 @@ static struct ifobject *ifobject_create(void)
static void ifobject_delete(struct ifobject *ifobj)
{
- close(ifobj->prog_fd);
- close(ifobj->xsk_map_fd);
-
free(ifobj->umem);
free(ifobj->xsk_arr);
free(ifobj);
@@ -1872,13 +1878,15 @@ static void change_to_drv_mode(struct ifobject *ifobj)
LIBBPF_OPTS(bpf_xdp_query_opts, opts);
int ret;
- close(ifobj->link_fd);
- ifobj->link_fd = xsk_attach_xdp_program(ifobj->ifindex, ifobj->prog_fd,
- XDP_FLAGS_DRV_MODE);
- if (ifobj->link_fd < 0) {
+ xsk_detach_xdp_program(ifobj->ifindex, ifobj->xdp_flags);
+ ifobj->xdp_flags = XDP_FLAGS_DRV_MODE;
+ ret = xsk_attach_xdp_program(ifobj->def_prog->progs.xsk_def_prog, ifobj->ifindex,
+ ifobj->xdp_flags);
+ if (ret) {
printf("Error attaching XDP program\n");
- exit_with_error(-ifobj->link_fd);
+ exit_with_error(-ret);
}
+ ifobj->xskmap = ifobj->def_prog->maps.xsk;
ret = bpf_xdp_query(ifobj->ifindex, XDP_FLAGS_DRV_MODE, &opts);
if (ret)
@@ -1963,6 +1971,8 @@ int main(int argc, char **argv)
pkt_stream_delete(tx_pkt_stream_default);
pkt_stream_delete(rx_pkt_stream_default);
+ xsk_unload_xdp_program(ifobj_tx);
+ xsk_unload_xdp_program(ifobj_rx);
ifobject_delete(ifobj_tx);
ifobject_delete(ifobj_rx);
@@ -5,6 +5,8 @@
#ifndef XSKXCEIVER_H_
#define XSKXCEIVER_H_
+#include "xsk_def_prog.skel.h"
+
#ifndef SOL_XDP
#define SOL_XDP 283
#endif
@@ -138,9 +140,8 @@ struct ifobject {
thread_func_t func_ptr;
validation_func_t validation_func;
struct pkt_stream *pkt_stream;
- int xsk_map_fd;
- int prog_fd;
- int link_fd;
+ struct xsk_def_prog *def_prog;
+ struct bpf_map *xskmap;
int ifindex;
u32 dst_ip;
u32 src_ip;