In this lab, you will start by learning the basics of running Mininet in a virtual machine. Mininet facilitates creating and manipulating Software Defined Networking components. Through mininet you will explore OpenFlow, which is an open interface for controlling the network elements through their forwarding tables. A network element may be converted into a switch, router or even an access points via low-level primitives defined in OpenFlow. This lab is your opportunity to gain hands-on experience with the platforms and debugging tools most useful for developing network control applications on OpenFlow.
The topology we are using is similar to the one in the Openflow Tutorial (https://github.com/osrg/ryu/wiki/OpenFlow_Tutorial). It has three hosts named h1, h2 and h3 respectively. Each host has an Ethernet interface called h1-eth0, h2-eth0 and h3-eth0 respectively. The three hosts are connected through a switch names s1. The switch s1 has three ports named s1-eth1, s1-eth2 and s1-eth3. The controller is connected on the loopback interface (in real life this may or may not be the case, it means the switch and controller are built in a single box). The controller is identified as c0 and connected through port 6633.
+---------------------------+ | | | C0 - Controller | | | +-------------+-------------+ | +-------------+-------------+ | | | S1 - OpenFlow | | Switch | | | +-+----------+----------+---+ s1-eth0 s1-eth1 s1-eth2 + + + | | | | | | v v v h1-eth0 h2-eth0 h3-eth0 +-+--+ +-+--+ +-+--+ | H1 | | H2 | | H3 | +----+ +----+ +----+
The instructor should have given everyone a different number. This will dictate which virtual machine you will be using. If the instructor happened to forget, then this is the time to remind them.
Write this number down on a piece of paper.
Anytime this lab mentions <NUMBER> substitute it with the number you have written down.
Open a terminal window on your machine. If you don't know how to do this ask an instructor for help.
At the prompt type:
ssh sysadm@10.10.0.1<NUMBER> (This is 100 + what your PC number was)
When you see the warning that looks something like this:
The authenticity of host '10.10.0.XXX (10.10.0.XXX)' can't be established. RSA key fingerprint is e8:05:43:d5:9a:4b:72:ad:c9:92:97:ca:df:32:86:ab. Are you sure you want to continue connecting (yes/no)? yes
Type "yes" and press ENTER.
When prompted with “sysadm@10.10.0.XXX's password:” enter the classroom Password
That should be it. You are now connected to a terminal session on your machine.
$ ssh sysadm@10.10.0.XXX sysadm@10.10.0.XXX's password: Welcome to Ubuntu 13.04 (GNU/Linux 3.8.0-19-generic x86_64) * Documentation: https://help.ubuntu.com/ Your Ubuntu release is not supported anymore. For upgrade information, please visit: http://www.ubuntu.com/releaseendoflife New release '13.10' available. Run 'do-release-upgrade' to upgrade to it. Last login: Wed Sep 3 08:22:23 2014 sysadm@sdnXXX:~$
To log out you can type:
exit
You will need two windows open to your VM for this lab. Go ahead and open the second one now.
All of the actions in this exercise are done as “root”, so if you are not root already type the following in both windows:
mininet@mininet-vm:~$ sudo bash root@mininet-vm:~#
Note that 'controller' is a simple OpenFlow reference controller implementation in linux. We want to ensure that this is not running to interfere with adding flows manually.root@mininet-vm:~# killall controller controller: no process found root@mininet-vm:~#
root@mininet-vm:~# mn -c *** Removing excess controllers/ofprotocols/ofdatapaths/pings/noxes killall controller ofprotocol ofdatapath ping nox_core lt-nox_core ovs-openflowd ovs-controller udpbwtest mnexec ivs 2> /dev/null killall -9 controller ofprotocol ofdatapath ping nox_core lt-nox_core ovs-openflowd ovs-controller udpbwtest mnexec ivs 2> /dev/null pkill -9 -f "sudo mnexec" *** Removing junk from /tmp rm -f /tmp/vconn* /tmp/vlogs* /tmp/*.out /tmp/*.log *** Removing old X11 tunnels *** Removing excess kernel datapaths ps ax | egrep -o 'dp[0-9]+' | sed 's/dp/nl:/' *** Removing OVS datapathsovs-vsctl --timeout=1 list-br ovs-vsctl del-br s1 ovs-vsctl del-br s2 ovs-vsctl del-br s3 ovs-vsctl del-br s4 *** Removing all links of the pattern foo-ethX ip link show | egrep -o '(\w+-eth\w+)' *** Cleanup complete. root@mininet-vm:~#
sudo mn --topo=single,3 --mac --switch ovsk --controller=none
mininet command helpmininet> help
Topology informationmininet> net
IP address informationmininet> dump
List of nodes and switchesmininet> nodes
Ping from each host to all other hostsmininet> pingall
ovs-ofctl command helpmininet> sh ovs-ofctl --help | less
Shows switch information including OpenFlow Feature support, port type, port speed and mac addresses.mininet> sh ovs-ofctl show s1
Shows active flow rules on the switchmininet> sh ovs-ofctl dump-flows s1
Show port traffic and error statisticsmininet> sh ovs-ofctl dump-ports s1
mininet> sh ovs-ofctl add-flow s1 arp,idle_timeout=180,priority=500,actions=output:1,2,3 mininet> sh ovs-ofctl add-flow s1 tcp,tp_dst=80,nw_dst=10.0.0.3,actions=output:3 mininet> sh ovs-ofctl add-flow s1 ip,nw_dst=10.0.0.1,actions=output:1
`
mininet> sh ovs-ofctl dump-flows s1 NXST_FLOW reply (xid=0x4): cookie=0x0, duration=47.91s, table=0, n_packets=0, n_bytes=0, idle_age=47, ip,nw_dst=10.0.0.1 actions=output:1 cookie=0x0, duration=73.85s, table=0, n_packets=18, n_bytes=756, idle_timeout=180, idle_age=1, priority=500,arp actions=output:1,output:2,output:3 cookie=0x0, duration=62.666s, table=0, n_packets=0, n_bytes=0, idle_age=62, tcp,nw_dst=10.0.0.3,tp_dst=80 actions=output:3
mininet> h3 python -m SimpleHTTPServer 80 &
mininet> h1 wget http://10.0.0.3 --2015-10-12 02:00:26-- http://10.0.0.3/ Connecting to 10.0.0.3:80... connected. HTTP request sent, awaiting response... 200 OK Length: 530 [text/html] Saving to: ‘index.html.1’ 0K 100% 49.5M=0s 2015-10-12 02:00:26 (49.5 MB/s) - ‘index.html.1’ saved [530/530]
mininet> pingall
mininet> sh ovs-ofctl add-flow s1 arp,in_port=1,actions=output:3 mininet> sh ovs-ofctl add-flow s1 arp,in_port=3,actions=output:1
root@mininet-vm:~# killall controller controller: no process found root@mininet-vm:~#
Note that 'controller' is a simple OpenFlow reference controller implementation in linux. We want to ensure that this is not running before we start our own controller.
root@mininet-vm:~# mn -c
root@mininet-vm:~# ryu-manager --verbose /usr/local/lib/python2.7/dist-packages/ryu/app/simple_switch_13.py loading app /usr/local/lib/python2.7/dist-packages/ryu/app/simple_switch_13.py loading app ryu.controller.ofp_handler instantiating app /usr/local/lib/python2.7/dist-packages/ryu/app/simple_switch_13.py of SimpleSwitch13 instantiating app ryu.controller.ofp_handler of OFPHandler BRICK SimpleSwitch13 CONSUMES EventOFPPacketIn CONSUMES EventOFPSwitchFeatures BRICK ofp_event PROVIDES EventOFPPacketIn TO {'SimpleSwitch13': set(['main'])} PROVIDES EventOFPSwitchFeatures TO {'SimpleSwitch13': set(['config'])} CONSUMES EventOFPEchoRequest CONSUMES EventOFPSwitchFeatures CONSUMES EventOFPHello CONSUMES EventOFPErrorMsg CONSUMES EventOFPPortDescStatsReply
We have now started the RYU controller with the simple_switch application. The simple switch keeps track of where the host with each MAC address is located and accordingly sends packets towards the destination and not flood all ports.
In the other window
root@mininet-vm:~# mn --topo=tree,1,3 --mac --controller=remote --switch ovsk,protocols=OpenFlow13 *** Creating network *** Adding controller *** Adding hosts: h1 h2 h3 *** Adding switches: s1 *** Adding links: (h1, s1) (h2, s1) (h3, s1) *** Configuring hosts h1 h2 h3 *** Starting controller *** Starting 1 switches s1 *** Starting CLI: mininet>
mininet> sh ovs-vsctl set bridge s1 protocols=OpenFlow13
In the RYU controller window you should see a message similar to the following to show that the switch has connected to the controller and has exchanged information about its capabilities.
connected socket:<eventlet.greenio.base.GreenSocket object at 0xb67fe8ac> address:('127.0.0.1', 39578) hello ev <ryu.controller.ofp_event.EventOFPHello object at 0xb67fe54c> move onto config mode EVENT ofp_event->SimpleSwitch13 EventOFPSwitchFeatures switch features ev version: 0x4 msg_type 0x6 xid 0xcfe991fe OFPSwitchFeatures(auxiliary_id=0,capabilities=71,datapath_id=1,n_buffers=256,n_tables=254) move onto main mode
A flow is the finest work unit of a switch. In Mininet, dpctl is a command that allows visibility and control over a single switch's flow table. It is especially useful for debugging, by viewing flow state and flow counters.
mininet> dpctl dump-flows -O OpenFlow13 *** s1 ------------------------------------------------------------------------ OFPST_FLOW reply (OF1.3) (xid=0x2): cookie=0x0, duration=2.481s, table=0, n_packets=0, n_bytes=0, priority=0 actions=FLOOD,CONTROLLER:64 mininet>
Mininet Window
mininet> h1 ping h2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_req=1 ttl=64 time=5.10 ms 64 bytes from 10.0.0.2: icmp_req=2 ttl=64 time=0.238 ms 64 bytes from 10.0.0.2: icmp_req=3 ttl=64 time=0.052 ms 64 bytes from 10.0.0.2: icmp_req=4 ttl=64 time=0.051 ms ^C --- 10.0.0.2 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3001ms rtt min/avg/max/mdev = 0.051/1.360/5.100/2.160 ms mininet>
In the RYU controller window we want to ensure that we see the EventOFPPacketIn messages along with the controller telling us that it is adding unicast flows.
EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:01 ff:ff:ff:ff:ff:ff 1 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:02 00:00:00:00:00:01 2 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:01 00:00:00:00:00:02 1
We can confirm that the unicast flows have been added by dumping the flow table on the switch
mininet> dpctl dump-flows -O OpenFlow13 *** s1 ------------------------------------------------------------------------ OFPST_FLOW reply (OF1.3) (xid=0x2): cookie=0x0, duration=112.044s, table=0, n_packets=3, n_bytes=182, priority=0 actions=CONTROLLER:65535 cookie=0x0, duration=40.563s, table=0, n_packets=3, n_bytes=238, priority=1,in_port=2,dl_dst=00:00:00:00:00:01 actions=output:1 cookie=0x0, duration=40.559s, table=0, n_packets=2, n_bytes=140, priority=1,in_port=1,dl_dst=00:00:00:00:00:02 actions=output:2 mininet>
mininet> exit *** Stopping 1 switches s1 ... *** Stopping 3 hosts h1 h2 h3 *** Stopping 1 controllers c0 *** Done completed in 3.678 seconds root@mininet-vm:~#
root@mininet-vm:~# mn --topo=tree,1,10 --mac --controller=remote --switch ovsk,protocols=OpenFlow13 *** Creating network *** Adding controller *** Adding hosts: h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 *** Adding switches: s1 *** Adding links: (h1, s1) (h2, s1) (h3, s1) (h4, s1) (h5, s1) (h6, s1) (h7, s1) (h8, s1) (h9, s1) (h10, s1) *** Configuring hosts h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 *** Starting controller *** Starting 1 switches s1 *** Starting CLI: mininet>
mininet> sh ovs-vsctl set bridge s1 protocols=OpenFlow13
mininet> dpctl dump-flows -O OpenFlow13 *** s1 ------------------------------------------------------------------------ OFPST_FLOW reply (OF1.3) (xid=0x2): cookie=0x0, duration=6.084s, table=0, n_packets=0, n_bytes=0, priority=0 actions=CONTROLLER:65535 mininet>
Mininet Window
mininet> h1 ping h2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_req=1 ttl=64 time=0.585 ms 64 bytes from 10.0.0.2: icmp_req=2 ttl=64 time=0.319 ms 64 bytes from 10.0.0.2: icmp_req=3 ttl=64 time=0.063 ms ^C --- 10.0.0.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 0.063/0.322/0.585/0.213 ms mininet>
Rootshell Window
mininet> dpctl dump-flows -O OpenFlow13 *** s1 ------------------------------------------------------------------------ OFPST_FLOW reply (OF1.3) (xid=0x2): cookie=0x0, duration=36.095s, table=0, n_packets=3, n_bytes=182, priority=0 actions=CONTROLLER:65535 cookie=0x0, duration=7.464s, table=0, n_packets=6, n_bytes=532,priority=1,in_port=2,dl_dst=00:00:00:00:00:01 actions=output:1 cookie=0x0, duration=7.462s, table=0, n_packets=5, n_bytes=434,priority=1,in_port=1,dl_dst=00:00:00:00:00:02 actions=output:2 mininet>
Mininet Window
mininet> pingall *** Ping: testing ping reachability h1 -> h2 h3 h4 h5 h6 h7 h8 h9 h10 h2 -> h1 h3 h4 h5 h6 h7 h8 h9 h10 h3 -> h1 h2 h4 h5 h6 h7 h8 h9 h10 h4 -> h1 h2 h3 h5 h6 h7 h8 h9 h10 h5 -> h1 h2 h3 h4 h6 h7 h8 h9 h10 h6 -> h1 h2 h3 h4 h5 h7 h8 h9 h10 h7 -> h1 h2 h3 h4 h5 h6 h8 h9 h10 h8 -> h1 h2 h3 h4 h5 h6 h7 h9 h10 h9 -> h1 h2 h3 h4 h5 h6 h7 h8 h10 h10 -> h1 h2 h3 h4 h5 h6 h7 h8 h9 *** Results: 0% dropped (90/90 received) mininet>
RYU Window
EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:07 ff:ff:ff:ff:ff:ff 7 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:09 00:00:00:00:00:07 9 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:07 00:00:00:00:00:09 7 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:07 ff:ff:ff:ff:ff:ff 7 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:0a 00:00:00:00:00:07 10 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:07 00:00:00:00:00:0a 7 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:08 ff:ff:ff:ff:ff:ff 8 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:09 00:00:00:00:00:08 9 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:08 00:00:00:00:00:09 8 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:08 ff:ff:ff:ff:ff:ff 8 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:0a 00:00:00:00:00:08 10 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:08 00:00:00:00:00:0a 8 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:09 ff:ff:ff:ff:ff:ff 9 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:0a 00:00:00:00:00:09 10 EVENT ofp_event->SimpleSwitch13 EventOFPPacketIn packet in 1 00:00:00:00:00:09 00:00:00:00:00:0a 9
mininet> dpctl dump-flows -O OpenFlow13 *** s1 ------------------------------------------------------------------------ OFPST_FLOW reply (OF1.3) (xid=0x2): cookie=0x0, duration=100.69s, table=0, n_packets=135, n_bytes=8190, priority=0 actions=CONTROLLER:65535 cookie=0x0, duration=41.876s, table=0, n_packets=2, n_bytes=140, priority=1,in_port=1,dl_dst=00:00:00:00:00:07 actions=output:7 cookie=0x0, duration=41.624s, table=0, n_packets=3, n_bytes=238, priority=1,in_port=9,dl_dst=00:00:00:00:00:08 actions=output:8 cookie=0x0, duration=41.692s, table=0, n_packets=3, n_bytes=238, priority=1,in_port=10,dl_dst=00:00:00:00:00:05 actions=output:5 cookie=0x0, duration=41.765s, table=0, n_packets=2, n_bytes=140, priority=1,in_port=3,dl_dst=00:00:00:00:00:0a actions=output:10 cookie=0x0, duration=41.622s, table=0, n_packets=2, n_bytes=140, priority=1,in_port=8,dl_dst=00:00:00:00:00:09 actions=output:9 cookie=0x0, duration=41.882s, table=0, n_packets=2, n_bytes=140, priority=1,in_port=1,dl_dst=00:00:00:00:00:06 actions=output:6 cookie=0x0, duration=41.738s, table=0, n_packets=2, n_bytes=140, priority=1,in_port=4,dl_dst=00:00:00:00:00:08 actions=output:8 cookie=0x0, duration=41.821s, table=0, n_packets=2, n_bytes=140, priority=1,in_port=2,dl_dst=00:00:00:00:00:08 actions=output:8 cookie=0x0, duration=41.783s, table=0, n_packets=2, n_bytes=140, priority=1,in_port=3,dl_dst=00:00:00:00:00:07 actions=output:7 ... ... ...
Mininet Window
mininet> pingall *** Ping: testing ping reachability h1 -> h2 h3 h4 h5 h6 h7 h8 h9 h10 h2 -> h1 h3 h4 h5 h6 h7 h8 h9 h10 h3 -> h1 h2 h4 h5 h6 h7 h8 h9 h10 h4 -> h1 h2 h3 h5 h6 h7 h8 h9 h10 h5 -> h1 h2 h3 h4 h6 h7 h8 h9 h10 h6 -> h1 h2 h3 h4 h5 h7 h8 h9 h10 h7 -> h1 h2 h3 h4 h5 h6 h8 h9 h10 h8 -> h1 h2 h3 h4 h5 h6 h7 h9 h10 h9 -> h1 h2 h3 h4 h5 h6 h7 h8 h10 h10 -> h1 h2 h3 h4 h5 h6 h7 h8 h9 *** Results: 0% dropped (90/90 received) mininet>
RYU Window
What happened that time?
mininet> iperf *** Iperf: testing TCP bandwidth between h1 and h10 waiting for iperf to start up...*** Results: ['22.5 Gbits/sec', '22.6 Gbits/sec'] mininet>
mininet> dpctl dump-flows -O OpenFlow13 *** s1 ------------------------------------------------------------------------ OFPST_FLOW reply (OF1.3) (xid=0x2): cookie=0x0, duration=188.223s, table=0, n_packets=135, n_bytes=8190, priority=0 actions=CONTROLLER:65535 ... ... cookie=0x0, duration=129.393s, table=0, n_packets=207403, n_bytes=13688658, priority=1,in_port=10,dl_dst=00:00:00:00:00:01 actions=output:1 ... ... cookie=0x0, duration=129.391s, table=0, n_packets=290931, n_bytes=14129626606, priority=1,in_port=1,dl_dst=00:00:00:00:00:0a actions=output:10 ... ...
Did any packets come to the controller? Where were most of the packets sent?