歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

Linux內核分析 - 網絡[六]:網橋

看完了路由表,重新回到netif_receive_skb ()函數,在提交給上層協議處理前,會執行下面一句,這就是網橋的相關操作,也是這篇要講解的內容。  
  1. 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。
        首先是創建新的網橋:

 
  1. dev = new_bridge_dev(net, name);  

        然後設置dev->dev.type為br_type,而br_type是個全局變量,只初始化了一個名字變量

 
  1. SET_NETDEV_DEVTYPE(dev, &br_type);  
  2. static struct device_type br_type = {  
  3.  .name = "bridge",  
  4. };  

        然後注冊新創建的設備dev,網橋就相當一個虛擬網卡設備,注冊過的設備用ifconfig就可查看到:

 
  1. ret = register_netdevice(dev);  

        最後在sysfs文件系統中也創建相應項,便於查看和管理:

 
  1. 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實際代表的就是網卡設備。

 
  1. 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。

 
  1. err = br_fdb_insert(br, p, dev->dev_addr);   

        設備的br_port指向p。這裡要明白的是,net_bridge可以看作全局量,是網橋,而net_bridge_port則是與網卡相對應的端口,因此每個設備dev有個指針br_port指向該端口。

 
  1. 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的[具體如下圖]。 

 
  1. list_add_rcu(&p->list, &br->port_list);  

        重新計算網橋的ID,這裡根據br->port_list鏈表中的net_bridge_port的最小的addr來作為網橋的ID。

 
  1. br_stp_recalculate_bridge_id(br);  

        網卡設備的刪除br_del_bridge()與端口的移除add_del_if()與添加差不多,不再詳述。

Copyright © Linux教程網 All Rights Reserved