3

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,它会继续。我究竟做错了什么?

4

1 回答 1

4

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 连接:作为操作,或作为分类器。带有 的分类tc filter add器应该用于过滤数据包,默认情况下不应用操作。这意味着它们的返回值具有以下含义(来自man tc-bpf):

0 , 表示不匹配

-1 ,表示从命令行配置的默认classid

否则,其他所有内容都将覆盖默认的 classid 以提供非线性匹配的工具

tc action add另一方面,带有 的操作可以丢弃或镜像或对数据包执行其他操作,但它们不应该实际过滤它们。

因为 eBPF 比 tc 的传统动作和过滤器更灵活,实际上你可以同时做这两个,过滤一个数据包(即识别这个数据包)并对它执行一个动作。为了反映这种灵活性,添加了direct-actionda标志(对于内核 4.4 或更高版本,具有匹配的 iproute2 包)。它告诉内核使用分类器的动作TC_ACT_SHOTTC_ACT_OK等)的返回值。这就是您需要以内核理解您要丢弃数据包的方式返回的内容。TC_ACT_SHOT

如果我没记错的话,我们使用这个标志而不是仅仅为动作删除过滤器的原因是你需要一个带有 tc 的过滤器来附加你的动作?(待确认)。因此,使用该direct-action标志,您不必同时附加一个过滤器和一个操作,过滤器可以执行这两种操作。这应该是使用 tc 进行 eBPF 编程的首选方式。

于 2017-12-01T11:38:24.227 回答