【发布时间】:2022-06-15 17:54:26
【问题描述】:
加载了 ebpf 程序并且 xsk_socket__create() 成功后,ebpf 程序中的 BPF_MAP_TYPE_XSKMAP 数组中的元素仍未设置。流量被 ebpf 程序捕获,但不会重定向到用户空间套接字。
我正在使用linux-5.17.8 并从内核源代码构建 libbpf 和 bpftool。 ebpf程序被加载并链接到接口;
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
只有频道 0,并且在 xsk_socket__create() 调用中使用了 Q=0(所以这不是 XDP 文档中描述的“听错频道”问题)。
流量被捕获,我在内核程序中打印输出;
#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" : "-");
所以我可以验证元素是否为空。
来自linux-5.13 xsk_socket__create() 必须调用;
xsk_cfg.libbpf_flags = XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD;
否则你会得到;
libbpf: Netlink-based XDP prog detected, please unload it in order to launch AF_XDP prog
Failed xsk_socket__create (ingress); Invalid argument
谁能告诉我这里做错了什么?
由于xsk_socket__create() 成功,我假设 some BPF_MAP_TYPE_XSKMAP somewhere 已填充,但不是我的 ebpf 程序中的那个。我尝试过以新旧两种方式声明它;
// 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
【问题讨论】:
-
在linux-5.13 之前这个工作,但我加载了
ip link set dev eth1 xdpgeneric pinned /sys/fs/bpf/xdptest/xdp_prog_redirect(这样加载也不起作用)
标签: xdp-bpf