Reputation: 6892
With a ebpf program loaded and xsk_socket__create()
succesful the element in the BPF_MAP_TYPE_XSKMAP array in the ebpf program is still not set. Traffic is captured by the ebpf program but is not redirected to the user-space socket.
I am using linux-5.17.8
and build libbpf and bpftool from kernel source. The ebpf program is loaded and linked to the interface with;
bpftool prog loadall ./xdp_kern.o /sys/fs/bpf/xdptest pinmaps /sys/fs/bpf/xdptest
bpftool net attach xdpdrv pinned /sys/fs/bpf/xdptest/xdp_prog_redirect dev eth1
There is only channel 0 and Q=0 is used in the xsk_socket__create()
call (so this is not the "listen to wrong channel" problem described in the XDP docs).
Traffic is captured and I make a printout in the kernel program;
#define Dx(fmt, ...) \
({ \
char ____fmt[] = fmt; \
bpf_trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \
})
...
int index = ctx->rx_queue_index;
Dx("Q=%2d %s", index, bpf_map_lookup_elem(&xsks_map, &index) ? "AF_XDP" : "-");
So I can verify that the element is empty.
From linux-5.13
xsk_socket__create()
must be called with;
xsk_cfg.libbpf_flags = XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD;
Or you will get;
libbpf: Netlink-based XDP prog detected, please unload it in order to launch AF_XDP prog
Failed xsk_socket__create (ingress); Invalid argument
Can any one tell what I do wrong here?
Since xsk_socket__create()
succeeds I assume some BPF_MAP_TYPE_XSKMAP somewhere is filled, but not the one in my ebpf program. I have tried to declare it in both old and new ways;
// https://github.com/libbpf/libbpf/wiki/Libbpf:-the-road-to-v1.0#drop-support-for-legacy-bpf-map-declaration-syntax
// Socket map for redirect to user-space
#if 0
struct bpf_map_def SEC("maps") xsks_map = {
.type = BPF_MAP_TYPE_XSKMAP,
//.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(int),
.max_entries = 16, /* Must be > nqueues for the nic */
};
#else
struct {
__uint(type, BPF_MAP_TYPE_XSKMAP);
__uint(max_entries, 16);
__type(key, int);
__type(value, int);
} xsks_map SEC("maps");
#endif
Upvotes: 0
Views: 618
Reputation: 11
There has been a lot of changes since 5.13 in bpf, so things that worked before might not work anymore. The xdp-tutorial is not updated to work with the latest kernel versions either, so there is not much examples to use.
Regarding this particular question, it looks like the idea is to move away from netlink based bpf_prog* to bpf_link* APIs. But, after the change it seems to prefer only bpf_link* if the support is available, even if you have loaded the XDP program via "bpftool prog", it would have been nice to fallback to using XDP programs that were loaded using bpftool prog. So it would be better to use bpf_link instead. Or if you are building from kernel source, the following patch might help.
Subject: [PATCH] Allow bpf_link and netlink based program loading at the same
time
---
tools/lib/bpf/xsk.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c
index af136f73b09d..597d7102b25a 100644
--- a/tools/lib/bpf/xsk.c
+++ b/tools/lib/bpf/xsk.c
@@ -861,7 +861,8 @@ static int __xsk_setup_xdp_prog(struct xsk_socket *_xdp, int *xsks_map_fd)
if (ctx->has_bpf_link)
err = xsk_link_lookup(ctx->ifindex, &prog_id, &ctx->link_fd);
- else
+
+ if (!prog_id)
err = bpf_get_link_xdp_id(ctx->ifindex, &prog_id, xsk->config.xdp_flags);
if (err)
--
2.34.1
Upvotes: 1