一、实验内容
搭建如下网络拓扑,并熟悉相关指令。
二、搭建开发环境
2.1 开发环境搭建
2.1.1下载ubuntu镜像文件
镜像下载地址 https://www.ubuntu.com/download/desktop
下载后的文件:ubuntu-18.04.2-desktop-amd64.iso
2.1.2安装虚拟机
打开VMware,创建新的虚拟机,选择自定义,点击下一步
选择自定义硬件,应用镜像文件
选择已下载好的镜像文件
点击关闭后完成,VMware就会生成刚才安装的Ubuntu虚拟机:
2.2 应用软件安装
2.2.1安装mininet
安装mininet的方法具体有很多种,由于本地采用的是VM和Ubuntu虚拟机的环境,所以本次实验采用源码安装的方式。
要从源代码本地安装,首先需要获取源代码:
sudo apt-get update sudo apt-get install git sudo git clone git://github.com/mininet/mininet
下载源代码后,安装Mininet的命令是:
sudo ./mininet/util/install.sh -a
(-a:安装Mininet VM中包含的所有内容,包括Open vSwitch等依赖项以及OpenFlow wireshark dissector和POX等附加项。默认情况下,这些工具将构建在主目录中创建的目录中。)
安装完成后,测试基本的Mininet功能:
sudo apt install net-tools(不安装net-tools会提示找不到所需要的可执行的ifconfig)
sudo mn --test pingall
2.2.2安装ryu
使用pip命令安装:
sudo apt install python-pip pip install ryu
2.2.3获取Open vSwitch源代码
Open vSwitch源代码的规范位置是它的Git存储库,您可以将其克隆到名为“ovs”的目录中:
sudo git clone https://github.com/openvswitch/ovs.git
三、搭建网络环境
3.1 启动ryu控制器
ryu-manager --verbose ryu.app.simple_switch_13
3.2 启动mininet搭建网络拓扑
搭建网络topo,由于所要求的网络拓扑结构为比较简单的线性拓扑,可以直接使用--topo linear,x构建,选用Open vSwitch交换机:--switch ovsk。启动mininet:
mn --topo linear,2 --mac --switch ovsk --controller remote
这时候就可以看到mininet已经连接到ryu控制器了:
至此,所要求的网络环境已经搭建完成,对其进行简单的测试,在mininet的控制命令行里执行pingall:
四、实验步骤
4.1 使用wireshark抓取OpenFlow消息
(1)在安装mininet时已经安装了wireshark,于是只需要在主机启动wireshark:
sudo wireshark
等待一会wireshark便会启动:
(2)在mininet的控制命令行中执行:
h1 ping -c 4 h2
(2)wireshark中选择监听any,过滤器filter中输入openflow_v4即可抓取交换机s1与控制器c0之间的openflow消息:
4.2 OpenFlow报文分析
4.2.1 packet-in消息
(1) 当交换机收到一个数据包后,并未与流表中匹配成功,那么交换机就会将数据封装在Packer-in消息中,发送给控制器处理。此时数据包会被缓存在交换机中等待处理。
交换机流表所指示的action列表中包含转发给控制器的动作(Output=Controller),此时数据不会被缓存在控制器中。
(2)In_port数据包进入交换机的入端口号
Reason为packet-in事件的产生原因
同时,从reason的消息格式也可以看出触发packet-in的两种情况:OFPR_NO_MATCH和OFPR_ACTION。
4.2.2 packet-out消息
(1)当控制器希望交换机发送某个数据包,其使用Packet_out消息。例子:arp报文在广播的时候,在交换机中不能直接将arp广播,而是,将其封装在Packet_out里面,交换机泛洪的是Packet_out。
(2)控制器向一个交换机发送packet-out消息,buffer_id=-1,data段为某种特殊数据包,actions为从交换机的某个端口进行转发,如果发出这个数据包的端口另一端也连接一个Open vSwitch交换机,对端的交换机会产生一个packet-in消息将这个特殊的数据包包上交给控制器,从而控制器他侧到一条链路的存在(控制器实现链路发现,就是依靠packet-out消息)。
(3)当控制器断电或者交换机与控制器之间的连接断开,则交换机会寻找备用控制器,当无法找到备用控制器时便会进入紧急模式(交换机初始化时也是在这个模式下),在紧急模式下,交换机默认将所有接受到的数据包丢弃。
4.2.3 echo-request消息,echo-reply消息
echo消息为对称的消息,作用譬如心跳机制,定期给另一方发送echo-request消息,另一方需要给予echo-reply消息回应,确保控制器与交换机的连接状态。双方发送的echo消息只有OpenFlow报文头部,每一个request和reply的请求transcation的ID相同。
4.2.4 flow-mod消息
Flow-Mod消息用开添加、删除、修改openflow交换机的消息; Flow-Mod消息共有5种类型:ADD、DEKETE、DELETE-STRICT、MODIFY、MODIFY-STRICT。Flow_mod这个消息是OpenFlow中最重要的消息,用来添加、删除、修改OpenFlow交换机的流表信息。当交换机收到一个无法处理的数据包,封装到Packet_in消息转发给控制器后,控制器可以发送一个Flow_mod消息下发一个流表到交换机,并且指定该数据包按照此流表项的action处理。
Flow_mod消息包含四个部分:OpenFlow报文头、Flow_mod固定字段、Match字段和Instruction字段。分别用来标识该消息的类型、流表项的内容等。
4.3 测试主机连通性
先使主机1可以ping 通主机2,主机2也可以ping 通主机1。
4.4 操作流表项
然后对流表进行操作,使主机1不能ping 通主机2,主机2也不能ping 通主机1。
查看s1中已经存在的流表项:
ovs-ofctl dump-flows s1
4.4.1删除流表项
执行删除命令:
ovs-ofctl del-flows s1 in_port='s1-eth2'"
可见交换机s1流表中in_port='s1-eth2'的流表项已经删除,再执行:h1 ping h2
在删除流表项之后,h1已无法ping通h2。
4.4.2修改流表项
执行添加流表项命令:(注意add-flow后面不加s)
ovs-ofctl add-flow s1 'in_port="s1-eth1",dl_src=00:00:00:00:00:01, dl_dst=00:00:00:00:00:02 actions=drop'
修改流表项之后,h1 ping h2
4.5 修改流表项
限制该主机1一定时间(比如一分钟)内再次与主机2通信。限制时间过后,主机1可以与主机2通信。
由于流表具有存活时间,设置错误的流表使其无法通信,再通过hard_timeout定期删除流表,删除流表后又可以通信。
idle_timeout,空闲时间,如值为 10,表示若某条流表在最近 10s 内没有被匹配过则删除。
hard_timeout,存活时间,如值为 10,则从该流表被安装经过 10s 后无论被使用情况如何,立即被删除。
idle_age,未命中时间,如值为 10,表示已经有 10s 没有匹配到过这条流表了。当这个值等于 idle_timeout 时,这条流表就真的失效了。
duration,流表年龄,指的是流表自从安装到交换机上总共所经过的时间。
因此可以通过修改流表设置,使主机1和主机2无法通信,具体实施的是以下三种方法。
4.5.1将接收到的数据包丢弃
sudo ovs-ofctl add-flow s1 "hard_timeout=60,actions=drop"
4.5.2设置一个错误端口
sudo ovs-ofctl add-flow s1 "hard_timeout=60,actions=output:100"
4.5.3设置错误ip地址
sudo ovs-ofctl add-flow s1 "hard_timeout=60,actions=mod_nw_src: 192.168.1.111"
设置hard_timeout=60
一分钟后,主机1和主机2又可以实现通信
五、问题与分析
问题1:执行mn命令构建网络拓扑时出现:“Unable to contact the remote cotroller at 127.0.0.1:6633”。
分析:在搭建网络拓扑之前没有启动ryu控制器,导致无法连接到控制器。
问题2:利用在mininet的控制命令行里执行Python脚本添加host、link、swtich之后原来的主机与新增的主机无法ping通。
分析:(1)在增加一个host之后,需要给它配置IP以及虚拟网卡信息;(2)新增的switch与控制器之间没有添加网桥,需要在xterm c0中执行添加网桥的命令“ovs-vsctl add-br s3”以及添加相应的端口“ovs-vsctl add-port s3 s3-eth0”等。
问题3:删除有三个端口的交换机流表项之后只能添加三条流表项。
分析:(1)添加流表项时执行的命令
ovs-ofctl add-flow s1“in_port=s1-eth1,actions=output:s1-eth2” ovs-ofctl add-flow s1“in_port=s1-eth1,actions=output:s1-eth3”
(2)在in_port相同的情况下,流表里面只会保存最新的一条流表项,解决方法就是修改命令为ovs-ofctl add-flow s1“in_port=s1-eth1,actions=output:s1-eth2,s1-eth3” 。