eBPF Talk: 揭秘 XDP 转发网络包
文章目录
书接上回 eBPF Talk: 解密 XDP generic 模式,本文从源代码层面剖析 XDP 转发网络包的实现。
demo
按需将网络包从另一张网卡转发走。
|
|
其中,REDIRECT_IFINDEX
常量需要用户应用程序重写成目标网口的 ifindex。
bpf_xdp_redirect()
咦,为什么 XDP 具体的 bpf_redirect()
函数的实现是 bpf_xdp_redirect()
而不是 bpf_redirect()
呢?
好问题,又有一个可以深入挖掘的地方。
|
|
从如上代码片段可知,对于 XDP 程序而言,为 bpf_redirect()
BPF 函数
(BPF_FUNC_redirect
)注册的函数是 bpf_xdp_redirect()
。所以,不要被
C 代码里的 bpf_redirect()
函数名称给欺骗了哦。
bpf_xdp_redirect()
syscall
其源代码如下:
|
|
如上代码片段做了如下处理:
- 取出每个 CPU 的
struct bpf_redirect_info
。 - 将 ifindex 和 flags 保存到
struct bpf_redirect_info
中。 - 返回
XDP_REDIRECT
。
bpf_xdp_redirect_map()
其源代码如下:
|
|
处理逻辑类似 bpf_xdp_recirect()
,这里多了一步:保存 map 到 struct bpf_redirect_info
中。
BPF_REDIRECT
此时再来看 eBPF Talk: 解密 XDP generic 模式 中关于转发网络包的处理逻辑。
|
|
其中的 BPF_MAP_TYPE_XSKMAP
涉及 AF_XDP,先跳过吧。
对于 XDP bpf_redirect_map()
中向另一张网卡转发网络包的处理逻辑跟 bpf_redirect()
类似,最终都会
- 从每个 CPU 的
struct bpf_redirect_info
中获取目标 ifindex。 - 重置
struct bpf_redirect_info
。 - 检查能否从目标网卡发包出去。
- 设置
skb->dev
为目标网卡设备。 - 调用
generic_xdp_tx()
函数进行发包。
对于
XDP_TX
的处理,不就是调用generic_xdp_tx()
函数进行发包吗?哈哈。
generic_xdp_tx()
其源代码如下:
|
|
该函数的处理逻辑:
- 取出
skb->dev
,bpf_xdp_redirect()
和bpf_xdp_redirect_map()
都将skb->dev
设置为目标网卡设备了。 - 选择发包队列
txq
。 - 调用
dev_xmit_start_xmit()
进行发包。
小结
至此,XDP 转发网络包的实现分析完毕。
填了 XDP 转发网络包这坑后,又留了 BPF_FUNC_xxx
的坑;这真的是,知道的越多、未知的更多。
文章作者 Leon Hwang
上次更新 2023-05-20