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