内核中的 eBPF 程序如何访问用户空间程序创建的映射?

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

是的,了解类似的问题之前已发布过多次,例如

但说了这么多、做了这么多之后,我们仍然没有就如何做到这一点达成肯定的答案。

最近在developers.redhat.com上看到一篇题为“eBPF应用程序开发:超越基础”的文章,https://developers.redhat.com/articles/2023/10/19/ebpf-application-development-beyond-基础知识.

最有趣的是,图 6 中展示了正在运行的 eBPF 程序的架构,其中有大量要点,我希望它可以帮助解决我的问题。

Architecture of a running BPF program

俗话说,一图胜千言。所以我的问题是:

关于相关架构图,假设用户空间程序app1使用带有BPF_MAP_CREATE的bpf()系统调用来创建“map 1”,那么app1.bpf的SEC(“tc”)tc_rx_main(__sk_buf* ctx)如何访问map 1来自内核?

提前非常感谢。

dictionary kernel ebpf
1个回答
0
投票

内核中的 eBPF 程序如何访问用户空间程序创建的映射?

关于相关架构图,假设用户空间程序app1使用带有BPF_MAP_CREATE的bpf()系统调用来创建“map 1”,那么app1.bpf的SEC(“tc”)tc_rx_main(__sk_buf* ctx)如何访问map 1来自内核?

所有地图始终由用户空间创建。 BPF 程序无法自行创建映射。每当您在 eBPF 程序中定义映射时,映射定义都会出现在生成的 ELF 的

maps
/
.maps
部分中。

用户空间中的加载程序读取所有映射定义并执行

BPF_MAP_CREATE
系统调用来实际创建映射。这会导致映射创建,并为用户空间程序提供这些映射的文件描述符。

ELF 还在其自己的部分中包含您的程序。每当代码中引用映射(例如使用

bpf_map_lookup_elem(&my_map.....
)时,编译器都会创建一条 eBPF 指令来将 64 位数字加载到寄存器中。它还为该指令和映射名称创建一个 ELF 重定位条目。

加载器检查 eBPF 字节码,并将这些加载指令的值设置为等于创建映射时给定的文件描述符。然后将修改后的 eBPF 字节码加载到内核中。

内核将在验证和 JITing 过程中将这些文件描述符转换为映射的实际内存地址,该地址将在机器代码中用于与映射交互。

用户空间进程仍然可以使用文件描述符通过系统调用访问映射,从而实现共享映射访问。

大部分工作是由加载器库自动完成的,但是,您通常可以通过几个步骤手动完成此操作,使您有机会在加载之前更改地图定义,或者使用特定的现有地图而不是创建新地图来共享地图程序之间。

这是我去年做的一次演讲,详细介绍了:https://archive.fosdem.org/2023/schedule/event/bpf_loader/

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