我们假设有两个程序(用户程序和内核程序)。
用户程序由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.
发布评论
评论(2)
您可能应该查看libbpf的函数 ,它允许将文件描述符指向BPF程序的现有映射。
:我们首先检索指针指向
struct bpf_object
通过调用bpf_object__find_map_map_by_name()
,然后告诉它重复使用现有的现有现有的现有fd。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 callingbpf_object__find_map_by_name()
, and then tell it to reuse the existing fd.动态添加地图到现有EBPF程序的唯一方法是使用
bpf_map_type_array_aray_of_maps
或bpf_map_type_hash_hash_hash_of_of_maps
。要使用它,我们定义了内部
和外部
地图类型。用户空间程序/加载程序创建ofter
映射,并用ofter
映射加载程序。之后,我们可以在用户空间中修改此外部
映射,以随时向其添加一个或多个Inner
映射。请查看内核中的样品:和 nofollow noreferrer“>
为了进一步解释并澄清一些事情:
内部
映射定义以确保代码有效。然后,当用户空间更新地图中的地图时,存储了地图的实际存储地址,可以通过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
orBPF_MAP_TYPE_HASH_OF_MAPS
. To use it we define ainner
andouter
map type. The userspace program/loader creates theouter
map and loads the program with a reference to theouter
map. After that we can modify thisouter
map from userspace to add one or moreinner
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:
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.