不同ebpf程序类型之间的地图共享

问题描述 投票:1回答:1

是否可以在不同程序类型之间共享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',但它是struct bpf_map_def。因此,在cgroup bpf程序中,同一映射定义为struct bpf_map_def而不是struct bpf_elf_map。

可能由于这个原因,cgroup程序在我转储地图时会获得一个新的map_id(并且不共享预期的地图),理想情况下,当在bpf程序之间共享同一地图时,这些bpf程序将具有与他们独特的prog_id。

linux-kernel elf bpf ebpf iproute
1个回答
0
投票

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

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

当它们被加载到内核时,eBPF程序通过文件映射器引用给定映射表。这意味着,首先调用bpf()系统调用来加载程序的进程必须将文件描述符检索到映射中才能使用。因此,可能发生以下两种情况:

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

  • 或用户应用程序解析ELF对象文件,并以某种方式发现该程序已经存在应使用的现有映射。例如,它找到ID为1337的地图,或在/sys/fs/bpf/下的固定地图。在那种情况下,它将检索到该映射的文件描述符(从具有bpf() syscall的id到具有open()的固定路径)。然后,与第一种情况一样,它使用此文件描述符准备并加载程序。

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

foomap
© www.soinside.com 2019 - 2024. All rights reserved.