This tutorial is intended for beginners to SDN application development for the POX platform. Some Python knowledge will be useful, though it isn’t absolutely necessary.

1. Quickstart

  • To get started, download and set up the SDN Hub Tutorial VM in Virtualbox or VMware Player.
  • Run Mininet on a terminal window using the following command. This starts a network emulation environment to emulate 1 switch with 3 hosts. The switch tries to connect to port 6633 on localhost. Initially, there is no controller listening.
$ sudo mn --topo single,3 --mac --controller remote --switch ovsk
  • Since POX does not support OpenFlow 1.3 yet, it is best to statically set the OpenFlow version of the OVS
$ sudo ovs-vsctl set bridge s1 protocols=OpenFlow10
  • Next, start the POX Controller. Assuming that the main folder where POX is installed is /home/ubuntu/pox, the command below starts the controller by initiating the OpenFlow Protocol Handler and our tutorial_hub application.
$ cd /home/ubuntu/pox && ./pox.py log.level --DEBUG forwarding.tutorial_l2_hub
  • The above command runs POX controller in DEBUG mode. This prints additional output of messages exchanged with the switch
POX 0.1.0 (betta) / Copyright 2011-2013 James McCauley, et al.
DEBUG:core:POX 0.1.0 (betta) going up...
DEBUG:core:Running on CPython (2.7.3/Sep 26 2013 16:35:25)
DEBUG:core:Platform is Linux-3.5.0-30-generic-x86_64-with-Ubuntu-12.10-quantal
INFO:core:POX 0.1.0 (betta) is up.
DEBUG:openflow.of_01:Listening on 0.0.0.0:6633
INFO:openflow.of_01:[00-00-00-00-00-01 1] connected
  • Next, check if the hosts in the mininet topology can reach each other
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=49.1 ms
64 bytes from 10.0.0.2: icmp_req=2 ttl=64 time=46.3 ms
64 bytes from 10.0.0.2: icmp_req=3 ttl=64 time=29.1 ms
64 bytes from 10.0.0.2: icmp_req=4 ttl=64 time=42.9 ms
64 bytes from 10.0.0.2: icmp_req=5 ttl=64 time=26.2 ms

2. Understanding the code

The code for the hub application we used above is in /home/ubuntu/pox/pox/forwarding/tutorial_l2_hub.py. When the application is started, the launch() function is automatically invoked. This is the function where the application registers all event listeners, and creates objects of any application class. For instance, the tutorial_l2_hub has the following launch() function:

def launch ():
    def start_switch (event):
        L2Hub(event.connection)

    core.openflow.addListenerByName("ConnectionUp", start_switch)

The above function instantiates a new L2Hub object for every new switch that connects to it.

2A. Listening to events

There are two common ways for an application to register with the controller for events.

  1. Register callback functions for specific events thrown by either the OpenFlow handler module or specific modules like Topology Discovery
    • From the launch or from the init of a class, perform core.openflow.addListenerByName(“EVENTNAME”, CALLBACK_FUNC, PRIORITY)
  2. Register object with the OpenFlow handler module or specific modules like Topology Discovery
    • From typically the init of a class, perform addListeners(self). Once this is added, the controller will look for a function with the name _handle_EVENTNAME(self, event). This method is automatically registered as an event handler.

2B. Parsing packets

POX provides several primitives to parse well-known packets. The ethernet packet received through a packet_in event can be extracted using this command and then the match for the flow rules can be created using the from_packet function:

packet = event.parsed
src_mac = packet.src
dst_mac = packet.dst
if packet.type == ethernet.IP_TYPE:
    ipv4_packet = event.parsed.find("ipv4")
    # Do more processing of the IPv4 packet
    src_ip = ipv4_packet.srcip
    src_ip = ipv4_packet.dstip

POX provides a simple way to construct the match headers from an incoming packet:

match = of.ofp_match.from_packet(packet)

2C. Sending messages to switch

Sending packet_out, flow_mod and other OpenFlow messages to program the switch is simple with POX. The steps are to construct the appropriate message object and populate it with the decision fields and the send to the switch using the connection object self.connection.send(). Here is an example from the hub implementation:

        msg = of.ofp_packet_out()              # Create packet out message
        msg.buffer_id = event.ofp.buffer_id    # Use the incoming packet as the data for the packet out
        msg.in_port = packet_in.in_port        # Set the in_port so that the switch knows 
        msg.match = of.ofp_match.from_packet(packet)

        # Add an action to send to the specified port
        action = of.ofp_action_output(port = of.OFPP_FLOOD)
        msg.actions.append(action)

        # Send message to switch
        self.connection.send(msg)

2D. Managing multiple applications

POX supports spawning multiple applications simultaneously. The call back functions for the events received by the controller are processed in the priority specified in the addListenerByName()

3. More Theory

Events generated from messages from switch Packets parsed by pox/lib

FlowRemoved, FeaturesReceived
ConnectionUp, FeaturesReceived
RawStatsReply, PortStatus
PacketIn, BarrierIn, SwitchDescReceived,
FlowStatsReceived, QueueStatsReceived,
AggregateFlowStatsReceived,
TableStatsReceived, PortStatsReceived

arp, dhcp, dns
eapol, eap
ethernet, icmp
igmp, ipv4
llc, lldp, mpls
rip, tcp, udp, vlan

Also see `grep class pox/pox/openflow/libopenflow_01.py` for a list of messages that the application can send to the switch.

4. More Example applications

  • L2 MAC Learning Switch: Convert pox/pox/misc/of_tutorial.py to L2 switch using the hints provided
  • Stateless load-balancer: pox/pox/forwarding/tutorial_stateless_lb.py implements a load-balancer where incoming HTTP requests are sent, on a round-robin basis, to a list of servers. In the code, we statically set the IP addresses of the servers. When traffic arrives for the virtual IP of the load-balancer, it selects the server in a round-robin basis and sends request to a different server after doing IP header rewriting in both directions. The mininet setup for this example is available here.

4 comments on “POX Controller Tutorial

  1. on November 21, 2014
    Sridhar Gude says:

    after emulating the topology in mininet i’m trying to bridge s1 to openflow10
    $ sudo ovs-vsctl set bridge s1 protocols=OpenFlow10
    by giving this command, but it shows unknown command.. help me out

  2. on March 11, 2015

    I saw the same thing.
    Please go openvswitch directory, do a make, sudo make install, and follow the instructions in the INSTALL.md to configure and detach server process.
    Then start the mininet. It worked for me.

  3. on May 12, 2015

    How can we find all the EVENTNAME used in core.openflow.addListenerByName(“EVENTNAME”, CALLBACK_FUNC, PRIORITY)

  4. on February 17, 2016

    Hello,
    Is it possbile to run and emulate several pox controllers in single large network, using mininet?
    Thanks in advance

Leave a Reply