как собрать программу BPF из дерева ядра

Ядро предоставляет ряд примеров в samples/bpf. Я заинтересован в сборке одного из примеров вне дерева, точно так же, как мы собираем модуль ядра, где Makefile может быть достаточно простым. Можно ли сделать то же самое с bpf? Я попробовал это, вырвав ненужные части из samples/bpf/Makefile и сохранив зависимости от libbpf и других, однако это оказалось не так просто.

Например, попытка собрать samples/bpf/bpf_tcp_kern.c вне дерева ядра с помощью следующей командной строки (я заглянул в sample/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 на стороне пользователя. Эта часть работает, строит просто отлично.

Я что-то упускаю? Я считаю, что эта задача должна быть довольно простой ;-)


person Mark    schedule 19.12.2017    source источник


Ответы (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 вы пытаетесь скомпилировать, вам потребуются заголовки ядра (в частности, <linux/bpf.h>), достаточно свежие для поддержки вашей программы (см. также этой страницы).
  • Не уверен, для чего вы собираетесь использовать libbpf. Если я правильно помню, он используется для загрузки и управления программами eBPF из внешней программы, а не для включения в сами программы eBPF?
  • [Изменить] Также кажется, что программы eBPF под samples/bpf построены с инфраструктурой модуля ядра. Они сами по себе не модули, а каким-то образом скомпилированы, как если бы они были, с доступом к заголовкам ядра. Поэтому, если вы попытаетесь скомпилировать их вне дерева и без make-файлов ядра, вы можете потерять доступ к заголовкам <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, вам придется это выяснить.

person Qeole    schedule 19.12.2017
comment
Мой Makefile на самом деле включает include/generated/uapi, но мне не хватало linux/kconfig.h, вот в чем проблема. Спасибо. - person Mark; 21.12.2017
comment
Один дополнительный ресурс: Makefile, по-видимому, производный от файла в kernel/sample/bpf/ для сборки этих примеров, но вне дерева ядра: ссылка - person Qeole; 22.01.2018