Add support for specifying the actions when a Flow is created by the user.
The user could either:
(a) Specify each action per Flow Entry (when the Flow Entries are provided
by the user).
(b) Specify the additional actions (apart of ACTION_OUTPUT) for the
first Flow Entry. E.g., if the Flow Entry is overwriting various
fields. Those actions are stored in the Flow Path header, so
they can be used after the Flow Entries are created by
the ONOS Shortest Path computation.
diff --git a/web/measurement_store_flow.py b/web/measurement_store_flow.py
index ad0eadf..0e39465 100755
--- a/web/measurement_store_flow.py
+++ b/web/measurement_store_flow.py
@@ -87,7 +87,7 @@
if "KEEP_ONLY_FIRST_HOP_ENTRY" in arg2:
flowPathFlags = flowPathFlags + 0x2
elif arg1 == "matchInPort":
- # Just mark whether inPort matching is enabled
+ # Mark whether ACTION_OUTPUT action is enabled
matchInPortEnabled = arg2 in ['True', 'true']
# inPort = {}
# inPort['value'] = int(arg2, 0)
@@ -135,18 +135,19 @@
match['dstTcpUdpPort'] = int(arg2, 0)
# match['matchDstTcpUdpPort'] = True
elif arg1 == "actionOutput":
- # Just mark whether ACTION_OUTPUT action is enabled
+ # Mark whether ACTION_OUTPUT action is enabled
actionOutputEnabled = arg2 in ['True', 'true']
- #
- # TODO: Complete the implementation for ACTION_OUTPUT
- # actionOutput = {}
- # outPort = {}
- # outPort['value'] = int(arg2, 0)
- # actionOutput['port'] = outPort
- # actionOutput['maxLen'] = int(arg3, 0)
- # action['actionOutput'] = actionOutput
- # # action['actionType'] = 'ACTION_OUTPUT'
- # actions.append(action)
+ # If ACTION_OUTPUT is explicitly enabled, add an entry with a fake
+ # port number. We need this entry to preserve the action ordering.
+ if actionOutputEnabled == True:
+ actionOutput = {}
+ outPort = {}
+ outPort['value'] = 0xffff
+ actionOutput['port'] = outPort
+ actionOutput['maxLen'] = 0
+ action['actionOutput'] = actionOutput
+ # action['actionType'] = 'ACTION_OUTPUT'
+ actions.append(action)
#
elif arg1 == "actionSetVlanId":
vlanId = {}
@@ -264,6 +265,8 @@
flowPathFlags = {}
flowPathFlags['flags'] = myFlowPathFlags
+ flowEntryActions = {}
+
flow_path = {}
flow_path['flowId'] = flow_id
flow_path['installerId'] = installer_id
@@ -285,6 +288,11 @@
my_data_path['flowEntries'][idx]['flowEntryMatch'] = copy.deepcopy(match)
idx = idx + 1
+
+ if (len(actions) > 0):
+ flowEntryActions['actions'] = copy.deepcopy(actions)
+ flow_path['flowEntryActions'] = flowEntryActions
+
#
# Set the actions for each flow entry
# NOTE: The actions from the command line are aplied
@@ -306,11 +314,12 @@
action['actionOutput'] = copy.deepcopy(actionOutput)
# action['actionType'] = 'ACTION_OUTPUT'
actions.append(copy.deepcopy(action))
+ flowEntryActions = {}
+ flowEntryActions['actions'] = copy.deepcopy(actions)
- my_data_path['flowEntries'][idx]['flowEntryActions'] = copy.deepcopy(actions)
+ my_data_path['flowEntries'][idx]['flowEntryActions'] = flowEntryActions
idx = idx + 1
-
flow_path['dataPath'] = my_data_path
debug("Flow Path: %s" % flow_path)
return flow_path
@@ -396,6 +405,7 @@
usage_msg = usage_msg + " actionSetIpToS <IP ToS (DSCP field, 6 bits)>\n"
usage_msg = usage_msg + " actionSetTcpUdpSrcPort <source TCP/UDP port>\n"
usage_msg = usage_msg + " actionSetTcpUdpDstPort <destination TCP/UDP port>\n"
+ usage_msg = usage_msg + " Actions (not implemented yet):\n"
usage_msg = usage_msg + " actionEnqueue <dummy argument>\n"
# app.debug = False;