Tutorial 5 - SDN & VLANs
Submission process:
- Submission deadline is January 22, 14:00 CET (before the lecture) .
- Commit and push your solution as separate notebook files per subtask via git as ./tutorial/tutorial5/tutorial5_1.ipynb. Please take care of the correct subfolder/filename since submission is denied otherwise.
- During the first lecture after the deadline we will discuss a sample solution in class.
- Afterwards, you have time until January 27, 16:00 CET (before the lecture) to submit a corrected version of your submission:
- Rework your solution according to our discussion in class.
- Commit and push the corrected version as a separate file per subtask via git as ./tutorial/tutorial5/tutorial5_1.ipynb. Please take care of the correct filename since submission is denied otherwise.
Remarks:
- Grading is done based on both versions of your submission.
- If the first submission is missing or contains major flaws a deduction of up to 50% of the achieved points will be applied
- A sample solution is provided after January 27, 16:00 CET eventually.
- Do NOT duplicate cells or change the type of cells, otherwise you might receive zero points for your submission
- Please use acn@net.in.tum.de for questions regarding lecture, tutorial, and project of ACN.
This cell is used to verify the structure of the submission
DO NOT DELETE OR CHANGE THIS CELL, otherwise the task will be graded with 0 pointsProblem 1- OpenFlow [2.95 credits]
For the following exercise we use the network emulator mininet. The emulated network consists of two hosts called 'h1' and 'h2'. Both hosts are connected via the switch 's1'. For the switching solution we use the software switch Open vSwitch. We use the tool ovs-ofctl (see documentation), which is a CLI controller controlling OpenFlow devices manually.
# in case mininet stops working execute this cell
!mn -c
*** Removing excess controllers/ofprotocols/ofdatapaths/pings/noxes killall controller ofprotocol ofdatapath ping nox_corelt-nox_core ovs-openflowd ovs-controllerovs-testcontroller udpbwtest mnexec ivs ryu-manager 2> /dev/null
killall -9 controller ofprotocol ofdatapath ping nox_corelt-nox_core ovs-openflowd ovs-controllerovs-testcontroller udpbwtest mnexec ivs ryu-manager 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 datapaths ovs-vsctl --timeout=1 list-br
ovs-vsctl --timeout=1 list-br *** Removing all links of the pattern foo-ethX ip link show | egrep -o '([-_.[:alnum:]]+-eth[[:digit:]]+)' ip link show *** Killing stale mininet node processes pkill -9 -f mininet:
*** Shutting down stale tunnels pkill -9 -f Tunnel=Ethernet
pkill -9 -f .ssh/mn rm -f ~/.ssh/mn/* *** Cleanup complete.
a) [0.25 credits] What is the task of the control plane?
Make the decisions for the forwarding plane.
b) [0.25 credits] What is the task of the data plane?
Forwarding packets.
c) [0.20 credits] What is the forwarding plane?
Another word for data plane.
Execute the following cell to test the mininet setup. The setup works if all hosts are reachable using pingAll().
from mininet.net import Mininet
from mininet.topo import Topo
from mininet.link import TCLink
from mininet.node import OVSSwitch
from mininet.log import setLogLevel, info
class simpleTopo(Topo):
"Four switches connected to 2 hosts as specified in the task."
def __init__(self, **opts):
# initialize topology and default options
Topo.__init__(self, **opts)
switch1 = self.addSwitch('s1')
host1 = self.addHost('h1', ip='10.0.0.1')
host2 = self.addHost('h2', ip='10.0.0.2')
self.addLink(host1, switch1, bw=1, delay='1ms')
self.addLink(host2, switch1, bw=1, delay='1ms')
def simpleTest(cmds):
# create and start network
topo = simpleTopo()
net = Mininet(topo, link=TCLink, switch=OVSSwitch)
net.start()
# preparing switch for this exercise
s1 = net.get('s1')
info(s1.cmd('echo switch info:'))
info(s1.cmd('ovs-vsctl show')) # output switch info
info(s1.cmd('ovs-ofctl dump-flows s1')) # print flow info
info(s1.cmd('ovs-ofctl del-flows s1')) # remove all default flows
info(s1.cmd('ovs-ofctl dump-flows s1'))
for cmd in cmds:
info(s1.cmd(cmd))
# tests reachability of all hosts
net.pingAll()
# shut down network
net.stop()
if __name__ == '__main__':
# tell mininet to print useful information
setLogLevel('info')
# enter user specified OpenFlow rules on the switch
cmds = [
'ovs-ofctl add-flow s1 actions=output:flood'
]
simpleTest(cmds)
*** Creating network
*** Adding controller
*** Adding hosts:
h1
h2
*** Adding switches:
s1
*** Adding links:
(1.00Mbit 1ms delay)
(1.00Mbit 1ms delay)
(h1, s1)
(1.00Mbit 1ms delay)
(1.00Mbit 1ms delay)
(h2, s1)
*** Configuring hosts
h1
h2
*** Starting controller
c0
*** Starting 1 switches
s1
...
(1.00Mbit 1ms delay)
(1.00Mbit 1ms delay)
switch info:
3c6fad27-14fe-45d2-974c-7625df3728ea
Bridge s1
Controller "tcp:127.0.0.1:6653"
fail_mode: secure
Port s1-eth2
Interface s1-eth2
Port s1-eth1
Interface s1-eth1
Port s1
Interface s1
type: internal
ovs_version: "3.5.0"
cookie=0x0, duration=0.035s, table=0, n_packets=0, n_bytes=0, priority=0 actions=CONTROLLER:128
*** Ping: testing ping reachability
h1 ->
h2
h2 ->
h1
*** Results: 0% dropped (2/2 received)
*** Stopping 1 controllers
c0
*** Stopping 2 links
.
.
*** Stopping 1 switches
s1
*** Stopping 2 hosts
h1
h2
*** Done
d) [0.5 credits] Execute the code of the network. The output gives the result of the ping (search for "Ping: testing ping reachability" in the output). What does the command "ovs-ofctl add-flow s1 actions=output:flood" do? How does the switch behave when receiving a packet?
| Argument | Description |
|---|---|
| add-flow | '' |
| s1 | '' |
| actions=output:flood | '' |
Adds an OpenFlow rule (add-flow) on the device called (s1) which performs forwards the packet to all available ports except the receiving port (actions=output:flood).
This transforms the switch (OpenFlow device) into a hub.
e) [0.25 credits] After installing the rule, which packets can be seen by the controller?
The controller cannot see any further packets.
f) [1.5 credits] Execute the following cell. Explain why the ping is not successful. Enter OpenFlow rules at the given location to fix this problem.
Note: You can ignore the following error: "*** Error: RTNETLINK answers: No such file or directory". This does not influence the behavior of the given program.
Explain why ping was unsuccessful: Hosts h1 and h2 do not know the MAC addresses of each other. Both hosts try to get this information via ARP. However, the ARP requests cannot pass the switch because the OpenFlow rules are only valid for IPv4 (0x0800). To fix this problem rules for ARP forwarding, must be installed.
from mininet.net import Mininet
from mininet.topo import Topo
from mininet.link import TCLink
from mininet.node import OVSSwitch
from mininet.log import setLogLevel, info
class simpleTopo(Topo):
"Four switches connected to 2 hosts as specified in the task."
def __init__(self, **opts):
# initialize topology and default options
Topo.__init__(self, **opts)
switch1 = self.addSwitch('s1')
host1 = self.addHost('h1', ip='10.0.0.1')
host2 = self.addHost('h2', ip='10.0.0.2')
self.addLink(host1, switch1, bw=1, delay='1ms')
self.addLink(host2, switch1, bw=1, delay='1ms')
def simpleTest(cmds):
# create and start network
topo = simpleTopo()
net = Mininet(topo, link=TCLink, switch=OVSSwitch)
net.start()
# preparing switch for this exercise
s1 = net.get('s1')
info(s1.cmd('echo switch info:'))
info(s1.cmd('ovs-vsctl show')) # output switch info
info(s1.cmd('ovs-ofctl dump-flows s1')) # print flow info
info(s1.cmd('ovs-ofctl del-flows s1')) # remove all default flows
for cmd in cmds:
info(s1.cmd(cmd))
info(s1.cmd('ovs-ofctl dump-flows s1'))
# tests reachability of all hosts
net.pingAll()
# remove '#' of next line to see statistics after ping
#info(s1.cmd('ovs-ofctl dump-flows s1'))
# shut down network
net.stop()
if __name__ == '__main__':
# tell mininet to print useful information
setLogLevel('info')
# enter user specified OpenFlow rules on the switch
cmds = [
'ovs-ofctl add-flow s1 dl_type=0x0800,nw_dst=10.0.0.2,actions=output:2',
'ovs-ofctl add-flow s1 dl_type=0x0800,nw_dst=10.0.0.1,actions=output:1',
# begin insert code
# simple solution
#'ovs-ofctl add-flow s1 dl_type=0x0806,actions=output:flood'
# more sophisticated solution
'ovs-ofctl add-flow s1 in_port:1,dl_type=0x0806,actions=output:2',
'ovs-ofctl add-flow s1 in_port:2,dl_type=0x0806,actions=output:1'
# end insert code
]
simpleTest(cmds)
*** Creating network
*** Adding controller
*** Adding hosts:
h1
h2
*** Adding switches:
s1
*** Adding links:
(1.00Mbit 1ms delay)
(1.00Mbit 1ms delay)
(h1, s1)
(1.00Mbit 1ms delay)
(1.00Mbit 1ms delay)
(h2, s1)
*** Configuring hosts
h1
h2
*** Starting controller
c0
*** Starting 1 switches
s1
...
(1.00Mbit 1ms delay)
(1.00Mbit 1ms delay)
switch info:
3c6fad27-14fe-45d2-974c-7625df3728ea
Bridge s1
Controller "tcp:127.0.0.1:6653"
fail_mode: secure
Port s1
Interface s1
type: internal
Port s1-eth1
Interface s1-eth1
Port s1-eth2
Interface s1-eth2
ovs_version: "3.5.0"
cookie=0x0, duration=0.074s, table=0, n_packets=0, n_bytes=0, priority=0 actions=CONTROLLER:128
cookie=0x0, duration=0.026s, table=0, n_packets=0, n_bytes=0, ip,nw_dst=10.0.0.2 actions=output:"s1-eth2" cookie=0x0, duration=0.020s, table=0, n_packets=0, n_bytes=0, ip,nw_dst=10.0.0.1 actions=output:"s1-eth1" cookie=0x0, duration=0.014s, table=0, n_packets=0, n_bytes=0, arp,in_port="s1-eth1" actions=output:"s1-eth2" cookie=0x0, duration=0.005s, table=0, n_packets=0, n_bytes=0, arp,in_port="s1-eth2" actions=output:"s1-eth1"
*** Ping: testing ping reachability
h1 ->
h2
h2 ->
h1
*** Results: 0% dropped (2/2 received)
*** Stopping 1 controllers
c0
*** Stopping 2 links
.
.
*** Stopping 1 switches
s1
*** Stopping 2 hosts
h1
h2
*** Done
Advanced Computer Networking by Prof. Dr.-Ing. Georg Carle
Teaching assistants: Christian Dietze, Sebastian Gallenmüller, Marcel Kempf, Lorenz Lehle, Nikolas Gauder, Patrick Dirks