Author Archives: Daniel Fredrick

POX webservice/JSON issue

While trying to enable the openflow.webservice.py and web.webcore.py modules from pox on RedHat 6.4 Linux… I kept receiving the following error…

[root@sdn-A4 Python-2.7.3]# python -u /opt/pox/pox.py --verbose forwarding.l2_pairs web.webcore openflow.webservice
POX 0.2.0 (carp) / Copyright 2011-2013 James McCauley, et al.
Traceback (most recent call last):
 File "/opt/pox/pox/boot.py", line 91, in do_import2
  __import__(name, level=0)
 File "/opt/pox/pox/openflow/webservice.py", line 50, in <module>
from pox.openflow.of_json import *
 File "/opt/pox/pox/openflow/of_json.py", line 111
 _unfix_map = {k:_unfix_null for k in of.ofp_match_data.keys()}
                                  ^
SyntaxError: invalid syntax
Could not import module: openflow.webservice

It was working fine on my MacOSx with Mavericks, but was getting the above error on Red Hat. After looking at the version of pox on both systems… I saw no difference. The only difference was Red Hat was running Python 2.6.6 and MacOSx was running 2.7.3.

The fix? Upgrade Python, BUT do not replace version 2.6.6 in the system path because YUM depends on it.

Run the following commands…

mkdir /opt/Python-273
cd /opt/Python-273
wget http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz
tar -xvzf Python-2.7.3.tgz
yum install gcc
cd Python-2.7.3
./configure
make altinstall
alias python273="/opt/Python-273/Python-2.7.3/python"

Now that python 2.7.3 is installed… just make sure you run POX with the new version alias command.

python273 pox.py

POX openflow NEC flow test Nov 30th, 2013

POX openflow NEC flow test

Lesson learned:

1. In order for the NEC switch to start see a new controller you must disable openflow on the specified vlan then reenable it after configuring the new openflow controller

Example…

VLAN 213
openflow-id 0 #disables openflow
no openflow controller 1
openflow controller 1 address 10.138.32.3 DATA
openflow-id 1 #enables openflow again on the vlan

2. to see what ports are openflow enabled run the “show openflow 1” command
PortList Status State Config Current Advertised Supported Peer
57 e 0x200 0x2 0x140 0x0 0x0 0x0
58 e 0x200 0x2 0x140 0x0 0x0 0x0
59 e 0x200 0x2 0x140 0x0 0x0 0x0
60 e 0x200 0x2 0x140 0x0 0x0 0x0

Then you can manually add one port.
NEC Tests

Test1 – Layer 2 flows – Add 10 flows per second, max of 1000 flows, statically adding to port 57
Results – The rate didn’t appear to be an issue, but there is a max of 750 flows L2

ERROR:openflow.of_01:[74-99-75-81-b3-00|213 1] OpenFlow Error:
[74-99-75-81-b3-00|213 1] Error: header:
[74-99-75-81-b3-00|213 1] Error: version: 1
[74-99-75-81-b3-00|213 1] Error: type: 1 (OFPT_ERROR)
[74-99-75-81-b3-00|213 1] Error: length: 76
[74-99-75-81-b3-00|213 1] Error: xid: 1005
[74-99-75-81-b3-00|213 1] Error: type: OFPET_FLOW_MOD_FAILED (3)
[74-99-75-81-b3-00|213 1] Error: code: OFPFMFC_ALL_TABLES_FULL (0)
[74-99-75-81-b3-00|213 1] Error: datalen: 64
[74-99-75-81-b3-00|213 1] Error: 0000: 01 0e 00 50 00 00 03 ed 00 3f ff f7 ff ff 00 00 …P…..?……
[74-99-75-81-b3-00|213 1] Error: 0010: 00 00 00 00 01 23 45 36 a0 de 00 00 00 00 00 00 …..#E6……..
[74-99-75-81-b3-00|213 1] Error: 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
[74-99-75-81-b3-00|213 1] Error: 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 …………….

Test2 – Layer 2 flows – Add 10 flows per second, max of 1000 flows, statically adding from range for ports 57 to 60
Results – same as test1 – The rate didn’t appear to be an issue, but there is a max of 750 flows L2

ERROR:openflow.of_01:[74-99-75-81-b3-00|213 1] OpenFlow Error:
[74-99-75-81-b3-00|213 1] Error: header:
[74-99-75-81-b3-00|213 1] Error: version: 1
[74-99-75-81-b3-00|213 1] Error: type: 1 (OFPT_ERROR)
[74-99-75-81-b3-00|213 1] Error: length: 76
[74-99-75-81-b3-00|213 1] Error: xid: 974
[74-99-75-81-b3-00|213 1] Error: type: OFPET_FLOW_MOD_FAILED (3)
[74-99-75-81-b3-00|213 1] Error: code: OFPFMFC_ALL_TABLES_FULL (0)
[74-99-75-81-b3-00|213 1] Error: datalen: 64
[74-99-75-81-b3-00|213 1] Error: 0000: 01 0e 00 50 00 00 03 ce 00 3f ff f7 ff ff 00 00 …P…..?……
[74-99-75-81-b3-00|213 1] Error: 0010: 00 00 00 00 01 23 45 50 21 c7 00 00 00 00 00 00 …..#EP!…….
[74-99-75-81-b3-00|213 1] Error: 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
[74-99-75-81-b3-00|213 1] Error: 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 …………….
Test3 – Layer 2 flows – Add 50 flows per second, max of 749 flows, statically adding from range for ports 57 to 60
Results – The rate didn’t appear to be an issue, this time there were no errors

Apparently the NEC does state that it only supports 750 12 tuple flows, but supports over 80K layer2 flows.

Mininet, Pox, and Generating Flows per Second

Development for testing Layer2 flows per second was successful! The goals were the following:

  • get a controller to generate X number of flows (currently L2 flows) to see how many flows a switch could handle
  • 2nd, get a controller to generate X number of flows per second

Both were successful thanks to mininet. http://mininet.org/

Mininet creates virtual hosts, controllers, and switches in an instant. This was developed by people that wanted create a tool to help with openflow/SDN development.

It was pretty easy to get setup by just following their directions on their website. Once I downloaded the mininet VM, installed it… it was up and running.

The entire testing setup consisted:

  • a Mininet VM, which had an openflow switch and two hosts
  • a POX openflow controller on my local machine

All I had to do to get mininet to connect to the controller on my local machine was to point it to my actual network interface that go me outside of my machine on to our production network.

sudo mn --controller=remote,ip=10.180.0.207,port=6633

I tried from mininet to have it use my loopback address and the nat’d gateway address, but neither worked until I used my local computers prodcuction network NIC.

Once I did that, mininet connected to my machines POX controller…

INFO:openflow.of_01:[00-00-00-00-00-01 1] connected
DEBUG:forwarding.ryan_l2:Switch 00-00-00-00-00-01 has come up.

Here is the code that is used for Flows per second testing…

http://sites.duke.edu/dukesdn/2013/11/06/pox-l2-flow-generator-code/ 

The default for the code is 100 flows total, 10 per second. This can be changed by edit a couple of the numbers commented in the code.

In mininet, in order to see the flows you type the following…

mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=31.849s, table=0, n_packets=0, n_bytes=0, idle_age=31, dl_dst=01:23:45:d6:52:a3 actions=output:2
 cookie=0x0, duration=34.973s, table=0, n_packets=0, n_bytes=0, idle_age=34, dl_dst=01:23:45:98:8d:f4 actions=output:2
 cookie=0x0, duration=33.935s, table=0, n_packets=0, n_bytes=0, idle_age=33, dl_dst=01:23:45:2f:8d:55 actions=output:4
 cookie=0x0, duration=36.006s, table=0, n_packets=0, n_bytes=0, idle_age=36, dl_dst=01:23:45:d5:1a:2e actions=output:4
 cookie=0x0, duration=32.899s, table=0, n_packets=0, n_bytes=0, idle_age=32, dl_dst=01:23:45:db:89:8d actions=output:4

Since each line is a flow (except the first line) we can just use the wc (word count) command to see the number…

The output will be:

# of lines, # of words, and # of characters

mininet> dpctl dump-flows | wc
*** s1 ------------------------------------------------------------------------
 101 803 12107

So we have 101 lines, or 100 flows.

POX L2 Flow Generator Code module

from pox.core import core

from pox.lib.util import dpid_to_str

import pox.openflow.libopenflow_01 as of

import pox.lib.packet as pkt

from pox.lib.addresses import IPAddr, EthAddr

from random import randrange

from pox.lib.recoco import Timer

 

 

log = core.getLogger()

flows = 0 #flows counts the number of flows we want there in the end it’s defined as a global VAR

 

class testFlows (object):

def __init__ (self):

core.openflow.addListeners(self)

 

def _handle_ConnectionUp (self, event): # as soon as a switch starts up we’re going to start writing random flows to it

log.debug(“Switch %s has come up.”, dpid_to_str(event.dpid))

def pushflows():

global flows

if flows < 100: #Change this number to the maximum number of flows you want installed

print “starting timer in 1secs” #you can take or leave this one… just a test

for x in range(0, 10): # set the number of rules that you want per second to the second number in the range

macaddress = ’01:23:45:’+hex(randrange(16,255))[2:]+’:’+hex(randrange(16,255))[2:]+’:’+hex(randrange(16,255))[2:] # create a random mac. random number 16-255 and then convert to hex

port = randrange(2,5) # assign to random port in a range

msg = of.ofp_flow_mod()

#msg.priority = 32768 # set priority

msg.match.dl_dst = EthAddr(macaddress) # match our random mac address to a destination port

msg.actions.append(of.ofp_action_output(port = port)) # set destination port

event.connection.send(msg) # send our flow out

log.debug(“installing flow for destination of %s” % (macaddress)) # log it

flows = flows + 1

Timer(1, pushflows, recurring = True)  #timer is set to 1 second

def launch ():

core.registerNew(testFlows) # startup and run class