不同ebpf程序类型之间的地图共享 [英] Map sharing between different ebpf program types

查看:191
本文介绍了不同ebpf程序类型之间的地图共享的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to share ebpf maps between different program types. I need to share a map between a tc-bpf program and a cgroup bpf program. This should be possible if the map is pinned to file system that act as global namespace. But, I haven't got this working.

该映射是由tc-bpf程序创建的,并固定到全局名称空间.由于它是tc-bpf程序,因此映射的类型为struct bpf_elf_map.该bpf程序是通过iproute2加载的.

The map is created by tc-bpf program and pinned to global namespace. Since it is tc-bpf program, the map is of type struct bpf_elf_map. This bpf program is loaded via 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.

Now, I have a cgroup bpf program that should be accessing this map, but since it is loaded via a user.c (libbpf) or bpftool and not iproute, the map that is defined here cannot be ‘bpf_elf_map’, but it is struct bpf_map_def. So in the cgroup bpf program, the same map is defined as struct bpf_map_def and not struct bpf_elf_map.

可能是因为这样,当我转储地图时,cgroup程序获得了一个新的map_id(并且不共享预期的地图),理想情况下,当跨bpf程序共享同一地图时,这些bpf程序将具有相同的map_id以及它们独特的prog_id.

Probably because of this the cgroup program gets a new map_id when I dump the maps (and does not share the intended map), ideally when the same map is shared across bpf programs, these bpf programs would be having the same map_id associated with their unique prog_ids.

推荐答案

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

It is possible to share access to eBPF maps between programs of different types.

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

First, you can forget about those differences between struct bpf_elf_map and struct bpf_map_def. They are structs used in user space to build the objects to pass to the kernel. Iproute2 and libbpf may not use the same struct/attribute names, but they both end up passing the map metadata to the bpf() system call in the same format, or the kernel would not understand what map is to be created.

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

When they are loaded to the kernel, eBPF programs refer to a given map through file descriptors to this map. This means that the process calling the bpf() system call to load the program first has to retrieve file descriptors to the map to use. So the two following cases may happen:

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

  • User space application (ip, tc, bpftool...) parses the ELF object file and collects map-related metadata. It does not identify (and possibly did not even try to identify) any existing map that should be reused for the program. So it creates a new map with the bpf() syscall, which returns a file descriptor to this newly-created map. This file descriptor is used in the program instructions referring to map access (once the program is loaded in the kernel, those file descriptors will be replaced by the map address), and the program is then loaded with the bpf() syscall. This is what happens with your tc program, and in your case it seems, with your cgroup program which is creating a second map.

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

Or user application parses the ELF object file, and finds somehow that there is already an existing map that the program should use. For example, it finds a map of id 1337, or a pinned map under /sys/fs/bpf/. In that case it retrieves a file descriptor to that map (from the id with bpf() syscall, from a pinned path with open()). Then as in the first case, it uses this file descriptor to prepare and then load the program.

Libbpf提供了一种为给定映射重用文件描述符以与程序一起使用的方法.例如,参见 bpf_map__reuse_fd().Bpftool

Libbpf provides a way to reuse a file descriptor for a given map to use with a program. See for example bpf_map__reuse_fd(). Bpftool uses it to support reusing existing maps, with the map argument for bpftool prog load (see man bpftool-prog). For example, load a program from foo.o and tell it to reuse map of id 27 for the first map found in the object file, then the map pinned at /sys/fs/bpf/foomap for the map named foomap in the object file:

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

这篇关于不同ebpf程序类型之间的地图共享的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆