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 { |
函数关系汇总图
