如何访问内核程序(内核上下文)中用户程序制作的BPF地图?

发布于 2025-01-26 20:48:42 字数 710 浏览 3 评论 0 原文

我们假设有两个程序(用户程序和内核程序)。

用户程序由API BPF_CREATE_MAP_NAME ()制作了BPF地图,然后返回FD。使用此FD,我可以访问Syscalls的地图(例如, bpf_map_update (fd,..))。但是我只能在用户空间程序中执行此操作,因为FD仅适用于用户程序(=用户流程),然后我如何在BPF程序(位于内核空间)中访问此地图? /strong>

我被听到我可以通过libbpf的 bpf_obj_pin (fd,文件路径)将地图固定在FS中,并且可以通过libbpf的 bpf_obj_get (文件路径)获取此地图。但是问题是 bpf_obj_get 仅在用户空间中可用,因为这是系统调用。

我之前看到了类似的讨论(从内核空间访问bpf映射)。但这对我来说还不清楚。要通过 bpf_map_lookup_elem (fd,..)访问BPF地图,我必须提前知道地图的FD。但是正如我之前提到的,地图的FD在内核中无效。

我正在使用libbpf而不是BCC。

Let's suppose there are two programs (User program and Kernel program).

User program made bpf map by api bpf_create_map_name() and it returns fd. With this fd, I can access the map by syscalls (e.g., bpf_map_update(fd, ..)). But I can do this only in the user space programs because the fd is valid only to user program(=user process), then How can I access to this map in the bpf program (located in the kernel space)?

I was heard that I can pin the map in the fs via libbpf's bpf_obj_pin(fd, file path) and can get this map via libbpf's bpf_obj_get(file path) but the problem is bpf_obj_get is only available in the user space because this is system call.

I saw a similar discussion before (Accessing BPF maps from kernel space). but this was not clear to me. To access bpf map via bpf_map_lookup_elem(fd, ..) in the kernel space, I have to know map's fd in advance. But as I mentioned before, the map's fd is not valid in the kernel.

I am using libbpf not BCC.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浴红衣 2025-02-02 20:48:42

You should probably look at libbpf's function bpf_map__reuse_fd(), which allows to reuse a file descriptor pointing to an existing map for a BPF program.

Here is an example using this function: we first retrieve a pointer to the map to replace in the struct bpf_object by calling bpf_object__find_map_by_name(), and then tell it to reuse the existing fd.

赠佳期 2025-02-02 20:48:42

动态添加地图到现有EBPF程序的唯一方法是使用 bpf_map_type_array_aray_of_maps bpf_map_type_hash_hash_hash_of_of_maps 。要使用它,我们定义了内部外部地图类型。用户空间程序/加载程序创建 ofter 映射,并用 ofter 映射加载程序。之后,我们可以在用户空间中修改此外部映射,以随时向其添加一个或多个 Inner 映射。
请查看内核中的样品: nofollow noreferrer“>

为了进一步解释并澄清一些事情:

  • EBPF程序不会创建地图,ELF文件包含MAP定义,这些定义由用户空间程序/加载程序读取,然后创建它们。截至这一刻,EBPF程序无法创建地图。
  • 当加载程序创建地图时,内核会返回文件描述符。当将EBPF程序加载到内核中时,加载程序将动态重写程序并将此文件描述符注入其中。内核使用加载地图验证程序,然后将映射的实际存储地址放在程序中而不是文件描述符中,以便生成的计算机代码可以通过内存地址直接访问地图。此验证和转换步骤是程序无法动态“获取”地图引用的原因。
  • 地图中的地图类型确实可以动态工作。这是因为验证者在加载程序时验证了内部映射定义以确保代码有效。然后,当用户空间更新地图中的地图时,存储了地图的实际存储地址,可以通过EBPF程序访问该地图。但是即便如此,您仍需要在加载第一个程序之前知道内图的类型/结构。

The only way to dynamically add maps to an existing eBPF program is to use a map-in-map type like BPF_MAP_TYPE_ARRAY_OF_MAPS or BPF_MAP_TYPE_HASH_OF_MAPS. To use it we define a inner and outer map type. The userspace program/loader creates the outer map and loads the program with a reference to the outer map. After that we can modify this outer map from userspace to add one or more inner maps to it at any time.
Please take a look at samples in the kernel: test_map_in_map_user.c and test_map_in_map_kern.c.

To explain further and to clarify some things:

  • eBPF programs don't create maps, the ELF files contain map definitions which are read by the userspace program/loader which then creates them. eBPF programs can't create maps as of this moment.
  • When the loader creates a map, the kernel returns a file descriptor. When a eBPF program is loaded into the kernel, the loader will dynamically rewrite the program and inject this file descriptor into it. The kernel verifies the program using the loaded map, after which the actual memory address of the map is placed in the program instead of the file descriptor so the generated machine code can access the map directly by memory address. This verification and conversion step is the reason programs can't dynamically "get" map references.
  • Map-in-map types do work dynamically. That is because the verifier validates the inner map definition when the program is loaded to make sure the code is valid. Then when the userspace updates the map-in-map, the actual memory address of the map is stored which can be accesses by the eBPF program. But even so, you need to know how the type/structure of the inner map before loading the first program.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文