如何从内核树中构建BPF程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从内核树中构建BPF程序相关的知识,希望对你有一定的参考价值。
内核在samples/bpf
中提供了许多示例。我有兴趣在树之外构建一个示例,就像我们构建一个内核模块一样,Makefile
可以很简单。是否有可能对bpf做同样的事情?我试图通过从samples/bpf/Makefile
中删除不必要的部分并保持对libbpf
和其他人的依赖,但事实证明并非那么容易。
例如,尝试使用以下命令行在内核树之外构建samples/bpf/bpf_tcp_kern.c
(我偷看了samples / bpf / Makefile,以及make samples/bpf V=1
的输出):
clang -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/5/include
-I/home/mark/work/net-next.git/arch/x86/include -I/home/mark/work/net-next.git/arch/x86/include/generated -I./include -I/home/mark/work/net-next.git/arch/x86/include/uapi -I/home/mark/work/net-next.git/arch/x86/include/generated/uapi -I/home/mark/work/net-next.git/include -I/home/mark/work/net-next.git/generated/uapi -I./
-D__KERNEL__ -Wno-unused-value -Wno-pointer-sign
-D__TARGET_ARCH_x86 -Wno-compare-distinct-pointer-types
-Wno-gnu-variable-sized-type-not-at-end
-Wno-address-of-packed-member -Wno-tautological-compare
-Wno-unknown-warning-option
-O2 -emit-llvm -c bpf_tcp_kern.c -o -| llc -march=bpf -filetype=obj -o bpf_tcp_kern.o
In file included from bpf_tcp_kern.c:15:
In file included from /home/mark/work/net-next.git/include/uapi/linux/bpf.h:11:
In file included from /home/mark/work/net-next.git/include/linux/types.h:6:
In file included from /home/mark/work/net-next.git/include/uapi/linux/types.h:5:
/home/mark/work/net-next.git/arch/x86/include/uapi/asm/types.h:5:10: fatal error: 'asm-generic/types.h' file not found
#include <asm-generic/types.h>
^
1 error generated
这是与clang-llvm 3.8.0
我需要libbpf
来构建用户端的bpf应用程序。这部分工作正常。
我错过了什么吗?我相信这项任务应该相当容易;-)
假设这是“eBPF”。是的,这应该是可能的。基本上,您应该能够使用以下内容编译最简单的eBPF程序:
clang -O2 -emit-llvm -c bpf.c -o - | llc -march=bpf -filetype=obj -o bpf.o
(摘自tc-bpf(8)
的手册页)
当然,如果你的程序使用本地头文件中的定义,你必须找到一种方法来包含它们(即保留足够的文件来编译你的文件,即使你“扯掉”其他所有内容)。
一些说明:
- clang和llvm(llc)应该是3.7或更高版本(越高越好)。
- 根据您尝试编译的eBPF功能,您需要内核头文件(特别是
<linux/bpf.h>
)足以支持您的程序(另请参阅this page)。 - 不知道你打算用什么
libbpf
。如果我没记错的话,它用于从外部程序加载和管理eBPF程序,而不是包含在eBPF程序中? - [编辑]此外,
samples/bpf
下的eBPF程序似乎是使用内核模块基础结构构建的。它们本身不是模块,但以某种方式编译就像它们一样,可以访问内核头文件。因此,如果您尝试在树之外编译它们而没有内核makefile,则可能无法访问<linux/*.h>
标头,并且必须用<uapi/linux/*.h>
替换<linux/*.h>
。
作为一般建议,尝试简化您的程序,直到它编译,然后再添加功能:)。我担心,如果没有源代码或错误消息,真的无法帮到你。祝好运!
[在问题本身更新后编辑]我能够通过在命令中添加以下三行来编译示例(通过运行make samples/bpf/tcp_bufs_kern.o V=1
获取它们,不确定是否将它们修剪掉或者如果你有不同的东西):
…
-I/home/mark/work/net-next.git/include/generated/uapi
-I/home/mark/work/net-next.git/tools/testing/selftests/bpf/
-include /home/mark/work/net-next.git/include/linux/kconfig.h
…
你命令抱怨的asm-generic.h
标题的第一行;第二行是"bpf-helpers.h"
,您可以轻松地复制到您的工作目录。最后一行可能更难以删除,我没有详细搜索为什么需要kconfig.h
,你将不得不调查。
以上是关于如何从内核树中构建BPF程序的主要内容,如果未能解决你的问题,请参考以下文章