Work toward Issue #215 and Issue #216:
* Add front-end arguments to the add_flow.py Python script
to support matching conditions and actions for flows.
* Fix some Json-related issues in the backend so the
matching conditions and actions are properly deserialized.
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java b/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
index 304bb5c..1fc1783 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
@@ -54,6 +54,15 @@
// if the port is set to PORT_CONTROLLER
/**
+ * Default constructor.
+ */
+ public ActionOutput() {
+ this.port = null;
+ this.maxLen = 0;
+ }
+
+
+ /**
* Constructor for a given output port and maximum length.
*
* @param port the output port to set.
@@ -66,6 +75,16 @@
}
/**
+ * Constructor for a given output port.
+ *
+ * @param port the output port to set.
+ */
+ public ActionOutput(Port port) {
+ this.port = port;
+ this.maxLen = 0;
+ }
+
+ /**
* Get the output port.
*
* @return the output port.
@@ -113,11 +132,18 @@
private short vlanId; // The VLAN ID to set
/**
+ * Default constructor.
+ */
+ public ActionSetVlanId() {
+ this.vlanId = 0;
+ }
+
+ /**
* Constructor for a given VLAN ID.
*
* @param vlanId the VLAN ID to set.
*/
- ActionSetVlanId(short vlanId) {
+ public ActionSetVlanId(short vlanId) {
this.vlanId = vlanId;
}
@@ -156,11 +182,18 @@
private byte vlanPriority; // The VLAN priority to set
/**
+ * Default constructor.
+ */
+ public ActionSetVlanPriority() {
+ this.vlanPriority = 0;
+ }
+
+ /**
* Constructor for a given VLAN priority.
*
* @param vlanPriority the VLAN priority to set.
*/
- ActionSetVlanPriority(byte vlanPriority) {
+ public ActionSetVlanPriority(byte vlanPriority) {
this.vlanPriority = vlanPriority;
}
@@ -199,11 +232,18 @@
private boolean stripVlan; // If true, strip the VLAN header
/**
+ * Default constructor.
+ */
+ public ActionStripVlan() {
+ this.stripVlan = false;
+ }
+
+ /**
* Constructor for a given boolean flag.
*
* @param stripVlan if true, strip the VLAN header.
*/
- ActionStripVlan(boolean stripVlan) {
+ public ActionStripVlan(boolean stripVlan) {
this.stripVlan = stripVlan;
}
@@ -243,11 +283,18 @@
private MACAddress addr; // The MAC address to set
/**
+ * Default constructor.
+ */
+ public ActionSetEthernetAddr() {
+ this.addr = null;
+ }
+
+ /**
* Constructor for a given MAC address.
*
* @param addr the MAC address to set.
*/
- ActionSetEthernetAddr(MACAddress addr) {
+ public ActionSetEthernetAddr(MACAddress addr) {
this.addr = addr;
}
@@ -287,11 +334,18 @@
private IPv4 addr; // The IPv4 address to set
/**
+ * Default constructor.
+ */
+ public ActionSetIPv4Addr() {
+ this.addr = null;
+ }
+
+ /**
* Constructor for a given IPv4 address.
*
* @param addr the IPv4 address to set.
*/
- ActionSetIPv4Addr(IPv4 addr) {
+ public ActionSetIPv4Addr(IPv4 addr) {
this.addr = addr;
}
@@ -331,11 +385,18 @@
private byte ipToS; // The IP ToS to set DSCP field, 6 bits)
/**
+ * Default constructor.
+ */
+ public ActionSetIpToS() {
+ this.ipToS = 0;
+ }
+
+ /**
* Constructor for a given IP ToS (DSCP field, 6 bits).
*
* @param ipToS the IP ToS (DSCP field, 6 bits) to set.
*/
- ActionSetIpToS(byte ipToS) {
+ public ActionSetIpToS(byte ipToS) {
this.ipToS = ipToS;
}
@@ -375,11 +436,18 @@
private short port; // The TCP/UDP port to set
/**
+ * Default constructor.
+ */
+ public ActionSetTcpUdpPort() {
+ this.port = 0;
+ }
+
+ /**
* Constructor for a given TCP/UDP port.
*
* @param port the TCP/UDP port to set.
*/
- ActionSetTcpUdpPort(short port) {
+ public ActionSetTcpUdpPort(short port) {
this.port = port;
}
@@ -421,6 +489,14 @@
private int queueId; // Where to enqueue the packets
/**
+ * Default constructor.
+ */
+ public ActionEnqueue() {
+ this.port = null;
+ this.queueId = 0;
+ }
+
+ /**
* Constructor for a given port and queue ID.
*
* @param port the port to set.
@@ -515,11 +591,21 @@
/**
* Set the output action on a port.
*
- * @param port the output port to set.
+ * @param action the action to set.
*/
@JsonProperty("actionOutput")
+ public void setActionOutput(ActionOutput action) {
+ actionOutput = action;
+ actionType = ActionValues.ACTION_OUTPUT;
+ }
+
+ /**
+ * Set the output action on a port.
+ *
+ * @param port the output port to set.
+ */
public void setActionOutput(Port port) {
- actionOutput = new ActionOutput(port, (short)0);
+ actionOutput = new ActionOutput(port);
actionType = ActionValues.ACTION_OUTPUT;
}
@@ -528,7 +614,6 @@
*
* @param maxLen the maximum length (in bytes) to send to controller.
*/
- @JsonProperty("actionOutputToController")
public void setActionOutputToController(short maxLen) {
Port port = new Port(Port.PortValues.PORT_CONTROLLER);
actionOutput = new ActionOutput(port, maxLen);
@@ -546,9 +631,19 @@
/**
* Set the action to set the VLAN ID.
*
- * @param vlanId the VLAN ID to set.
+ * @param action the action to set.
*/
@JsonProperty("actionSetVlanId")
+ public void setActionSetVlanId(ActionSetVlanId action) {
+ actionSetVlanId = action;
+ actionType = ActionValues.ACTION_SET_VLAN_VID;
+ }
+
+ /**
+ * Set the action to set the VLAN ID.
+ *
+ * @param vlanId the VLAN ID to set.
+ */
public void setActionSetVlanId(short vlanId) {
actionSetVlanId = new ActionSetVlanId(vlanId);
actionType = ActionValues.ACTION_SET_VLAN_VID;
@@ -567,9 +662,19 @@
/**
* Set the action to set the VLAN priority.
*
- * @param vlanPriority the VLAN priority to set.
+ * @param action the action to set.
*/
@JsonProperty("actionSetVlanPriority")
+ public void setActionSetVlanPriority(ActionSetVlanPriority action) {
+ actionSetVlanPriority = action;
+ actionType = ActionValues.ACTION_SET_VLAN_PCP;
+ }
+
+ /**
+ * Set the action to set the VLAN priority.
+ *
+ * @param vlanPriority the VLAN priority to set.
+ */
public void setActionSetVlanPriority(byte vlanPriority) {
actionSetVlanPriority = new ActionSetVlanPriority(vlanPriority);
actionType = ActionValues.ACTION_SET_VLAN_PCP;
@@ -588,9 +693,19 @@
/**
* Set the action to strip the VLAN header.
*
- * @param stripVlan if true, strip the VLAN header.
+ * @param action the action to set.
*/
@JsonProperty("actionStripVlan")
+ public void setActionStripVlan(ActionStripVlan action) {
+ actionStripVlan = action;
+ actionType = ActionValues.ACTION_STRIP_VLAN;
+ }
+
+ /**
+ * Set the action to strip the VLAN header.
+ *
+ * @param stripVlan if true, strip the VLAN header.
+ */
public void setActionStripVlan(boolean stripVlan) {
actionStripVlan = new ActionStripVlan(stripVlan);
actionType = ActionValues.ACTION_STRIP_VLAN;
@@ -609,9 +724,19 @@
/**
* Set the action to set the Ethernet source address.
*
- * @param addr the MAC address to set as the Ethernet source address.
+ * @param action the action to set.
*/
@JsonProperty("actionSetEthernetSrcAddr")
+ public void setActionSetEthernetSrcAddr(ActionSetEthernetAddr action) {
+ actionSetEthernetSrcAddr = action;
+ actionType = ActionValues.ACTION_SET_DL_SRC;
+ }
+
+ /**
+ * Set the action to set the Ethernet source address.
+ *
+ * @param addr the MAC address to set as the Ethernet source address.
+ */
public void setActionSetEthernetSrcAddr(MACAddress addr) {
actionSetEthernetSrcAddr = new ActionSetEthernetAddr(addr);
actionType = ActionValues.ACTION_SET_DL_SRC;
@@ -630,9 +755,19 @@
/**
* Set the action to set the Ethernet destination address.
*
- * @param addr the MAC address to set as the Ethernet destination address.
+ * @param action the action to set.
*/
@JsonProperty("actionSetEthernetDstAddr")
+ public void setActionSetEthernetDstAddr(ActionSetEthernetAddr action) {
+ actionSetEthernetDstAddr = action;
+ actionType = ActionValues.ACTION_SET_DL_DST;
+ }
+
+ /**
+ * Set the action to set the Ethernet destination address.
+ *
+ * @param addr the MAC address to set as the Ethernet destination address.
+ */
public void setActionSetEthernetDstAddr(MACAddress addr) {
actionSetEthernetDstAddr = new ActionSetEthernetAddr(addr);
actionType = ActionValues.ACTION_SET_DL_DST;
@@ -651,9 +786,19 @@
/**
* Set the action to set the IPv4 source address.
*
- * @param addr the IPv4 address to set as the IPv4 source address.
+ * @param action the action to set.
*/
@JsonProperty("actionSetIPv4SrcAddr")
+ public void setActionSetIPv4SrcAddr(ActionSetIPv4Addr action) {
+ actionSetIPv4SrcAddr = action;
+ actionType = ActionValues.ACTION_SET_NW_SRC;
+ }
+
+ /**
+ * Set the action to set the IPv4 source address.
+ *
+ * @param addr the IPv4 address to set as the IPv4 source address.
+ */
public void setActionSetIPv4SrcAddr(IPv4 addr) {
actionSetIPv4SrcAddr = new ActionSetIPv4Addr(addr);
actionType = ActionValues.ACTION_SET_NW_SRC;
@@ -672,9 +817,19 @@
/**
* Set the action to set the IPv4 destination address.
*
- * @param addr the IPv4 address to set as the IPv4 destination address.
+ * @param action the action to set.
*/
@JsonProperty("actionSetIPv4DstAddr")
+ public void setActionSetIPv4DstAddr(ActionSetIPv4Addr action) {
+ actionSetIPv4DstAddr = action;
+ actionType = ActionValues.ACTION_SET_NW_DST;
+ }
+
+ /**
+ * Set the action to set the IPv4 destination address.
+ *
+ * @param addr the IPv4 address to set as the IPv4 destination address.
+ */
public void setActionSetIPv4DstAddr(IPv4 addr) {
actionSetIPv4DstAddr = new ActionSetIPv4Addr(addr);
actionType = ActionValues.ACTION_SET_NW_DST;
@@ -693,9 +848,19 @@
/**
* Set the action to set the IP ToS (DSCP field, 6 bits).
*
- * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+ * @param action the action to set.
*/
@JsonProperty("actionSetIpToS")
+ public void setActionSetIpToS(ActionSetIpToS action) {
+ actionSetIpToS = action;
+ actionType = ActionValues.ACTION_SET_NW_TOS;
+ }
+
+ /**
+ * Set the action to set the IP ToS (DSCP field, 6 bits).
+ *
+ * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+ */
public void setActionSetIpToS(byte ipToS) {
actionSetIpToS = new ActionSetIpToS(ipToS);
actionType = ActionValues.ACTION_SET_NW_TOS;
@@ -714,9 +879,19 @@
/**
* Set the action to set the TCP/UDP source port.
*
- * @param port the TCP/UDP port to set as the TCP/UDP source port.
+ * @param action the action to set.
*/
@JsonProperty("actionSetTcpUdpSrcPort")
+ public void setActionSetTcpUdpSrcPort(ActionSetTcpUdpPort action) {
+ actionSetTcpUdpSrcPort = action;
+ actionType = ActionValues.ACTION_SET_TP_SRC;
+ }
+
+ /**
+ * Set the action to set the TCP/UDP source port.
+ *
+ * @param port the TCP/UDP port to set as the TCP/UDP source port.
+ */
public void setActionSetTcpUdpSrcPort(short port) {
actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(port);
actionType = ActionValues.ACTION_SET_TP_SRC;
@@ -735,9 +910,19 @@
/**
* Set the action to set the TCP/UDP destination port.
*
- * @param port the TCP/UDP port to set as the TCP/UDP destination port.
+ * @param action the action to set.
*/
@JsonProperty("actionSetTcpUdpDstPort")
+ public void setActionSetTcpUdpDstPort(ActionSetTcpUdpPort action) {
+ actionSetTcpUdpDstPort = action;
+ actionType = ActionValues.ACTION_SET_TP_DST;
+ }
+
+ /**
+ * Set the action to set the TCP/UDP destination port.
+ *
+ * @param port the TCP/UDP port to set as the TCP/UDP destination port.
+ */
public void setActionSetTcpUdpDstPort(short port) {
actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(port);
actionType = ActionValues.ACTION_SET_TP_DST;
@@ -754,10 +939,20 @@
/**
* Set the action to output to queue on a port.
*
+ * @param action the action to set.
+ */
+ @JsonProperty("actionEnqueue")
+ public void setActionEnqueue(ActionEnqueue action) {
+ actionEnqueue = action;
+ actionType = ActionValues.ACTION_ENQUEUE;
+ }
+
+ /**
+ * Set the action to output to queue on a port.
+ *
* @param port the port to set.
* @param int queueId the queue ID to set.
*/
- @JsonProperty("actionEnqueue")
public void setActionEnqueue(Port port, int queueId) {
actionEnqueue = new ActionEnqueue(port, queueId);
actionType = ActionValues.ACTION_ENQUEUE;
diff --git a/web/add_flow.py b/web/add_flow.py
index 18846b7..30de975 100755
--- a/web/add_flow.py
+++ b/web/add_flow.py
@@ -1,6 +1,7 @@
#! /usr/bin/env python
# -*- Mode: python; py-indent-offset: 4; tab-width: 8; indent-tabs-mode: t; -*-
+import copy
import pprint
import os
import sys
@@ -84,7 +85,36 @@
exit(1)
if __name__ == "__main__":
- usage_msg = "Usage: %s <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port>" % (sys.argv[0])
+ usage_msg = "Usage: %s <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port> [Match Conditions] [Actions]\n" % (sys.argv[0])
+ usage_msg = usage_msg + " Match Conditions:\n"
+ usage_msg = usage_msg + " matchInPort <True|False> (default to True)\n"
+ usage_msg = usage_msg + " matchSrcMac <source MAC address>\n"
+ usage_msg = usage_msg + " matchDstMac <destination MAC address>\n"
+ usage_msg = usage_msg + " matchSrcIPv4Net <source IPv4 network address>\n"
+ usage_msg = usage_msg + " matchDstIPv4Net <destination IPv4 network address>\n"
+
+ usage_msg = usage_msg + " Match Conditions (not implemented yet):\n"
+ usage_msg = usage_msg + " matchVlanId <VLAN ID>\n"
+ usage_msg = usage_msg + " matchVlanPriority <VLAN priority>\n"
+ usage_msg = usage_msg + " matchEthernetFrametype <Ethernet frame type>\n"
+ usage_msg = usage_msg + " matchIpToS <IP ToS (DSCP field, 6 bits)>\n"
+ usage_msg = usage_msg + " matchIpProto <IP protocol>\n"
+ usage_msg = usage_msg + " matchSrcTcpUdpPort <source TCP/UDP port>\n"
+ usage_msg = usage_msg + " matchDstTcpUdpPort <destination TCP/UDP port>\n"
+ usage_msg = usage_msg + " Actions:\n"
+ usage_msg = usage_msg + " actionOutput <True|False> (default to True)\n"
+ usage_msg = usage_msg + " actionSetEthernetSrcAddr <source MAC address>\n"
+ usage_msg = usage_msg + " actionSetEthernetDstAddr <destination MAC address>\n"
+ usage_msg = usage_msg + " actionSetIPv4SrcAddr <source IPv4 address>\n"
+ usage_msg = usage_msg + " actionSetIPv4DstAddr <destination IPv4 address>\n"
+ usage_msg = usage_msg + " Actions (not implemented yet):\n"
+ usage_msg = usage_msg + " actionSetVlanId <VLAN ID>\n"
+ usage_msg = usage_msg + " actionSetVlanPriority <VLAN priority>\n"
+ 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 + " actionStripVlan <True|False>\n"
+ usage_msg = usage_msg + " actionEnqueue <dummy argument>\n"
# app.debug = False;
@@ -98,10 +128,16 @@
log_error(usage_msg)
exit(1)
- # Do the work
+ # Extract the mandatory arguments
my_flow_id = sys.argv[1]
- my_installer_id = sys.argv[2]; # 'ONOS-Path-Computation-Python'
- data_path = shortest_path(sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])
+ my_installer_id = sys.argv[2]
+ my_src_dpid = sys.argv[3]
+ my_src_port = sys.argv[4]
+ my_dst_dpid = sys.argv[5]
+ my_dst_port = sys.argv[6]
+
+ # Compute the shortest path
+ data_path = shortest_path(my_src_dpid, my_src_port, my_dst_dpid, my_dst_port)
debug("Data Path: %s" % data_path)
@@ -113,6 +149,214 @@
flow_path = {}
flow_path['flowId'] = flow_id
flow_path['installerId'] = installer_id
+
+ #
+ # Extract the "match" and "action" arguments
+ #
+ idx = 7
+ match = {}
+ matchInPortEnabled = True # NOTE: Enabled by default
+ actions = []
+ actionOutputEnabled = True # NOTE: Enabled by default
+ while idx < len(sys.argv):
+ action = {}
+ arg1 = sys.argv[idx]
+ idx = idx + 1
+ # Extract the second argument
+ if idx >= len(sys.argv):
+ error_arg = "ERROR: Missing or invalid '" + arg1 + "' argument"
+ log_error(error_arg)
+ log_error(usage_msg)
+ exit(1)
+ arg2 = sys.argv[idx]
+ idx = idx + 1
+
+ if arg1 == "matchInPort":
+ # Just mark whether inPort matching is enabled
+ matchInPortEnabled = arg2 in ['True', 'true']
+ # inPort = {}
+ # inPort['value'] = int(arg2)
+ # match['inPort'] = inPort
+ ## match['matchInPort'] = True
+ elif arg1 == "matchSrcMac":
+ srcMac = {}
+ srcMac['value'] = arg2
+ match['srcMac'] = srcMac
+ # match['matchSrcMac'] = True
+ elif arg1 == "matchDstMac":
+ dstMac = {}
+ dstMac['value'] = arg2
+ match['dstMac'] = dstMac
+ # match['matchDstMac'] = True
+ elif arg1 == "matchVlanId":
+ match['vlanId'] = int(arg2)
+ # match['matchVlanId'] = True
+ elif arg1 == "matchVlanPriority":
+ match['vlanPriority'] = int(arg2)
+ # match['matchVlanPriority'] = True
+ elif arg1 == "matchEthernetFrameType":
+ match['ethernetFrameType'] = int(arg2)
+ # match['matchEthernetFrameType'] = True
+ elif arg1 == "matchIpToS":
+ match['ipToS'] = int(arg2)
+ # match['matchIpToS'] = True
+ elif arg1 == "matchIpProto":
+ match['ipProto'] = int(arg2)
+ # match['matchIpProto'] = True
+ elif arg1 == "matchSrcIPv4Net":
+ srcIPv4Net = {}
+ srcIPv4Net['value'] = arg2
+ match['srcIPv4Net'] = srcIPv4Net
+ # match['matchSrcIPv4Net'] = True
+ elif arg1 == "matchDstIPv4Net":
+ dstIPv4Net = {}
+ dstIPv4Net['value'] = arg2
+ match['dstIPv4Net'] = dstIPv4Net
+ # match['matchDstIPv4Net'] = True
+ elif arg1 == "matchSrcTcpUdpPort":
+ match['srcTcpUdpPort'] = int(arg2)
+ # match['matchSrcTcpUdpPort'] = True
+ elif arg1 == "matchDstTcpUdpPort":
+ match['dstTcpUdpPort'] = int(arg2)
+ # match['matchDstTcpUdpPort'] = True
+ elif arg1 == "actionOutput":
+ # Just 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)
+ # actionOutput['port'] = outPort
+ # actionOutput['maxLen'] = int(arg3)
+ # action['actionOutput'] = actionOutput
+ # # action['actionType'] = 'ACTION_OUTPUT'
+ # actions.append(action)
+ #
+ elif arg1 == "actionSetVlanId":
+ vlanId = {}
+ vlanId['vlanId'] = int(arg2)
+ action['actionSetVlanId'] = vlanId
+ # action['actionType'] = 'ACTION_SET_VLAN_VID'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetVlanPriority":
+ vlanPriority = {}
+ vlanPriority['vlanPriority'] = int(arg2)
+ action['actionSetVlanPriority'] = vlanPriority
+ # action['actionType'] = 'ACTION_SET_VLAN_PCP'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetIpToS":
+ ipToS = {}
+ ipToS['ipToS'] = int(arg2)
+ action['actionSetIpToS'] = ipToS
+ # action['actionType'] = 'ACTION_SET_NW_TOS'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetTcpUdpSrcPort":
+ tcpUdpSrcPort = {}
+ tcpUdpSrcPort['port'] = int(arg2)
+ action['actionSetTcpUdpSrcPort'] = tcpUdpSrcPort
+ # action['actionType'] = 'ACTION_SET_TP_SRC'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetTcpUdpDstPort":
+ tcpUdpDstPort = {}
+ tcpUdpDstPort['port'] = int(arg2)
+ action['actionSetTcpUdpDstPort'] = tcpUdpDstPort
+ # action['actionType'] = 'ACTION_SET_TP_DST'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionStripVlan":
+ stripVlan = {}
+ stripVlan['stripVlan'] = arg2 in ['True', 'true']
+ action['actionStripVlan'] = stripVlan
+ # action['actionType'] = 'ACTION_STRIP_VLAN'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetEthernetSrcAddr":
+ ethernetSrcAddr = {}
+ ethernetSrcAddr['value'] = arg2
+ setEthernetSrcAddr = {}
+ setEthernetSrcAddr['addr'] = ethernetSrcAddr
+ action['actionSetEthernetSrcAddr'] = setEthernetSrcAddr
+ # action['actionType'] = 'ACTION_SET_DL_SRC'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetEthernetDstAddr":
+ ethernetDstAddr = {}
+ ethernetDstAddr['value'] = arg2
+ setEthernetDstAddr = {}
+ setEthernetDstAddr['addr'] = ethernetDstAddr
+ action['actionSetEthernetDstAddr'] = setEthernetDstAddr
+ # action['actionType'] = 'ACTION_SET_DL_DST'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetIPv4SrcAddr":
+ IPv4SrcAddr = {}
+ IPv4SrcAddr['value'] = arg2
+ setIPv4SrcAddr = {}
+ setIPv4SrcAddr['addr'] = IPv4SrcAddr
+ action['actionSetIPv4SrcAddr'] = setIPv4SrcAddr
+ # action['actionType'] = 'ACTION_SET_NW_SRC'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetIPv4DstAddr":
+ IPv4DstAddr = {}
+ IPv4DstAddr['value'] = arg2
+ setIPv4DstAddr = {}
+ setIPv4DstAddr['addr'] = IPv4DstAddr
+ action['actionSetIPv4DstAddr'] = setIPv4DstAddr
+ # action['actionType'] = 'ACTION_SET_NW_DST'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionEnqueue":
+ # TODO: Implement ACTION_ENQUEUE
+ actionEnqueue = {}
+ # actionEnqueue['queueId'] = int(arg2)
+ # enqueuePort = {}
+ # enqueuePort['value'] = int(arg3)
+ # actionEnqueue['port'] = enqueuePort
+ # action['actionEnqueue'] = actionEnqueue
+ # # action['actionType'] = 'ACTION_ENQUEUE'
+ # actions.append(copy.deepcopy(action))
+ #
+ else:
+ log_error("ERROR: Unknown argument '%s'" % (arg1))
+ log_error(usage_msg)
+ exit(1)
+
+
+ #
+ # Add the match conditions to each flow entry
+ #
+ if (len(match) > 0) or matchInPortEnabled:
+ idx = 0
+ while idx < len(data_path['flowEntries']):
+ if matchInPortEnabled:
+ inPort = data_path['flowEntries'][idx]['inPort']
+ match['inPort'] = copy.deepcopy(inPort)
+ # match['matchInPort'] = True
+ data_path['flowEntries'][idx]['flowEntryMatch'] = copy.deepcopy(match)
+ idx = idx + 1
+
+ #
+ # Set the actions for each flow entry
+ # NOTE: The actions from the command line are aplied
+ # ONLY to the first flow entry.
+ #
+ # If ACTION_OUTPUT action is enabled, then apply it
+ # to each flow entry.
+ #
+ if (len(actions) > 0) or actionOutputEnabled:
+ idx = 0
+ while idx < len(data_path['flowEntries']):
+ if idx > 0:
+ actions = [] # Reset the actions for all but first entry
+ action = {}
+ outPort = data_path['flowEntries'][idx]['outPort']
+ actionOutput = {}
+ actionOutput['port'] = copy.deepcopy(outPort)
+ # actionOutput['maxLen'] = 0 # TODO: not used for now
+ action['actionOutput'] = copy.deepcopy(actionOutput)
+ # action['actionType'] = 'ACTION_OUTPUT'
+ actions.append(copy.deepcopy(action))
+
+ data_path['flowEntries'][idx]['flowEntryActions'] = copy.deepcopy(actions)
+ idx = idx + 1
+
+
flow_path['dataPath'] = data_path
flow_path_json = json.dumps(flow_path)