设置 BPF Netfilter 挂钩环境/依赖项

问题描述 投票:0回答:1

我正在尝试创建一个简单的 BPF 程序来丢弃传入/传出数据包并仅接受转发的数据包,由

bpftool
加载。 我使用的是 Ubuntu 24.04 和 Linux 内核版本 6.8。这是我的程序:

#include <linux/bpf.h>
  
#include <bpf/bpf_endian.h>
#include <bpf/bpf_helpers.h>
#include <linux/netfilter.h>

SEC("netfilter") /* hint to BPF loader that this is an netfilter BPF program */
int filter(const struct bpf_nf_ctx *ctx) {
  const struct nf_hook_state *state = ctx->state;
  unsigned int routing_decision = state->hook;

  if (routing_decision == NF_INET_LOCAL_IN ||
      routing_decision == NF_INET_LOCAL_OUT)
    return NF_DROP;

  return NF_ACCEPT;
}

char LICENSE[] SEC("license") = "GPL";

但是,当我尝试将其编译成目标文件时,我得到:

clang --target=bpf -O2 -Wall -I/usr/include/x86_64-linux-gnu -c filter.c -o filter.bpf.o
filter.c:8:27: warning: declaration of 'struct bpf_nf_ctx' will not be visible outside of this function [-Wvisibility]
    8 | int filter(const struct bpf_nf_ctx *ctx) {
      |                           ^
filter.c:9:42: error: incomplete definition of type 'struct bpf_nf_ctx'
    9 |   const struct nf_hook_state *state = ctx->state;
      |                                       ~~~^
filter.c:8:27: note: forward declaration of 'struct bpf_nf_ctx'
    8 | int filter(const struct bpf_nf_ctx *ctx) {
      |                           ^
filter.c:10:29: error: incomplete definition of type 'struct bpf_nf_ctx'
   10 |   int routing_decision = ctx->state->hook;
      |                          ~~~^
filter.c:8:27: note: forward declaration of 'struct bpf_nf_ctx'
    8 | int filter(const struct bpf_nf_ctx *ctx) {
      |                           ^
1 warning and 2 errors generated.

意识到

struct bpf_nf_ctx
nf_bpf_link.h
中定义后,我添加了正确的包含(
#include <net/netfilter/nf_bpf_link.h>
,当完整路径为
/usr/src/linux-headers-6.8.0-48/include/net/netfilter/nf_bpf_link.h
时),这就是输出:

clang --target=bpf -O2 -Wall -I/usr/include/x86_64-linux-gnu -I/usr/src/linux-headers-6.8.0-48/include -c filter.c -o filter.bpf.o
In file included from filter.c:1:
In file included from /usr/src/linux-headers-6.8.0-48/include/linux/bpf.h:8:
In file included from /usr/src/linux-headers-6.8.0-48/include/uapi/linux/filter.h:9:
/usr/src/linux-headers-6.8.0-48/include/linux/compiler.h:251:10: fatal error: 'asm/rwonce.h' file not found
  251 | #include <asm/rwonce.h>
      |          ^~~~~~~~~~~~~~
1 error generated.
make: *** [Makefile:7: all] Error 1

如何正确设置环境以使用 netfilter hooks 编译 BPF 程序?

linux ebpf bpf netfilter
1个回答
0
投票

您正在包含内部内核标头(非 uapi 标头)。这些需要一堆生成的依赖项才能工作,这就是您遇到包含问题的原因。

对于 netfilter 程序,内核开发人员决定不使用像

__sk_buff
这样的投影类型,而是让您访问真实的内部
sk_buff
结构。为了获得这些的定义,他们希望您使用 vmlinux.h 或手动定义您需要的结构,就像编写访问内部内核类型的跟踪程序一样。

对于新手,您可以使用

bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h

从本地内核生成 vmlinux.h 文件

引用介绍它的补丁集

新的程序类型是“跟踪式”,即没有上下文 由验证器完成的访问重写,函数参数(struct bpf_nf_ctx) 不稳定。 不支持直接数据包访问,应使用 dynptr api 相反。

这也意味着如果您需要此程序在未来的内核上运行,您应该使用 CO-RE do do read。

© www.soinside.com 2019 - 2024. All rights reserved.