Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 網橋實現原理:從 brctl 配置工具看核心模組初始化

編輯:Linux 教學

Linux 核心內建的網橋功能實現了完整的第二層交換邏輯,支援生成樹協議(STP)、MAC 地址學習與老化機制。本文從用戶空間配置工具 brctl 切入,追蹤核心模組初始化流程,揭示網橋子系統的啟動機制。

網橋核心轉發邏輯回顧

網橋作為二層設備,其核心轉發流程可概括為四步:

  1. 學習源 MAC:接收數據幀,檢查 CAM 表(轉發資料庫)中是否存在源 MAC 對應項,若無則建立「源 MAC ↔ 接收端口」映射。
  2. 判斷目的地:若目的 MAC 為本機,送往上層協議棧;否則查詢 CAM 表尋找輸出端口。
  3. 轉發或泛洪:找到出口端口則單播轉發;未找到則向除接收端口外的所有端口泛洪。
  4. 老化機制:CAM 表項在預設時間(300 秒)內未更新則被刪除。

brctl 配置工具與 ioctl 接口

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

網橋核心模組在載入時調用 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 的初始化序列,是掌握橋子系統架構的鑰匙。

Copyright © Windows教程網 All Rights Reserved