Views
OpenFlow Sigmetrics 2009 Hands-on Tutorial Instructions
From OpenFlow Wiki
NOTE: THIS TUTORIAL IS OBSOLETE. Please use the newer one at HOTI2010Tutorial
Contents |
Overview
Welcome to the OpenFlow tutorial!
The goal of this tutorial is to give you experience with OpenFlow tools and debugging. To get you started quickly, we provide a preconfigured virtual machine with the needed software. The controller you program in Python will be built on top of NOX. From noxrepo.org:
NOX is an open-source platform that simplifies the creation of software for controlling or monitoring networks. Programs written within NOX (using either C++ or Python) have flow-level control of the network. This means that they can determine which flows are allowed on the network and the path they take.
By the end, you'll have turned a simple hub into a layer-2 learning switch, and then a flow-accelerated learning switch. From here, you can run your code on a hardware-speed switch, add features to your software switch, or just about anything else.
Innovate in your network!
Pre-requisites
You will need a computer with at least 1GB (preferably 2GB+) of RAM and at least 5GB of free hard disk space (more preferred). A faster processor may speed up the virtual machine boot time, and a larger screen may help to manage the plethora of open terminal windows (6+).
These instructions consider Linux, OS X, and Windows. Linux and OS X are preferred - there's less to install, and VirtualBox has seemed more reliable.
You will need administrative access to the machine.
Stuck?
If at some point you get stuck, email openflow-discuss@lists.stanford.edu with as many details about your setup as possible. Include your OS, VirtualBox version, memory size, and the step you're on.
Found a Bug?
Please report any bugs with this tutorial to bugs@openflow.org.
Install Required Software
The OpenFlow tutorial flash drives being passed around include all of the software you will need for the tutorial. Please save the available wireless bandwidth for other traffic!
Install VirtualBox
Download and install a copy from virtualbox.org for your platform.
Windows Users Only: note that the Windows VirtualBox installation will interrupt network connectivity for a moment, so you probably don't want to have other stuff downloading when you do the install.
Linux
An X server is required; most graphical Linux installs will already have included this.
OS X
An X server is required; this may need to be installed, depending on your OS X version:
- Leopard: X11 is part of the operating system, no separate install is needed
- Tiger: X11 is an optional install from the Tiger install DVD
- Panther: X11 can be downloaded here
Now install X11 (if needed).
Windows XP
An X server is required; we suggest installing Xming (X11-Server). Download here and follow the installer's instructions.
To access the VM via SSH, you will need to install putty. Download putty here and follow the installer's instructions. Note the install location.
A program capable of handling .tar.gz files is also required - we'll use 7-zip. Download 7-Zip here and follow the installer's instructions.
Set up Virtual Machine
Get Virtual Machine Disk Image
Download the virtual machine image here (~1.3GB). Remember this location; you'll need it shortly. Warning This a large file, and the download will take awhile.
Unpack Virtual Machine Disk Image
To create a VM with the provided image in Virtual Box, we need to unzip it first. The file format, '.vdi', stands for VM Disk Image.
Warning This step will take awhile - the unpacked .vdi file is over 4 GB.
OS X and Linux Users: from a terminal, unzip the virtual machine image:
tar xzf OpenFlowTutorial.tgz
Windows Users: open the virtual machine image in 7-zip. Extract the image, and note the location.
Setup Virtual Machine
Next, open VirtualBox and click 'New' in the top left. Click 'Next'. Set the name to OpenFlowTutorial, set the Operating System to Linux and Version to Debian. Click 'Next'. Set the machine to 512 MB RAM (this is our recommended minimum) and click 'Next'. Select 'Use existing hard disk' and select the disk image you downloaded earlier, OpenFlowTutorial.vdi. Click 'Finish'.
Boot Virtual Machine
Click 'Start' at the top of the VirtualBox window; the VM should boot. Do not change the kernel choice during boot - anything other than the default may lead to odd errors.
At the boot prompt, enter the username and password, which are both openflow. Note that the openflow user is a sudoer.
Choose Preferred Editor
Nano, Vim, and Emacs come installed on the OpenFlowTutorial VM.
On Nano, you can immediately modify a file. When you're done, hit 'ctrl-x', then say 'Yes' to the prompt, to save and quit.
On Vim, to modify a file, type 'i' to enter Insert mode, then use the arrow keys to navigate and edit. When you're done, hit 'esc', type ':wq', then press enter, to save and quit.
On Emacs, you can immediately modify a file. When you're done, hit 'ctrl-x', 'ctrl-s', then hit 'ctrl-x', 'ctrl-c' to exit.
If you have another preferred text editor, feel free to install it now:
sudo apt-get install <editor>
Setup Network Access
To allow network access in the VM, execute:
sudo dhclient eth1
which grabs an IP address.
Now we need to provide SSH access from your local machine into the VM.
OS X / Linux Users Run the VBoxManage commands below from a local terminal (not the VM window).
Windows Users If you are using Windows Vista, first close Virtual box, to ensure that config files aren't locked. Then open a command line prompt, by click on 'Start', then 'Run', then typing 'cmd' and hitting enter. In the terminal that appears, change to the VirtualBox directory:
cd "C:\Program Files\Sun\xVM VirtualBox"
All OSes: From a terminal on your local machine (NOT the VM/VirtualBox), run:
VBoxManage setextradata OpenFlowTutorial "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort" 2222 VBoxManage setextradata OpenFlowTutorial "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/GuestPort" 22 VBoxManage setextradata OpenFlowTutorial "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/Protocol" TCP
Verify the settings:
VBoxManage getextradata OpenFlowTutorial enumerate
The three values you added above should be shown.
Save your network settings for future reboots, by powering down the VM, from the VM window:
sudo poweroff
Restart the OpenFlowTutorial VM once again, by clicking 'Start' at the top of VirtualBox. Login again as user openflow with password openflow.
Windows Users You may need to change the VM configuration. Edit /etc/network/interfaces. Check that it says:
allow hot-plug eth1 iface eth1 inet dhcp
If it says eth0, change it to eth1; note that to write the file you'll need to use sudo. If you changed the interfaces file, poweroff the machine (sudo poweroff) and then start it again.
Access VM via SSH
You will need to bring up multiple concurrent SSH terminals into the OpenFlowTutorial VM.
Mac OS X and Linux
To SSH from the local machine to the VM, on the local machine run:
ssh -Y -l openflow -p 2222 localhost
with password openflow. Test the X11 forwarding by running on the local machine:
xterm
and a new terminal window should appear. If you have succeeded, you are done with the basic setup. Close the xterm.
Windows XP
Start Xming; nothing exciting will happen but it will show an icon on the right of the toolbar.
Open a terminal: click 'Start', 'run', then enter 'cmd'.
Change to the directory where you saved putty.
cd <dir>
Run:
putty.exe -X -P 2222 -l openflow localhost
A new window will pop up; type in the password 'openflow'. Now, type:
xterm
A white terminal window should appear. If you have succeeded, you are done with the basic setup. Close the xterm.
Bring up Development Environment
The testing and development environment provides:
- a set of 4 hosts connected to a single OpenFlow switch
- a controller, NOX
- debugging tools: tcpdump, Wireshark dissector
... all running within the OpenFlowTutorial VM.
Yes, this is a set of VMs (qemu instances) running inside a VM (OpenFlowTutorial on VirtualBox).
Once you start up the network (next), there's going to be an overwhelming number of terminal windows of different types. Let's define some terminology, starting with 4 terminal types:
- VirtualBox terminal: connects to OpenFlowTutorial; this is the one spawned by VirtualBox. Minimize this NOW, if you haven't already done so. Once you've used it to set up networking, it won't be needed.
- Local terminal: connects to your computer; used for running the VirtualBoxManage commands previously. Created by doing 'Start','Run',enter 'cmd' in Windows, opening the Terminal application in OS X, or starting a terminal in Linux.
- SSH terminal: connects to OpenFlowTutorial. Created by using putty on Windows or SSH on OS X / Linux, as described in the previous section.
- xterm terminal: connects to a host in the virtual network. Created in the next section when you execute 'run.sh'. Will be labeled at the top with the name of the host.
Modify Configuration File
The configuration file, vms.conf, represents the network and host configuration. You can make arbitrary networks with the number of switches and hosts limited only by available memory and processing speed. The OpenFlowTutorial VM comes configured for 4 hosts; we'll only need 3. In an SSH terminal, open the file '~/proj1/vms.conf' and remove all references to 'sw4' and 'host4'. Make it look like this:
SWITCHES="ofsw sw1 sw2 sw3" ofsw_SLIRP=yes VMS="openflowsw host1 host2 host3" openflowsw_NETS="ofsw sw1 sw2 sw3" host1_NETS=sw1 host2_NETS=sw2 host3_NETS=sw3
Fewer hosts will make the network of VMs run a little bit faster. Save and close this file.
Modify Startup Script
The startup script, run.sh, restarts the network of VMs and spawns xterms. Since we just changed our configuration to use 4 hosts, we don't need a fourth xterm spawned. In an SSH terminal, edit '~/proj1/run.sh'. Modify the line:
for x in `seq 1 4`
to
for x in `seq 1 3`
Save and close this file.
Modify OpenFlow Switch Startup
Each VM, running as a host or an OpenFlow switch, has a corresponding .cd file to customize what it runs when it starts up. By default, the OpenFlow reference switch will act as a standalone learning switch when it gets disconnected. This can complicate the tutorial, so we'll ensure that the VM running an OpenFlow switch fails such that flows time out naturally, but no flows are added by the switch until it reconnects to the controller. In an SSH terminal, open '~/proj1/openflowsw.cd/runme'. Modify the line:
/cdrom/secchan nl:0 tcp:10.0.2.2:2525 &
to look like this:
/cdrom/secchan --fail=closed nl:0 tcp:10.0.2.2:2525 &
Save and close this file.
Start Network
To start up the network of 3 hosts and the OpenFlow switch, in an SSH terminal run:
cd ~/proj1 ./run.sh
This will take at least a few minutes. While the 3 xterms show booting hosts, arrange these 3 windows, and optionally make them smaller, to 10 lines height or so.
Each xterm is its own host. The username/password for each host will be root/root. The IP address of host x is 192.168.0.x. You will see the following print out during the boot process:
modprobe: FATAL: Could not load /lib/modules/2.6.26/modules.dep: No such file or directory
Ignore this.
Now, minimize this SSH terminal (but DON'T close it or enter commands, which will also close the virtual network). Open a second SSH terminal, and log into the OpenFlowTutorial VM. You will need this terminal soon.
Verify Lack of Connectivity
When you do 'run.sh', an OpenFlow switch VM is started up. Earlier, you configured this switch to only consider existing flows when it loses its controller connection. Since you haven't connected a controller, the VM hosts in the network have no connectivity. We'll now verify that hosts can't connect.
In the host2 and host3 xterms, start up tcpdump:
tcpdump -n -i eth0
Tcpdump will print a line for each packet that arrives. You can ignore any BOOTP messages. The '-n' flag to tcpdump prevents delayed output.
In the host1 xterm, attempt to ping another machine:
ping -c 1 192.168.0.2
You should see no packets print in tcpdump.
Run Provided Controller
To run the starter application, go to the NOX source directory in the SSH window:
cd ~/noxcore/src
Then, in the same window, start the base Python hub code:
./nox_core -v -i ptcp:2525 pylearningswitch
Wait until the hub application indicates that the OpenFlow switch has connected. The provided OpenFlow switch will increase the period of its attempts to contact the controller, up to a maximum of 15 seconds. Since the OpenFlow switch has not connected yet, this delay may be anything between 0 and 15 seconds. When the switch connects, you will see NOX print something like this:
00035|nox|DBG:Registering switch with DPID = 2320e8378a
Verify Connectivity
Now we verify that hosts can ping each other, and that all hosts see the exact same traffic - the behavior of a hub. In the host1 xterm:
ping -c 1 192.168.0.2
The ping packets are now going up to the controller, which then floods them out all interfaces except the sending one. You should see identical ARP and ICMP packets corresponding to the ping in both xterms running tcpdump.
Now, see what happens when a non-existent host doesn't reply. From the host1 xterm:
ping -c 1 192.168.0.5
You should see three unanswered ARP requests in the tcpdump xterms. If your code is off, three unanswered ARP requests is a signal that you might be accidentally dropping packets.
View Ping in Wireshark
The VM image includes the OpenFlow Wireshark dissector pre-installed. Wireshark is extremely useful for watching OpenFlow protocol messages, as well as general debugging. In a new SSH terminal, open Wireshark:
sudo wireshark
Click on Capture->Interfaces, in the menu bar. Click on the Start button next to 'lo', the loopback interface. You should see plenty of packets rushing by.
Now, set up a filter for OpenFlow control traffic, by typing 'of' in Filter box near the top:
of
Click enter to apply this filter to all recorded traffic. To force some new control traffic, cancel nox_core (Ctrl-C), then restart nox_core, as in the previous section. You should see a bunch of messages displayed from the Hello exchange to the message sent by NOX to initialize the flow table. Feel free to expand the 'OpenFlow Protocol' line in the center section. Each field of each message will be displayed.
Now, send a ping from one host to another:
ping -c 1 192.168.0.3
You should see this traffic on all the tcpdump windows, as well as in the Wireshark window. Specifically, you should see 4 packets for a ping, two for ARP resolution, and two for the ICMP echo request.
Create Learning Switch
Next, you'll modify the provided hub to act as an L2 learning switch.
Sample Pseudocode
Your learning switch should learn the port of hosts from packets it receive. This is summarized by the following sequence, run when a packet is received:
- if (source mac of the packet is known)
- record mac as being bound to input port of packet received
- if (destination mac of the packet is known)
- setup flow to the learned port
- else
- send flood packet
Open Hub Code and Begin
The file you will modify is ~/noxcore/src/nox/coreapps/learningswitch/pylearningswitch.py. Most of the code will go in one function, learn_and_forward().
Each time you change and save this file, make sure to restart NOX, then use pings to verify hub or Ethernet learning switch behavior. Hosts that are not the destination should display no tcpdump traffic after the initial broadcast ARP request.
Good luck!
See how far you can get on your own. If you get stuck, look through the next section for some pointers, or consult the sample code two sections down.
Learning Python
A list of built-in functions in Python is at:
http://docs.python.org/lib/built-in-funcs.html
You may find it faster to look at the provided code to get a sense of Python syntax first. Any suggestions for quick beginner tutorials/overviews?
The main files for the NOX Python API are at:
~/noxcore/src/nox/lib/core.py
To discover MAC addrs on each VM, which may prove useful:
ifconfig eth0 | grep HWaddr
Sample Python Learning Switch Code
Note that in Python, the tab indent must be consistent through a file; make sure to align text after copying. Replace the code in learn_and_forward() with the following:
# global mac -> port mappings
m2p = {}
def learn_and_forward(dpid, inport, packet, buf, bufid):
"""Learn MAC source and port association.
Forward according to learned port, else flood.
"""
global inst
# learn the port for the source MAC
s = mac_to_str(packet.src)
m2p[s] = inport
# forward the packet to the destination
d = mac_to_str(packet.dst)
if m2p.has_key(d):
outport = m2p.get(d)
# send packet; replace the line below with a flow mod next
inst.send_openflow(dpid, bufid, buf, outport, inport)
else:
inst.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
Test this code by running pings; check that only the destination sees the intended packets. The messages in Wireshark should look the same.
Sample Flow-Accelerated Learning Switch Code
To speed up the learning switch by pushing flow entries down to the switch when the source and dest MAC addresses are known, use the sample code below.
Modify the line below 'send packet; replace the line below with a flow mod next', to instead add a flow entry and send the buffered packet out the switch:
# add a flow wildcarded on all fields except MAC dst
attrs = {}
attrs[core.IN_PORT] = inport
attrs[core.DL_DST] = packet.dst
action = [[openflow.OFPAT_OUTPUT, [0, outport]]]
inst.install_datapath_flow(dpid, attrs, CACHE_TIMEOUT, CACHE_TIMEOUT, action,
bufid, openflow.OFP_DEFAULT_PRIORITY, inport, buf)
Go back and check in Wireshark that flow entries are getting pushed by the controller.
You should notice dramatically reduced ping times, too. In the host1 xterm:
ping -c 3 192.168.0.1
The second and third pings should be much faster, since subsequent packets for a flow no longer have to go to the controller. Instead, they can cut through the switch. These entries are getting added with a 5 second timeout, but you can always change this.
End of Tutorial
This completes the tutorial. Congratulations on finishing it!
From here, you can learn more about OpenFlow at [1].
Notes
Bugs
To fix:
- Add picture of VMs
- Debug Occasional ARP storms for 10.0.2.3 and BOOTP messages
- Multiple kernels can be selected - should have only one choice.
- Need to change the configured OF port to 2525. Temporarily hacked packet-openflow.h for dissector; it's not reading the proper port.
Improvements
- Add some more detailed explanation on what those two nox API
(install_... and send_...) functions do/take as parameters, since they are the most important ones for a beginner developing an app.
Speedups
Stuff to that would speed up the tutorial, but is not strictly necessary:
- Modify VM image sudoers file to not require password
- Switch to LiveCD to eliminate double-virtualization
Questions
- How does one scroll an xterm?
- possible answer: start it with the flag -sl 500 to store 500 lines of output
Frequently Asked Questions (FAQ)
Why doesn't my VirtualBox image allows a SSH connection using Windows XP?
Before trying anything else, check your firewall. If that does not help, it appears that VirtualBox is not very stable in Windows XP. Try version 2.0.6. For those with 100% utilization, switching to version 1.6 might help.
Are we restricted to using L2 frame fields for defining flows?
You'll want to define the flows over all relevant fields up to the transport ports (packet type depending).
What is the "modprobe: FATAL: Could not load /lib/modules/2.6.26/modules.dep" message?
This error is not really fatal. You can safely ignore it.
Why am I waiting for host VM indefinitely?
Please make sure you have 512 MB RAM for the VirtualBox VM. For Windows, throw it a bit more, like 768 MB. That should solve the problem.
