是否可以尾调用使用不同模式的 eBPF 代码?

Is it possible to tail call eBPF codes that use different modes?

是否可以尾调用使用不同模式的 eBPF 代码?

例如,如果我使用 kprobe 编写了 printk("hello world") 的代码,

之后我能否尾调用 XDP 代码,反之亦然?

我在 eBPF 上编写了一些使用套接字缓冲区的程序,当我尝试尾调用另一个使用 kprobe 的代码时,它似乎没有加载程序。

我想在使用 BPF.SOCKET_FILTER 模式后尾调用使用 XDP_PASS 的代码,但尾调用似乎不起作用。

我一直在努力解决这个问题,但我找不到任何关于使用不同模式的尾部调用代码的文档:P

提前致谢!

不,不是。

查看内核提交 04fd61ab36ec,它引入了尾调用:第一段代码中的注释(在内部内核头文件 bpf.h),定义 struct bpf_array,设置一个 owner_prog_type 成员,并在评论中解释以下内容:

/* 'ownership' of prog_array is claimed by the first program that
 * is going to use this map or by the first program which FD is stored
 * in the map to make sure that all callers and callees have the same
 * prog_type and JITed flag
 */

因此,一旦定义了与用于尾调用的 BPF 程序数组关联的程序类型,就不可能将其与其他程序类型一起使用。这是有道理的,因为不同的程序类型使用不同的上下文(数据包数据 VS 跟踪函数上下文 VS ...),可以使用不同的助手,具有 return 具有不同含义的函数,需要验证者进行不同的检查,.. . 所以很难看出从一种类型跳到另一种类型是如何工作的。你怎么能从处理网络数据包开始,然后突然跳到一段应该跟踪内核内部的代码? :)

请注意,如结构的 owner_jited 所示,也不可能混合使用 JIT-ed 和非 JIT-ed 程序。