zoukankan      html  css  js  c++  java
  • 网桥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地址设置时需要留意一下。

  • 相关阅读:
    UIAction 公共界面访问控制(拦截控制)
    MD5加密
    SVN的简单用法
    Spring AOP基础之JDK动态代理
    Spring中的事务管理模块基础
    Spring添加Junit4支持
    Spring里面dbcp连接池的配置和使用
    vue.js自定义指令详解
    vue input输入框联想
    export ,export default 和 import 区别 以及用法
  • 原文地址:https://www.cnblogs.com/wlei/p/2819429.html
Copyright © 2011-2022 走看看