RYU+mininet——mininet

1. mininet基本操作

Mininet是一个网络仿真器,它在单个Linux内核上运行一组终端主机,交换机,路由器和链接。它使用轻量级虚拟化使单个系统看起来像一个完整的网络,运行相同的内核,系统和用户代码。 Mininet主机的行为就像真机一样;你可以ssh到它并运行任意程序。你运行的程序可以通过看似真正的以太网接口发送数据包,具有给定的链接速度和延迟。数据包会通过一定数量的真实以太网交换机,路由器或中间盒进行处理。详见mininet

1.1 mininet命令(mininet CLI环境)

在终端输入sudo mn,打开mininet进入CLI交互窗口。

  • 基本命令:

在CLI环境下输入help便可以获取可执行命令的信息,在2.3版本中有以下28个命令:

EOF    gterm  iperfudp  nodes        pingpair      py      switch
dpctl  help   link      noecho       pingpairfull  quit    time  
dump   intfs  links     pingall      ports         sh      x     
exit   iperf  net       pingallfull  px            source  xterm

输入:help command便可以获取该命令的详细帮助信息。下面介绍几组常用命令:

mininet>nodes                查看全部节点信息
mininet>net                  查看链路信息
mininet>dump                 查看各节点详细信息
mininet>pingall              测试所有结点是否连通
mininet>pingpair	         两个主机将互 ping

mininet>link s1 h2 up/down   启用/禁用s1跟h2之间的链路
mininet>links                报告所有链路状态
mininet>iperf h1 h2	         两个节点之间用指定简单的 TCP 测试
mininet>iperfudp 10M h1 h2   两个节点之间用指定简单 udp 进行测试,10M指自己设置的带宽
mininet>time [command]	     测量命令所执行的时间

mininet>xterm/gterm s1       打开某结点控制终端
mininet>sh [cmd args]        运行外部 shell 命令
mininet>px/py	             执行 python 语句
mininet>source <file>        从输入文件读入命令
           
mininet>exit/quit/EOF	     退出 mininet 命令行
  • 在节点执行系统命令:

前面提到mininet采用轻量级的虚拟化技术,使得其模拟的每台主机和交换机都是独立的,所以可以像在真实主机的终端中执行命令一样,在模拟的主机或交换机上执行任何系统命令。在CLI环境中执行的格式为:node command,command 格式和用法同Linux主机,如:

mininet>h1 ifconfig                                             查看h1节点网络信息
mininet>h1 ping -c 4 h2                                         实现两主机互连测试
mininet>h1 ifconfig h1-eth0 10.108.126.3 netmask 255.255.255.0  修改虚拟的主机的ip以及mask地址

还可以运行python脚本,比如在主机建立web服务器,并获取HTTP请求:

mininet> h1 python -m SimpleHTTPServer 80 &     #在主机 h1 开启 Web 服务
mininet> h2 wget -O - h1                        #在主机 h2 获取网页内容

这种用法和运行xterm node为节点打开单独的终端,在单独终端中运行系统命令一样。

1.1 dpctl 流表操作:

dpctl 和 ovs-ofctl 都是命令行的OpenFlow交换机管理工具,可以用来操作和管理流表。在CLI中管理流表的用法如下:

mininet>dpctl command [arg1] [arg2]        在所有交换机上运行 dpctl 或 ovs-ofctl 命令

1.2 mininet可视化界面

2.2.0以后版本的mininet支持可视化,在/home/mininet/mininet/examples目录下提供miniedit.py脚本,切换到相应目录下,在终端中执行:

sudo python miniedit.py

便会弹出Mininet的可视化界面,如下图所示。可以很方便的在界面上可进行自定义拓扑和自定义设置,还支持将创建的拓扑保存成脚本,也支持从脚本打开拓扑,十分方便。具体可以参考Mininet可视化应用
在这里插入图片描述

1.3 mn启动参数,格式mn [options]

和其他Linux命令一样,以下参数可以随意组合跟在mn后面,但要注意每个参数格式的区别,有些参数面的值是用等号连接的,但有些是用空格连接【。。。】,使用的时候需要注意。

  • 自动设置MAC地址和ARP条目
--mac       自动设置MAC地址,MAC地址与IP地址的最后一个字节相同
--arp       为每个主机设置静态ARP表,存储同一网段的主机的mac和IP
  • 设置交换机
--switch default|ivs|lxbr|ovs|ovsbr|ovsk|user[,param=value...]   
    其中,ovs,defaul,ovsk都为OVS(openvswitch)交换机,lxbr=LinuxBridge user=UserSwitch ivs=IVSSwitch ovsbr=OVSBridge
  • 设置控制器
--controller=default|none|nox|ovsc|ref|remote|ryu[,param=value...]
                       其中, ovsc=OVSController none=NullController
                        remote=RemoteController default=DefaultController
                        nox=NOX ryu=Ryu ref=Controller
--controller=remote,ip=[controller IP] ,port=[controller listening port]    设置远程控制器

比如:设定启动支持openflow1.3的交换机和IP为10.108.125.9的远程交换机:

sudo mn --controller=remote,ip=10.108.125.9,port=6653 --switch ovsk,protocols=OpenFlow13
  • 定义网络拓扑
--topo single,n                 单交换机,星型拓扑, n表示主机数

--topo linear,n                 线性拓仆,n表示n个交换机直线连接

--topo tree,depth=a,fanout=b    树状拓仆,depth表示树深度,fanout表示每个结点有几个子结点。所有叶子结点都为主机,非叶子结点为交换机

--topo minimal|reversed|torus[,param=value]       MinimalTopo,SingleSwitchReversedTopo,TorusTopo
--custom ~/mininet/custom/mytopo.py --topo=mytopo  用户自定义拓扑(mytopo.py是自己定义拓扑的python文件)

注: 一般在实际应用的时候,我们并不会通过上述两种方式创建网络拓扑,而是直接创建python脚本,在脚本中导入相关的模块,调用mininet的功能,python解释器直接执行。这样方便结合其他项目进行开发。具体可以参考mininet搭建自定义网络拓扑。需要注意的是在topo类和mininet类里面都有addhost,addswitch,addlink函数,但定义并不相同,具体参考源文件。

  • 为所有主机,包括交换机和主机、控制器,在运行时打开各自的xterm
mn –x       //作用同在cli环境中运行xterm
  • 退出并且清理
mn –c

注: 这里要注意的是经常在退出mininet后,再次进入会发现报如下错误:
Exception: Error creating interface pair (s5-eth1,s1-eth3): RTNETLINK answers: File exists
这是由于进程未被完全杀死造成的,所以在退出mininet环境后进行清理的时候,需要使用sudo权限:
sudo mn –c

  • 其他可用的mn命令
  --host=HOST           cfs|proc|rt[,param=value...]
                        rt=CPULimitedHost{'sched': 'rt'} 
                        proc=Host
                        cfs=CPULimitedHost{'sched': 'cfs'}
  --link=LINK           default|ovs|tc|tcu[,param=value...] 
                        default=Link ovs=OVSLink tcu=TCULink tc=TCLink
  --custom=CUSTOM       read custom classes or params from .py file(s)
  --test=TEST           none|build|all|iperf|pingpair|iperfudp|pingall
  -i IPBASE, --ipbase=IPBASE
                        base IP address for hosts
  -v VERBOSITY, --verbosity=VERBOSITY
                        info|warning|critical|error|debug|output
  --innamespace         sw and ctrl in namespace?
  --listenport=LISTENPORT
                        base port for passive switch listening
  --nolistenport        don't use passive listening port
  --pre=PRE             CLI script to run before tests
  --post=POST           CLI script to run after tests
  --pin                 pin hosts to CPU cores (requires --host cfs or --host rt)
  --nat                 [option=val...] adds a NAT to the topology that connects Mininet hosts to the physical network.
                        Warning: This may route any traffic on the machine that uses Mininet's IP subnet into the 
                        Mininet network. If you need to change Mininet's IP subnet, see the --ipbase option.
  --version             prints the version and exits
  --cluster=server1,server2...
                        run on multiple servers (experimental!)
  --placement=block|random
                        node placement for --cluster (experimental!)

.

2. 流表操作

2.1 使用命令查看交换机中的流表

  • 查看流表项:
mininet>dpctl dump-flows

在一个depth=2,fanout=2的树形拓扑中,执行h1 ping -c1 h2,得到流表项如下:

mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
*** s2 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=4.087s, table=0, n_packets=1, n_bytes=42, idle_timeout=60, idle_age=4, priority=65535,arp,in_port=2,vlan_tci=0x0000,dl_src=06:7d:8b:e3:9f:b5,dl_dst=22:7e:4a:a6:25:c7,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,arp_op=2 actions=output:1
 cookie=0x0, duration=4.086s, table=0, n_packets=1, n_bytes=98, idle_timeout=60, idle_age=4, priority=65535,icmp,in_port=1,vlan_tci=0x0000,dl_src=22:7e:4a:a6:25:c7,dl_dst=06:7d:8b:e3:9f:b5,nw_src=10.0.0.1,nw_dst=10.0.0.2,nw_tos=0,icmp_type=8,icmp_code=0 actions=output:2
 cookie=0x0, duration=4.085s, table=0, n_packets=1, n_bytes=98, idle_timeout=60, idle_age=4, priority=65535,icmp,in_port=2,vlan_tci=0x0000,dl_src=06:7d:8b:e3:9f:b5,dl_dst=22:7e:4a:a6:25:c7,nw_src=10.0.0.2,nw_dst=10.0.0.1,nw_tos=0,icmp_type=0,icmp_code=0 actions=output:1
*** s3 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
mininet> 
  • 添加流表项:
mininet>dpctl add-flow in_port=2,actions=output:1  
mininet>dpctl add-flow in_port=1,actions=output:2

在所有的交换机中添加流表,让从1号端口进入的报文都从2号端口转发,添加后流表项如下(在操作之前先清空交换机中的流表):

mininet> dpctl add-flow in_port=1,actions=output:2
*** s1 ------------------------------------------------------------------------
*** s2 ------------------------------------------------------------------------
*** s3 ------------------------------------------------------------------------
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=3.454s, table=0, n_packets=0, n_bytes=0, idle_age=3, in_port=1 actions=output:2
*** s2 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=3.454s, table=0, n_packets=0, n_bytes=0, idle_age=3, in_port=1 actions=output:2
*** s3 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=3.455s, table=0, n_packets=0, n_bytes=0, idle_age=3, in_port=1 actions=output:2

流表匹配的报文数n_packets都为0,这时候通过h1 ping h2,再查看流表项:

mininet> h1 ping -c1 h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=1.79 ms

--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.793/1.793/1.793/0.000 ms
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=35.967s, table=0, n_packets=2, n_bytes=140, idle_age=0, in_port=1 actions=output:2
*** s2 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=35.967s, table=0, n_packets=2, n_bytes=140, idle_age=0, in_port=1 actions=output:2
*** s3 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=35.968s, table=0, n_packets=0, n_bytes=0, idle_age=35, in_port=1 actions=output:2

这时候直接可以ping通,发现s2中的流表匹配到两个报文(一个arp请求,一个icmp请求),但通过h1 ping h3,却发现不通,因为从1端口的报文都会无条件匹配到2号端口:

mininet> h1 ping -c1 h3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
From 10.0.0.1 icmp_seq=1 Destination Host Unreachable

--- 10.0.0.3 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
  • 删除表项:
mininet>dpctl del-flows

删除后再查看,流表为空:

mininet> dpctl del-flows
*** s1 ------------------------------------------------------------------------
*** s2 ------------------------------------------------------------------------
*** s3 ------------------------------------------------------------------------
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
*** s2 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
*** s3 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):

这种流表的操作方式十分不方便,也很少有人这样使用。一般操作流表都使用ovs-ofctl,ofctl等工具在终端中操作或通过控制器环境操作。具体见下一节。

2.2 使用命令查看交换机中的流表

ovs-ofctl是命令行下的交换机管理工具,也可以在终端中用来管理openflow 流表。

查看交换机中的流表项:

sudo ovs-ofctl dump-flows -O openflow13 s1   # -O参数后面跟协议,s1表示交换机的id。
ovs-ofctl dump-flows br-sw

当然,也可在mininet的命令行窗口使用sh命令来直接调用上述指令:

mininet> sh ovs-ofctl dump-flows -O openflow13 s1   # 效果同在终端中执行

执行如下命令,增加一条流表项,将主机1发给主机2的数据包丢弃:

ovs-ofctl add-flow br-sw ‘dl_type=0x0800,nw_src=10.0.0.7,nw_dst=10.0.0.11, priority=27,table=0,actions=drop’

该流表项的匹配字段包括:dl_type=0x0800(MAC帧上一层为IP协议)、nw_src=10.0.0.7(源IP地址为10.0.0.7)、nw_dst=10.0.0.11(目的IP地址为10.0.0.11);优先级priority设为27,高于其他流表,故优先执行;table id为0,即将该流表项下发到table 0中。该流表项表示:从主机10.0.0.7发往主机10.0.0.11的IP包将被抛弃。

其他流表操作
1.列出br-int网桥的接口
ovs-ofctl -O OpenFlow13 show br-int

2.列出br-int网桥的接口
ovs-ofctl dump-ports -O OpenFlow13 br-int

3.列出br-int网桥的某个接口的详细信息
ovs-ofctl dump-ports -O OpenFlow13 br-int 1

4.查看 Open vSwitch 中的端口信息
ovs-ofctl show -O OpenFlow13 br-int

5.获得网络接口的 OpenFlow 编号
ovs-vsctl get Interface tap8f178fef-10 ofport

6.查看网桥下的流表
ovs-ofctl dump-flows -O OpenFlow13 br-int

7.查看ovs下的 datapath 的信息
ovs-dpctl show

8.根据流量显示在流表中的走向
ovs-appctl ofproto/trace br-int in_port=2 | grep “Rule|action”

9.ovs设置控制器
ovs-vsctl set-controller br0 tcp:1.2.3.4:663

10.ovs添加流表
ovs-ofctl add-flow br0 in_port=1,actions=output:2

11.删除网桥中所有的流表
ovs-ofctl del-flows br0

12.删除根据匹配项删除网桥中的流表
ovs-ofctl del-flows br0 “in_port=1”

流表

在传统网络设备中,交换机和路由器的数据转发需要依赖设备中保存的二层MAC地址转发表或者三层IP地址路由表,而OpenFlow交换机中使用的流表也是如此,不过在它的表项中整合了网络中各个层次的网络配置信息,从而在进行数据转发时可以使用更丰富的规则。

OpenFlow v1.3中流表项主要由7部分组成,分别是匹配域(用来识别该条表项对应的flow)、优先级(定义流表项的优先顺序)、计数器(用于保存与条目相关统计信息),指令(匹配表项后需要对数据分组执行的动作)、超时:最大时间计数值或流在交换机中失效之前的剩余时间、Cookie:由控制器选择的不透明数据值、Flags。
匹配字段:对数据包匹配。包括入端口和数据包头,以及由前一个表指定的可选的元数据。流表项通过匹配字段和优先级决定,在一个流表中匹配字段和优先级共同确定唯一的流表项。

  • 11
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值