Linux 核心內建的網橋功能實現了完整的第二層交換邏輯,支援生成樹協議(STP)、MAC 地址學習與老化機制。本文從用戶空間配置工具 brctl 切入,追蹤核心模組初始化流程,揭示網橋子系統的啟動機制。
網橋作為二層設備,其核心轉發流程可概括為四步:
brctl 代碼極簡潔,僅封裝 ioctl 系統調用:
brctl addbr br0 → ioctl(br_socket_fd, SIOCBRADDBR, brname)brctl addif br0 eth0 → ioctl(br_socket_fd, SIOCBRADDIF, &ifr)所有配置操作最終均通過 SIOCBRADDBR、SIOCBRADDIF 等命令進入核心處理邏輯。
網橋核心模組在載入時調用 br_init(net/bridge/br.c),完成關鍵子系統註冊:
static int __init br_init(void)
{
br_fdb_init(); // 初始化轉發資料庫(CAM 表)slab 緩存
#ifdef CONFIG_BRIDGE_NETFILTER
if (br_netfilter_init()) return 1; // Netfilter 掛鉤初始化
#endif
brioctl_set(br_ioctl_deviceless_stub); // 註冊 ioctl 處理函數
br_handle_frame_hook = br_handle_frame; // 設置數據幀處理掛鉤
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
br_fdb_get_hook = br_fdb_get;
br_fdb_put_hook = br_fdb_put;
#endif
register_netdevice_notifier(&br_device_notifier); // 註冊網絡設備通知鏈
return 0;
}
| 初始化項 | 功能說明 |
|---|---|
br_fdb_init() | 為轉發資料庫(FDB)條目分配 slab 緩存,支援高效的 MAC 地址查找與老化 |
brioctl_set() | 註冊用戶空間 ioctl 命令的處理入口 br_ioctl_deviceless_stub |
br_handle_frame_hook | 全域函數指針,指向 br_handle_frame,作為核心協議棧接收路徑中橋處理的入口 |
register_netdevice_notifier() | 註冊網絡設備事件通知鏈,監聽端口設備的增刪狀態變化 |
在 netif_receive_skb 中,核心通過 handle_bridge 檢查接收設備是否屬於某個橋端口(skb->dev->br_port),若是則調用 br_handle_frame_hook 進入橋轉發邏輯:
static inline int handle_bridge(struct sk_buff **pskb,
struct packet_type **pt_prev, int *ret)
{
struct net_bridge_port *port = rcu_dereference((*pskb)->dev->br_port);
if ((*pskb)->pkt_type == PACKET_LOOPBACK || !port)
return 0; // 非橋端口或回環包,跳過橋處理
if (*pt_prev) {
*ret = deliver_skb(*pskb, *pt_prev);
*pt_prev = NULL;
}
return br_handle_frame_hook(port, pskb); // 進入橋核心處理
}
此設計實現了橋模組的動態載入/卸載:未配置橋時 br_handle_frame_hook 為空,handle_bridge 直接返回 0,零性能損耗。
Linux 網橋實現展現了核心模組化設計的精髓:用戶空間工具極簡,核心初始化集中註冊關鍵掛鉤,數據路徑通過函數指針動態接入。理解 br_init 的初始化序列,是掌握橋子系統架構的鑰匙。