1.5Mininet流表应用实战1——手动添加流表
Mininet流表应用实战1——手动添加流表
实验目的
1、掌握SDN交换机的工作原理。
2、掌握Open vSwitch下发流表的方法。
3、通过Mininet自定义创建拓扑,不使用控制器,手动添加流表操作实现主机间的通信。
4、掌握Mininet中添加、删除流表命令。
实验环境
Mininet流表应用实战1——手动添加流表实验的拓扑如下图所示。
实验环境信息如下表所示。
设备名称 | 软件环境 | 硬件环境 |
---|---|---|
主机 | Ubuntu 14.04桌面版 Mininet 2.2.0 | CPU:1核 内存:2G 磁盘:20G |
注:系统默认的账户为:
管理员权限用户名:root,密码:root@openlab;
普通用户用户名:openlab,密码:user@openlab。
可查看当前实验环境右侧“钥匙” 按钮获取对应的密码。
任务内容
1、使用Mininet创建实验拓扑,并测试无流表状态下主机间的ping操作。
2、在交换机中添加流表并测试主机间的ping操作。
3、在交换机中添加协议流表使主机h1和h2通信。
实验原理
在SDN环境下,当交换机收到一个数据包并且交换机中没有与该数据包匹配的流表项,且交换机未被SDN控制器控制,交换机将此数据包丢弃。可以通过对流表操作来控制交换机的转发行为,通过手动对交换机下发流表,当交换机交换机收到一个数据包时,因已手工添加相对应的流表,交换机根据流表操作转发数据包,使主机间通信。
操作步骤
一、创建拓扑
步骤1
登录Mininet主机,打开命令行执行终端,执行命令cd /home/openlab/openlab/mininet/custom进入custom目录。
步骤2
执行命令sudo vim exper1.py创建python自定义拓扑脚本文件exper1.py,脚本代码如下:
#!/usr/bin/python
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import RemoteController
from mininet.link import TCLink
from mininet.util import dumpNodeConnections
class MyTopo( Topo ):
"Simple topology example."
def __init__( self ):
"Create custom topo."
# Initialize topology
Topo.__init__( self )
# Add hosts and switches
Host1 = self.addHost( 'h1' )
Host2 = self.addHost( 'h2' )
Host3 = self.addHost( 'h3' )
Switch1 = self.addSwitch( 's1' )
Switch2 = self.addSwitch( 's2' )
# Add links
self.addLink( Host1, Switch1 )
self.addLink( Host2, Switch1 )
self.addLink( Host3, Switch2 )
self.addLink( Switch1, Switch2 )
topos = { 'mytopo': ( lambda: MyTopo() ) }
说明:为方便用户实验,脚本文件在/home/ftp/exper.py中已预置。
步骤3执行如下命令运行自定义脚本,并远程指定一个不存在的控制器,使交换机不受控制器控制。
步骤3
执行如下命令运行自定义脚本,并远程指定一个不存在的控制器,使交换机不受控制器控制。
# sudo mn --custom exper1.py --topo mytopo --controller=remote,ip=127.0.0.1,port=6653
二、测试无流表状态下主机间的通信
步骤1
执行命令xterm h1 h2 h3打开h1、h2和h3的可视化终端。
步骤2
执行命令dpctl dump-flows查看交换机当前的flow table信息。
可以看到交换机s1和s2中没有流表。
步骤3
在主机h2中执行命令tcpdump -n -i h2-eth0抓取网卡h2-eth0上的数据包。
步骤4
在主机h3中执行命令tcpdump -n -i h3-eth0抓取网卡h3-eth0上的数据包。
步骤5
在主机h1中执行如下命令分别ping主机h2和h3,结果如下所示。
# ping -c 3 10.0.0.2
# ping -c 3 10.0.0.3
步骤6
在主机h2和h3上查看tcpdump的抓包结果。
可以看到主机h1 Ping h2和h3失败了,主机h2和h3上没有收到任何ICMP echo request packet。原理解析:ping操作时,由于拓扑里没有SDN控制器,也没有用dptcl给OpenFlow交换机添加任何flow entry,所以交换机不会做转发决定,并直接丢弃h1到h2及h1到h3的ping包。
三、添加流表并测试主机间的通信
步骤1
执行如下命令添加交换机端口流表使主机h1和h2通信。
mininet> dpctl add-flow in_port=1,actions=output:2
mininet> dpctl add-flow in_port=2,actions=output:1
步骤2
执行命令dpctl dump-flows查看交换机流表,两条flow entry添加成功。
步骤3
在主机h1中执行如下命令分别ping主机h2和h3。
# ping -c 3 10.0.0.2
# ping -c 3 10.0.0.3
步骤4
在主机h2和h3上查看tcpdump抓包结果。
可以看到主机h1成功ping通h2,且h3没收到任何ping包。原理解析:用dpctl对交换机添加flow,让交换机从s1-eth1这个端口接收到的所有traffic都从s1-eth2这个端口发出去。用dpctl给交换机添加双向流表,因为ping包除了echo request还有echo reply。所以还需要用dpctl对交换机添加flow,让交换机从s1-eth2这个端口接收到的所有traffic都从s1-eth1这个端口发出去。添加这两条flow后,h1能够ping通h2,但是并没有为h1和h3之间添加对应的端口流表,所以h1与h3不通。
四、添加协议流表使h1/h2通信
步骤1
执行如下命令删除之前通过端口添加的流表并查看流表,确保交换机flow table为空。
# dpctl del-flows
# dpctl dump-flows
步骤2
执行如下命令添加两条traffic类型为IPv4(0x0800)协议相关的flow entry,并查看下发的流表。
# dpctl add-flow dl_type=0x0800,nw_dst=10.0.0.2,actions=output:2
# dpctl add-flow dl_type=0x0800,nw_dst=10.0.0.1,actions=output:1
# dpctl dump-flows
步骤3
在主机h1中执行如下命令分别ping主机h2和h3。
# ping -c 3 10.0.0.2
# ping -c 3 10.0.0.3
可以看到无法ping通。
步骤4
在主机h2和h3上查看tcpdump抓包结果。
原理解析:用dpctl对交换机添加flow,让交换机把所有EtherType为0x0800(IPv4)并且destiation IP为10.0.0.2的traffic从s1-eth2这个端口发出去。用dpctl对交换机添加flow,让交换机把所有EtherType为0x0800(IPv4)并且destiation IP为10.0.0.1的traffic从s1-eth1这个端口发出去。但处在同一网段下的主机,它们之间的交流是L2 forwarding,需要靠ARP来解析MAC地址,之前只匹配了0x0800(IPv4)协议,并没有匹配到0x0806(ARP),这样当交换机收到h1的ARP包后,因为没有控制器,flow table里面也没有相应的flow告诉它如何转发这个ARP包,交换机只能将它丢弃,从而导致h1 ping h2失败,所以需要添加ARP协议的流表来使通信。
步骤5
执行命令dpctl add-flow dl_type=0x0806,actions=NORMAL添加ARP(0x0806)协议相关的流表,让交换机以NORMAL形式(即广播)将所有ARP包从各个端口广播出去。
步骤6
执行命令dpctl dump-flows查看流表。
步骤7
在主机h1中执行如下命令分别ping主机h2和h3。
# ping -c 3 10.0.0.2
# ping -c 3 10.0.0.3
步骤8
在主机h2和h3上查看tcpdump抓包结果。
可以看到主机h1能够ping通h2。