2 from flow_config_blaster import FlowConfigBlaster
9 __author__ = "Jan Medved"
10 __copyright__ = "Copyright(c) 2014, Cisco Systems, Inc."
11 __license__ = "New-style BSD"
12 __email__ = "jmedved@cisco.com"
15 class FlowConfigBlasterFLE(FlowConfigBlaster):
17 FlowConfigBlaster, Floodlight Edition; Uses the Floodlight Static Flow Entry Pusher REST API to inject flows.
20 'switch': "00:00:00:00:00:00:00:01",
25 "dst-ip": "10.0.0.1/32",
27 "actions": "output=flood"
30 def __init__(self, host, port, ncycles, nthreads, nnodes, nflows, startflow):
31 FlowConfigBlaster.__init__(self, host, port, ncycles, nthreads, nnodes, nflows, startflow, False, '')
33 # Create the service URL
34 self.url = 'http://' + self.host + ":" + self.port + '/wm/staticflowentrypusher/json'
36 def get_num_nodes(self, session):
38 Determines the number of nodes in the network. Overrides the get_num_nodes method in FlowConfigBlaster.
42 url = 'http://' + self.host + ":" + self.port + '/wm/core/controller/switches/json'
45 r = session.get(url, headers=self.getheaders, stream=False)
47 if r.status_code == 200:
49 nodes = len(json.loads(r.content))
55 def post_flows(self, session, node, flow_id, ipaddr):
57 Adds a flow. Overrides the add_flow method in FlowConfigBlaster.
64 self.flow['switch'] = "00:00:00:00:00:00:00:%s" % '{0:02x}'.format(node)
65 self.flow['name'] = 'TestFlow-%d' % flow_id
66 self.flow['cookie'] = str(flow_id)
67 self.flow['dst-ip'] = "%s/32" % str(netaddr.IPAddress(ipaddr))
69 flow_data = json.dumps(self.flow)
73 r = session.post(self.url, data=flow_data, headers=self.putheaders, stream=False)
76 def delete_flow(self, session, node, flow_id):
78 Deletes a flow. Overrides the delete_flow method in FlowConfigBlaster.
84 f = {'name': 'TestFlow-%d' % flow_id}
85 flow_data = json.dumps(f)
87 r = session.delete(self.url, data=flow_data, headers=self.getheaders)
91 if __name__ == "__main__":
93 parser = argparse.ArgumentParser(description='Flow programming performance test for Floodlight: First adds and '
94 'then deletes flows using the Static Flow Entry Pusher REST API.')
96 parser.add_argument('--host', default='127.0.0.1',
97 help='Host where the controller is running (default is 127.0.0.1)')
98 parser.add_argument('--port', default='8080',
99 help='Port on which the controller\'s RESTCONF is listening (default is 8080)')
100 parser.add_argument('--cycles', type=int, default=1,
101 help='Number of flow add/delete cycles; default 1. Both Flow Adds and Flow Deletes are '
102 'performed in cycles. <THREADS> worker threads are started in each cycle and the cycle '
103 'ends when all threads finish. Another cycle is started when the previous cycle finished.')
104 parser.add_argument('--threads', type=int, default=1,
105 help='Number of request worker threads to start in each cycle; default=1. '
106 'Each thread will add/delete <FLOWS> flows.')
107 parser.add_argument('--flows', type=int, default=10,
108 help='Number of flows that will be added/deleted by each worker thread in each cycle; '
110 parser.add_argument('--nodes', type=int, default=16,
111 help='Number of nodes if mininet is not connected; default=16. If mininet is connected, '
112 'flows will be evenly distributed (programmed) into connected nodes.')
113 parser.add_argument('--delay', type=int, default=0,
114 help='Time (in seconds) to wait between the add and delete cycles; default=0')
115 parser.add_argument('--no-delete', dest='delete', action='store_false',
116 help='Do not perform the delete cycle.')
117 parser.add_argument('--startflow', type=int, default=0,
118 help='The starting Flow ID; default=0')
120 in_args = parser.parse_args()
122 fct = FlowConfigBlasterFLE(in_args.host, in_args.port, in_args.cycles, in_args.threads, in_args.nodes,
123 in_args.flows, in_args.startflow)
125 # Run through <cycles>, where <threads> are started in each cycle and <flows> are added from each thread
128 print '\n*** Total flows added: %s' % fct.get_total_flows()
129 print ' HTTP[OK] results: %d\n' % fct.get_ok_flows()
131 if in_args.delay > 0:
132 print '*** Waiting for %d seconds before the delete cycle ***\n' % in_args.delay
133 time.sleep(in_args.delay)
135 # Run through <cycles>, where <threads> are started in each cycle and <flows> previously added in an add cycle are
136 # deleted in each thread