When network engineers are learning the concepts of software defined networking and SDN controllers, they may want to experiment with SDN network scenarios before learning to write programs to be used by the SDN controllers.
POX is a simple-to-use SDN controller that is bundled with the Mininet SDN network emulator and is used in education and research as a learning and prototyping tool. POX components are Python programs that implement networking functions and can be invoked when POX is started. POX comes with a few stock components ready to use.
In this tutorial, we will use stock POX components to implement basic switching functionality with loop prevention in a software defined network, without writing any code. Then, we will explore how the SDN controller programs the OpenFlow-enabled switched in a network created using the Mininet network emulator.
Prerequisite knowledge required
This tutorial assumes you already have the the prerequisite knowledge defined in the list below. If you need to understand more about any of the topics listed below, the list provides links to resources that offer enough information to prepare you to work through this tutorial.
- You have a basic understanding of Ethernet networks, IP networking, and software defined networking.
- You have set up the Mininet 2.2.1 virtual machine on your computer.
- You have a basic understanding of how Mininet commands work.
- You know how to use the MiniEdit GUI.
- You are familiar with the POX SDN controller.
- You have completed the OpenFlow Tutorial.
Create the network scenario using Mininet
We will use the Mininet network emulator to create a test network that we will control using POX. We will use the MiniEdit GUI for Mininet to create the network.
Log into the Mininet VM
The Mininet VM should be running on your computer and should be accessible at the IP address assigned by the VirtualBox host-only interface. If this is not yet the case, please read my post about how to set up the Mininet 2.2.1 virtual machine. In our example, the VirtualBox host-only adapter’s IP address 192.168.56.101. Check the interface on the Mininet VM to see which IP address is assigned in your case.
From a terminal window on your host computer, access the Mininet VM with the command:1
t400:~$ ssh -X email@example.com
Enter the password, which is mininet. The prompt will show you are now logged into the Mininet VM:
Repeat this at least three times so you have three terminal windows open and logged into the Mininet VM.
Create the network
We will use MiniEdit to create our network scenario. The MiniEdit script is located in Mininet’s examples folder. To run MiniEdit, execute the command:
$ sudo ~/mininet/examples/miniedit.py
Remember that Mininet needs to run with root privileges so use the sudo command.
Using the MiniEdit GUI, create a network that includes hosts, switches, and a controller. Add redunant links between switches, which creates loops in the network. In our example, we create a network topology as shown below:
Remember to configure the MiniEdit preferences so that the Start CLI function is enabled. Also, configure the controller as a Remote Controller.
Start the simulation
To start the simulation scenario, click the Run button on the MiniEdit GUI. Assuming you set up MiniEdit using the procedures in my post about using MiniEdit, you should now see the Mininet prompt in the terminal window you used to start MiniEdit.
Next, we start Wireshark and start capturing packets on the Mininet VM’s loopback interface. We start Wireshark now, before starting the POX controller, because we need to capture the switch setup messages sent by the POX controller in order to learn which switch uses which port address.
In one of the terminal windows, start Wireshark with the command:
$ sudo wireshark &
Then select the loopback interface interface and start capturing. The enter the text
of in the filter box and click the Apply button. Now you will see only openflow messages captured on the loopback interface.
Next, we will start the POX controller.
To create network applications using the POX software defined network controller, developers create and run Python programs that use the POX API to modify the state of switches in the network and to respond to information those switches send to the POX controller. Programmers can write standalone programs that use the POX API or they can write programs that add functionality to POX directly. The latter type of program is called a POX component.
Open a new terminal session. In the new terminal window (or tab), we will run the POX SDN controller. We will call this window the POX console.
The command we use to start POX is:
$ sudo ~/pox/pox.py forwarding.l2_learning \ openflow.spanning_tree --no-flood --hold-down \ log.level --DEBUG samples.pretty_log \ openflow.discovery host_tracker \ info.packet_dump
This starts POX and invokes POX components that create a network application that performs switching based on Ethernet MAC addresses and provides redundant links in the network while preventing packet storms due to loops. It also implements functions that will display more network events to the POX console and sets up debug mode in the console so we can see those network events.
See below to learn more about what each of these components does.
The stock POX components
Below is a list of the stock POX components we will used in this tutorial, with explanations of what each component does. To learn about other POX components, see the POX component documentation.
The L2 Learning component makes OpenFlow switches act like Ethernet learning switches. It learns Ethernet MAC addresses, and matches all fields in the packet header so it may install multiple flows in the network for each pair of MAC addresses. For example, different TCP connections will result in different flows being installed.
This L2 Learning component creates flows with idle timeout values so switches will automatically delete flows that have not serviced packets during the timeout period (which is ten seconds). This helps keep flow tables manageable.
The OpenFlow Discovery component uses LLDP messages sent to and received from OpenFlow switches to discover the network topology. It also detects when network links go up or down. This information may be used by other components.
openflow.spanning_tree ‐‐no-flood ‐‐hold-down
The Spanning Tree component is required in cases where the topology of the network contains loops. It works with the OpenFlow Discovery component to build a view of the network topology and constructs a spanning tree by disabling flooding on switch ports that aren’t on the tree. The options no-flood and hold-down are used to ensure no packets are flooded in the network before the component creates the spanning tree.
The Spanning Tree component will respond to changes in the network topology. If a link is broken, and if an alternate link exists, it can maintain connectivity in a network by creating a new tree that enables flooding on the ports connected to the alternate link.
When using the Spanning Tree component, also use a forwarding component that creates flows that have a timeout value set. In this example, we used the L2 Learning component.
The Host Tracker component attempts to keep track of hosts in the network. Host Tracker examines messages received by POX and learns MAC and IP of hosts in the network. Host Tracker will work in our example but it relies on packets coming to the controller. Packet forwarding in the network must be done reactively so we need to use a forwarding component like forwarding.l2_learning.
The Packet Dump component will display on the log console information about data packets received by POX from switches. This will help us see how the switches interact with the POX controller without running tcpdump.
The Log Level component allows the POX user to specify the amount of detail they will see in the log information produced by POX. The most detailed level is DEGUG, so we will use that in our example. By default, logs appear on the POX console so you will see them on the same terminal session used to start POX.
The Pretty Log component formats log messages into a custom log format to provide attractive and readable log output on the POX console.
Wireshark packet captures
In the Wireshark window, you should start to see OpenFlow messages. We will come back to these later in this tutorial. We will use the setup messages exchanged between the POX controller and the switches to identify the TCP port associated with each switch’s OpenFlow interface, and to study the operation of the Spanning Tree POX component.
Monitor the POX console
Now we see that POX is running. On the terminal session we used to start POX, we see the POX log messages showing actions detected or performed by each POX component that is running.
Network simulation scenario is now running
At this point, you have the Mininet network running and you see the Mininet command prompt in the terminal session from which you started either MiniEdit.
We can look at the POX SDN controller console and see the openflow events being handled by the POX controller, which are displayed in the POX log messages because we set the log level to DEBUG. We see the POX SDN controller connecting to switches and setting up the spanning tree.
Identify network details and topology
We have set up a simulated SDN network that can pass traffic from one host to another, and that can manage redundant links in the network to support rerouting of traffic when an active link fails.
We need to create a more detailed diagram of the network first, by gathering some network information and making some notes we will use later as we explore the network functionality. We need to make a note of the port names and the status of each port.
Note port names in the network diagram
MiniEdit does not show the switch port numbers in the network diagram. We need to know which ports connect to ports on other switches. Then, we need to determine which ports have been disabled by the POX controller to implement the spanning tree.
To see which ports are connect to which switches, use the Mininet net command:
mininet> net h6 h6-eth0:s5-eth2 h2 h2-eth0:s4-eth2 h3 h3-eth0:s3-eth1 h4 h4-eth0:s3-eth2 h1 h1-eth0:s4-eth1 h5 h5-eth0:s5-eth1 s3 lo: s3-eth1:h3-eth0 s3-eth2:h4-eth0 s3-eth3:s2-eth1 s3-eth4:s4-eth4 s3-eth5:s5-eth4 s3-eth6:s1-eth3 s5 lo: s5-eth1:h5-eth0 s5-eth2:h6-eth0 s5-eth3:s2-eth2 s5-eth4:s3-eth5 s1 lo: s1-eth1:s4-eth3 s1-eth2:s2-eth3 s1-eth3:s3-eth6 s4 lo: s4-eth1:h1-eth0 s4-eth2:h2-eth0 s4-eth3:s1-eth1 s4-eth4:s3-eth4 s2 lo: s2-eth1:s3-eth3 s2-eth2:s5-eth3 s2-eth3:s1-eth2 c0
From this, we will mark up a screen capture of the network diagram using any image editor.2 Our examples results in the following annotated diagram:
Map the spanning tree topology in the network diagram
To find the current spanning tree topology, we need to determine the state of each port on each switch.
The Mininet dump ports description command shows the status of each port. This command writes a lot of information to the terminal so, for simplicity, I just show the output related to one switch in the output below:
mininet> dpctl dump-ports-desc *** s5 ---------------------------- OFPST_PORT_DESC reply (xid=0x2): 1(s5-eth1): addr:de:af:97:f0:dc:48 config: 0 state: 0 current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max 2(s5-eth2): addr:82:0b:13:ee:75:3a config: 0 state: 0 current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max 3(s5-eth3): addr:4e:11:d4:dc:17:a9 config: 0 state: 0 current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max 4(s5-eth4): addr:52:23:3a:3f:a4:0f config: NO_FLOOD state: 0 current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max LOCAL(s5): addr:a2:5d:62:e7:b7:48 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max
The switch ports with status NO_FLOOD have been blocked by the POX controller which, after calculating the spanning tree, sends OpenFlow commands to the Open vSwitch bridges to disable ports and prevent loops.
Looking at all the information provided by the full output of the dump ports description command, we can map disabled ports and so create a view of the current spanning tree.
See our notes below, created using an image editor to write on top of the MiniEdit topology screen capture, that show the blocked ports and the forwarding ports that make the spanning tree.
Test spanning tree functionality
Based on the initial state of the network shown above we expect that, if we disable the link between switches s2 and s5, the POX controller will detect a link failure and create a new spanning tree by changing the status other ports.
Let’s give this a try. First, we disable the link between switchs s2 and s5 by right-clicking on the link in the MiniEdit GUI and selecting Link Down from the options that appear. When we do this, we see in the POX Console that a link timeout was detected and the POX controller updated the spanning tree and made changes to the switches s2, s3, and s5.
When we dump the switch descriptions again, we see that the status of the ports has changed as shown below. Again, we only show output for one switch even though the command will dump information for all switches.
mininet> dpctl dump-ports-desc *** s5 ---------------------------- OFPST_PORT_DESC reply (xid=0x2): 1(s5-eth1): addr:de:af:97:f0:dc:48 config: 0 state: 0 current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max 2(s5-eth2): addr:82:0b:13:ee:75:3a config: 0 state: 0 current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max 3(s5-eth3): addr:4e:11:d4:dc:17:a9 config: PORT_DOWN NO_FLOOD state: LINK_DOWN current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max 4(s5-eth4): addr:52:23:3a:3f:a4:0f config: 0 state: 0 current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max LOCAL(s5): addr:a2:5d:62:e7:b7:48 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max
From this, we can map out the new logical network topology and we see how the spanning tree has changed.
If we bring the link between switches s2 and s5 back up, we see that the POX controller does not change the spanning tree back to the original configuration. This is probably a design decision made by the developers of the spanning tree POX component and it differs from the way the Spanning Tree Protocol works in normal Ethernet networks.
Breaking links in the network
We observed in the previous section that the POX SDN controller can monitor LLDP messages received from switches and respond to changes in switch port status by unblocking other ports as required.
Now we will observe the POX controller set up data flows in the switches based on events detected in the network. In this example, the events are triggered by one host sending data to another host in the network.
The simplest way to send data from one host to another is to use the ping command. This command also offers basic performance information.
Test ping between two hosts. Open a terminal window on host h1 and start the ping command to ping host h6:
# ping 10.0.0.6
See the events reported on the POX console.
Look at the packets captured in Wireshark. It is helpful to map TCP ports to switches before performing experiments. This makes it easier to track what is happening in the packet capture file.
In our example, the TCP port used by each switch to communicate with the POX controller is listed in the table below:
See the OpenFlow messages going to the switches to set up flows for ICMP packets. Once these flows are established, the ICMP packets generated by the ping command are exchanged between hosts h1 and h6.
While the ping is running on host h1, break a link and watch how the spanning tree recovers. In the MiniEdit GUI, right-click on a link that will break an actively forwarding port and click Link Down from the menu that appears. See how the POX controller responds by monitoring OpenFlow messages in Wireshark.
After the POX controller receives LLDP messages indicating a change in port status, we see the controller send OpenFlow port modification messages to the switches in the network to create a new logical topology. But, the ping command does not receive any responses from h1 for almost 40 seconds.
More investigation of the packet capture file shows us that, while the POX controller updates the port status on the switches within a few seconds of a failure occurring, the switches seem to take a long time to clear their flows and flood packets to the POX controller so it can create new flows that match the new spanning tree topology. Apparently, there is room to improve the POX spanning tree component’s functionality.
We showed how to create a basic software defined networking application using the Mininet SDN emulator, the POX SDN controller, and stock POX components, without writing any code.
We also performed some experiments in the network to test its functionality and used Wireshark, a packet analyzer, to see how the POX controller managed the OpenFlow switches in the network.
If your host computer is a Windows computer, use the PuTTY terminal program and ensure X Forwarding is enabled. Also, ensure you are running an X Server like Xming. If your host computer is a Mac, download and install XQuartz for Mac OS and use SSH as described in above. See the Apple Support web sit for more details at: http://support.apple.com/kb/HT5293. ↩