blob: ec847441b8a754a4581a0058eff2498061c9e4f3 [file] [log] [blame]
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -08001#! /usr/bin/env python
2# -*- Mode: python; py-indent-offset: 4; tab-width: 8; indent-tabs-mode: t; -*-
3
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -07004import copy
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -08005import pprint
6import os
7import sys
8import subprocess
9import json
10import argparse
11import io
12import time
13
14from flask import Flask, json, Response, render_template, make_response, request
15
16#
17# curl http://127.0.0.1:8080/wm/topology/route/00:00:00:00:00:00:0a:01/1/00:00:00:00:00:00:0a:04/1/json
18#
19
20## Global Var ##
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -070021ControllerIP = "127.0.0.1"
22ControllerPort = 8080
23MonitoringEnabled = False
Pavlin Radoslavovb549f082013-03-29 04:28:27 -070024MonitoringByOnos = False
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -070025ReadFromFile = ""
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080026
27DEBUG=0
28pp = pprint.PrettyPrinter(indent=4)
29
30app = Flask(__name__)
31
32## Worker Functions ##
33def log_error(txt):
34 print '%s' % (txt)
35
36def debug(txt):
37 if DEBUG:
38 print '%s' % (txt)
39
40# @app.route("/wm/topology/route/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
41#
42# Sample output:
43# {'dstPort': {'port': {'value': 0}, 'dpid': {'value': '00:00:00:00:00:00:00:02'}}, 'srcPort': {'port': {'value': 0}, 'dpid': {'value': '00:00:00:00:00:00:00:01'}}, 'flowEntries': [{'outPort': {'value': 1}, 'flowEntryErrorState': None, 'flowEntryMatch': None, 'flowEntryActions': None, 'inPort': {'value': 0}, 'flowEntryId': None, 'flowEntryUserState': 'FE_USER_UNKNOWN', 'dpid': {'value': '00:00:00:00:00:00:00:01'}, 'flowEntrySwitchState': 'FE_SWITCH_UNKNOWN'}, {'outPort': {'value': 0}, 'flowEntryErrorState': None, 'flowEntryMatch': None, 'flowEntryActions': None, 'inPort': {'value': 9}, 'flowEntryId': None, 'flowEntryUserState': 'FE_USER_UNKNOWN', 'dpid': {'value': '00:00:00:00:00:00:00:02'}, 'flowEntrySwitchState': 'FE_SWITCH_UNKNOWN'}]}
44#
45def shortest_path(v1, p1, v2, p2):
46 try:
47 command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (ControllerIP, ControllerPort, v1, p1, v2, p2)
48 debug("shortest_path %s" % command)
Pavlin Radoslavoveb2d5a22013-03-14 19:58:14 -070049 parsedResult = []
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080050
51 result = os.popen(command).read()
52 debug("result %s" % result)
53 if len(result) == 0:
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -070054 log_error("No Path found from %s/%s to %s/%s" % (v1, p1, v2, p2))
55 else:
56 parsedResult = json.loads(result)
57 debug("parsed %s" % parsedResult)
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080058
59 except:
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -070060 log_error("Controller IF has issue: No Path found from %s/%s to %s/%s" % (v1, p1, v2, p2))
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080061
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -070062 return parsedResult
63
64def print_data_path(data_path):
65 if len(data_path) == 0:
66 return
67
68 srcSwitch = data_path['srcPort']['dpid']['value'];
69 srcPort = data_path['srcPort']['port']['value'];
70 dstSwitch = data_path['dstPort']['dpid']['value'];
71 dstPort = data_path['dstPort']['port']['value'];
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080072
73 print "DataPath: (src = %s/%s dst = %s/%s)" % (srcSwitch, srcPort, dstSwitch, dstPort);
74
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -070075 for f in data_path['flowEntries']:
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080076 inPort = f['inPort']['value'];
77 outPort = f['outPort']['value'];
78 dpid = f['dpid']['value']
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -070079 print " FlowEntry: (%s, %s, %s)" % (inPort, dpid, outPort)
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080080
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080081def add_flow_path(flow_path):
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -070082 flow_path_json = json.dumps(flow_path)
83
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080084 try:
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -070085 command = "curl -s -H 'Content-Type: application/json' -d '%s' http://%s:%s/wm/flow/add/json" % (flow_path_json, ControllerIP, ControllerPort)
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080086 debug("add_flow_path %s" % command)
87 result = os.popen(command).read()
88 debug("result %s" % result)
89 # parsedResult = json.loads(result)
90 # debug("parsed %s" % parsedResult)
91 except:
92 log_error("Controller IF has issue")
93 exit(1)
94
Pavlin Radoslavovb549f082013-03-29 04:28:27 -070095def add_shortest_path_flow(flow_path):
96 flow_path_json = json.dumps(flow_path)
97
98 try:
99 command = "curl -s -H 'Content-Type: application/json' -d '%s' http://%s:%s/wm/flow/add-shortest-path/json" % (flow_path_json, ControllerIP, ControllerPort)
100 debug("add_shortest_path_flow %s" % command)
101 result = os.popen(command).read()
102 debug("result %s" % result)
103 # parsedResult = json.loads(result)
104 # debug("parsed %s" % parsedResult)
105 except:
106 log_error("Controller IF has issue")
107 exit(1)
108
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700109def delete_flow_path(flow_id):
110 command = "curl -s \"http://%s:%s/wm/flow/delete/%s/json\"" % (ControllerIP, ControllerPort, flow_id)
111 debug("delete_flow_path %s" % command)
112 result = os.popen(command).read()
113 debug("result %s" % result)
114 # parsedResult = json.loads(result)
115 # debug("parsed %s" % parsedResult)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700116
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700117def extract_flow_args(my_args):
118 # Check the arguments
119 if len(my_args) < 6:
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -0800120 log_error(usage_msg)
121 exit(1)
122
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700123 # Extract the mandatory arguments
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700124 my_flow_id = my_args[0]
125 my_installer_id = my_args[1]
126 my_src_dpid = my_args[2]
127 my_src_port = my_args[3]
128 my_dst_dpid = my_args[4]
129 my_dst_port = my_args[5]
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700130
131 #
132 # Extract the "match" and "action" arguments
133 #
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700134 match = {}
135 matchInPortEnabled = True # NOTE: Enabled by default
136 actions = []
137 actionOutputEnabled = True # NOTE: Enabled by default
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700138 idx = 6
139 while idx < len(my_args):
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700140 action = {}
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700141 arg1 = my_args[idx]
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700142 idx = idx + 1
143 # Extract the second argument
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700144 if idx >= len(my_args):
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700145 error_arg = "ERROR: Missing or invalid '" + arg1 + "' argument"
146 log_error(error_arg)
147 log_error(usage_msg)
148 exit(1)
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700149 arg2 = my_args[idx]
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700150 idx = idx + 1
151
152 if arg1 == "matchInPort":
153 # Just mark whether inPort matching is enabled
154 matchInPortEnabled = arg2 in ['True', 'true']
155 # inPort = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700156 # inPort['value'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700157 # match['inPort'] = inPort
158 ## match['matchInPort'] = True
159 elif arg1 == "matchSrcMac":
160 srcMac = {}
161 srcMac['value'] = arg2
162 match['srcMac'] = srcMac
163 # match['matchSrcMac'] = True
164 elif arg1 == "matchDstMac":
165 dstMac = {}
166 dstMac['value'] = arg2
167 match['dstMac'] = dstMac
168 # match['matchDstMac'] = True
Pavlin Radoslavovad3a1e62013-07-09 13:30:16 -0700169 elif arg1 == "matchEthernetFrameType":
170 match['ethernetFrameType'] = int(arg2, 0)
171 # match['matchEthernetFrameType'] = True
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700172 elif arg1 == "matchVlanId":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700173 match['vlanId'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700174 # match['matchVlanId'] = True
175 elif arg1 == "matchVlanPriority":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700176 match['vlanPriority'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700177 # match['matchVlanPriority'] = True
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700178 elif arg1 == "matchSrcIPv4Net":
179 srcIPv4Net = {}
180 srcIPv4Net['value'] = arg2
181 match['srcIPv4Net'] = srcIPv4Net
182 # match['matchSrcIPv4Net'] = True
183 elif arg1 == "matchDstIPv4Net":
184 dstIPv4Net = {}
185 dstIPv4Net['value'] = arg2
186 match['dstIPv4Net'] = dstIPv4Net
187 # match['matchDstIPv4Net'] = True
Pavlin Radoslavovad3a1e62013-07-09 13:30:16 -0700188 elif arg1 == "matchIpProto":
189 match['ipProto'] = int(arg2, 0)
190 # match['matchIpProto'] = True
191 elif arg1 == "matchIpToS":
192 match['ipToS'] = int(arg2, 0)
193 # match['matchIpToS'] = True
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700194 elif arg1 == "matchSrcTcpUdpPort":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700195 match['srcTcpUdpPort'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700196 # match['matchSrcTcpUdpPort'] = True
197 elif arg1 == "matchDstTcpUdpPort":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700198 match['dstTcpUdpPort'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700199 # match['matchDstTcpUdpPort'] = True
200 elif arg1 == "actionOutput":
201 # Just mark whether ACTION_OUTPUT action is enabled
202 actionOutputEnabled = arg2 in ['True', 'true']
203 #
204 # TODO: Complete the implementation for ACTION_OUTPUT
205 # actionOutput = {}
206 # outPort = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700207 # outPort['value'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700208 # actionOutput['port'] = outPort
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700209 # actionOutput['maxLen'] = int(arg3, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700210 # action['actionOutput'] = actionOutput
211 # # action['actionType'] = 'ACTION_OUTPUT'
212 # actions.append(action)
213 #
214 elif arg1 == "actionSetVlanId":
215 vlanId = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700216 vlanId['vlanId'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700217 action['actionSetVlanId'] = vlanId
218 # action['actionType'] = 'ACTION_SET_VLAN_VID'
219 actions.append(copy.deepcopy(action))
220 elif arg1 == "actionSetVlanPriority":
221 vlanPriority = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700222 vlanPriority['vlanPriority'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700223 action['actionSetVlanPriority'] = vlanPriority
224 # action['actionType'] = 'ACTION_SET_VLAN_PCP'
225 actions.append(copy.deepcopy(action))
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700226 elif arg1 == "actionStripVlan":
227 stripVlan = {}
228 stripVlan['stripVlan'] = arg2 in ['True', 'true']
229 action['actionStripVlan'] = stripVlan
230 # action['actionType'] = 'ACTION_STRIP_VLAN'
231 actions.append(copy.deepcopy(action))
232 elif arg1 == "actionSetEthernetSrcAddr":
233 ethernetSrcAddr = {}
234 ethernetSrcAddr['value'] = arg2
235 setEthernetSrcAddr = {}
236 setEthernetSrcAddr['addr'] = ethernetSrcAddr
237 action['actionSetEthernetSrcAddr'] = setEthernetSrcAddr
238 # action['actionType'] = 'ACTION_SET_DL_SRC'
239 actions.append(copy.deepcopy(action))
240 elif arg1 == "actionSetEthernetDstAddr":
241 ethernetDstAddr = {}
242 ethernetDstAddr['value'] = arg2
243 setEthernetDstAddr = {}
244 setEthernetDstAddr['addr'] = ethernetDstAddr
245 action['actionSetEthernetDstAddr'] = setEthernetDstAddr
246 # action['actionType'] = 'ACTION_SET_DL_DST'
247 actions.append(copy.deepcopy(action))
248 elif arg1 == "actionSetIPv4SrcAddr":
249 IPv4SrcAddr = {}
250 IPv4SrcAddr['value'] = arg2
251 setIPv4SrcAddr = {}
252 setIPv4SrcAddr['addr'] = IPv4SrcAddr
253 action['actionSetIPv4SrcAddr'] = setIPv4SrcAddr
254 # action['actionType'] = 'ACTION_SET_NW_SRC'
255 actions.append(copy.deepcopy(action))
256 elif arg1 == "actionSetIPv4DstAddr":
257 IPv4DstAddr = {}
258 IPv4DstAddr['value'] = arg2
259 setIPv4DstAddr = {}
260 setIPv4DstAddr['addr'] = IPv4DstAddr
261 action['actionSetIPv4DstAddr'] = setIPv4DstAddr
262 # action['actionType'] = 'ACTION_SET_NW_DST'
263 actions.append(copy.deepcopy(action))
Pavlin Radoslavovad3a1e62013-07-09 13:30:16 -0700264 elif arg1 == "actionSetIpToS":
265 ipToS = {}
266 ipToS['ipToS'] = int(arg2, 0)
267 action['actionSetIpToS'] = ipToS
268 # action['actionType'] = 'ACTION_SET_NW_TOS'
269 actions.append(copy.deepcopy(action))
270 elif arg1 == "actionSetTcpUdpSrcPort":
271 tcpUdpSrcPort = {}
272 tcpUdpSrcPort['port'] = int(arg2, 0)
273 action['actionSetTcpUdpSrcPort'] = tcpUdpSrcPort
274 # action['actionType'] = 'ACTION_SET_TP_SRC'
275 actions.append(copy.deepcopy(action))
276 elif arg1 == "actionSetTcpUdpDstPort":
277 tcpUdpDstPort = {}
278 tcpUdpDstPort['port'] = int(arg2, 0)
279 action['actionSetTcpUdpDstPort'] = tcpUdpDstPort
280 # action['actionType'] = 'ACTION_SET_TP_DST'
281 actions.append(copy.deepcopy(action))
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700282 elif arg1 == "actionEnqueue":
283 # TODO: Implement ACTION_ENQUEUE
284 actionEnqueue = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700285 # actionEnqueue['queueId'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700286 # enqueuePort = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700287 # enqueuePort['value'] = int(arg3, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700288 # actionEnqueue['port'] = enqueuePort
289 # action['actionEnqueue'] = actionEnqueue
290 # # action['actionType'] = 'ACTION_ENQUEUE'
291 # actions.append(copy.deepcopy(action))
292 #
293 else:
294 log_error("ERROR: Unknown argument '%s'" % (arg1))
295 log_error(usage_msg)
296 exit(1)
297
Pavlin Radoslavov8a002d92013-03-13 20:20:43 -0700298 return {
299 'my_flow_id' : my_flow_id,
300 'my_installer_id' : my_installer_id,
301 'my_src_dpid' : my_src_dpid,
302 'my_src_port' : my_src_port,
303 'my_dst_dpid' : my_dst_dpid,
304 'my_dst_port' : my_dst_port,
305 'match' : match,
306 'matchInPortEnabled' : matchInPortEnabled,
307 'actions' : actions,
308 'actionOutputEnabled' : actionOutputEnabled
309 }
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700310
311def compute_data_path(parsed_args):
312
313 my_src_dpid = parsed_args['my_src_dpid']
314 my_src_port = parsed_args['my_src_port']
315 my_dst_dpid = parsed_args['my_dst_dpid']
316 my_dst_port = parsed_args['my_dst_port']
317
318 # Compute the shortest path
319 data_path = shortest_path(my_src_dpid, my_src_port, my_dst_dpid, my_dst_port)
320
321 debug("Data Path: %s" % data_path)
322 return data_path
323
324def compute_flow_path(parsed_args, data_path):
325
326 my_flow_id = parsed_args['my_flow_id']
327 my_installer_id = parsed_args['my_installer_id']
328 match = parsed_args['match']
329 matchInPortEnabled = parsed_args['matchInPortEnabled']
330 actions = parsed_args['actions']
331 actionOutputEnabled = parsed_args['actionOutputEnabled']
332 my_data_path = copy.deepcopy(data_path)
333
334 flow_id = {}
335 flow_id['value'] = my_flow_id
336 installer_id = {}
337 installer_id['value'] = my_installer_id
338
339 flow_path = {}
340 flow_path['flowId'] = flow_id
341 flow_path['installerId'] = installer_id
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700342
Pavlin Radoslavov67b3ef32013-04-03 02:44:48 -0700343 if (len(match) > 0):
344 flow_path['flowEntryMatch'] = copy.deepcopy(match)
345
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700346 #
347 # Add the match conditions to each flow entry
348 #
349 if (len(match) > 0) or matchInPortEnabled:
350 idx = 0
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700351 while idx < len(my_data_path['flowEntries']):
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700352 if matchInPortEnabled:
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700353 inPort = my_data_path['flowEntries'][idx]['inPort']
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700354 match['inPort'] = copy.deepcopy(inPort)
355 # match['matchInPort'] = True
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700356 my_data_path['flowEntries'][idx]['flowEntryMatch'] = copy.deepcopy(match)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700357 idx = idx + 1
358
359 #
360 # Set the actions for each flow entry
361 # NOTE: The actions from the command line are aplied
362 # ONLY to the first flow entry.
363 #
364 # If ACTION_OUTPUT action is enabled, then apply it
365 # to each flow entry.
366 #
367 if (len(actions) > 0) or actionOutputEnabled:
368 idx = 0
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700369 while idx < len(my_data_path['flowEntries']):
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700370 if idx > 0:
371 actions = [] # Reset the actions for all but first entry
372 action = {}
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700373 outPort = my_data_path['flowEntries'][idx]['outPort']
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700374 actionOutput = {}
375 actionOutput['port'] = copy.deepcopy(outPort)
376 # actionOutput['maxLen'] = 0 # TODO: not used for now
377 action['actionOutput'] = copy.deepcopy(actionOutput)
378 # action['actionType'] = 'ACTION_OUTPUT'
379 actions.append(copy.deepcopy(action))
380
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700381 my_data_path['flowEntries'][idx]['flowEntryActions'] = copy.deepcopy(actions)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700382 idx = idx + 1
383
384
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700385 flow_path['dataPath'] = my_data_path
386 debug("Flow Path: %s" % flow_path)
Pavlin Radoslavovb549f082013-03-29 04:28:27 -0700387 return flow_path
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -0800388
Pavlin Radoslavovb549f082013-03-29 04:28:27 -0700389def exec_monitoring_by_onos(parsed_args):
390 idx = 0
391 while idx < len(parsed_args):
392 data_path = {}
393 src_dpid = {}
394 src_port = {}
395 dst_dpid = {}
396 dst_port = {}
397 src_switch_port = {}
398 dst_switch_port = {}
Pavlin Radoslavovb549f082013-03-29 04:28:27 -0700399 flow_entries = []
400
401 src_dpid['value'] = parsed_args[idx]['my_src_dpid']
402 src_port['value'] = parsed_args[idx]['my_src_port']
403 dst_dpid['value'] = parsed_args[idx]['my_dst_dpid']
404 dst_port['value'] = parsed_args[idx]['my_dst_port']
405 src_switch_port['dpid'] = src_dpid
406 src_switch_port['port'] = src_port
407 dst_switch_port['dpid'] = dst_dpid
408 dst_switch_port['port'] = dst_port
Pavlin Radoslavovb549f082013-03-29 04:28:27 -0700409
410 data_path['srcPort'] = copy.deepcopy(src_switch_port)
411 data_path['dstPort'] = copy.deepcopy(dst_switch_port)
412 data_path['flowEntries'] = copy.deepcopy(flow_entries)
413
414 #
415 # XXX: Explicitly disable the InPort matching, and
416 # the Output action, because they get in the way
417 # during the compute_flow_path() processing.
418 #
419 parsed_args[idx]['matchInPortEnabled'] = False
420 parsed_args[idx]['actionOutputEnabled'] = False
421
422 flow_path = compute_flow_path(parsed_args[idx], data_path)
423 add_shortest_path_flow(flow_path)
424
425 idx = idx + 1
426
427
428def exec_processing_by_script(parsed_args):
429 #
430 # Initialization
431 #
432 last_data_paths = []
433 idx = 0
434 while idx < len(parsed_args):
435 last_data_path = []
436 last_data_paths.append(copy.deepcopy(last_data_path))
437 idx = idx + 1
438
439 #
440 # Do the work: install and/or periodically monitor each flow
441 #
442 while True:
443 idx = 0
444 while idx < len(parsed_args):
445 last_data_path = last_data_paths[idx]
446 my_flow_id = parsed_args[idx]['my_flow_id']
447 data_path = compute_data_path(parsed_args[idx])
448 if data_path != last_data_path:
449 print_data_path(data_path)
450 if len(last_data_path) > 0:
451 delete_flow_path(my_flow_id)
452 if len(data_path) > 0:
453 flow_path = compute_flow_path(parsed_args[idx], data_path)
454 add_flow_path(flow_path)
455 last_data_paths[idx] = copy.deepcopy(data_path)
456 idx = idx + 1
457
458 if MonitoringEnabled != True:
459 break
460 time.sleep(1)
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -0800461
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700462
463if __name__ == "__main__":
464 usage_msg = "Usage: %s [Flags] <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port> [Match Conditions] [Actions]\n" % (sys.argv[0])
Pavlin Radoslavov7be3bac2013-03-27 09:59:34 -0700465 usage_msg = usage_msg + "\n"
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700466 usage_msg = usage_msg + " Flags:\n"
Pavlin Radoslavovb549f082013-03-29 04:28:27 -0700467 usage_msg = usage_msg + " -m [monitorname] Monitor and maintain the installed shortest path(s)\n"
468 usage_msg = usage_msg + " If 'monitorname' is specified and is set to 'ONOS'\n"
469 usage_msg = usage_msg + " ((case insensitive), then the flow generation and\n"
470 usage_msg = usage_msg + " maintanenance is done by ONOS itself.\n"
471 usage_msg = usage_msg + " Otherwise, it is done by this script.\n"
472 usage_msg = usage_msg + " -f <filename> Read the flow(s) to install from a file\n"
473 usage_msg = usage_msg + " File format: one line per flow starting with <flow-id>\n"
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -0700474 usage_msg = usage_msg + "\n"
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700475 usage_msg = usage_msg + " Match Conditions:\n"
476 usage_msg = usage_msg + " matchInPort <True|False> (default to True)\n"
477 usage_msg = usage_msg + " matchSrcMac <source MAC address>\n"
478 usage_msg = usage_msg + " matchDstMac <destination MAC address>\n"
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700479 usage_msg = usage_msg + " matchEthernetFrameType <Ethernet frame type>\n"
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700480 usage_msg = usage_msg + " matchVlanId <VLAN ID>\n"
481 usage_msg = usage_msg + " matchVlanPriority <VLAN priority>\n"
Pavlin Radoslavovad3a1e62013-07-09 13:30:16 -0700482 usage_msg = usage_msg + " matchSrcIPv4Net <source IPv4 network address>\n"
483 usage_msg = usage_msg + " matchDstIPv4Net <destination IPv4 network address>\n"
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700484 usage_msg = usage_msg + " matchIpProto <IP protocol>\n"
Pavlin Radoslavovad3a1e62013-07-09 13:30:16 -0700485 usage_msg = usage_msg + " matchIpToS <IP ToS (DSCP field, 6 bits)>\n"
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700486 usage_msg = usage_msg + " matchSrcTcpUdpPort <source TCP/UDP port>\n"
487 usage_msg = usage_msg + " matchDstTcpUdpPort <destination TCP/UDP port>\n"
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -0700488 usage_msg = usage_msg + "\n"
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700489 usage_msg = usage_msg + " Actions:\n"
490 usage_msg = usage_msg + " actionOutput <True|False> (default to True)\n"
491 usage_msg = usage_msg + " actionSetEthernetSrcAddr <source MAC address>\n"
492 usage_msg = usage_msg + " actionSetEthernetDstAddr <destination MAC address>\n"
493 usage_msg = usage_msg + " actionSetIPv4SrcAddr <source IPv4 address>\n"
494 usage_msg = usage_msg + " actionSetIPv4DstAddr <destination IPv4 address>\n"
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -0700495 usage_msg = usage_msg + "\n"
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700496 usage_msg = usage_msg + " Actions (not implemented yet):\n"
497 usage_msg = usage_msg + " actionSetVlanId <VLAN ID>\n"
498 usage_msg = usage_msg + " actionSetVlanPriority <VLAN priority>\n"
499 usage_msg = usage_msg + " actionSetIpToS <IP ToS (DSCP field, 6 bits)>\n"
500 usage_msg = usage_msg + " actionSetTcpUdpSrcPort <source TCP/UDP port>\n"
501 usage_msg = usage_msg + " actionSetTcpUdpDstPort <destination TCP/UDP port>\n"
502 usage_msg = usage_msg + " actionStripVlan <True|False>\n"
503 usage_msg = usage_msg + " actionEnqueue <dummy argument>\n"
504
505 # app.debug = False;
506
507 # Usage info
508 if len(sys.argv) > 1 and (sys.argv[1] == "-h" or sys.argv[1] == "--help"):
509 print(usage_msg)
510 exit(0)
511
512 #
513 # Check the flags
514 #
515 start_argv_index = 1
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -0700516 idx = 1
517 while idx < len(sys.argv):
518 arg1 = sys.argv[idx]
519 idx = idx + 1
520 if arg1 == "-m":
521 MonitoringEnabled = True
Pavlin Radoslavovb549f082013-03-29 04:28:27 -0700522 if idx < len(sys.argv):
523 arg2 = sys.argv[idx]
524 if arg2.lower() == "onos":
525 MonitoringByOnos = True
526 idx = idx + 1
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -0700527 start_argv_index = idx
528 elif arg1 == "-f":
529 if idx >= len(sys.argv):
530 error_arg = "ERROR: Missing or invalid '" + arg1 + "' argument"
531 log_error(error_arg)
532 log_error(usage_msg)
533 exit(1)
534 ReadFromFile = sys.argv[idx]
535 idx = idx + 1
536 start_argv_index = idx
537 else:
538 break;
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700539
540 #
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -0700541 # Read the arguments from a file or from the remaining command line options
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700542 #
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -0700543 my_lines = []
544 if len(ReadFromFile) > 0:
545 f = open(ReadFromFile, "rt")
546 my_line = f.readline()
547 while my_line:
548 if len(my_line.rstrip()) > 0 and my_line[0] != "#":
549 my_token_line = my_line.rstrip().split()
550 my_lines.append(my_token_line)
551 my_line = f.readline()
552 else:
553 my_lines.append(copy.deepcopy(sys.argv[start_argv_index:]))
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700554
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -0700555 #
556 # Initialization
557 #
558 last_data_paths = []
559 parsed_args = []
560 idx = 0
561 while idx < len(my_lines):
562 last_data_path = []
563 last_data_paths.append(copy.deepcopy(last_data_path))
564 #
565 # Parse the flow arguments
566 #
567 my_args = my_lines[idx]
568 parsed_args.append(copy.deepcopy(extract_flow_args(my_args)))
569 # Cleanup leftover state
570 my_flow_id = parsed_args[idx]['my_flow_id']
571 delete_flow_path(my_flow_id)
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700572
Pavlin Radoslavov2a0bd8b2013-03-15 18:45:51 -0700573 idx = idx + 1
574
575 #
Pavlin Radoslavovb549f082013-03-29 04:28:27 -0700576 if MonitoringByOnos == True:
577 exec_monitoring_by_onos(parsed_args)
578 else:
579 exec_processing_by_script(parsed_args)
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700580