如何在内核树之外构建BPF程序 [英] how to build BPF program out of the kernel tree
问题描述
内核在samples/bpf
中提供了许多示例.我有兴趣在树外构建示例之一,就像我们构建内核模块一样,其中Makefile
可能足够简单. bpf是否可以做同样的事情?我尝试通过从samples/bpf/Makefile
中删除不必要的部分并保留对libbpf
和其他内容的依赖来进行尝试,但是事实并非如此.
The kernel provides a number of examples in samples/bpf
. I am interested in building one of examples outside of the tree, just like we build a kernel module, where Makefile
can be simple enough. Is it possible to do the same with bpf? I tried it by ripping out unnecessary parts from samples/bpf/Makefile
and keeping dependencies to libbpf
and others, however it turned out to be not that easy.
例如,尝试使用以下命令行在内核树之外构建samples/bpf/bpf_tcp_kern.c
(我窥视了samples/bpf/Makefile以及make samples/bpf V=1
的输出):
For example, trying to build samples/bpf/bpf_tcp_kern.c
outside of the kernel tree, with the following command line (I peeked into samples/bpf/Makefile, as well as the output of 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应用程序.这部分工程可以很好地构建.
And I need libbpf
to build user-side bpf applications. This part works builds just fine.
我错过了什么吗?我相信这个任务应该很容易;-)
Am I missing something? I believe this task should be fairly easy ;-)
推荐答案
假定这是"eBPF".是的,那应该是可能的.基本上,您应该可以使用以下代码来编译最简单的eBPF程序:
Assuming this is "eBPF". Yes, that should be possible. Basically, you should be able to compile the simplest eBPF programs with something like this:
clang -O2 -emit-llvm -c bpf.c -o - | llc -march=bpf -filetype=obj -o bpf.o
(摘录自tc-bpf(8)
的手册页)
当然,如果您的程序使用本地头文件中的定义,则必须找到一种方法来包含它们(即,即使您删除"其他所有内容,也要保留这些头中的足够内容以进行文件编译).
Of course, if your program uses definitions from local header files, you must find a way to include them (i.e. keep enough from those headers to have your file compiling, even if you "rip out" everything else).
一些注意事项:
- clang and llvm (llc) should be in version 3.7 or higher (the higher the better).
- Depending on what eBPF features you're trying to compile, you will need kernel headers (in particular,
<linux/bpf.h>
) to be recent enough to support your program (see also this page). - Not sure what you intend to use
libbpf
for. If I remember correctly, it's used to load and manage eBPF programs from an external program, not to be included in eBPF programs themselves? - Also the eBPF programs under
samples/bpf
seem to be built with the kernel module infrastructure. They are not modules themselves, but somehow compiled as if they were, with access to kernel headers. So if you try to compile them outside of the tree and without the kernel makefiles, you may loose access to the<linux/*.h>
headers, and have to replace the<uapi/linux/*.h>
by<linux/*.h>
instead..
作为一般建议,请尝试简化程序,直到编译为止,然后再次添加功能:).恐怕如果没有源代码或错误消息,就无法真正为您提供更多帮助.祝你好运!
As a general advice, try to simplify your program until it compiles, then add features back again :). Cannot really help you more without source code or error messages, I'm afraid. Good luck!
[编辑]
我可以通过在命令中添加以下三行来编译示例(通过运行make samples/bpf/tcp_bufs_kern.o V=1
可以获取它们,不确定是否将它们修剪掉或是否有所不同):
[Edit after the question itself was updated]
I was able to compile an example by adding the following three lines to the command (got them by running make samples/bpf/tcp_bufs_kern.o V=1
, not sure if you trimmed them out or if you got something different):
…
-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
的原因,因此您必须对此进行调查.
First line for the asm-generic.h
header that your command complains about; the second line is for "bpf-helpers.h"
, that you can easily copy to your work directory instead. The last line might be more difficult to remove, I didn't search in details why kconfig.h
is needed, you'll have to investigate about that.
这篇关于如何在内核树之外构建BPF程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!