看完了路由表,重新回到netif_receive_skb ()函數,在提交給上層協議處理前,會執行下面一句,這就是橋接器的相關操作 ,也是這篇要講解的內容。
skb = handle_bridge(skb, &pt_prev, &ret, orig_dev);
橋接器可以簡單理 解為交換器,以下圖為例,一台linux機器可以看作橋接器和路由的結合,橋接器將物理上的兩個區域網路LAN1、LAN2當作一個區域網路 處理,路由串連了兩個子網1.0和2.0。從eth0和eth1網卡收到的報文在Bridge模組中會被處理成是由Bridge收到的,因此Bridge 也相當於一個虛擬網卡。
STP五種狀態
DISABLED
BLOCKING
LISTENING
LEARNING
FORWARDING
建立新的橋接器br_add_bridge [net\bridge\br_if.c]
當使用SIOCBRADDBR調用ioctl時,會建立新的橋接器br_add_bridge。
首先是建立新的橋接器:
dev = new_bridge_dev(net, name);
然後設定dev->dev.type為br_type,而br_type是個全域變數,只初始化了一個名字變 量
SET_NETDEV_DEVTYPE(dev, &br_type); static struct device_type br_type = { .name = "bridge", };
然後註冊新建立的裝置dev,橋接器就相當一個虛擬網卡裝置,註冊過的裝置用ifconfig就可查看到:
ret = register_netdevice(dev);
最後在sysfs檔案系統中也建立相應項,便於查看和管理:
ret = br_sysfs_addbr (dev);
將連接埠加入橋接器br_add_if() [net\bridge\br_if.c]
當使用SIOCBRADDIF調用ioctl時,會向網卡加入新的連接埠br_add_if。
建立新的net_bridge_port p,會從br- >port_list中分配一個未用的port_no,p->br會指向br,p->state設為BR_STATE_DISABLED。這裡的p實際代表的就是 網卡裝置。
p = new_nbp(br, dev);
將新建立的p加入CAM表中,CAM表是用來記錄mac地址與物理連接埠的對應關係 ;而剛剛建立了p,因此也要加入CAM表中,並且該表項應是local的[關係如下圖],可以看到,CAM表在實現中作為net_bridge的 hash表,以addr作為hash值,鏈入net_bridge_fdb_entry,再由它的dst指向net_bridge_port。
err = br_fdb_insert (br, p, dev->dev_addr);
裝置的br_port指向p。這裡要明白的是,net_bridge可以看作全域量,是橋接器,而net_bridge_port則 是與網卡相對應的連接埠,因此每個裝置dev有個指標br_port指向該連接埠。
rcu_assign_pointer(dev->br_port, p);
將新建立的net_bridge_port加入br的鏈表port_list中,在建立新的net_bridge_port時,會分配一個未用的port_no ,而這個port_no就是根據br->port_list中的已經添加的net_bridge_port來找到未用的port_no的[具體如下圖]。
list_add_rcu(&p->list, &br->port_list);