上一篇文章讲过bpf_prog_run_xdp是XDP 程序的最终调用函数,想要跟踪Generic XDP的代码可以从该函数入手。很显然你不应该从driver/,而是已改在net/目录下检索。
jensonqiu@Bing$ grep -rn "bpf_prog_run_xdp" net
net/core/dev.c:4349: act = bpf_prog_run_xdp(xdp_prog, xdp);
稍微过滤一下真相就呼之欲出了,函数的调用关系如下:
bpf_prog_run_xdp
netif_receive_generic_xdp
do_xdp_generic
netif_rx_internal/netif_receive_skb_internal/netif_receive_skb_list_internal
netif_receive_skb
ixgb_clean_rx_irq //Send received data up the network stack
从调用关系上很容易推导出 Generic XDP的Hook点是在网卡中断的下半部。也即是在网卡软中断的收包流程中,软中断收到报文后直接传递给网络协议栈。
网卡的两种工作模式
网卡有两种工作模式:
1) 软中断收包模式,该机制的特点是直接在软中断函数将报文传递到网络协议栈。
2)软中断唤醒触发轮询模式(NAPI),该机制的特点是在软中断函数中唤醒网卡驱动注册的poll函数,通过poll函数轮询收包。
API 是一种新技术,目前不是所有网卡驱动都支持这种能力,你如果想确定网卡是不是支持NAPI,有很多方式,其中一种就是查一下网卡驱动是否有实现xxxx_poll函数,比如ixgbe的驱动实现了ixgbe_poll函数。
这两种模式分别对应了XDP的 Generic XDP 和 Native XDP模式。
两种模式的代码汇总点其实都在软中断函数中,Generic XDP是在网卡不支持Native XDP模式时候,通过在ixgb_clean_rx_irq函数中调用netif_receive_skb实现,如果支持Native XDP模式则是通过调用网卡实现的xxxx_poll函数实现。
讲到这里,你肯定已经清楚Generic XDP、Native XDP的挂载点差异性了,如果还有不懂的地方可以连续我,我们单独交流。
|