我通过非常简单的更改从samples/bpf/pare_simple.c
(来自Linux内核树)编译了BPF示例:
SEC("simple")
int handle_ingress(struct __sk_buff *skb)
{
return TC_ACT_SHOT;
}
所以我希望删除任何数据包。我安装如下:
这发生在Ubuntu 16.04.3 LTS上,内核4.4.0-98,llvm和版本3.8的clang从软件包安装,iproute2是github的最新版本。
$ tc qdisc add dev eth0 clsact
$ tc filter add dev eth0 ingress bpf \
object-file ./net-next.git/samples/bpf/parse_simple.o \
section simple verbose
Prog section 'simple' loaded (5)!
- Type: 3
- Instructions: 2 (0 over limit)
- License: GPL
Verifier analysis:
0: (b7) r0 = 2
1: (95) exit
processed 2 insns, stack depth 0
所以它似乎安装成功,但是这个过滤器/ ebpf不丢弃数据包,我在eth0
接口上生成入口流量,例如ICMP,它传递。我做错了什么?
答案 0 :(得分:3)
TL; DR:您应该在direct-action
命令中添加tc filter
标志,如
tc filter add dev eth0 ingress bpf \
object-file ./net-next.git/samples/bpf/parse_simple.o \
section simple direct-action verbose
^^^^^^^^^^^^^
tc bpf filter bpf help
的简短帮助提到了这个标志,但如果我没记错的话,目前还没有进入tc-bpf(8)
手册页。
那么,这个标志是什么?
eBPF程序可以通过两种方式附加tc:as actions 或 classifiers 。附加tc filter add
的分类器应该用于过滤数据包,默认情况下不应用操作。这意味着它们的返回值具有以下含义(来自man tc-bpf
):
0,表示不匹配
-1表示从命令行配置的默认classid
否则,其他所有内容都将覆盖默认的classid以提供非线性匹配的工具
另一方面,附加tc action add
的操作可以丢弃或镜像或执行其他数据包操作,但它们不应该实际过滤它们。
由于eBPF比tc的传统操作和过滤器更灵活,您实际上可以同时执行这两项操作,过滤数据包(即识别此数据包)并对其执行操作。为了反映这种灵活性,添加了direct-action
或da
标志(对于内核4.4或更新版本,使用匹配的iproute2包)。它告诉内核为分类器使用 actions (TC_ACT_SHOT
,TC_ACT_OK
等)的返回值。这就是你需要以内核理解你想丢弃数据包的方式返回TC_ACT_SHOT
。
如果我没记错的话,我们之所以使用这个标志而不仅仅是为操作删除过滤器的原因是你需要一个过滤器来使用tc将你的动作附加到? (待确认)。因此,使用direct-action
标志,您不必同时附加一个过滤器和一个操作,过滤器可以执行这两个操作。这应该是使用tc进行eBPF编程的首选方式。