【问题标题】:Map sharing between different ebpf program types不同 ebpf 程序类型之间的地图共享
【发布时间】:2020-02-15 17:33:13
【问题描述】:

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

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

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

可能正因为如此,当我转储地图(并且不共享预期的地图)时,cgroup 程序会获得一个新的 map_id,理想情况下,当 bpf 程序共享相同的地图时,这些 bpf 程序将具有相同的关联 map_id带有他们独特的 prog_id。

【问题讨论】:

  • 我可以通过各种可用的系统调用实用程序访问用户空间中的地图,但目的是从不同附加类型的不同 bpf 程序 (_kern.c) 访问地图。

标签: linux-kernel elf bpf ebpf iproute


【解决方案1】:

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

首先,您可以忘记struct bpf_elf_mapstruct bpf_map_def 之间的区别。它们是用户空间中用于构建传递给内核的对象的结构。 Iproute2 和 libbpf 可能不使用相同的结构/属性名称,但它们最终都会以相同的格式将映射元数据传递给 bpf() 系统调用,否则内核将无法理解要创建的映射。

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

  • 用户空间应用程序(ip、tc、bpftool...)解析 ELF 对象文件并收集与地图相关的元数据。它没有识别(甚至可能没有尝试识别)任何应该为程序重用的现有地图。因此它使用bpf() 系统调用创建了一个新映射,该系统调用将一个文件描述符返回到这个新创建的映射。该文件描述符用于涉及映射访问的程序指令中(一旦程序加载到内核中,这些文件描述符将被映射地址替换),然后使用bpf() 系统调用加载程序。这就是您的 tc 程序发生的情况,在您的情况下,您的 cgroup 程序似乎正在创建第二张地图。

  • 或者用户应用程序解析 ELF 对象文件,并以某种方式发现程序应该使用现有的映射。例如,它会找到 id 为 1337 的地图,或者在/sys/fs/bpf/ 下的固定地图。在这种情况下,它会检索到该映射的文件描述符(从带有bpf() 系统调用的id,从带有open() 的固定路径)。然后和第一种情况一样,它使用这个文件描述符来准备然后加载程序。

Libbpf 提供了一种方法来重用给定映射的文件描述符以与程序一起使用。参见例如bpf_map__reuse_fd()。 Bpftool uses it 支持重用现有地图,map 参数用于bpftool prog load(请参阅man bpftool-prog)。例如,从foo.o 加载一个程序,并告诉它为在目标文件中找到的第一个地图重用ID 27 的地图,然后在目标文件中为名为@9​​87654340@ 的地图固定在/sys/fs/bpf/foomap 的地图:

# bpftool prog load foo.o /sys/fs/bpf/foo_prog \
        map idx 0 id 27 \
        map foomap stats pinned /sys/fs/bpf/foomap

【讨论】:

  • 对于您的第一个示例,如果tc 创建了一个新地图,另一个用户空间程序可以访问该地图吗?换句话说,我怎样才能找出tc创建的新地图的fd是什么,以便我可以访问该地图?如果我应该提出这个新问题,请告诉我,谢谢
  • 是的,你可以。至少有两种方法可以做到这一点。 1)在声明地图时,如果将tc使用的struct bpf_elf_map.pinning字段设置为例如PIN_GLOBAL_NS,地图将固定到bpffs。您可以稍后从固定路径中检索文件描述符。请注意,较新版本的 iproute2/tc 现在可以与 libbpf 一起使用,这可能已经有所改变,我需要仔细检查。 2)列出你的程序使用的地图(bpftool prog show),找到你的地图的id,从那个id中得到一个fd
猜你喜欢
  • 2023-02-17
  • 2011-08-24
  • 2021-04-15
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多