修改Mininet拓扑后Ryu控制器无法转发数据包问题排查
问题:Mininet修改拓扑后Ryu控制器无法转发数据包
原工作拓扑
原拓扑为无环线性结构,可与Ryu控制器正常配合:
h1 <-> of1 h2 <-> of2 h3 <-> of2 h4 <-> of3 of1 <-> of2 of2 <-> of3
修改后的拓扑与代码
拓扑图

Mininet代码
import os from mininet.log import info from mininet.cli import CLI from mininet.link import TCLink from mininet.net import Mininet from mininet.node import RemoteController, OVSSwitch def setup_network(): net = Mininet(controller=RemoteController, switch=OVSSwitch, link=TCLink) # Add Ryu controller info('[+] Adding Ryu controller\n') c0 = net.addController('c0', controller=RemoteController) # Add switches, hosts, and links as before info('[+] Adding OpenFlow switches\n') of1 = net.addSwitch('of1') of2 = net.addSwitch('of2') of3 = net.addSwitch('of3') of4 = net.addSwitch('of4') of5 = net.addSwitch('of5') # Adding hosts info('[+] Adding hosts\n') h1 = net.addHost('h1', ip='10.0.0.1') h2 = net.addHost('h2', ip='10.0.0.2') h3 = net.addHost('h3', ip='10.0.0.3') h4 = net.addHost('h4', ip='10.0.0.4') h5 = net.addHost('h5') h6 = net.addHost('h6') # Adding links based on the diagram (switches connected to each other and hosts) info('[+] Adding links between switches, hosts, and edge servers\n') # Links between Switches net.addLink(of1, of2) # horizontal connection net.addLink(of2, of3) net.addLink(of4, of5) net.addLink(of1, of4) # Vertical connection net.addLink(of2, of4) net.addLink(of3, of5) # Link between Host & Switched net.addLink(of1, h1) net.addLink(of1, h2) net.addLink(of2, h3) net.addLink(of2, h4) net.addLink(of3, h5) net.addLink(of3, h6) # Start the network net.build() c0.start() # Start the controller net.start() # Discover the topology topology = topology_discovery(net) CLI(net) net.stop() return net, topology # --------------------------------------- TOPOLOGY DISCOVERY ------------------------------------------ def topology_discovery(net): info('[*] Discovering topology\n') topology = { 'switches': {}, 'hosts': {}, 'links': [] } for switch in net.switches: topology['switches'][switch.name] = switch for host in net.hosts: topology['hosts'][host.name] = host for link in net.links: topology['links'].append((link.intf1.node.name, link.intf2.node.name)) print("\n===================================================================================================") print("[!] Discovered Topology:") print("Switches:", topology['switches'].keys()) print("Hosts:", topology['hosts'].keys()) print("Links:", topology['links']) print("===================================================================================================") return topology if __name__ == '__main__': # os.system("mn -c") setup_network()
问题说明
修改拓扑后,原Ryu控制器逻辑无法正常转发数据包,调研后推测可能需要使用STP协议,但对相关实现不了解,寻求解决帮助。
核心问题分析
拓扑存在二层环路
修改后的拓扑中,of1-of2-of4-of1形成了明确的二层环路,同时of3-of5链路也存在潜在环路风险。原拓扑为无环结构,Ryu控制器逻辑是基于无环场景设计的,当出现环路后:- 数据包会在环路内无限转发,引发网络拥塞
- 控制器拓扑发现模块会收到重复链路信息,无法生成正确转发路径
- 交换机MAC地址表频繁更新,出现MAC漂移,导致转发混乱
原控制器未适配有环拓扑
原Ryu控制器没有实现环路抑制机制(如STP/RSTP),也没有针对有环拓扑的路径计算逻辑(如最短路径优先),因此无法处理有环拓扑下的转发需求。
解决方案
方案1:在Mininet中启用STP
OVS交换机原生支持STP,只需在创建交换机时开启该功能即可自动阻塞冗余链路,将有环拓扑转换为无环生成树,适配原控制器逻辑:
# 修改添加交换机的代码,开启STP of1 = net.addSwitch('of1', stp=True) of2 = net.addSwitch('of2', stp=True) of3 = net.addSwitch('of3', stp=True) of4 = net.addSwitch('of4', stp=True) of5 = net.addSwitch('of5', stp=True)
方案2:修改Ryu控制器适配有环拓扑
若需保留冗余链路实现故障切换,可对Ryu控制器进行调整:
- 使用Ryu内置的
ryu.app.simple_switch_stp模块,该模块在基础交换机逻辑上集成了STP功能 - 基于LLDP拓扑发现+SPF算法实现路径计算:通过
ryu.app.topology模块获取拓扑信息,再计算最短路径生成对应流表
额外注意事项
h5和h6未配置IP地址,可能导致ping测试失败,建议补充IP配置(如h5 = net.addHost('h5', ip='10.0.0.5'))- 启动网络前执行
mn -c清理旧环境,避免残留配置干扰
内容的提问来源于stack exchange,提问作者farhan jatt
相关产品推荐
相关产品推荐

