控制器是为了更好集中控制网络的行为,当然在实际中我们可以根据需要选择是否选择控制器,或是结合ovs交换机的特点进行针对性的转发行为设置(功能需要书写代码进行软件定义),转发功能需要手工添加流表才能实现
我们仍然采用博文:1-3 mininet中使用python API直接拓扑定义以及启动方式对比中的拓扑:topo_32.py,具体代码如下
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.cli import CLI #导入模块
class MyTopology(Topo):
def build(self):
# 创建交换机
switch = self.addSwitch('s1')
# 创建主机
host1 = self.addHost('h1')
host2 = self.addHost('h2')
# 创建链路
self.addLink(host1, switch)
self.addLink(host2, switch)
topo = MyTopology()
net = Mininet(topo,controller=None)#net = Mininet(topo) 会默认在start时启用控制器
net.start() #会自动启用mininet内置的控制器,默认情况)
CLI(net) #调用cli
net.stop()
这段代码中net = Mininet(topo,controller=None)表示当前采用无控制器启用,启用后各个host之间将无法ping通,OVS上的流表为空。
需要在mininet运行环境中输入xterm 进入交换机s1后手工添加流表才能使得各个host之间互通
如:ovs-ofctl add-flow s1 in_port=1,actions=output:2
ovs-ofctl add-flow s1 in_port=2,actions=output:1
也可以采用以下方式直接在代码中实现
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.cli import CLI #导入模块
class MyTopology(Topo):
def build(self):
# 创建交换机
switch = self.addSwitch('s1')
# 创建主机
host1 = self.addHost('h1')
host2 = self.addHost('h2')
# 创建链路
self.addLink(host1, switch)
self.addLink(host2, switch)
topo = MyTopology()
net = Mininet(topo,controller=None)#net = Mininet(topo) 会默认在start时启用控制器
net.start() #会自动启用mininet内置的控制器,默认情况)
# 在交换机上下发流表(无法读取类中的成员s1,导致运行异常,需要使用下面的topo_36.py中函数定义的方式实现)
s1.cmd('ovs-ofctl add-flow s1 in_port=1,actions=output:2')
s1.cmd('ovs-ofctl add-flow s1 in_port=2,actions=output:1')
CLI(net) #调用cli
net.stop()
多接口转发
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.cli import CLI #导入模块
class MyTopology(Topo):
def build(self):
# 创建交换机
switch = self.addSwitch('s1')
# 创建主机
host1 = self.addHost('h1')
host2 = self.addHost('h2')
host3 = self.addHost('h3')
# 创建链路
self.addLink(host1, switch)
self.addLink(host2, switch)
self.addLink(host3, switch)
topo = MyTopology()
net = Mininet(topo,controller=None)#
net.start() #会自动启用mininet内置的控制器,默认情况)
# 在交换机上下发流表(此处无法识别类中的对象,运行出错)
s1.cmd('ovs-ofctl add-flow s1 in_port=1,actions=output:2,3')
s1.cmd('ovs-ofctl add-flow s1 in_port=2,actions=output:1,3')
s1.cmd('ovs-ofctl add-flow s1 in_port=3,actions=output:1,2')
CLI(net) #调用cli
net.stop()
在mininet中使用mininet定义网络如,并下发流表:topo_36.py原理同上
#自定义流表,无控制器,交换机将无法从控制器中自学习到流表,需要手动往交换机中添加流表才能使得连接在同一个交换机中的两个主机之间互相通信topo_36.py
from mininet.net import Mininet
from mininet.node import OVSSwitch
from mininet.cli import CLI
def create_topology():
net = Mininet(switch=OVSSwitch)
# 添加交换机
s1 = net.addSwitch('s1')
# 添加主机
h1 = net.addHost('h1')
h2 = net.addHost('h2')
# 添加链路
net.addLink(h1, s1,port2=1)
net.addLink(h2, s1,port2=2)
net.start()
# 在交换机上下发流表
s1.cmd('ovs-ofctl add-flow s1 in_port=1,actions=output:2')
s1.cmd('ovs-ofctl add-flow s1 in_port=2,actions=output:1')
# 在主机之间进行ping测试
#h1.cmd('ping -c 3', h2.IP())
# 进入Mininet的命令行界面
CLI(net)
net.stop()
if __name__ == '__main__':
create_topology()
以上代码据采用python3启用(ubuntu环境)
注意,本文涉及的流表设置是采用cmd命令,流表与预定义的流数据行为相匹配,因此需要与网络拓扑中的端口连接相对应。一般情况下,在用net模块创建网络环境时,增加连接时如果没有制定连接的端口,则按照默认的代码先后顺序进行编号,如本文代码中的 net.addLink(h1, s1,port2=1)指定h1连接在s1的1号端口,代码中采用的拓扑如图1