简述网桥的特点_网桥MAC地址的特点

在实际工作中碰到一个问题:设备有两个网口,当把这两个网口桥接到br0上时,之后如果设置了mac地址,就会发现数据包不能正常收发。

如下是相关解释

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

先说现象

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地址设置时需要留意一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值