eBPF内核程序中是否允许循环?

时间:2019-05-13 07:15:08

标签: llvm-clang bpf ebpf

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

我尝试循环5次,在循环中我打算克隆数据包,修改DST IP地址,更新cksum,然后在接收到的相同intf上发送数据包。

我读到某处循环不能在XDP中使用,所以不确定这是否行得通吗?

请需要专家的建议。

2 个答案:

答案 0 :(得分:1)

从技术上讲,BPF字节码程序的控制流程图中的后端是禁止的,而不是循环。具体来说,这意味着您可以在C语言中编写有界循环,但是必须在编译时展开它们

要展开循环,您可以使用Clang's #pragma unroll directive 。这应该适用于5次迭代的循环,但是不会适用于很长的循环。

答案 1 :(得分:1)

否,目前,eBPF程序中不允许循环。不允许使用后沿,以便内核验证程序可以确保程序终止(并且不会挂起内核)。

随着内核开发人员正在support for bounding loops上工作,这种情况将来可能会改变。

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

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

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

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

这意味着在生成的目标文件中,该功能将展开,它将被要执行的全部指令系列所取代,而没有实际的向后跳转。

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