分享

linux协议栈之链路层上的数据传输(向网桥添加接口续)

 enchen008 2012-04-10
从上图中可以反应出接口与桥之间的关系。我们可以用brctl show指令看到当前所有的桥,以及桥里相应的接口。用ifconfig br0可以看当前桥的状态,如果细心一点可以看到,bro已经有了对应的MAC。这是怎么来的呢?
桥MAC地址的更新:
注意到在br_add_if中调用了函数br_stp_recalculate_bridge_id()
在上面的代码分析中,为了简化分析,把stp的相关流程忽略掉了,现在我们看下这个函数做了些什么
/* called under bridge lock */
void br_stp_recalculate_bridge_id(struct net_bridge *br)
{
const unsigned char *addr = br_mac_zero;
struct net_bridge_port *p;
//遍历桥中所有的端口
list_for_each_entry(p, &br->port_list, list) {
//取所有接口中MAC的最少值
if (addr == br_mac_zero ||
memcmp(p->dev->dev_addr, addr, ETH_ALEN)
addr = p->dev->dev_addr;

}
//如果不与现在桥的MAC相同
if (memcmp(br->bridge_id.addr, addr, ETH_ALEN))
br_stp_change_bridge_id(br, addr);
}
这个函数比较简单,它就是遍历桥对应的所有接口,然后取最小的MAC。然后判断最小MAC跟现在的MAC是否相同
继续跟踪br_stp_change_bridge_id
static void br_stp_change_bridge_id(struct net_bridge *br,
const unsigned char *addr)
{
unsigned char oldaddr[6];
struct net_bridge_port *p;
int wasroot;

wasroot = br_is_root_bridge(br);

memcpy(oldaddr, br->bridge_id.addr, ETH_ALEN);
memcpy(br->bridge_id.addr, addr, ETH_ALEN);
//注意到这里,呵呵,桥的MAC更新了
memcpy(br->dev->dev_addr, addr, ETH_ALEN);

list_for_each_entry(p, &br->port_list, list) {
if (!memcmp(p->designated_bridge.addr, oldaddr, ETH_ALEN))
memcpy(p->designated_bridge.addr, addr, ETH_ALEN);

if (!memcmp(p->designated_root.addr, oldaddr, ETH_ALEN))
memcpy(p->designated_root.addr, addr, ETH_ALEN);

}

br_configuration_update(br);
br_port_state_selection(br);
if (br_is_root_bridge(br) && !wasroot)
br_become_root_bridge(br);
}
看到上面的注释了吧,桥的MAC就是在这里得到更新的,所以,桥的MAC地址取得是所有接口中的最小值
OK。到这里为止,网桥的配置已经讲述完了。我们来看一下网桥是怎么对数据包进行处理的


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多