实验2:Open vSwitch虚拟交换机实践
一、实验目的
- 能够对Open vSwitch进行基本操作;
- 能够通过命令行终端使用OVS命令操作Open vSwitch交换机,管理流表;
- 能够通过Mininet的Python代码运行OVS命令,控制网络拓扑中的Open vSwitch交换机
二、实验环境
- 下载虚拟机软件Oracle VisualBox 或 VMware;
- 在虚拟机中安装Ubuntu 20.04 Desktop amd64,并完整安装Mininet;
三、实验要求
(一)基本要求
1.创建OVS交换机,并以ovs-switchxxx命名,其中xxx为本人在选课班级中的序号,例如ovs-switch001, ovs-switch088等。在创建的交换机上增加端口p0和p1,设置p0的端口号为100,p1的端口号为101,类型均为internal;为了避免网络接口上的地址和本机已有网络地址冲突,需要创建虚拟网络空间(参考命令netns)ns0和ns1,分别将p0和p1移入,并分别配置p0和p1端口的ip地址为192.168.0.100、192.168.0.101,子网掩码为255.255.255.0;最后测试p0和p1的连通性。
- 创建ovs交换机,并添加端口和配置虚拟空间
#创建ovs交换机
sudo ovs-vsctl add-br ovs-switch012
#添加p0、p1端口,并按要求配置
sudo ovs-vsctl add-port ovs-switch012 p0 -- set Interface p0 ofport_request=100 type=internal
sudo ovs-vsctl add-port ovs-switch012 p1 -- set Interface p1 ofport_request=101 type=internal
#查看端口信息
sudo ethtool -i p0
sudo ethtool -i p1
#创建并配置虚拟空间
sudo ip netns add ns0
sudo ip link set p0 netns ns0
sudo ip netns exec ns0 ip addr add 192.168.0.100/24 dev p0
sudo ip netns exec ns0 ifconfig p0 promisc up
sudo ip netns add ns1
sudo ip link set p1 netns ns1
sudo ip netns exec ns1 ip addr add 192.168.0.101/24 dev p1
sudo ip netns exec ns1 ifconfig p1 promisc up
- 查看ovs交换机状态
- 测试连通性
2.使用Mininet搭建的SDN拓扑,如下图所示,要求支持OpenFlow 1.3协议,主机名、交换机名以及端口对应正确。
-
使用Miniedit生成拓扑
-
更改支持OpenFlow1.3协议
-
保存为126.py文件
-
修改链路连接的端口
-
生成网络拓扑并检查网络连接情况
3.通过命令行终端输入“ovs-ofctl”命令,直接在s1和s2上添加流表,划分出所要求的VLAN。
VLAN_ID | hosts |
---|---|
0 | h1 h3 |
1 | h2 h4 |
- 重新打开一个命令行
4.主机连通性要求:
- h1 – h3互通
- h2 – h4互通
- 其余主机不通
-
测试连通性
-
查看下发流表
-
使用
sudo wireshark
运行wireshark,同时mininet使用pingall,令wireshark抓取数据包(由下面两图可知对h1 和 h3发送包vlan标记为0,对h2 和 h4发送包vlan标记为1)
(二)进阶要求
阅读SDNLAB实验使用Mininet,编写Python代码,生成(一)中的SDN拓扑,并在代码中直接使用OVS命令,做到可以直接运行Python程序完成和(一)相同的VLAN划分。
- python代码如下:(根据第一部分中126.py文件的代码添加了添加流表和划分VLAN的代码)
#!/usr/bin/env python
from mininet.net import Mininet
from mininet.node import Controller, RemoteController, OVSController
from mininet.node import CPULimitedHost, Host, Node
from mininet.node import OVSKernelSwitch, UserSwitch
from mininet.node import IVSSwitch
from mininet.cli import CLI
from mininet.log import setLogLevel, info
from mininet.link import TCLink, Intf
from subprocess import call
def myNetwork():
net = Mininet( topo=None,
build=False,
ipBase='192.168.0.0/24')
info( '*** Adding controller\n' )
c0=net.addController(name='c0',
controller=Controller,
protocol='tcp',
port=6633)
info( '*** Add switches\n')
s1 = net.addSwitch('s1', cls=OVSKernelSwitch)
s2 = net.addSwitch('s2', cls=OVSKernelSwitch)
info( '*** Add hosts\n')
h1 = net.addHost('h1', cls=Host, ip='192.168.0.1', defaultRoute=None)
h2 = net.addHost('h2', cls=Host, ip='192.168.0.2', defaultRoute=None)
h3 = net.addHost('h3', cls=Host, ip='192.168.0.3', defaultRoute=None)
h4 = net.addHost('h4', cls=Host, ip='192.168.0.4', defaultRoute=None)
info( '*** Add links\n')
net.addLink(h1, s1, 1, 1)
net.addLink(s1, h2, 2, 1)
net.addLink(s1, s2, 3, 3)
net.addLink(h3, s2, 1, 1)
net.addLink(s2, h4, 2, 1)
info( '*** Starting network\n')
net.build()
info( '*** Starting controllers\n')
for controller in net.controllers:
controller.start()
info( '*** Starting switches\n')
net.get('s1').start([c0])
net.get('s2').start([c0])
info( '*** Post configure switches and hosts\n')
s1.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:3')
s1.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:3')
s1.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,dl_vlan=0,actions=pop_vlan,output:1')
s1.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,dl_vlan=1,actions=pop_vlan,output:2')
s2.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:3')
s2.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:3')
s2.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,dl_vlan=0,actions=pop_vlan,output:1')
s2.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,dl_vlan=1,actions=pop_vlan,output:2')
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
myNetwork()
- 运行结果
- 查看流表
(三)实验心得体会
实验难度
这次试验的难度相比于实验一来说,有了比较大的提升,难点主要在于对流表和vlan划分概念的理解。还有一部分的难点在于对一长串命令各个部分的理解,比如output对应的是交换机输出的端口,理解了命令的各个部分才有机会自己独立地完成一次实验。
实验过程遇到的困难及解决办法
(1)使用查看交换机状态的命令时,可能会出现很多的网桥。如下:
解决方法:使用删除网桥的命令逐个删除多余网桥即可。
(2)检查连通性时出现如下错误:
解决方法:将p0,p1端口删除重新配置
(3)在解决第二个问题,分配虚拟空间时,可能会出现如下错误:
解决方法:这是因为之前创建的虚拟空间依然存在,不能创建同名的虚拟空间。所以直接跳过这条命令即可。
个人感想
因为这次实验难度较大,所以很多部分都是上网查资料或者询问同学才解决的。所以希望自己可以在后面的实验中不借助其他工具自己编写出完整的代码。综合两次实验来看,我在python编程方面较弱,有时候会犯很多莫名其妙的错误,所以我会是在课余时间提升下自己的编程能力,并且了解更多的网络知识,帮助自己更好地完成实验。