網橋MAC地址的特點


在實際工作中碰到一個問題:設備有兩個網口,當把這兩個網口橋接到br0上時,之后如果設置了mac地址,就會發現數據包不能正常收發。

如下是相關解釋

--------------------------------------------------------------------

轉自(http://blog.csdn.net/fanwenbo/article/details/2131193

先說現象
brctl addbr br0
ifconfig br0
br0 MAC is 00:00:00:00:00:00

brctl addif br0 eth1  (eth1 is xx:xx:xx:xx:xx:33)
ifconfig br0
br0 MAC is xx:xx:xx:xx:xx:33  same as eth1, auto change

brctl addif br0 eth2  (eth2 is xx:xx:xx:xx:xx:30)
ifconfig br0
br0 MAC is xx:xx:xx:xx:xx:30  same as eth2, For eth2 less than eth1, auto change

ifconfig eth2 hw ether xx:xx:xx:xx:xx:50
ifconfig br0
br0 MAC is xx:xx:xx:xx:xx:33  same as eth1, auto change

ifconfig br0 hw ether xx:xx:xx:xx:xx:99
ifconfig br0
br0 MAC is xx:xx:xx:xx:xx:33  same as eth1, NOT change


ifconfig br0 hw ether xx:xx:xx:xx:xx:33  ;same as eth1
ifconfig eth2 hw ether xx:xx:xx:xx:xx:20  ;less than eth1
ifconfig br0
br0 MAC is xx:xx:xx:xx:xx:33  same as eth1, `ifconfig br0 hw` NOT effective

ifconfig eth1 hw ether xx:xx:xx:xx:xx:50  ;upper op,we set br0 = eth1's MAC,now we change eth1 MAC
ifconfig br0
br0 MAC is xx:xx:xx:xx:xx:20  same as eth2, auto change

結論:
  br0如果沒有指定hw MAC, br0的MAC地址會根據bridge中port的變化,自動選擇port中最小的一個MAC地址作為br0的MAC地址。
  br0只能指定port中有的interface的MAC作為br0的MAC地址。
 
源代碼分析:
  source code dir is: linux-2.4.x/net/bridge
 
  - br_device.c
      br_dev_setup() 注冊了一些函數,其中  dev->set_mac_address = br_set_mac_address;  //這個就是ifconfig br0 hw ether調用的函數了
     
      static int  br_set_mac_address(struct net_device *dev, void *addr)
          {
            struct net_bridge *br = dev->priv;
            struct sockaddr *sa = (struct sockaddr *) addr;
           
          。。。。。 
          //here ! copy MAC addr to br->preferred_id.addr
            memcpy(br->preferred_id.addr, sa->sa_data, ETH_ALEN);
         
            br_stp_recalculate_bridge_id(br);
         
          。。。。。
          }

 
  - br_stp_if.c
      static unsigned char br_mac_zero[6] = {0,0,0,0,0,0};
     
      /* called under bridge lock */
      void br_stp_recalculate_bridge_id(struct net_bridge *br)
      {
        unsigned char *addr;
        struct net_bridge_port *p;
     
        //初始br0的MAC為00:00:00:00:00:00
        addr = br_mac_zero;
     
        p = br->port_list;
        while (p != NULL) {
          /* match against preferred address first */
          if (memcmp(p->dev->dev_addr, br->preferred_id.addr, ETH_ALEN) == 0) {
            addr = p->dev->dev_addr;
            //匹配port的MAC地址與首選MAC是否相符
            break;
          }
         
          if (addr == br_mac_zero ||
              memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
          //尋找MAC最小的那一個
            addr = p->dev->dev_addr;
     
          p = p->next;
        }
     
        //如果沒有Port的話,就為0;
        //如果沒有設置首選MAC,就等於最小的那一個。
        //如果設置了首選MAC,則首選MAC必須同其中一個port的MAC匹配,才等於首選MAC
        if (memcmp(br->bridge_id.addr, addr, ETH_ALEN))
          br_stp_change_bridge_id(br, addr);
      }
 
  - 什么時候會執行br_stp_recalculate_bridge_id呢
      - in br_device.c 中 br_set_mac_address()
      - in br_if.c 中 br_del_if() & br_add_if()
      - in br_notify.c 中 br_devic_event()的 NETDEV_CHANGEADDR 事件,該事件是任意port有修改addr就會觸發的
     
     
看過代碼就很容易理解bridge在處理自身MAC地址時的行為了

 ----------------------------------------------------------------------------

針對這種情況,目前采用的方法就是先去設置網口的mac地址,然后再橋接成br0,這樣mac地址就不需要操心了,網橋端口的mac地址設置時需要留意一下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM