XDP framework
xdp在内核里的有三个关键步骤:
load
: 加载到内核attach
: 绑定到一个网口run
:网口收包时候,调用并执行bpf prog
load
加载: 通过ebpf系统调用, 把prog加载到内核
fd = sys_bpf(BPF_PROG_LOAD, attr, size);
- 在内核里创建一个
bfp_prog
结构体用以存储bpf prog。 - 通过
bpf_check
检查prog程序的安全性和合法性。 - 通过
bpf_prog_select_runtime
指定bpf prog对应的执行函数 - 这个函数指针保存在
bpf_func
这个字段里。这里的function最终指向通用的bfp run函数___bpf_prog_run
。
关于___bpf_prog_run
这个具体封装和实现见另外一篇文章。
attach
绑定: 将prog程序绑定到一个特定的网口的struct net_device
上
libpf函数do_attach
将上一步加载在内核里的prog跟一个网口绑定, 具体实现是通过下发netlink命令。
这是个generic类型的netlink命令,最终通过dev_change_xdp_fd
将prog挂载到对应netdev下面。
1 | 2056 struct net_device { |
struct net_device
下的xdp_prog
指向对应的prog
注意这里的加载分skb模式和DRV驱动模式。 驱动模式是加载到网卡驱动里面。以mlx5为例是加载到接收队列rq下面的xdp_prog
run
运行: 当有网络报文从网口进入到协议栈处理时候,调用prog程序并运行
还是以SKB模式为例
网络协议栈在入口函数__netif_receive_skb
时候,通过多层调用,最终会
1 | --> __netif_receive_skb |
核心数据结构
bfp_prog
1 | 1461 struct bpf_prog { |