BPF_CORE_READ
是 eBPF 中一个宏,用于简化从内核数据结构中读取字段的操作,尤其是在处理复杂多层引用时。它是 BPF CO-RE(Compile Once, Run Everywhere)机制的一部分,旨在提高 eBPF 程序的可移植性和开发效率。
功能与用法
-
简化链式引用读取:
- 传统方式需要多次调用
bpf_probe_read
或bpf_probe_read_kernel
来逐层读取内核数据结构中的字段。例如:struct task_struct *t = ...; struct mm_struct *mm; struct file *exe_file; struct dentry *dentry; const char *name; bpf_core_read(&mm, sizeof(mm), &t->mm); bpf_core_read(&exe_file, sizeof(exe_file), &mm->exe_file); bpf_core_read(&dentry, sizeof(dentry), &exe_file->path.dentry); bpf_core_read(&name, sizeof(name), &dentry->d_name.name);
- 使用
BPF_CORE_READ
后,可以一行代码完成:const char *name = BPF_CORE_READ(t, mm, exe_file, fpath.dentry, d_name.name);
- 传统方式需要多次调用
-
底层实现:
BPF_CORE_READ
是一个宏,其定义如下:#define bpf_core_read(dst, sz, src) \ bpf_probe_read_kernel(dst, sz, (const void *)__builtin_preserve_access_index(src))
- 它依赖于 Clang 的
__builtin_preserve_access_index
特性,通过内核的 BTF(BPF Type Format)信息计算结构体字段的偏移量,从而实现跨内核版本的兼容性[1][2][3].
-
错误处理:
- 如果在读取链条中某个指针为空,
BPF_CORE_READ
不会返回错误,而是最终返回0
或NULL
,这需要开发者在使用时注意[1].
- 如果在读取链条中某个指针为空,
-
扩展功能:
- 宏扩展如
BPF_CORE_READ_INTO
和BPF_CORE_READ_STR_INTO
提供了额外的功能,例如将结果直接写入数组或字符串[1][2].
- 宏扩展如
使用限制与注意事项
-
内核版本要求:
- 需要支持 BTF 的内核版本(通常为 5.2 及以上)。低于 5.2 的内核无法使用 CO-RE 功能,只能使用传统的
bpf_probe_read
[1][4].
- 需要支持 BTF 的内核版本(通常为 5.2 及以上)。低于 5.2 的内核无法使用 CO-RE 功能,只能使用传统的
-
依赖 BTF 信息:
- 内核必须启用
CONFIG_DEBUG_INFO_BTF=y
,以便暴露结构体布局等信息供 BPF 程序使用[4].
- 内核必须启用
-
兼容性问题:
- 如果目标内核版本发生了字段名或结构体布局的变化,可能需要调整程序逻辑,但 CO-RE 的设计已经尽量减少了这种情况的影响[3][4].
总结
BPF_CORE_READ
是 eBPF 开发中的重要工具,极大地简化了复杂数据结构读取的代码,同时提升了跨内核版本的兼容性。通过结合 BTF 和 CO-RE 技术,它让 eBPF 程序更高效、更易维护,但需要开发者对目标内核环境有一定了解以确保正确使用。
Citations:
[1] https://github.com/g0dA/linuxStack/blob/master/ebpf%E8%B7%A8%E5%86%85%E6%A0%B8%E7%89%88%E6%9C%AC%E4%BD%BF%E7%94%A8(%E6%8C%81%E7%BB%AD%E6%9B%B4%E6%96%B0).md
[2] https://blog.csdn.net/qq_32783703/article/details/127970880
[3] https://www.strickland.cloud/post/1
[4] https://arthurchiao.github.io/blog/bpf-portability-and-co-re-zh/
[5] https://www.cnblogs.com/charlieroro/p/14206214.html
[6] https://eunomia.dev/eunomia-bpf/manual/
[7] https://blog.nsfocus.net/ebpf/
[8] https://openanolis.cn/sig/ebpfresearch/doc/646023027267993641