Link layer之Bridge

3.6 Bridging

Hub:也叫repeater hub,是一个Layer-1 device,也就是说它只会将数据包广播到所有port上。

Mac bridge:也叫bridgeLayer-2 switch,因为它可以分析ethernet header,所以有self-learning(自学习)功能,可以有效的避免广播,节省带宽。当发生组播时,打开GMRP 功能,可以有效的减少组播的带宽。

3.6.1 self-learning

linuxself-learning是如何实现的。


一个很重要的数据结构就是forwarding tablebridge就是根据它来转发frame的,而向forwarding table中添加tuple(记录)的过程就是self-learning的过程。Forwarding talbe定义在br_private.h中的net_bridge struct中,所有的macport的对应关系都放在这个结构中,而该结构使用hash来实现的。

检索forwarding table的代码在net/bridge/br_fdb.c中,就是用目的mac address来算hash并迅速定位到forwarding table中正确的tupleHash函数叫做br_mac_hash(),下面的代码段指摘自net/bridge/br_fdb.c,用于检索该forwarding table

 

struct net_bridge_fdb_entry *_br_fdb_get(struct net_bridge *br, const unsigned char *addr)

{

struct hlist_node *h;

struct net_bridge_fdb_entry *fdb;

hlist_for_each_entry_rcu(fdb,h,&br->hash[br_mac_hash(addr)],hlist) {

if (!compare_ether_addr(fdb->addr.addr,addr)) {

if (unlikely(has_expired(br, fdb)))

break;

return fdb;

}

}

return NULL;

}

 

hlist_for_each_entry_rcu()在检索由&br->hash[br_mac_hash(addr)]所指向的一个链表,目的是要找到正确的net_bridge_fdb_entry,而net_bridge_fdb_entry包含了要转发的port的信息。rcuread-copy-update)是一种同步机制提供了线程间的互斥。

bridge收到一个frame时,会向forwarding table中插入一个net_bridge_fdb_entry,下面的代码段指摘自net/bridge/br_fdb.c,用于插入。

static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, const unsigned char *addr)

{

struct hlist_head *head = &br->hash[br_mac_hash(addr)]; 

struct net_bridge_fdb_entry *fdb;

if (!is_valid_ether_addr(addr))

return -EINVAL;

fdb = fdb_find(head, addr);

if (fdb) {                       //找到了就删掉该fdb

if (fdb->is_local)

return 0;

fdb_delete(fdb);

}

if (!fdb_create(head, source, addr, 1))     //生成新的fdb

return -ENOMEM;

return 0;

}

3.6.2 Spanning Tree Protocol

当一个bridged network变得越来越大和复杂时,可能会形成loop,一旦形成loop就会让frameloop中不停的传输(如果有一个station发送了一个广播包,则形成广播风暴),并使forwarding table变得不稳定。我将根据下图讲述STP的原理。


 

1、一开始,给个switchport都会被分配一个ID,该ID包括一个priority valueswitch address(对于port ID来说,就是port number),在该例子中,我使用16作为ID

2、每个link上都有一个cost,该costlink speed成反比。我假设所有的linkcost都是1

3、拥有最小idswitch叫做rootroot是被动态选举出来的。

4、发送来自于rootframeport叫做designated port(DP),而该switch叫做designated bridge;接收来自rootframeport叫做root portRP)如上图所示。

5、Bridge protocol data unit,简称BPDU,该BPDU frame的目的地址是01-80-C2-00-00-00(一个固定的保留的多播地址),该BPDU frame包含的内容有:root idtransmitting switch idtransmitting port id、从root到当前switchcost。该BPDU frameroot开始向下发送。

6、每个switch都根据BPDU来配置自己,配置规则如下:

A) 如果一个switch发现它能够提供一个更低的cost,那么它就成为一个designated bridge,并发送BPDU

B) 当存在多条link而这些linkcost都相等时,id最小的那个switch会被选为designated bridge(or port)

C) 如果当前的一个switch发现自己的id要小于root id,则它会变成新的root并发送MPDU

D) 一个switch不能够转发BPDU,它只能create一个新的BPDU,并发给其他的switch

7、通过以上步骤就找出了所有的DPRP,既不是DP又不是RPport就被阻塞,通过阻塞port就破解了loop

 

3.6.3 STP的实现

下图是STP的调用流程:


 

br_config_bpdu是最重要的结构,定义在net/bridge/br_private_stp.h中,这个结构中的很多成员都对应于BPDU frame的字段。

br_stp_rcv()定义在/net/bridge/br_stp_bpdu.c中,该函数分析bpdu并建立一个br_config_bpdu结构。该bpdu结构和port信息被传递给br_received_config_bpdu(),它定义在br_stp.c中,该函数首先调用br_record_config_information()注册bpdu信息,然后调用br_configuration_update()来更新bridge的配置,然后再调用br_port_state_selection()来更新port状态。

br_configuration_update()调用br_root_selection() and br_designated_port_selection()来选择一个new root和决定一个designated port

 

Remark:在br_root_selection()中有root是如何被选举出来的代码。

3.6.4 VLAN

One-armed router:它一个port链接在switchtrunk port上,用来做两个vlan的路由。

Vlan id一共12bits,共4096vlans

Framesource mac后面增加了4bytestag,这4byte,前2byte表示协议类型(0x8100),后两个bytevlan的控制域,而控制域由3field构成:priorityCFIvlan id


 [此为原创,转载请标明出处,谢谢!]


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值