Native xdp hook 点

XDP 支持三种操作模式:

Native XDP(XDP_FLAGS_DRV_MODE)

默认的工作模式,Native工作在网卡驱动的RX队列上。

Offloaded XDP(XDP_FLAGS_HW_MODE)

offloaded 模式,XDP BPF程序直接工作在NIC中处理报文,一般是智能网卡的模式。

Generic XDP(XDP_FLAGS_SKB_MODE)

通用模式,当上述两种模式都不支持的时候,还可以使用通用模式。

这三种模式分别工作在不同的层次,Native XDP在网卡驱动中,Offloaded XDP 硬件中,Generic XDP网络协议中。性能有很大的差别。

今天我们重点看看Native XDP的hook点,所以Native XDP是我们今天的主角。

看到xdp功能的时候,你可能已经猜到了xdp一定有在内核中有hook,你也可能猜到了xdp的hook应该在网卡程序中,但是你可能不知道xdp hook 具体在网卡驱动的那个流程中,今天走读了一遍xdp的代码逻辑,简单记录内容如下。

bpf_prog_run_xdp

bpf_prog_run_xdp函数是xdp的框架函数,你注册的xdp程序将会在这个函数中被调用。

xdp的hook是在内核驱动中 ? 你可以过滤一下这个函数,大概应该和我的差不多:

xxx@xxx$ grep -rn "bpf_prog_run_xdp" .
./net/core/dev.c:4324:	act = bpf_prog_run_xdp(xdp_prog, xdp);
./drivers/net/tun.c:1634:		act = bpf_prog_run_xdp(xdp_prog, &xdp);
./drivers/net/ethernet/intel/i40e/i40e_txrx.c:2242:	act = bpf_prog_run_xdp(xdp_prog, xdp);
./drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:2214:	act = bpf_prog_run_xdp(xdp_prog, xdp);
./drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c:1067:	act = bpf_prog_run_xdp(xdp_prog, xdp);
./drivers/net/ethernet/qlogic/qede/qede_fp.c:1084:	act = bpf_prog_run_xdp(prog, &xdp);
./drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c:106:	act = bpf_prog_run_xdp(xdp_prog, &xdp);
./drivers/net/ethernet/mellanox/mlx4/en_rx.c:775:			act = bpf_prog_run_xdp(xdp_prog, &xdp);
./drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c:71:	act = bpf_prog_run_xdp(prog, &xdp);
./drivers/net/ethernet/netronome/nfp/nfp_net_common.c:1744:			act = bpf_prog_run_xdp(xdp_prog, &xdp);
./drivers/net/ethernet/cavium/thunder/nicvf_main.c:538:	action = bpf_prog_run_xdp(prog, &xdp);
./drivers/net/veth.c:399:		act = bpf_prog_run_xdp(xdp_prog, &xdp);
./drivers/net/veth.c:525:	act = bpf_prog_run_xdp(xdp_prog, &xdp);
./drivers/net/virtio_net.c:668:		act = bpf_prog_run_xdp(xdp_prog, &xdp);
./drivers/net/virtio_net.c:823:		act = bpf_prog_run_xdp(xdp_prog, &xdp);
./include/linux/filter.h:619:static __always_inline u32 bpf_prog_run_xdp(const struct bpf_prog *prog,

当然,这不是关键,这只是印证了前面的第二个 猜测。

下面我们具体看看这个函数:

static __always_inline u32 bpf_prog_run_xdp(const struct bpf_prog *prog,
                                            struct xdp_buff *xdp)
{
        /* Caller needs to hold rcu_read_lock() (!), otherwise program
         * can be released while still running, or map elements could be
         * freed early while still having concurrent users. XDP fastpath
         * already takes rcu_read_lock() when fetching the program, so
         * it's not necessary here anymore.
         */
        return BPF_PROG_RUN(prog, xdp);
}



#define BPF_PROG_RUN(filter, ctx)  (*(filter)->bpf_func)(ctx, (filter)->insnsi)

BPF_PROG_RUN在执行你挂载的函数,看上去在xdp的框架函数中只能挂载有一个xdp程序?

当然你可能对怎么挂载感兴趣,下一篇再讲。

xdp的挂载点

顺着 bpf_prog_run_xdp  的线索,去查找它的调用关系,你很快就能找到xdp的真正挂载点。

bpf_prog_run_xdp

ixgbe_run_xdp

ixgbe_clean_rx_irq

ixgbe_poll

/**
 * ixgbe_poll - NAPI Rx polling callback
 * @napi: structure for representing this polling device
 * @budget: how many packets driver is allowed to clean
 *
 * This function is used for legacy and MSI, NAPI mode
 **/
int ixgbe_poll(struct napi_struct *napi, int budget)

看到这差不多已经知道他的挂载点了吗 ?

另外,上面的调用关系只在rx方向有逻辑,tx是没有的。所以xdp支持在rx的报文处理,如果想要在tx方向处理,你只能转而研究tc epbf 了,tc比xdp强大的是rx tx都有hook点,但是论性能就比xdp差了,为啥差呢,已经很明显了吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值