如何从内核树中构建 BPF 程序 [英] how to build BPF program out of the kernel tree

查看:28
本文介绍了如何从内核树中构建 BPF 程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

内核在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 和 llvm (llc) 应该是 3.7 或更高版本(越高越好).
  • 根据您尝试编译的 eBPF 功能,您需要内核头文件(特别是 <linux/bpf.h>)足够新以支持您的程序(请参阅还有此页面).
  • 不确定您打算将 libbpf 用于什么目的.如果我没记错的话,它用于从外部程序加载和管理 eBPF 程序,而不是包含在 eBPF 程序本身中?
  • [Edit] 此外,samples/bpf 下的 eBPF 程序似乎是使用内核模块基础结构构建的.它们本身不是模块,而是以某种方式编译,就好像它们是模块一样,可以访问内核头文件.因此,如果您尝试在树外编译它们并且没有内核 makefile,您可能无法访问 <linux/*.h> 头文件,并且必须替换 <uapi/linux/*.h> 代替..
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆