blob: 28819c93d22b9ebcff89b4299da97e50c20479ea [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 Radoslavovf4ad9892013-03-04 14:15:19 -080024
25DEBUG=0
26pp = pprint.PrettyPrinter(indent=4)
27
28app = Flask(__name__)
29
30## Worker Functions ##
31def log_error(txt):
32 print '%s' % (txt)
33
34def debug(txt):
35 if DEBUG:
36 print '%s' % (txt)
37
38# @app.route("/wm/topology/route/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
39#
40# Sample output:
41# {'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'}]}
42#
43def shortest_path(v1, p1, v2, p2):
44 try:
45 command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (ControllerIP, ControllerPort, v1, p1, v2, p2)
46 debug("shortest_path %s" % command)
47
48 result = os.popen(command).read()
49 debug("result %s" % result)
50 if len(result) == 0:
51 log_error("No Path found")
52 exit(1);
53
54 parsedResult = json.loads(result)
55 debug("parsed %s" % parsedResult)
56
57 except:
58 log_error("Controller IF has issue")
59 exit(1)
60
61 srcSwitch = parsedResult['srcPort']['dpid']['value'];
62 srcPort = parsedResult['srcPort']['port']['value'];
63 dstSwitch = parsedResult['dstPort']['dpid']['value'];
64 dstPort = parsedResult['dstPort']['port']['value'];
65
66 print "DataPath: (src = %s/%s dst = %s/%s)" % (srcSwitch, srcPort, dstSwitch, dstPort);
67
68 for f in parsedResult['flowEntries']:
69 inPort = f['inPort']['value'];
70 outPort = f['outPort']['value'];
71 dpid = f['dpid']['value']
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -070072 print " FlowEntry: (%s, %s, %s)" % (inPort, dpid, outPort)
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080073
74 return parsedResult
75
76def add_flow_path(flow_path):
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -070077 flow_path_json = json.dumps(flow_path)
78
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -080079 try:
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -070080 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 -080081 debug("add_flow_path %s" % command)
82 result = os.popen(command).read()
83 debug("result %s" % result)
84 # parsedResult = json.loads(result)
85 # debug("parsed %s" % parsedResult)
86 except:
87 log_error("Controller IF has issue")
88 exit(1)
89
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -070090def delete_flow_path(flow_id):
91 command = "curl -s \"http://%s:%s/wm/flow/delete/%s/json\"" % (ControllerIP, ControllerPort, flow_id)
92 debug("delete_flow_path %s" % command)
93 result = os.popen(command).read()
94 debug("result %s" % result)
95 # parsedResult = json.loads(result)
96 # debug("parsed %s" % parsedResult)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -070097
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -070098def extract_flow_args(my_args):
99 # Check the arguments
100 if len(my_args) < 6:
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -0800101 log_error(usage_msg)
102 exit(1)
103
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700104 # Extract the mandatory arguments
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700105 my_flow_id = my_args[0]
106 my_installer_id = my_args[1]
107 my_src_dpid = my_args[2]
108 my_src_port = my_args[3]
109 my_dst_dpid = my_args[4]
110 my_dst_port = my_args[5]
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700111
112 #
113 # Extract the "match" and "action" arguments
114 #
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700115 match = {}
116 matchInPortEnabled = True # NOTE: Enabled by default
117 actions = []
118 actionOutputEnabled = True # NOTE: Enabled by default
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700119 idx = 6
120 while idx < len(my_args):
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700121 action = {}
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700122 arg1 = my_args[idx]
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700123 idx = idx + 1
124 # Extract the second argument
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700125 if idx >= len(my_args):
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700126 error_arg = "ERROR: Missing or invalid '" + arg1 + "' argument"
127 log_error(error_arg)
128 log_error(usage_msg)
129 exit(1)
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700130 arg2 = my_args[idx]
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700131 idx = idx + 1
132
133 if arg1 == "matchInPort":
134 # Just mark whether inPort matching is enabled
135 matchInPortEnabled = arg2 in ['True', 'true']
136 # inPort = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700137 # inPort['value'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700138 # match['inPort'] = inPort
139 ## match['matchInPort'] = True
140 elif arg1 == "matchSrcMac":
141 srcMac = {}
142 srcMac['value'] = arg2
143 match['srcMac'] = srcMac
144 # match['matchSrcMac'] = True
145 elif arg1 == "matchDstMac":
146 dstMac = {}
147 dstMac['value'] = arg2
148 match['dstMac'] = dstMac
149 # match['matchDstMac'] = True
150 elif arg1 == "matchVlanId":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700151 match['vlanId'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700152 # match['matchVlanId'] = True
153 elif arg1 == "matchVlanPriority":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700154 match['vlanPriority'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700155 # match['matchVlanPriority'] = True
156 elif arg1 == "matchEthernetFrameType":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700157 match['ethernetFrameType'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700158 # match['matchEthernetFrameType'] = True
159 elif arg1 == "matchIpToS":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700160 match['ipToS'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700161 # match['matchIpToS'] = True
162 elif arg1 == "matchIpProto":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700163 match['ipProto'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700164 # match['matchIpProto'] = True
165 elif arg1 == "matchSrcIPv4Net":
166 srcIPv4Net = {}
167 srcIPv4Net['value'] = arg2
168 match['srcIPv4Net'] = srcIPv4Net
169 # match['matchSrcIPv4Net'] = True
170 elif arg1 == "matchDstIPv4Net":
171 dstIPv4Net = {}
172 dstIPv4Net['value'] = arg2
173 match['dstIPv4Net'] = dstIPv4Net
174 # match['matchDstIPv4Net'] = True
175 elif arg1 == "matchSrcTcpUdpPort":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700176 match['srcTcpUdpPort'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700177 # match['matchSrcTcpUdpPort'] = True
178 elif arg1 == "matchDstTcpUdpPort":
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700179 match['dstTcpUdpPort'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700180 # match['matchDstTcpUdpPort'] = True
181 elif arg1 == "actionOutput":
182 # Just mark whether ACTION_OUTPUT action is enabled
183 actionOutputEnabled = arg2 in ['True', 'true']
184 #
185 # TODO: Complete the implementation for ACTION_OUTPUT
186 # actionOutput = {}
187 # outPort = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700188 # outPort['value'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700189 # actionOutput['port'] = outPort
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700190 # actionOutput['maxLen'] = int(arg3, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700191 # action['actionOutput'] = actionOutput
192 # # action['actionType'] = 'ACTION_OUTPUT'
193 # actions.append(action)
194 #
195 elif arg1 == "actionSetVlanId":
196 vlanId = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700197 vlanId['vlanId'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700198 action['actionSetVlanId'] = vlanId
199 # action['actionType'] = 'ACTION_SET_VLAN_VID'
200 actions.append(copy.deepcopy(action))
201 elif arg1 == "actionSetVlanPriority":
202 vlanPriority = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700203 vlanPriority['vlanPriority'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700204 action['actionSetVlanPriority'] = vlanPriority
205 # action['actionType'] = 'ACTION_SET_VLAN_PCP'
206 actions.append(copy.deepcopy(action))
207 elif arg1 == "actionSetIpToS":
208 ipToS = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700209 ipToS['ipToS'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700210 action['actionSetIpToS'] = ipToS
211 # action['actionType'] = 'ACTION_SET_NW_TOS'
212 actions.append(copy.deepcopy(action))
213 elif arg1 == "actionSetTcpUdpSrcPort":
214 tcpUdpSrcPort = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700215 tcpUdpSrcPort['port'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700216 action['actionSetTcpUdpSrcPort'] = tcpUdpSrcPort
217 # action['actionType'] = 'ACTION_SET_TP_SRC'
218 actions.append(copy.deepcopy(action))
219 elif arg1 == "actionSetTcpUdpDstPort":
220 tcpUdpDstPort = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700221 tcpUdpDstPort['port'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700222 action['actionSetTcpUdpDstPort'] = tcpUdpDstPort
223 # action['actionType'] = 'ACTION_SET_TP_DST'
224 actions.append(copy.deepcopy(action))
225 elif arg1 == "actionStripVlan":
226 stripVlan = {}
227 stripVlan['stripVlan'] = arg2 in ['True', 'true']
228 action['actionStripVlan'] = stripVlan
229 # action['actionType'] = 'ACTION_STRIP_VLAN'
230 actions.append(copy.deepcopy(action))
231 elif arg1 == "actionSetEthernetSrcAddr":
232 ethernetSrcAddr = {}
233 ethernetSrcAddr['value'] = arg2
234 setEthernetSrcAddr = {}
235 setEthernetSrcAddr['addr'] = ethernetSrcAddr
236 action['actionSetEthernetSrcAddr'] = setEthernetSrcAddr
237 # action['actionType'] = 'ACTION_SET_DL_SRC'
238 actions.append(copy.deepcopy(action))
239 elif arg1 == "actionSetEthernetDstAddr":
240 ethernetDstAddr = {}
241 ethernetDstAddr['value'] = arg2
242 setEthernetDstAddr = {}
243 setEthernetDstAddr['addr'] = ethernetDstAddr
244 action['actionSetEthernetDstAddr'] = setEthernetDstAddr
245 # action['actionType'] = 'ACTION_SET_DL_DST'
246 actions.append(copy.deepcopy(action))
247 elif arg1 == "actionSetIPv4SrcAddr":
248 IPv4SrcAddr = {}
249 IPv4SrcAddr['value'] = arg2
250 setIPv4SrcAddr = {}
251 setIPv4SrcAddr['addr'] = IPv4SrcAddr
252 action['actionSetIPv4SrcAddr'] = setIPv4SrcAddr
253 # action['actionType'] = 'ACTION_SET_NW_SRC'
254 actions.append(copy.deepcopy(action))
255 elif arg1 == "actionSetIPv4DstAddr":
256 IPv4DstAddr = {}
257 IPv4DstAddr['value'] = arg2
258 setIPv4DstAddr = {}
259 setIPv4DstAddr['addr'] = IPv4DstAddr
260 action['actionSetIPv4DstAddr'] = setIPv4DstAddr
261 # action['actionType'] = 'ACTION_SET_NW_DST'
262 actions.append(copy.deepcopy(action))
263 elif arg1 == "actionEnqueue":
264 # TODO: Implement ACTION_ENQUEUE
265 actionEnqueue = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700266 # actionEnqueue['queueId'] = int(arg2, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700267 # enqueuePort = {}
Pavlin Radoslavov14748912013-03-12 15:44:56 -0700268 # enqueuePort['value'] = int(arg3, 0)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700269 # actionEnqueue['port'] = enqueuePort
270 # action['actionEnqueue'] = actionEnqueue
271 # # action['actionType'] = 'ACTION_ENQUEUE'
272 # actions.append(copy.deepcopy(action))
273 #
274 else:
275 log_error("ERROR: Unknown argument '%s'" % (arg1))
276 log_error(usage_msg)
277 exit(1)
278
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700279 return {
280 'my_flow_id' : my_flow_id,
281 'my_installer_id' : my_installer_id,
282 'my_src_dpid' : my_src_dpid,
283 'my_src_port' : my_src_port,
284 'my_dst_dpid' : my_dst_dpid,
285 'my_dst_port' : my_dst_port,
286 'match' : match,
287 'matchInPortEnabled' : matchInPortEnabled,
288 'actions' : actions,
289 'actionOutputEnabled' : actionOutputEnabled
290 }
291
292def compute_data_path(parsed_args):
293
294 my_src_dpid = parsed_args['my_src_dpid']
295 my_src_port = parsed_args['my_src_port']
296 my_dst_dpid = parsed_args['my_dst_dpid']
297 my_dst_port = parsed_args['my_dst_port']
298
299 # Compute the shortest path
300 data_path = shortest_path(my_src_dpid, my_src_port, my_dst_dpid, my_dst_port)
301
302 debug("Data Path: %s" % data_path)
303 return data_path
304
305def compute_flow_path(parsed_args, data_path):
306
307 my_flow_id = parsed_args['my_flow_id']
308 my_installer_id = parsed_args['my_installer_id']
309 match = parsed_args['match']
310 matchInPortEnabled = parsed_args['matchInPortEnabled']
311 actions = parsed_args['actions']
312 actionOutputEnabled = parsed_args['actionOutputEnabled']
313 my_data_path = copy.deepcopy(data_path)
314
315 flow_id = {}
316 flow_id['value'] = my_flow_id
317 installer_id = {}
318 installer_id['value'] = my_installer_id
319
320 flow_path = {}
321 flow_path['flowId'] = flow_id
322 flow_path['installerId'] = installer_id
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700323
324 #
325 # Add the match conditions to each flow entry
326 #
327 if (len(match) > 0) or matchInPortEnabled:
328 idx = 0
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700329 while idx < len(my_data_path['flowEntries']):
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700330 if matchInPortEnabled:
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700331 inPort = my_data_path['flowEntries'][idx]['inPort']
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700332 match['inPort'] = copy.deepcopy(inPort)
333 # match['matchInPort'] = True
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700334 my_data_path['flowEntries'][idx]['flowEntryMatch'] = copy.deepcopy(match)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700335 idx = idx + 1
336
337 #
338 # Set the actions for each flow entry
339 # NOTE: The actions from the command line are aplied
340 # ONLY to the first flow entry.
341 #
342 # If ACTION_OUTPUT action is enabled, then apply it
343 # to each flow entry.
344 #
345 if (len(actions) > 0) or actionOutputEnabled:
346 idx = 0
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700347 while idx < len(my_data_path['flowEntries']):
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700348 if idx > 0:
349 actions = [] # Reset the actions for all but first entry
350 action = {}
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700351 outPort = my_data_path['flowEntries'][idx]['outPort']
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700352 actionOutput = {}
353 actionOutput['port'] = copy.deepcopy(outPort)
354 # actionOutput['maxLen'] = 0 # TODO: not used for now
355 action['actionOutput'] = copy.deepcopy(actionOutput)
356 # action['actionType'] = 'ACTION_OUTPUT'
357 actions.append(copy.deepcopy(action))
358
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700359 my_data_path['flowEntries'][idx]['flowEntryActions'] = copy.deepcopy(actions)
Pavlin Radoslavovf13923a2013-03-11 19:42:17 -0700360 idx = idx + 1
361
362
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700363 flow_path['dataPath'] = my_data_path
364 debug("Flow Path: %s" % flow_path)
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -0800365
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700366 add_flow_path(flow_path)
Pavlin Radoslavovf4ad9892013-03-04 14:15:19 -0800367
Pavlin Radoslavov3f3778a2013-03-13 08:16:57 -0700368
369if __name__ == "__main__":
370 usage_msg = "Usage: %s [Flags] <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port> [Match Conditions] [Actions]\n" % (sys.argv[0])
371 usage_msg = usage_msg + " Flags:\n"
372 usage_msg = usage_msg + " -m Monitor and maintain the installed shortest path\n"
373 usage_msg = usage_msg + " Match Conditions:\n"
374 usage_msg = usage_msg + " matchInPort <True|False> (default to True)\n"
375 usage_msg = usage_msg + " matchSrcMac <source MAC address>\n"
376 usage_msg = usage_msg + " matchDstMac <destination MAC address>\n"
377 usage_msg = usage_msg + " matchSrcIPv4Net <source IPv4 network address>\n"
378 usage_msg = usage_msg + " matchDstIPv4Net <destination IPv4 network address>\n"
379 usage_msg = usage_msg + " matchEthernetFrameType <Ethernet frame type>\n"
380
381 usage_msg = usage_msg + " Match Conditions (not implemented yet):\n"
382 usage_msg = usage_msg + " matchVlanId <VLAN ID>\n"
383 usage_msg = usage_msg + " matchVlanPriority <VLAN priority>\n"
384 usage_msg = usage_msg + " matchIpToS <IP ToS (DSCP field, 6 bits)>\n"
385 usage_msg = usage_msg + " matchIpProto <IP protocol>\n"
386 usage_msg = usage_msg + " matchSrcTcpUdpPort <source TCP/UDP port>\n"
387 usage_msg = usage_msg + " matchDstTcpUdpPort <destination TCP/UDP port>\n"
388 usage_msg = usage_msg + " Actions:\n"
389 usage_msg = usage_msg + " actionOutput <True|False> (default to True)\n"
390 usage_msg = usage_msg + " actionSetEthernetSrcAddr <source MAC address>\n"
391 usage_msg = usage_msg + " actionSetEthernetDstAddr <destination MAC address>\n"
392 usage_msg = usage_msg + " actionSetIPv4SrcAddr <source IPv4 address>\n"
393 usage_msg = usage_msg + " actionSetIPv4DstAddr <destination IPv4 address>\n"
394 usage_msg = usage_msg + " Actions (not implemented yet):\n"
395 usage_msg = usage_msg + " actionSetVlanId <VLAN ID>\n"
396 usage_msg = usage_msg + " actionSetVlanPriority <VLAN priority>\n"
397 usage_msg = usage_msg + " actionSetIpToS <IP ToS (DSCP field, 6 bits)>\n"
398 usage_msg = usage_msg + " actionSetTcpUdpSrcPort <source TCP/UDP port>\n"
399 usage_msg = usage_msg + " actionSetTcpUdpDstPort <destination TCP/UDP port>\n"
400 usage_msg = usage_msg + " actionStripVlan <True|False>\n"
401 usage_msg = usage_msg + " actionEnqueue <dummy argument>\n"
402
403 # app.debug = False;
404
405 # Usage info
406 if len(sys.argv) > 1 and (sys.argv[1] == "-h" or sys.argv[1] == "--help"):
407 print(usage_msg)
408 exit(0)
409
410 #
411 # Check the flags
412 #
413 start_argv_index = 1
414 if len(sys.argv) > 1 and sys.argv[1] == "-m":
415 MonitoringEnabled = True
416 start_argv_index = start_argv_index + 1
417
418 #
419 # Parse the remaining arguments
420 #
421 my_args = sys.argv[start_argv_index:]
422 parsed_args = copy.deepcopy(extract_flow_args(my_args))
423
424 last_data_path = []
425 my_flow_id = parsed_args['my_flow_id']
426 # Cleanup leftover state
427 delete_flow_path(my_flow_id)
428
429 while True:
430 data_path = compute_data_path(parsed_args)
431 if data_path != last_data_path:
432 if len(last_data_path) > 0:
433 delete_flow_path(my_flow_id)
434 flow_path = compute_flow_path(parsed_args, data_path)
435 add_flow_path(flow_path)
436 last_data_path = data_path
437
438 if MonitoringEnabled != True:
439 break
440 time.sleep(1)