【问题标题】:how to build BPF program out of the kernel tree如何从内核树中构建 BPF 程序
【发布时间】:2023-03-10 07:47:01
【问题描述】:

内核在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 应用程序。这部分工作正常。

我错过了什么吗?我相信这项任务应该相当容易;-)

【问题讨论】:

    标签: linux-kernel jit llvm-clang bpf


    【解决方案1】:

    假设这是“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 功能,您需要最新的内核头文件(特别是 &lt;linux/bpf.h&gt;)以支持您的程序(另请参阅 this page)。
    • 不确定您打算使用 libbpf 做什么。如果我没记错的话,它是用来从外部程序加载和管理 eBPF 程序的,而不是包含在 eBPF 程序本身中?
    • [编辑] 此外,samples/bpf 下的 eBPF 程序似乎是使用内核模块基础架构构建的。它们本身不是模块,但以某种方式编译,就好像它们是一样的,可以访问内核头文件。因此,如果您尝试在树之外编译它们并且没有内核 makefile,您可能无法访问 &lt;linux/*.h&gt; 标头,而必须将 &lt;uapi/linux/*.h&gt; 替换为 &lt;linux/*.h&gt;..

    作为一般建议,请尽量简化您的程序,直到它编译,然后再次添加功能 :)。如果没有源代码或错误消息,恐怕无法真正为您提供更多帮助。祝你好运!

    [在问题本身更新后编辑] 我可以通过在命令中添加以下三行来编译一个示例(通过运行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,您必须对此进行调查。

    【讨论】:

    • 我的Makefile 实际上确实包含include/generated/uapi,但我缺少linux/kconfig.h,这就是问题所在。谢谢。
    • 一个附加资源:一个 Makefile 显然是从 kernel/sample/bpf/ 中的那个派生的,用于构建这些示例,但在内核树之外:link
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    相关资源
    最近更新 更多