RYUbook(5)Spanning Tree

13 篇文章 4 订阅
12 篇文章 1 订阅

一: Spanning Tree

        生成树是为了防止在网络的拓扑中出现循环(loop)进而产生广播风暴(broadcast streams)的技术。而且,借着应用原本防止循环的这项功能,当网络发生问题的时候,则可以达到确保网络的拓扑被重新计算的目的,如此一来就不会让部分的问题影响整个网络的连通。生成树有许多的种类,例如:STP、RSTP、PVST+、MSTP…等不同的种类。本章将说明最基本的STP。STP(spanning tree protocol:IEEE 802.1D)是让网络的拓璞在逻辑上是树状的结构。经由设定每一个交换器(本章节中有时候会使用网桥称呼)的连接埠让讯框(frame)的传送为可通过与不可通过,来防止循环的产生进而达到阻止网络风暴发生。 

        STP会在网桥之间交换BPDU(Bridge Protocol Data Unit)封包,分析及比对网桥之间的连接埠信息,决定哪些连接埠可以传送哪些不行。具体来说,会以下列的顺序完成。

        1.Root交换器(Root bridge)选举网桥之间的BPDU封包在交换过后,拥有最小的网桥ID即为Root。接下来的Root网桥会发送original BPDU,而其他的网桥仅接收及转发BPDU。

        备注:网桥ID的计算方式是组合已经被设定的网桥priority和特定端口的MAC位址而成。网桥ID:

Upper 2byte Lower 6byte
桥接器priorityMAC 位址

        2.决定连接埠的角色基于每一个连接埠到Root网桥的距离来决定该连接埠的角色。

        Root port网桥内连接到Root距离最短的连接埠。该连接埠将会接收来自Root的BPDU。

        Designated port该连接埠从各个联机到Root网桥距离最短。主要转送来自Root桥接器的BPDU封包,Root网桥的所有连接埠均为此种类。

        Non designated port除了Root port、designated port以外的连接埠。讯框的传送是被禁止的。

        

备注:每一个连接埠到Root网桥的距离是基于收到BPDU中的设定值,并加上下列的比较计算出来。

第一优先:比较root path cost的值各网桥在转送BPDU的时候,会将封包中root path cost值加上设定的path cost。因此root path cost值即是各个端口到Root网桥的总和。

第二优先:root path cost相同的话,则比较网桥ID

第三优先:若是网桥ID相同时(每一个端口都连接到相同的网桥),则比较连接埠ID连接埠ID

         3.连接埠的状态变化连接埠的角色决定了之后(STP的处理完成),每一个连接埠会处于LISTEN状态。之后会如下图进行状态的转换,最后每一个连接埠的角色会进入FORWARD状态或者BLOCK状态。若是设定为无效的连接埠之后,就会进入DISABLE状态,接着不会进行任何状态的转移。

        当这些程序在每一台网桥开始执行之后,进行连接埠传送封包或抑制封包的决定,如此一来便可以防止循环在网络拓璞中发生。另外,断线或BPDU封包的最大时限(预设20秒)内未收到封包的故障侦测、新的连接埠加入导致网络拓扑改变。这些变化都会让每一台网桥执行上述1,2和3程序以建立新的树状拓扑(STP re-calculation)。

 二:执行Ryu应用程序

        1.建置实验环境

        首先是mininet的拓扑代码:

#!/ usr/bin/env python
from mininet.cli import CLI  
from mininet.link import Link  
from mininet.net import Mininet  
from mininet.node import RemoteController  
from mininet.term import makeTerm

# 创建 Mininet 对象  
net = Mininet(controller=RemoteController)

# 添加控制器  
c0 = net.addController('c0')

# 添加交换机  
s1 = net.addSwitch('s1')
s2 = net.addSwitch('s2')
s3 = net.addSwitch('s3')

#添加主机
h1 = net.addHost('h1') 
h2 = net.addHost('h2')  
h3 = net.addHost('h3')  

#连接
Link(s1 , h1) 
Link(s2 , h2)
Link(s3 , h3)
Link(s1 , s2) 
Link(s2 , s3)
Link(s3 , s1)

# 构建拓扑并启动所有节点  
net.build()  
c0.start()  
s1.start([ c0])
s2.start([ c0])
s3.start([ c0])

# 添加终端节点  
net.terms.append(makeTerm(c0))
net.terms.append(makeTerm(s1))
net.terms.append(makeTerm(s2))
net.terms.append(makeTerm(s3))
net.terms.append(makeTerm(h1))
net.terms.append(makeTerm(h2))
net.terms.append(makeTerm(h3))

CLI(net)
net.stop()

        输入net指令可以看到: 

        2.设定 OpenFlow 版本

        对Node s1,s2,s3:

ovs-vsctl set Bridge s1 protocols = OpenFlow13
ovs-vsctl set Bridge s2 protocols = OpenFlow13
ovs-vsctl set Bridge s3 protocols = OpenFlow13

        3.执行switching hub 

        对Node c0:

ryu-manager ./simple_switch_stp_13.py

        OpenFlow交换器启动时的STP计算

        每一台OpenFlow交换器和Controller的连接完成后,BPDU封包的交换就开始了。包括Root网桥的选举、连接埠的角色、连接埠的状态转移。

        以上的结果,最后每一个连接埠分别为FORWARD状态或BLOCK状态。

        

 

        为了确认封包不会产生循环现象,从host 1向host 2发送ping指令。在ping命令执行之前,先执行tcpdump命令以确认封包的接收状况。

Node s1,s2,s3:

tcpdump -i s1-eth2 arp
tcpdump -i s2-eth2 arp
tcpdump -i s3-eth2 arp

 在使用script进行网络拓璞的建构的终端机中,进行接下来的指令,从host 1向host 2发送ping封包。

mininet> h1 ping h2 -c4

        从tcpdump的结果看来,ARP并没有出现循环的状态已被确认。 

        网络发现故障时重新计算STP接下来,确认断线发生的时候会进行STP的重新计算。在每一个OpenFlow交换器启动之后以及STP的计算完成之后,执行下列指令后让线路中断。

        Node s2:

ifconfig s2-eth2 down

        断线被侦测到的时候,STP会被重新计算。 

 

         在此之前s3-eth2为BLOCK状态,但现在连接埠的状态为FORWARD,而讯框将可以再次被传送。

        从线路故障的状态回复时重新计算STP接下来,断线回复的时候STP将被重新计算。在断线的状态下执行下列的命令让连接埠恢复。 

        Node s2:

ifconfig s2-eth2 up

         联机恢复后被侦测到,STP就会进行再次的计算。可以确认目前的状态跟应用程序启动时有相同的树状结构,而讯框可以再次被传送。

        3.使用OpenFlow完成生成树

        让我们看一下在Ryu生成树应用程序中,如何使用OpenFlow完成生成树的功能。OpenFlow 1.3提供config来设定连接埠的状态。发送Port Modification信息到OpenFlow交换器以控制连接埠对讯框的转送行为。

名称说明
OFPPC_PORT_DOWN连接埠无效状态
OFPPC_NO_RECV丢弃所有接收到的封包
OFPPC_NO_FWD停止转送封包
OFPPC_NO_PACKET_INtable-miss发生时,不发送Packet-In信息

        为了控制连接埠接收BPDU封包和非BPDU封包,收到BPDU封包就发送Packet-In的Flow Entry和接收BPDU以外的封包就丢弃的Flow Entry,分别透过Flow Mod信息新增到OpenFlow交换器中。

        Controller对各个OpenFlow交换器进行下面port设定和Flow Entry的管理,以达到控制连接端口状态对于BPDU的接收传送和MAC位址的学习(BPDU以外则是封包的接收)和讯框的转送(BPDU以外则是封包的传送)。

        备注:为了精简化,Ryu里的生成树函式库并不处理LEARN状态的MAC位址(接收BPDU以外的封包)学习。为了做这些设定,Controller产生BPDU封包基于OpenFlow交换器连接时所收集的连接埠信息和每一个OpenFlow交换器所接收的BPDU封包中所设定的Root网桥信息,来发送Packet-Out信息达到交换器之间互相交换BPDU的效果。 

        4.使用Ryu实作生成树

        接下来,检视一下Ryu所用来实作生成树的原始码。生成树的原始码存放在Ryu的原始码当中。ryu/lib/stplib.py ryu/app/simple_switch_stp_13.py stplib.py是用来提供BPDU封包的交换和连接埠的角色、状态管理的生成树函式库。simple_switch_stp_13.py是一个应用程序,用来让交换器的应用程序新增生成树函式库以增加生成树功能使用。

 

STP函式库(STP实体)侦测到OpenFlow交换器和Controller已经连接时,Bridge类别的实体和Port类别的实体就会被产生。当每一个类别的实体产生、启动之后。

 从STP类别实体接收到OpenFlow信息。

 Bridge类别实体运算STP(Root网桥的选择,每一个连接埠的角色选择)

 Port类别实体的状态变化,BPDU封包接收及传送

以上动作完成后,即可达成生成树的功能。

        5.代码解析

        

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值