You are on page 1of 17

Basic Enterprise Network Management

(OpenFlow)
Overview 2

Use-case Network Topology Diagram 2


Precondition 2
Resources 3
Step By Step Tutorial 3

References 24
Overview
In this use-case, we will show the basic L2 and L3 networking using OpenDaylight and mininet
as a simulated network. The network topology consists of 2 OpenFlow switches, 5 hosts and
OpenDaylight as an SDN controller. Two hosts will be attached to the first switch at the same
subnet. The other three hosts will be attached to the second switch with different subnets. The
following diagram shows how our use-case network topology is constructed.

Use-case Network Topology Diagram

Pre-requisites
OpenDaylight Boron release: Download an OpenDaylight distribution from
https://www.opendaylight.org/downloads
VirtualBox: Download VirtualBox on your host machine and install it from
https://www.virtualbox.org/wiki/Downloads
Vagrant: Download Vagrant on your host machine and install it from
https://www.vagrantup.com/downloads.html

Resources:
The VMs vagrant file and mininet custom topology can be found here:
https://github.com/serngawy/DevOp-VMs/tree/master/Vagrant-mininet
Step By Step Tutorial:
1. After downloading the tutorial resources, go to the vagrant-mininet directory and run the
following command to spawn the mininet VM:

$ cd vagrant-mininet
$ vagrant up

2. Start OpenDaylight and install the required OpenFlow features. Go to the OpenDaylight
distribution directory and start OpenDaylight using the karaf script (as shown below).

$ cd distribution-karaf-0.5.2-Boron-SR2/
$ ./bin/karaf
Apache Karaf starting up. Press Enter to open the shell now 100%
[========================================================================]

Karaf started in 4s. Bundle stats: 64 active, 64 total

________ ________ .__ .__ .__ __


\_____ \ ______ ____ ____ \______ \ _____ ___.__.| | |__| ____ | |___/ |_
/ | \\____ \_/ __ \ / \ | | \\__ \< | || | | |/ ___\| | \ __\
/ | \ |_> > ___/| | \| ` \/ __ \\___ || |_| / /_/ > Y \ |
\_______ / __/ \___ >___| /_______ (____ / ____||____/__\___ /|___| /__|
\/|__| \/ \/ \/ \/\/ /_____/ \/

Hit '<tab>' for a list of available commands


and '[cmd] --help' for help on a specific command.
Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown OpenDaylight.

opendaylight-user@root>

Install OpenFlows features using the following command in the OpenDaylight karaf
console:

opendaylight-user@root>feature:install odl-openflowplugin-flow-services-ui odl-dlux-all

3. After successfully spawning the VM, login to the mininet VM using the following
command:

$ vagrant ssh
vagrant@vagrant-mininet#$

4. We will create the custom network topology using the myTopology.py python script.
You will need to change the controller IP-address in the myTopology.py file to match
your OpenDaylight distribution host IP-Address. Use the following commands to open
myTopology.py and change the IP-Address:

vagrant@vagrant-mininet#$ cd /vagrant/
vagrant@vagrant-mininet#$ sudo vi myTopology.py
#!/usr/bin/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)
info( '*** Adding controller\n' )
c1=net.addController(name='c1',
controller=RemoteController,
ip='{ODL_IP-Address}',
protocol='tcp',
port=6633)
info( '*** Add switches\n')
#r5 = net.addHost('r5', cls=Node, ip='10.0.2.5')
#r5.cmd('sysctl -w net.ipv4.ip_forward=1')
s4 = net.addSwitch('s4', cls=OVSKernelSwitch)
s3 = net.addSwitch('s3', cls=OVSKernelSwitch)
info( '*** Add hosts\n')
h1 = net.addHost('h1', cls=Host, ip='10.0.1.2', defaultRoute=None)
h2 = net.addHost('h2', cls=Host, ip='10.0.1.3', defaultRoute=None)
h3 = net.addHost('h3', cls=Host, ip='10.0.2.3', defaultRoute=None)
h4 = net.addHost('h4', cls=Host, ip='10.0.2.4', defaultRoute=None)
h5 = net.addHost('h5', cls=Host, ip='10.0.5.5', defaultRoute=None)
info( '*** Add links\n')
net.addLink(s3, s4)
net.addLink(s4, h5)
#net.addLink(s3, r5)
net.addLink(h1, s3)
net.addLink(h2, s3)
net.addLink(s4, h3)
net.addLink(s4, h4)
info( '*** Starting network\n')
net.build()
info( '*** Starting controllers\n')
for controller in net.controllers:
controller.start()
info( '*** Starting switches\n')
net.get('s4').start([c1])
net.get('s3').start([c1])
info( '*** Post configure switches and hosts\n')
#s4.cmd('ifconfig s4 10.0.2.0/24')
#s3.cmd('ifconfig s3 10.0.1.0/24')
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
myNetwork()

5. After you change the IP-Address, we will execute myTopology.py to create the network
using the following command:

$ sudo python myTopology.py


*** Adding controller
*** Add switches
*** Add hosts
*** Add links
*** Starting network
*** Configuring hosts
h1 h2 h3 h4 h5
*** Starting controllers
*** Starting switches
*** Starting CLI:
mininet>

6. At the tutorial host machine, open another console session to the mininet VM and check
the flow rules for the created bridges, S1 and S2.

$ cd vagrant-mininet
$ vagrant ssh
vagrant@vagrant-mininet#$ sudo ovs-ofctl dump-flows s3
NXST_FLOW reply (xid=0x4):
vagrant@vagrant-mininet#$ sudo ovs-ofctl dump-flows s4
NXST_FLOW reply (xid=0x4):
Note: there are currently no flow rules for the switches, S1 and S2.
7. We will allow the hosts (h1 and h2) at S3 to communicate with each other by pushing the
following flow rules. In the OpenDaylight distribution host, run the following commands:

$ curl -X PUT -u admin:admin -H "Content-Type: application/xml" -H


"Cache-Control: no-cache" -d '<flow xmlns="urn:opendaylight:flow:inventory">
<strict>false</strict>
<flow-name>flow3</flow-name>
<id>134</id>
<cookie_mask>255</cookie_mask>
<cookie>104</cookie>
<table_id>0</table_id>
<priority>0</priority>
<hard-timeout>1200</hard-timeout>
<idle-timeout>3400</idle-timeout>
<installHw>false</installHw>
<match>
<in-port>2</in-port>
</match>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>3</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>'
"http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow
:3/flow-node-inventory:table/0/flow/134"
$ curl -X PUT -u admin:admin -H "Content-Type: application/xml" -H
"Cache-Control: no-cache" -d '<flow xmlns="urn:opendaylight:flow:inventory">
<strict>false</strict>
<flow-name>flow3</flow-name>
<id>135</id>
<cookie_mask>255</cookie_mask>
<cookie>105</cookie>
<table_id>0</table_id>
<priority>0</priority>
<hard-timeout>1200</hard-timeout>
<idle-timeout>3400</idle-timeout>
<installHw>false</installHw>
<match>
<in-port>3</in-port>
</match>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>2</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>'
"http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow
:3/flow-node-inventory:table/0/flow/135"

In the mininet VM console, re-run the dump flow command at S3, you will see there are
2 flow rules that have been written to the switch.

vagrant@vagrant-mininet#$ sudo ovs-ofctl dump-flows s3

NXST_FLOW reply (xid=0x4):


cookie=0x68, duration=172.860s, table=0, n_packets=6, n_bytes=252, idle_timeout=3400,
hard_timeout=1200, idle_age=150, priority=0,in_port=2 actions=output:3
cookie=0x69, duration=7.532s, table=0, n_packets=0, n_bytes=0, idle_timeout=3400,
hard_timeout=1200, idle_age=7, priority=0,in_port=3 actions=output:2
Back in the mininet console (CLI), test the connection between H1 and H2 by executing
the following ping command:

mininet> h1 ping h2
PING 10.0.1.3 (10.0.1.3) 56(84) bytes of data.
64 bytes from 10.0.1.3: icmp_seq=1 ttl=64 time=0.038 ms
64 bytes from 10.0.1.3: icmp_seq=2 ttl=64 time=0.053 ms
64 bytes from 10.0.1.3: icmp_seq=3 ttl=64 time=0.000 ms

8. We will allow the communication between H3, H4 and H5 by pushing the following flow
rules to S4. In the OpenDaylight distribution host, run the following curl commands:

$ curl -X PUT -u admin:admin -H "Content-Type: application/xml" -H


"Cache-Control: no-cache" -d '<flow xmlns="urn:opendaylight:flow:inventory">
<strict>false</strict>
<flow-name>flow4</flow-name>
<id>145</id>
<cookie_mask>255</cookie_mask>
<cookie>104</cookie>
<table_id>0</table_id>
<priority>0</priority>
<hard-timeout>1200</hard-timeout>
<idle-timeout>3400</idle-timeout>
<installHw>false</installHw>
<match>
<in-port>2</in-port>
</match>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>3</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
<action>
<order>1</order>
<output-action>
<output-node-connector>4</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>'
"http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow
:4/flow-node-inventory:table/0/flow/145"

$ curl -X PUT -u admin:admin -H "Content-Type: application/xml" -H


"Cache-Control: no-cache" -d '<flow xmlns="urn:opendaylight:flow:inventory">
<strict>false</strict>
<flow-name>flow4</flow-name>
<id>146</id>
<cookie_mask>255</cookie_mask>
<cookie>105</cookie>
<table_id>0</table_id>
<priority>0</priority>
<hard-timeout>1200</hard-timeout>
<idle-timeout>3400</idle-timeout>
<installHw>false</installHw>
<match>
<in-port>3</in-port>
</match>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>2</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
<action>
<order>1</order>
<output-action>
<output-node-connector>4</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>'
"http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow
:4/flow-node-inventory:table/0/flow/146"

$ curl -X PUT -u admin:admin -H "Content-Type: application/xml" -H


"Cache-Control: no-cache" -d '<flow xmlns="urn:opendaylight:flow:inventory">
<strict>false</strict>
<flow-name>flow4</flow-name>
<id>147</id>
<cookie_mask>255</cookie_mask>
<cookie>106</cookie>
<table_id>0</table_id>
<priority>0</priority>
<hard-timeout>1200</hard-timeout>
<idle-timeout>3400</idle-timeout>
<installHw>false</installHw>
<match>
<in-port>4</in-port>
</match>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>2</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
<action>
<order>1</order>
<output-action>
<output-node-connector>3</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>'
"http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow
:4/flow-node-inventory:table/0/flow/147"

Back to the mininet VM console, re-run the dump flow command at S4, you will see
there are 3 flow rules that have been written to the switch.

vagrant@vagrant-mininet#$ sudo ovs-ofctl dump-flows s4

NXST_FLOW reply (xid=0x4):


cookie=0x68, duration=175.838s, table=0, n_packets=0, n_bytes=0,
idle_timeout=3400, hard_timeout=1200, idle_age=175, priority=0,in_port=2
actions=output:3,output:4
cookie=0x69, duration=121.968s, table=0, n_packets=0, n_bytes=0,
idle_timeout=3400, hard_timeout=1200, idle_age=121, priority=0,in_port=3
actions=output:2,output:4
cookie=0x6a, duration=36.333s, table=0, n_packets=0, n_bytes=0,
idle_timeout=3400, hard_timeout=1200, idle_age=36, priority=0,in_port=4
actions=output:2,output:3

In the mininet console (CLI), test the connection between the hosts by executing the
pingall command.

mininet> pingall
*** Ping: testing ping reachability
h1 -> h2 X X X
h2 -> h1 X X X
h3 -> X X h4 h5
h4 -> X X h3 h5
h5 -> X X h3 h4
*** Results: 60% dropped (8/20 received)

Note: as you can see, the connection between S4 and S3 is not reachable, which means that H1
and H2 cannot connect to H3, H4 and H5.
9. In the previous steps, we learn how to use OpenDaylight to push initial flow rules that
allow communication between specific hosts in our network. Now, we will install
OpenDaylights L2Switch features that will let OpenDaylight work as ARP resolver to
the coming ARP requests in our network. In the OpenDaylight distribution karaf CLI, use
the following command to install the L2Switch features:

opendaylight-user@root>feature:install odl-l2switch-hosttracker odl-l2switch-arphandler


10. At the mininet-vagrant VM, re-run the dump flow command for S3 and S4.

vagrant@vagrant-mininet#$ sudo ovs-ofctl dump-flows s3

NXST_FLOW reply (xid=0x4):


cookie=0x2b00000000000000, duration=63.886s, table=0, n_packets=12, n_bytes=1020,
idle_age=4, priority=100,dl_type=0x88cc actions=CONTROLLER:65535
cookie=0x68, duration=969.260s, table=0, n_packets=16, n_bytes=840,
idle_timeout=3400, hard_timeout=1200, idle_age=250, priority=0,in_port=2
actions=output:3
cookie=0x2b00000000000000, duration=56.238s, table=0, n_packets=0, n_bytes=0,
idle_age=56, priority=2,in_port=1 actions=output:2,output:3
cookie=0x2b00000000000001, duration=56.238s, table=0, n_packets=0, n_bytes=0,
idle_age=56, priority=2,in_port=2 actions=output:1,output:3,CONTROLLER:65535
cookie=0x2b00000000000002, duration=56.238s, table=0, n_packets=0, n_bytes=0,
idle_age=56, priority=2,in_port=3 actions=output:1,output:2,CONTROLLER:65535

$ sudo ovs-ofctl dump-flows s4

NXST_FLOW reply (xid=0x4):


cookie=0x2b00000000000001, duration=89.065s, table=0, n_packets=17, n_bytes=1445,
idle_age=4, priority=100,dl_type=0x88cc actions=CONTROLLER:65535
cookie=0x6a, duration=1146.148s, table=0, n_packets=14, n_bytes=812,
idle_timeout=3400, hard_timeout=1200, idle_age=952, priority=0,in_port=4
actions=output:2,output:3
cookie=0x2b00000000000003, duration=81.415s, table=0, n_packets=0, n_bytes=0,
idle_age=81, priority=2,in_port=1 actions=output:2,output:3,output:4
cookie=0x2b00000000000004, duration=81.414s, table=0, n_packets=0, n_bytes=0,
idle_age=81, priority=2,in_port=2
actions=output:1,output:3,output:4,CONTROLLER:65535
cookie=0x2b00000000000005, duration=81.414s, table=0, n_packets=0, n_bytes=0,
idle_age=81, priority=2,in_port=3
actions=output:1,output:2,output:4,CONTROLLER:65535
cookie=0x2b00000000000006, duration=81.413s, table=0, n_packets=0, n_bytes=0,
idle_age=81, priority=2,in_port=4
actions=output:1,output:2,output:3,CONTROLLER:65535

As you can see, OpenDaylight has pushed new flow rules to S3 and S4. Lets take a deeper look
at two of these flow rules (shown below).
A) c ookie=0x2b00000000000001, duration=89.065s, table=0, n_packets=17,
n_bytes=1445, idle_age=4, priority=100,dl_type=0x88cc
actions=CONTROLLER:65535
The previous flow rule will forward any LLDP packet that comes to the switch S3/S4 to
OpenDaylight. OpenDaylight will solve the LLDP request based on the network topology that
exists.
B) cookie=0x2b00000000000004, duration=81.414s, table=0, n_packets=0, n_bytes=0,
idle_age=81, priority=2,in_port=2
actions=output:1,output:3,output:4,CONTROLLER:65535
The previous flow rule will output the flow packets that comes from port 2 to all other ports that
are connected in the switch. Port 1, 3 and 4 will then output the flow packets to OpenDaylight.
11. Back in the mininet console (CLI), re-test the connection between the hosts by executing
the pingall command.

mininet> pingall
*** Ping: testing ping reachability
h1 -> h2 h3 h4 h5
h2 -> h1 h3 h4 h5
h3 -> h1 h2 h4 h5
h4 -> h1 h2 h3 h5
h5 -> h1 h2 h3 h4
*** Results: 0% dropped (20/20
received)

Note: all the connected hosts can reach one another.


12. OpenDaylight DLUX UI visualizes the network topology we have created. In the
OpenDaylight distribution host, open a browser and go to
http://localhost:8181/index.html#/topology. The default user-name and password are
admin:admin. Select the Topology tab to see our network topology (as shown below).
13. The Nodes tab gives you information about the connected switches and their ports.
Click on the Nodes tab then on the node connectors number (as shown below).

14. We can use OpenDaylight to write more advance flow rules to construct a flow rules
pipeline. The following flow rules show ARP packet type flow rules with ethernet source
and destination match, ICMP packet type flow rules with IPv4 source and destination
match and TCP packet type flow rules with IPv4 source and destination match. In the
OpenDaylight distribution host, you can run the following commands:

ARP type flow rules:


$ curl -X PUT -u admin:admin -H "Content-Type: application/xml" -H
"Cache-Control: no-cache" -d '<?xml version="1.0" encoding="UTF-8"
standalone="no"?>
<flow xmlns="urn:opendaylight:flow:inventory">
<strict>false</strict>
<flow-name>flow116</flow-name>
<id>116</id>
<cookie_mask>255</cookie_mask>
<cookie>103</cookie>
<table_id>0</table_id>
<priority>1024</priority>
<hard-timeout>1200</hard-timeout>
<idle-timeout>3400</idle-timeout>
<installHw>false</installHw>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>2</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
<match>
<ethernet-match>
<ethernet-type>
<type>2054</type>
</ethernet-type>
<ethernet-destination>
<address>76:f4:64:79:a1:40</address>
</ethernet-destination>
<ethernet-source>
<address>ff:ff:ff:ff:FF:ff</address>
</ethernet-source>
</ethernet-match>
</match>
</flow>'
"http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow
:3/flow-node-inventory:table/0/flow/116"

ICMP type flow rules:


$ curl -X PUT -u admin:admin -H "Content-Type: application/xml" -H
"Cache-Control: no-cache" -d '<?xml version="1.0" encoding="UTF-8"
standalone="no"?>
<flow xmlns="urn:opendaylight:flow:inventory">
<strict>false</strict>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>3</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
<table_id>0</table_id>
<id>134</id>
<cookie_mask>255</cookie_mask>
<match>
<ethernet-match>
<ethernet-type>
<type>2048</type>
</ethernet-type>
</ethernet-match>
<ipv4-source>10.0.1.0/24</ipv4-source>
<ipv4-destination>10.0.2.0/24</ipv4-destination>
<ip-match>
<ip-protocol>1</ip-protocol>
</ip-match>
</match>
<hard-timeout>1200</hard-timeout>
<cookie>11</cookie>
<idle-timeout>3400</idle-timeout>
<flow-name>FooXf11</flow-name>
<priority>200</priority>
</flow>'
"http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow
:3/flow-node-inventory:table/0/flow/134"

TCP type flow rules:


$ curl -X PUT -u admin:admin -H "Content-Type: application/xml" -H
"Cache-Control: no-cache" -d '<flow xmlns="urn:opendaylight:flow:inventory">
<installHw>false</installHw>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>2</output-node-connector>
<max-length>60</max-length>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
<table_id>0</table_id>
<id>119</id>
<match>
<ethernet-match>
<ethernet-type>
<type>2048</type>
</ethernet-type>
</ethernet-match>
<ipv4-source>10.0.2.0/24</ipv4-source>
<ipv4-destination>10.0.1.0/24</ipv4-destination>
<ip-match>
<ip-protocol>6</ip-protocol>
</ip-match>
</match>
<hard-timeout>0</hard-timeout>
<cookie>10</cookie>
<idle-timeout>0</idle-timeout>
<flow-name>flow118</flow-name>
<priority>200</priority>
</flow>'
"http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow
:3/flow-node-inventory:table/0/flow/119"

As you can see, these advance flow rules will let you control (allow/restrict) the network
communications based on the source/destination ethernet address, source/destination IPv4
address and packet type. In some situation such as mitigating DDoS attack, using these advanced
flow rules will be useful to provide the best solution.

References
https://github.com/mininet/openflow-tutorial/wiki/Advanced-Topology
https://github.com/mininet/openflow-tutorial/wiki/Router-Exercise
https://github.com/mininet/openflow-tutorial/wiki/Create-Firewall
https://github.com/mininet/openflow-tutorial/wiki
https://wiki.opendaylight.org/view/Editing_OpenDaylight_OpenFlow_Plugin:End_to_En
d_Flows:Example_Flows

You might also like