Skip to content
mscohen02 edited this page Jan 2, 2012 · 9 revisions

What is Static Flow Pusher?

Static Flow Pusher is a Floodlight module, exposed via REST API, that allows a user to manually insert flows into an OpenFlow network.

Proactive vs Reactive flow insertion

OpenFlow supports two methods of flow insertion: proactive and reactive. Reactive flow insertion occurs when a packet reaches an OpenFlow switch without a matching flow. The packet is sent to the controller, which evaluates it, adds the appropriate flows, and lets the switch continue its forwarding. Alternatively, flows can be inserted proactively by the controller in switches before packets arrive.

Floodlight supports both mechanisms of flow insertion. Static Flow Pusher is generally useful for proactive flow insertion.

How to use it?

Static Flow Pusher is accessible via a REST api so there are multiple ways to access it. For example, to insert a flow on switch 1 that takes packets from port 1 and outputs them on port 2, you can simply use a curl command. The second command will dump the flow so you can see it set.

curl -d '{"switch": "00:00:00:00:00:00:00:01", "name":"flow-mod-1", "cookie":"0", "priority":"32768", "ingressport":"1","active":"true", "actions":"output=2"}' http://:8080/wm/core/staticflowentrypusher/json

curl http://:8080/wm/core/switch/1/flow/json;

Using Static Flow Pusher in practice

Static Flow Pusher can we scripted using simple python code to control a network. As an example, set up a simple network in a mininet vm after starting the floodlight controller. The default topology is one switch (s1) and two hosts connected to it (h2 and h3).

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

The code below will insert a flow from h2 to h3 and one from h3 to h2.

	import httplib
	import json

	class StaticFlowPusher(object):

    	def __init__(self, server):
        	self.server = server

	    def get(self, data):
     	   ret = self.rest_call({}, 'GET')
        	return json.loads(ret[2])

    	def set(self, data):
        	ret = self.rest_call(data, 'POST')
        	return ret[0] == 200

    	def remove(self, objtype, data):
        	ret = self.rest_call(data, 'DELETE')
        	return ret[0] == 200

    	def rest_call(self, data, action):
        	path = '/wm/core/staticflowentrypusher/json'
        	headers = {
            	'Content-type': 'application/json',
            	'Accept': 'application/json',
            	}
        	body = json.dumps(data)
        	conn = httplib.HTTPConnection(self.server, 8080)
        	conn.request(action, path, body, headers)
        	response = conn.getresponse()
        	ret = (response.status, response.reason, response.read())
        	print ret
        	conn.close()
        	return ret

	pusher = StaticFlowPusher("insert_controller_ip")

	flow1 = { 
    	'switch':"00:00:00:00:00:00:00:01",
    	"name":"flow-mod-1",
    	"cookie":"0",
    	"priority":"32768",
    	"ingress-port":"1",
    	"active":"true",
    	"actions":"output=flood"
    	}

 	flow2 =	{
    	'switch':"00:00:00:00:00:00:00:01",
    	"name":"flow-mod-2",
    	"cookie":"0",
    	"priority":"32768",
    	"ingress-port":"2",
    	"active":"true",
    	"actions":"output=flood"
    	}

	pusher.set(flow1)
	pusher.set(flow2)

To test this out, run a pingtest in the mininet vm (note: you may want to disable the learning switch and other routing code in advance to make sure your static flows are taken).

mininet> h2 ping h3
Clone this wiki locally