参考Linux内核收包流程,函数调用链是:
硬件中断 -->do_IRQ–>handle_irq–>e1000_intr_msix_rx–>__napi_schedule(&adapter->napi)–>
____napi_schedule–>__raise_softirq_irqoff(NET_RX_SOFTIRQ)
do_IRQ–>irq_exit–>do_softirq–>call_softirq–>__do_softirq–>
net_rx_action->e1000e_poll–>e1000_receive_skb->napi_gro_receive–>
netif_receive_skb–>__netif_receive_skb–>__netif_receive_skb_core–>
deliver_skb–>ip_rcv–>NF_HOOK(NF_INET_PRE_ROUTING)–>
ip_rcv_finish–>dst_input–>ip_local_deliver–>
NF_HOOK(NF_INET_LOCAL_IN)–>ip_local_deliver_finish–>ipprot->handler()
如果ovs 或者普通的网桥如何报文在哪里接收呢?通过梳理代码发现上述调用流程中的__netif_receive_skb_core函数有个rx_handler,ovs bridge等都是通过设置该函数指针实现对报文的接管。
内核版本4.4
__netif_receive_skb_core函数中如下片段
rx_handler = rcu_dereference(skb->dev-