无控制器时利用流表来进行交换机与主机间的流量传输
在sdn里,一个拓扑如果没有控制器只有主机和交换机的话,主机之间是不会互相通信的,这时候需要给交换机加流表使得主机之间可以互相通信。举例如下。
下面是一个简单的拓扑代码:
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()
其中红字部分把控制器给ban掉了,此时我们可以试试主机之间互相ping能不能通信,效果如下:
很明显看到h1和h2之间是没有数据传输的。
此时我们可以用xterm给s1加流表,使得h1和h2可以通信。添加流表的代码如下:
ovs-ofctl add-flow s1 in_port=1,actions=output:2
其中的第一个红字部分是要根据自己设置的交换机名字来修改,第二个和第三个则和自己设置的主机连接到交换机的端口号有关,关于这个端口号设置作者在下面会给出新的例子来说明。
添加流表如下:
先xterm打开s1
添加流表
再主机互ping测试连通性:
发现主机之间可以互通了。
但是这样子添加有一个问题,就是很麻烦,毕竟用python3跑的话是不会执行代码之外的操作。所以我们可以把这段命令直接添加py文件里面,省略掉xterm这个步骤。
添加代码:
xx.cmd('ovs-ofctl add-flow s1 in_port=1,actions=output:2')
第一个xx是需要你先去net里面获取实例的,获取实例代码如下:
xx=net.get(‘s1’)
这个s1和黄框的内容是对应的
其他的就是把你xterm输入的内容替换到xx.cmd(‘xxx’)中黄色的xxx部分。
这个添加部分需要放在调用cli之前,如图所示:
(添加的时候记得先在控制台Exit出来才能修改)
添加完之后,我们重新运行一下该py文件看看效果:
可以看到不用再xterm就能全通了。
加一点小内容
假如我们有两台交换机的话,并且分别连接着不同数量的主机,那么应该怎么设置流表的入端口和出端口呢?下面举个例子。
还是先建个文件,命令:touch topo_36.py
然后我们再进入里面开始编辑:vim topo_36.py
将以下代码先复制进去,作者再拆解部分地方的代码:
from mininet.net import Mininet
from mininet.node import OVSSwitch, Host
from mininet.cli import CLI
from mininet.link import Link
def create_network():
net = Mininet()
# 创建两个OVS交换机
switch1 = net.addSwitch('s1', cls=OVSSwitch)
switch2 = net.addSwitch('s2', cls=OVSSwitch)
# 创建4个主机
host1 = net.addHost('h1', cls=Host, ip='192.168.0.1/24', defaultRoute='via 192.168.0.254')
host2 = net.addHost('h2', cls=Host, ip='192.168.0.2/24', defaultRoute='via 192.168.0.254')
host3 = net.addHost('h3', cls=Host, ip='192.168.0.3/24', defaultRoute='via 192.168.0.254')
host4 = net.addHost('h4', cls=Host, ip='192.168.0.4/24', defaultRoute='via 192.168.0.254')
# 连接主机到交换机
net.addLink(host1, switch1)
net.addLink(host2, switch1)
net.addLink(host3, switch2)
net.addLink(host4, switch2)
#连接交换机到交换机
net.addLink(switch1, switch2)
# 启动网络
net.start()
# 在OVS交换机上添加静态流表
switch1.cmd('ovs-ofctl add-flow s1 in_port=1,actions=output:2,3')
switch1.cmd('ovs-ofctl add-flow s1 in_port=2,actions=output:1,3')
switch1.cmd('ovs-ofctl add-flow s1 in_port=3,actions=output:1,2')
switch2.cmd('ovs-ofctl add-flow s2 in_port=1,actions=output:2,3')
switch2.cmd('ovs-ofctl add-flow s2 in_port=2,actions=output:1,3')
switch2.cmd('ovs-ofctl add-flow s2 in_port=3,actions=output:1,2')
# 打开命令行界面
CLI(net)
# 关闭网络
net.stop()
if __name__ == '__main__':
create_network()
作者在这里用函数直接跑该代码,更方便一点,不用去获取实例之类的。而且作者这里用的是同网段,不同网段的话需要额外再添加一些,但是我们就不说这个了。在添加连接上,端口都是默认先从1开始的,你再连就会往后加数字,当然也可以自定义。添加流表上记得区分一下端口就可以了。然后实际效果如下: