Tuesday, October 22, 2013

How to write a simple own POX component

POX is invoked by running pox.py and has a couple of optional command line arguments than can be used at the start of the command line

Eg : ./pox.py log.level --DEBUG samples.pretty_log openflow.keepalive --interval=15 forwarding.l2_pairs

POX functionality is provided by components(python modules) which are specified on the command line. In the above example forwarding.l2_pairs is the functionality of the openflow controller. We can invoke more then one component, especially when one component is dependent on the other

There are some of the components whcih come along with pox, but the main focus is to write our own component. Write your modules and place them where pox can find it(eg. PYTHONPATH) or in the "ext" directory ~/pox/ext/

POX has a core object to which components will register on the core object and other components  will query the core object.The POX OpenFlow component by default registers an instance of OpenFlowNexus as core.openflow, and other applications can then access a lot of the OpenFlow functionality from there.

#This component just monitors the connection up and down events
#when any switch connects and disconnections"

from pox.core import core
from pox.lib.util import dpid_to_str

log = core.getLogger()


core.openflow.addListeners():
                  Registers MyComponent class to listen for multiple events defined in openflow object. Which means for any method in openflow defined as _handle_EventName is replaced by the same method defined under MyComponent class and set as the listner.

_handle_ConnectionUp():
                 Event raised when the connection to an OpenFlow switch has been established

_handle_ConnectionDown():
                 Event raised when the connection to an OpenFlow switch has been lost.

class MyComponent(object):
    def __init__ (self):
        core.openflow.addListeners(self)
        log.debug("Hi starting the controller")
    def _handle_ConnectionUp (self, event):
        log.debug("Switch %s has come up", dpid_to_str(event.dpid))
    def _handle_ConnectionDown(self, event):
        log.debug("Swtich %s is down", dpid_to_str(event.dpid))

Each pox component should contain the launch() function via which pox initializes the component. Mainly used to pass the command line parameters for the component.
core.registerNew() registers a new component with the core object

def launch():
    core.registerNew(MyComponent)

Build your network topology in Mininet

In this post i will discuss about building a network topology without using default topology objects which come with Mininet.

Import all the modules as below.


#!/usr/bin/python
from mininet.net import Mininet
from mininet.node import Controller
from mininet.node import RemoteController
from mininet.cli import CLI
from mininet.link import TCLink
from mininet.log import setLogLevel, info 



Define a function myNet() which creates all the nodes and links them. The Mininet class returns a empty network object to which we add hosts, switches and controller. RemoteController class returns a controller object which runs outside Mininet. Assign the controller into our net object.

def myNet():

    "Create an empty network"
    net = Mininet( link=TCLink )

    "Create a RemoteController and add to network"
    info( '*** Adding RemoteController\n' )
    c = RemoteController('c', ip='127.0.0.1', port=6666)
    net.controllers = [ c ]


net.addHost() creates host nodes and adds to the network. net.addSwitch adds the openflow switch to the network
 
    "Create hosts and add to network"
    info( '*** Adding hosts\n' )
    h1 = net.addHost( 'h1', ip='10.0.0.1' )
    h2 = net.addHost( 'h2', ip='10.0.0.2' )
    h3 = net.addHost( 'h3', ip='10.0.0.3' )

    "Create switch and to network"
    info( '*** Adding switch\n' )
    s3 = net.addSwitch( 's3' )
    s4 = net.addSwitch( 's4' )

Connect the nodes by adding links between them as below. Then net.build() call will build the topology and net.start() will start all the nodes. CLI(net) will run the cli mode awaiting for user inputs.

    info( '*** Creating links\n' )
    h1.linkTo( s3 )
    h2.linkTo( s3 )
    s3.linkTo( s4 )
    h3.linkTo( s4 )

    info( '*** Starting network\n')
    net.build()
    net.start()

    info( '*** Running CLI\n' )
    CLI( net )

    info( '*** Stopping network' )
    net.stop()

if __name__ == '__main__':
    setLogLevel( 'info' )
    myNet()

Results :

*** Adding RemoteController
Unable to contact the remote controller at 127.0.0.1:6666
*** Adding hosts
*** Adding switch
*** Creating links
*** Starting network
*** Configuring hosts
h1 h2 h3
*** Starting controller
*** Starting 2 switches
s3 s4
*** Running CLI
*** Starting CLI:
mininet> dump
<RemoteController c: 127.0.0.1:6666 pid=5371>
<OVSSwitch s3: lo:127.0.0.1,s3-eth1:None,s3-eth2:None,s3-eth3:None pid=5383>
<OVSSwitch s4: lo:127.0.0.1,s4-eth1:None,s4-eth2:None pid=5388>
<Host h1: h1-eth0:10.0.0.1 pid=5378>
<Host h2: h2-eth0:10.0.0.2 pid=5379>
<Host h3: h3-eth0:10.0.0.3 pid=5380>
mininet>

Monday, October 14, 2013

Understanding Mininet Network Topology


Mininet has a set of default network topologies which can be chosen on the command line.

The below example creates a network topology with single openflow switch and 3 hosts connected to it.



Another example where mininet creates a linear network topology with each switch connected to one host and the switch adjacent to it.


In the above example mn is a launch script which executes the below python code.


The main class in the code snippet is Mininet which spawns hosts, switches and controller and add links between them. Mininet class takes topo parameter which describes the network topology.

The Topo class is the abstract class used to build custom topologies. One of the derived classes is LinearTopo which creates linear topology of k switches, with n hosts per switch.

net.start will start all the switches, controller and hosts. Next net.cli initiates a simple command line interface to talk to the nodes.

The other default topologies are SingleSwitchReversedTopo, SingleSwitchTopo  and TreeTopo

Saturday, October 5, 2013

Getting Started With MININET & POX

In this article i will discuss about a virtual network simulator MININET and openflow controller POX

Mininet  

It is virtual network environment that can run a single PC. We can use this to write SDN/Openflow applications and experiment by creating our own network topology.

Mininet creates a realistic virtual network, running real kernel, switch and application code, on a single machine. It allows to build custom topology constituting hosts, openflow switch, controller and links between them.   

In a nut shell when mininet process(mn) kick starts it forks a process for each host and assign them to separate network namespace. Then create virtual ethernet pairs and assign one for each namespace. Next it creates a openflow switch which connects to each host. Finally creates a openflow controller which installs flow table into switch using openflow protocol. 

POX Controller

POX is a lightweight OpenFlow controller that is written completely in Python that is targeted for developers to spin up their own controllers. You can write your Openflow application/controller which connects to the openflow switch created by Mininet. 

Below steps will launch a simple network topology which comes with Mininet. The mininet itself starts a controller but here we will launch a POX controller in another terminal and the network connects this remote controller.  

1) VM : 
       Create a virtual machine running any linux version. I am using Ubuntu 12.04.2

2) MININET :
        Install mininet and clone mininet to current directory

Note: if you are upgrading from an older version of Mininet, make sure you remove the old OVS from `/usr/local`:
#sudo rm /usr/local/sbin/ovs*
#sudo rm /usr/local/bin/ovs*
               


3) POX :

4) Kill all the controller and clear mininet 
5) Starting remote controller POX  
     
6) Launch Mininet to create a network in  a new terminal :
 7) Ping TEST :
     
Results :

SDN & OpenFlow Overview

SDN Overview 

Traditionally, every switch and router in a network has its own control and data plane, which means all routing decisions are made on the switch itself.

The idea behind SDNs is to abstract that control plane from the switches and routers and run it on a central controller. That leaves the switches with just the data plane that actually ships packets in and out; the decisions on where the packets will go is based on instructions coming from that central controller. 

The central controller helps in automatically adjusting the network architecture to deliver the fastest and most efficient data paths at the right time.

OpenFlow Overview 

OpenFlow is a new protocol implemented on an Ethernet switch that allows its forwarding plane to be managed by an external OpenFlow controller. 

OpenFlow exposes a switch’s forwarding plane as a set of Ethernet ports, flow tables, counters, queues, and capabilities. A flow table entry consists of a set of  L2/L3/L4 match conditions, which may be variously wildcarded or masked. Associated with each flow table rule is a set of one or more actions, including Forwarding (to a physical or virtual port, to the controller, or flooded), Enqueueing, and Packet Modification.

By default, packets arriving at an OpenFlow-managed port which do not match a flow entry are encapsulated and sent to the controller, which as a result may send a flow installation command to the switch and return the packet back to the switch for forwarding.