Tuesday, August 21, 2012

DjangoFlow part two: Quick and simple UI

In the last episode...

My previous blog post showed how to integrate POX with Django, and didn't have too much colour. It took a bit of playing to get it to integrate for the first time, but now it's done, it is incredibly easy to do cool stuff with this software combo, and make new apps for easy OpenFlow access.

Part 2: An actual User Interface

I put in about 10 minutes extra just so I could give you all some lovely pictures, and here's what it all looks like:

This is all Django - I've just turned on the admin interface. Here we can add and remove flows from the database.

Here's a list of the two flows that I put in for testing

And here's the output from my OpenFlow switch.

It doesn't update in real time, but you can manipulate the database via the interweb and push those flows directly out to your switch. Making this update in real time is going to be another half-hour's work, tops.

What's new?

I changed the model a bit - now we can choose ports as well. Remember to delete your old database before syncing again or else it'll get upset

class Flow(models.Model):
internalip = models.CharField(max_length=200)
externalip = models.CharField(max_length=200)
internalport = models.IntegerField()
externalport = models.IntegerField()
idletime = models.IntegerField()
hardtime = models.IntegerField()
def __unicode__(self):
return "Internal: IP=" + self.internalip + " port=" + str(self.internalport) +", External: IP=" + self.externalip + " port=" + str(self.externalport)

The code in l2_learning.py got a bit of a birthday too:

class LearningSwitch (EventMixin):
  def __init__ (self, connection, transparent):
    # Switch we'll be adding L2 learning switch capabilities to
    self.connection = connection
    self.transparent = transparent

    # Our table
    self.macToPort = {}

    # We want to hear PacketIn messages, so we listen

    #log.debug("Initializing LearningSwitch, transparent=%s",
    #          str(self.transparent))
    # add new flows by default
    for flow in Flow.objects.all():
  def AddFlowFromModel(self, flow):
    # add outgoing flow
    msg = of.ofp_flow_mod()
    msg.match = of.ofp_match()
    msg.match.dl_type = ethernet.IP_TYPE
    msg.match.nw_src = str(flow.internalip)
    msg.match.nw_dst = str(flow.externalip)
    msg.match.in_port = flow.internalport
    msg.idle_timeout = flow.idletime
    msg.hard_timeout = flow.hardtime
    msg.actions.append(of.ofp_action_output(port = flow.externalport))
    # add incoming flow
    msg = of.ofp_flow_mod()
    msg.match = of.ofp_match()
    msg.match.dl_type = ethernet.IP_TYPE
    msg.match.nw_src = str(flow.externalip)
    msg.match.nw_dst = str(flow.internalip)
    msg.match.in_port = flow.externalport
    msg.idle_timeout = flow.idletime
    msg.hard_timeout = flow.hardtime
    msg.actions.append(of.ofp_action_output(port = flow.internalport))

After this, it was just a case of enabling the admin interface as per https://docs.djangoproject.com/en/dev/intro/tutorial02/ - this is our admin.py:

from django.contrib import admin
from flew.models import Flow


And for the sake of completeness, here's how to start them - the web interface is

python manage.py runserver

and the controller is

python pox.py forwarding.l2_learning

What next?

I don't know... I thought this would be much harder? Authentication will be fun, some way to dynamically check the database and update flows in real time (and remove them maybe) - this is left as an exercise for the reader though

1 comment:

  1. After going thru' the entire exercise and trying out the below step :

    python pox.py forwarding.l2_learning

    1. Got lot of indentation errors
    2. "self.hold_down_expired =_flood_delay ==0"
    NameError: name 'self' is not defined.
    not able to move forward with these error. Can you tell me what could be the problem