【问题标题】:BPF_MAP_TYPE_XSKMAP element not set even though xsk_socket__create() succeeds即使 xsk_socket__create() 成功,也未设置 BPF_MAP_TYPE_XSKMAP 元素
【发布时间】: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


【解决方案1】:

自 5.13 以来,bpf 发生了很多变化,因此以前有效的东西可能不再有效。 xdp-tutorial 也没有更新为与最新的内核版本一起使用,因此没有太多示例可供使用。

关于这个特定的问题,看起来这个想法是move away from netlink based bpf_prog* to bpf_link* APIs。但是,在更改之后,如果支持可用,它似乎只喜欢 bpf_link*,即使您已经通过“bpftool prog”加载了 XDP 程序,回退到使用使用 bpftool prog 加载的 XDP 程序也会很好。所以最好改用bpf_link。或者,如果您是从内核源代码构建,以下补丁可能会有所帮助。

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

【讨论】:

    猜你喜欢
    • 2022-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    相关资源
    最近更新 更多