在 Linux 內核網絡協議棧中,數據包從網卡驅動接收後,進入核心處理流程的關鍵入口是 netif_receive_skb。這個函數位於 net/core/dev.c,負責協調分片重組、網橋處理以及根據協議類型分發給相應的傳輸層處理模塊。本文重點剖析 Linux 網橋的實現邏輯與數據流向。
netif_receive_skb 的主要職責包括:
ptype_all 鏈表,分發給所有註冊的協議處理器(如 tcpdump)handle_diverter 處理分片重組handle_bridge 進行網橋處理ptype_base 哈希表查找並調用對應處理函數當內核編譯時啟用 CONFIG_BRIDGE 或 CONFIG_BRIDGE_MODULE 時,handle_bridge 會被定義為實際處理函數,否則為空函數直接返回 0。其核心邏輯如下:
static __inline__ int handle_bridge(struct sk_buff **pskb,
struct packet_type **pt_prev, int *ret)
{
struct net_bridge_port *port;
// 過濾回環包或非以太網接口
if ((*pskb)->pkt_type == PACKET_LOOPBACK ||
(port = rcu_dereference((*pskb)->dev->br_port)) == NULL)
return 0;
// 若有待分發的 packet_type,先分發
if (*pt_prev) {
*ret = deliver_skb(*pskb, *pt_prev);
*pt_prev = NULL;
}
// 調用全局函數指針 br_handle_frame_hook
return br_handle_frame_hook(port, pskb);
}
關鍵點:
skb->dev->br_port 判斷接收接口是否屬於某個橋端口br_handle_frame_hook 是一個全局函數指針,指向具體的網橋幀處理函數(通常為 br_handle_frame)網卡驅動 → netif_receive_skb → handle_bridge → br_handle_frame_hook → 網橋轉發/本地處理決策 → 繼續協議棧或丟棄。這種設計使得網橋功能可以作為模塊動態加載,且不影響非網橋場景的性能。