gpt4 book ai didi

linux-kernel - 不同 ebpf 程序类型之间的映射共享

转载 作者:行者123 更新时间:2023-12-03 23:10:29 26 4
gpt4 key购买 nike

是否可以在不同的程序类型之间共享 ebpf 映射。我需要在 tc-bpf 程序和 cgroup bpf 程序之间共享一个映射。如果映射被固定到充当全局命名空间的文件系统,这应该是可能的。但是,我没有得到这个工作。

该映射由 tc-bpf 程序创建并固定到全局命名空间。由于是 tc-bpf 程序,所以映射的类型是 struct bpf_elf_map。这个 bpf 程序是通过 iproute2 加载的。

现在,我有一个应该访问此映射的 cgroup bpf 程序,但由于它是通过 user.c (libbpf) 或 bpftool 而不是 iproute 加载的,因此此处定义的映射不能是“bpf_elf_map”,但它是结构bpf_map_def。所以在 cgroup bpf 程序中,相同的映射被定义为 struct bpf_map_def 而不是 struct bpf_elf_map。

可能正因为如此,当我转储 map (并且不共享预期的 map )时,cgroup 程序会获得一个新的 map_id,理想情况下,当同一个 map 在 bpf 程序之间共享时,这些 bpf 程序将具有与其唯一关联的相同 map_id prog_ids。

最佳答案

可以在不同类型的程序之间共享对 eBPF 映射的访问。

首先,您可以忘记 struct bpf_elf_map 之间的那些差异。和 struct bpf_map_def .它们是在用户空间中用于构建要传递给内核的对象的结构。 Iproute2 和 libbpf 可能不会使用相同的结构/属性名称,但它们最终都会将 map 元数据传递给 bpf()格式相同的系统调用,否则内核将不知道要创建什么映射。

当它们被加载到内核时,eBPF 程序通过文件描述符引用一个给定的映射到这个映射。这意味着进程调用了 bpf()加载程序的系统调用首先必须检索文件描述符以供映射使用。所以可能会出现以下两种情况:

  • 用户空间应用程序(ip、tc、bpftool...)解析ELF对象文件并收集与 map 相关的元数据。它没有识别(甚至可能没有尝试识别)任何应该为程序重用的现有 map 。所以它创建了一个带有 bpf() 的新 map syscall,它返回一个文件描述符到这个新创建的映射。这个文件描述符用于引用映射访问的程序指令中(一旦程序被加载到内核中,那些文件描述符将被映射地址替换),然后程序被加载bpf()系统调用。这就是您的 tc 程序发生的情况,在您的情况下,您的 cgroup 程序似乎正在创建第二个 map 。
  • 或者用户应用程序解析 ELF 对象文件,并以某种方式发现已经存在程序应该使用的现有映射。例如,它会找到一个 id 为 1337 的 map ,或者 /sys/fs/bpf/ 下的一个固定 map 。 .在这种情况下,它检索该映射的文件描述符(从带有 bpf() 系统调用的 id,从带有 open() 的固定路径)。然后和第一种情况一样,它使用这个文件描述符来准备然后加载程序。

  • Libbpf 提供了一种方法来重用给定映射的文件描述符以与程序一起使用。参见例如 bpf_map__reuse_fd() . bpftool uses it支持重用现有 map ,使用 map bpftool prog load 的论据(见 man bpftool-prog )。例如,从 foo.o 加载程序并告诉它重用 id 27 的 map 对于在目标文件中找到的第一个 map ,然后该 map 固定在 /sys/fs/bpf/foomap对于名为 foomap 的 map 在目标文件中:
    # bpftool prog load foo.o /sys/fs/bpf/foo_prog \
    map idx 0 id 27 \
    map foomap stats pinned /sys/fs/bpf/foomap

    关于linux-kernel - 不同 ebpf 程序类型之间的映射共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58455605/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com