Linux 的 BPF 程序中是否允许循环?

Fer*_*ndo 3 llvm-clang bpf ebpf

我正在考虑在内核中复制数据包并转发到 5 个主机(单播)的解决方案。计划使用 eBPF/XDP。

我试图循环 5 次,在循环内我计划克隆数据包,修改 DST IP 地址,更新 cksum 并在收到的同一个 intf 上发送数据包。

我读到某处循环不能在 XDP 中使用,所以不确定这是否有效?

需要专家的意见请。

Qeo*_*ole 9

2019 年 6 月编辑: 有界循环现已登陆内核,并从 Linux 5.3 ( commit )开始可用

原答案:

不,目前 eBPF 程序中不允许循环。后边缘是不允许的,因此内核验证器可以确保程序终止(并且不挂起内核)。

这在未来可能会改变,因为内核开发人员正在努力支持边界循环

两种可能的解决方法值得一提。两者都假设您知道在编写程序时必须“循环”多少次

首先,关于功能,后边缘有一个例外。这意味着您可以拥有函数,并多次调用它们。因此,您可以将通常放入循环中的所有内容放在一个单独的函数中,并根据循环次数调用此函数。

第二件事是,您实际上可以在 C 代码中编写循环,并在编译时要求 clang 展开它们。如下所示:

#pragma clang loop unroll(full)
        for (i = 0; i < 4; i++) {
            /* Do stuff ... */
        }
Run Code Online (Sandbox Code Playgroud)

这意味着在生成的目标文件中,函数将被展开,它将被要执行的完整系列指令替换,没有实际的向后跳转。

目前没有任意数量循环的序列的解决方案。