Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to build BPF program out of the kernel tree

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.

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

This is with clang-llvm 3.8.0

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 ;-)

like image 963
Mark Avatar asked Dec 19 '17 21:12

Mark


1 Answers

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

(taken from man page for 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).

Some notes:

  • 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?
  • [Edit] 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!

[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 \
…

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.

like image 130
Qeole Avatar answered Sep 25 '22 17:09

Qeole