Work toward Issue #215 and Issue #216:
* Implemented the top-level API to support matching conditions and
actions for flows.
* Added Json serializer/deserializer for MACAddress.
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java b/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
new file mode 100644
index 0000000..304bb5c
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
@@ -0,0 +1,820 @@
+package net.floodlightcontroller.util;
+
+import net.floodlightcontroller.util.IPv4;
+import net.floodlightcontroller.util.MACAddress;
+import net.floodlightcontroller.util.Port;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * The class representing a single Flow Entry action.
+ *
+ * A set of Flow Entry actions need to be applied to each packet.
+ */
+public class FlowEntryAction {
+ /**
+ * Special action values.
+ *
+ * Those values are taken as-is from the OpenFlow-v1.0.0 specification
+ * (pp 21-22).
+ */
+ public enum ActionValues {
+ ACTION_OUTPUT ((short)0x0), // Output to switch port
+ ACTION_SET_VLAN_VID ((short)0x1), // Set the 802.1q VLAN id
+ ACTION_SET_VLAN_PCP ((short)0x2), // Set the 802.1q priority
+ ACTION_STRIP_VLAN ((short)0x3), // Strip the 802.1q header
+ ACTION_SET_DL_SRC ((short)0x4), // Ethernet source address
+ ACTION_SET_DL_DST ((short)0x5), // Ethernet destination address
+ ACTION_SET_NW_SRC ((short)0x6), // IP source address
+ ACTION_SET_NW_DST ((short)0x7), // IP destination address
+ ACTION_SET_NW_TOS ((short)0x8), // IP ToS (DSCP field, 6 bits)
+ ACTION_SET_TP_SRC ((short)0x9), // TCP/UDP source port
+ ACTION_SET_TP_DST ((short)0xa), // TCP/UDP destination port
+ ACTION_ENQUEUE ((short)0xb), // Output to queue on port
+ ACTION_VENDOR ((short)0xffff); // Vendor-specific
+
+ private final short value; // The value
+
+ /**
+ * Constructor for a given value.
+ *
+ * @param value the value to use for the initialization.
+ */
+ private ActionValues(short value) {
+ this.value = value;
+ }
+ }
+
+ /**
+ * Action structure for ACTION_OUTPUT: Output to switch port.
+ */
+ public class ActionOutput {
+ private Port port; // Output port
+ private short maxLen; // Max. length (in bytes) to send to controller
+ // if the port is set to PORT_CONTROLLER
+
+ /**
+ * Constructor for a given output port and maximum length.
+ *
+ * @param port the output port to set.
+ * @param maxLen the maximum length (in bytes) to send to controller
+ * if the port is set to PORT_CONTROLLER.
+ */
+ public ActionOutput(Port port, short maxLen) {
+ this.port = port;
+ this.maxLen = maxLen;
+ }
+
+ /**
+ * Get the output port.
+ *
+ * @return the output port.
+ */
+ @JsonProperty("port")
+ public Port port() {
+ return this.port;
+ }
+
+ /**
+ * Get the maximum length (in bytes) to send to controller if the
+ * port is set to PORT_CONTROLLER.
+ *
+ * @return the maximum length (in bytes) to send to controller if the
+ * port is set to PORT_CONTROLLER.
+ */
+ @JsonProperty("maxLen")
+ public short maxLen() {
+ return this.maxLen;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [port=XXX maxLen=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "port=" + port.toString();
+ ret += " maxLen=" + maxLen;
+ ret += "]";
+
+ return ret;
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_VLAN_VID: Set the 802.1q VLAN id
+ */
+ public class ActionSetVlanId {
+ private short vlanId; // The VLAN ID to set
+
+ /**
+ * Constructor for a given VLAN ID.
+ *
+ * @param vlanId the VLAN ID to set.
+ */
+ ActionSetVlanId(short vlanId) {
+ this.vlanId = vlanId;
+ }
+
+ /**
+ * Get the VLAN ID.
+ *
+ * @return the VLAN ID.
+ */
+ @JsonProperty("vlanId")
+ public short vlanId() {
+ return this.vlanId;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [vlanId=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "vlanId=" + this.vlanId;
+ ret += "]";
+
+ return ret;
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_VLAN_PCP: Set the 802.1q priority
+ */
+ public class ActionSetVlanPriority {
+ private byte vlanPriority; // The VLAN priority to set
+
+ /**
+ * Constructor for a given VLAN priority.
+ *
+ * @param vlanPriority the VLAN priority to set.
+ */
+ ActionSetVlanPriority(byte vlanPriority) {
+ this.vlanPriority = vlanPriority;
+ }
+
+ /**
+ * Get the VLAN priority.
+ *
+ * @return the VLAN priority.
+ */
+ @JsonProperty("vlanPriority")
+ public byte vlanPriority() {
+ return this.vlanPriority;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [vlanPriority=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "vlanPriority=" + this.vlanPriority;
+ ret += "]";
+
+ return ret;
+ }
+ }
+
+ /**
+ * Action structure for ACTION_STRIP_VLAN: Strip the 802.1q header
+ */
+ public class ActionStripVlan {
+ private boolean stripVlan; // If true, strip the VLAN header
+
+ /**
+ * Constructor for a given boolean flag.
+ *
+ * @param stripVlan if true, strip the VLAN header.
+ */
+ ActionStripVlan(boolean stripVlan) {
+ this.stripVlan = stripVlan;
+ }
+
+ /**
+ * Get the boolean flag whether the VLAN header should be stripped.
+ *
+ * @return the boolean flag whether the VLAN header should be stripped.
+ */
+ @JsonProperty("stripVlan")
+ public boolean stripVlan() {
+ return this.stripVlan;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [stripVlan=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "stripVlan=" + this.stripVlan;
+ ret += "]";
+
+ return ret;
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_DL_SRC and ACTION_SET_DL_DST:
+ * Set the Ethernet source/destination address.
+ */
+ public class ActionSetEthernetAddr {
+ private MACAddress addr; // The MAC address to set
+
+ /**
+ * Constructor for a given MAC address.
+ *
+ * @param addr the MAC address to set.
+ */
+ ActionSetEthernetAddr(MACAddress addr) {
+ this.addr = addr;
+ }
+
+ /**
+ * Get the MAC address.
+ *
+ * @return the MAC address.
+ */
+ @JsonProperty("addr")
+ public MACAddress addr() {
+ return this.addr;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "addr=" + addr.toString();
+ ret += "]";
+
+ return ret;
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_NW_SRC and ACTION_SET_NW_DST:
+ * Set the IPv4 source/destination address.
+ */
+ public class ActionSetIPv4Addr {
+ private IPv4 addr; // The IPv4 address to set
+
+ /**
+ * Constructor for a given IPv4 address.
+ *
+ * @param addr the IPv4 address to set.
+ */
+ ActionSetIPv4Addr(IPv4 addr) {
+ this.addr = addr;
+ }
+
+ /**
+ * Get the IPv4 address.
+ *
+ * @return the IPv4 address.
+ */
+ @JsonProperty("addr")
+ public IPv4 addr() {
+ return this.addr;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "addr=" + addr.toString();
+ ret += "]";
+
+ return ret;
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_NW_TOS:
+ * Set the IP ToS (DSCP field, 6 bits).
+ */
+ public class ActionSetIpToS {
+ private byte ipToS; // The IP ToS to set DSCP field, 6 bits)
+
+ /**
+ * Constructor for a given IP ToS (DSCP field, 6 bits).
+ *
+ * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+ */
+ ActionSetIpToS(byte ipToS) {
+ this.ipToS = ipToS;
+ }
+
+ /**
+ * Get the IP ToS (DSCP field, 6 bits).
+ *
+ * @return the IP ToS (DSCP field, 6 bits).
+ */
+ @JsonProperty("ipToS")
+ public byte ipToS() {
+ return this.ipToS;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [ipToS=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "ipToS=" + ipToS;
+ ret += "]";
+
+ return ret;
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_TP_SRC and ACTION_SET_TP_DST:
+ * Set the TCP/UDP source/destination port.
+ */
+ public class ActionSetTcpUdpPort {
+ private short port; // The TCP/UDP port to set
+
+ /**
+ * Constructor for a given TCP/UDP port.
+ *
+ * @param port the TCP/UDP port to set.
+ */
+ ActionSetTcpUdpPort(short port) {
+ this.port = port;
+ }
+
+ /**
+ * Get the TCP/UDP port.
+ *
+ * @return the TCP/UDP port.
+ */
+ @JsonProperty("port")
+ public short port() {
+ return this.port;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [port=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "port=" + port;
+ ret += "]";
+
+ return ret;
+ }
+ }
+
+ /**
+ * Action structure for ACTION_ENQUEUE: Output to queue on port.
+ */
+ public class ActionEnqueue {
+ private Port port; // Port that queue belongs. Should
+ // refer to a valid physical port
+ // (i.e. < PORT_MAX) or PORT_IN_PORT
+ private int queueId; // Where to enqueue the packets
+
+ /**
+ * Constructor for a given port and queue ID.
+ *
+ * @param port the port to set.
+ * @param queueId the queue ID on the port.
+ */
+ public ActionEnqueue(Port port, int queueId) {
+ this.port = port;
+ this.queueId = queueId;
+ }
+
+ /**
+ * Get the port.
+ *
+ * @return the port.
+ */
+ @JsonProperty("port")
+ public Port port() {
+ return this.port;
+ }
+
+ /**
+ * Get the queue ID.
+ *
+ * @return the queue ID.
+ */
+ @JsonProperty("queueId")
+ public int queueId() {
+ return this.queueId;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [port=XXX queueId=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "port=" + port.toString();
+ ret += " queueId=" + queueId;
+ ret += "]";
+
+ return ret;
+ }
+ }
+
+ private ActionValues actionType; // The action type
+
+ //
+ // The actions.
+ // NOTE: Only one action should be set.
+ //
+ private ActionOutput actionOutput;
+ private ActionSetVlanId actionSetVlanId;
+ private ActionSetVlanPriority actionSetVlanPriority;
+ private ActionStripVlan actionStripVlan;
+ private ActionSetEthernetAddr actionSetEthernetSrcAddr;
+ private ActionSetEthernetAddr actionSetEthernetDstAddr;
+ private ActionSetIPv4Addr actionSetIPv4SrcAddr;
+ private ActionSetIPv4Addr actionSetIPv4DstAddr;
+ private ActionSetIpToS actionSetIpToS;
+ private ActionSetTcpUdpPort actionSetTcpUdpSrcPort;
+ private ActionSetTcpUdpPort actionSetTcpUdpDstPort;
+ private ActionEnqueue actionEnqueue;
+
+ /**
+ * Default constructor.
+ */
+ public FlowEntryAction() {
+ actionType = ActionValues.ACTION_VENDOR; // XXX: Initial value
+ }
+
+ /**
+ * Get the action type.
+ *
+ * @return the action type.
+ */
+ @JsonProperty("actionType")
+ public ActionValues actionType() { return actionType; }
+
+ /**
+ * Get the output action.
+ *
+ * @return the output action.
+ */
+ @JsonProperty("actionOutput")
+ public ActionOutput actionOutput() { return actionOutput; }
+
+ /**
+ * Set the output action on a port.
+ *
+ * @param port the output port to set.
+ */
+ @JsonProperty("actionOutput")
+ public void setActionOutput(Port port) {
+ actionOutput = new ActionOutput(port, (short)0);
+ actionType = ActionValues.ACTION_OUTPUT;
+ }
+
+ /**
+ * Set the output action to controller.
+ *
+ * @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);
+ actionType = ActionValues.ACTION_OUTPUT;
+ }
+
+ /**
+ * Get the action to set the VLAN ID.
+ *
+ * @return the action to set the VLAN ID.
+ */
+ @JsonProperty("actionSetVlanId")
+ public ActionSetVlanId actionSetVlanId() { return actionSetVlanId; }
+
+ /**
+ * Set the action to set the VLAN ID.
+ *
+ * @param vlanId the VLAN ID to set.
+ */
+ @JsonProperty("actionSetVlanId")
+ public void setActionSetVlanId(short vlanId) {
+ actionSetVlanId = new ActionSetVlanId(vlanId);
+ actionType = ActionValues.ACTION_SET_VLAN_VID;
+ }
+
+ /**
+ * Get the action to set the VLAN priority.
+ *
+ * @return the action to set the VLAN priority.
+ */
+ @JsonProperty("actionSetVlanPriority")
+ public ActionSetVlanPriority actionSetVlanPriority() {
+ return actionSetVlanPriority;
+ }
+
+ /**
+ * Set the action to set the VLAN priority.
+ *
+ * @param vlanPriority the VLAN priority to set.
+ */
+ @JsonProperty("actionSetVlanPriority")
+ public void setActionSetVlanPriority(byte vlanPriority) {
+ actionSetVlanPriority = new ActionSetVlanPriority(vlanPriority);
+ actionType = ActionValues.ACTION_SET_VLAN_PCP;
+ }
+
+ /**
+ * Get the action to strip the VLAN header.
+ *
+ * @return the action to strip the VLAN header.
+ */
+ @JsonProperty("actionStripVlan")
+ public ActionStripVlan actionStripVlan() {
+ return actionStripVlan;
+ }
+
+ /**
+ * Set the action to strip the VLAN header.
+ *
+ * @param stripVlan if true, strip the VLAN header.
+ */
+ @JsonProperty("actionStripVlan")
+ public void setActionStripVlan(boolean stripVlan) {
+ actionStripVlan = new ActionStripVlan(stripVlan);
+ actionType = ActionValues.ACTION_STRIP_VLAN;
+ }
+
+ /**
+ * Get the action to set the Ethernet source address.
+ *
+ * @return the action to set the Ethernet source address.
+ */
+ @JsonProperty("actionSetEthernetSrcAddr")
+ public ActionSetEthernetAddr actionSetEthernetSrcAddr() {
+ return actionSetEthernetSrcAddr;
+ }
+
+ /**
+ * Set the action to set the Ethernet source address.
+ *
+ * @param addr the MAC address to set as the Ethernet source address.
+ */
+ @JsonProperty("actionSetEthernetSrcAddr")
+ public void setActionSetEthernetSrcAddr(MACAddress addr) {
+ actionSetEthernetSrcAddr = new ActionSetEthernetAddr(addr);
+ actionType = ActionValues.ACTION_SET_DL_SRC;
+ }
+
+ /**
+ * Get the action to set the Ethernet destination address.
+ *
+ * @return the action to set the Ethernet destination address.
+ */
+ @JsonProperty("actionSetEthernetDstAddr")
+ public ActionSetEthernetAddr actionSetEthernetDstAddr() {
+ return actionSetEthernetDstAddr;
+ }
+
+ /**
+ * Set the action to set the Ethernet destination address.
+ *
+ * @param addr the MAC address to set as the Ethernet destination address.
+ */
+ @JsonProperty("actionSetEthernetDstAddr")
+ public void setActionSetEthernetDstAddr(MACAddress addr) {
+ actionSetEthernetDstAddr = new ActionSetEthernetAddr(addr);
+ actionType = ActionValues.ACTION_SET_DL_DST;
+ }
+
+ /**
+ * Get the action to set the IPv4 source address.
+ *
+ * @return the action to set the IPv4 source address.
+ */
+ @JsonProperty("actionSetIPv4SrcAddr")
+ public ActionSetIPv4Addr actionSetIPv4SrcAddr() {
+ return actionSetIPv4SrcAddr;
+ }
+
+ /**
+ * Set the action to set the IPv4 source address.
+ *
+ * @param addr the IPv4 address to set as the IPv4 source address.
+ */
+ @JsonProperty("actionSetIPv4SrcAddr")
+ public void setActionSetIPv4SrcAddr(IPv4 addr) {
+ actionSetIPv4SrcAddr = new ActionSetIPv4Addr(addr);
+ actionType = ActionValues.ACTION_SET_NW_SRC;
+ }
+
+ /**
+ * Get the action to set the IPv4 destination address.
+ *
+ * @return the action to set the IPv4 destination address.
+ */
+ @JsonProperty("actionSetIPv4DstAddr")
+ public ActionSetIPv4Addr actionSetIPv4DstAddr() {
+ return actionSetIPv4DstAddr;
+ }
+
+ /**
+ * Set the action to set the IPv4 destination address.
+ *
+ * @param addr the IPv4 address to set as the IPv4 destination address.
+ */
+ @JsonProperty("actionSetIPv4DstAddr")
+ public void setActionSetIPv4DstAddr(IPv4 addr) {
+ actionSetIPv4DstAddr = new ActionSetIPv4Addr(addr);
+ actionType = ActionValues.ACTION_SET_NW_DST;
+ }
+
+ /**
+ * Get the action to set the IP ToS (DSCP field, 6 bits).
+ *
+ * @return the action to set the IP ToS (DSCP field, 6 bits).
+ */
+ @JsonProperty("actionSetIpToS")
+ public ActionSetIpToS actionSetIpToS() {
+ return actionSetIpToS;
+ }
+
+ /**
+ * Set the action to set the IP ToS (DSCP field, 6 bits).
+ *
+ * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+ */
+ @JsonProperty("actionSetIpToS")
+ public void setActionSetIpToS(byte ipToS) {
+ actionSetIpToS = new ActionSetIpToS(ipToS);
+ actionType = ActionValues.ACTION_SET_NW_TOS;
+ }
+
+ /**
+ * Get the action to set the TCP/UDP source port.
+ *
+ * @return the action to set the TCP/UDP source port.
+ */
+ @JsonProperty("actionSetTcpUdpSrcPort")
+ public ActionSetTcpUdpPort actionSetTcpUdpSrcPort() {
+ return actionSetTcpUdpSrcPort;
+ }
+
+ /**
+ * Set the action to set the TCP/UDP source port.
+ *
+ * @param port the TCP/UDP port to set as the TCP/UDP source port.
+ */
+ @JsonProperty("actionSetTcpUdpSrcPort")
+ public void setActionSetTcpUdpSrcPort(short port) {
+ actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(port);
+ actionType = ActionValues.ACTION_SET_TP_SRC;
+ }
+
+ /**
+ * Get the action to set the TCP/UDP destination port.
+ *
+ * @return the action to set the TCP/UDP destination port.
+ */
+ @JsonProperty("actionSetTcpUdpDstPort")
+ public ActionSetTcpUdpPort actionSetTcpUdpDstPort() {
+ return actionSetTcpUdpDstPort;
+ }
+
+ /**
+ * Set the action to set the TCP/UDP destination port.
+ *
+ * @param port the TCP/UDP port to set as the TCP/UDP destination port.
+ */
+ @JsonProperty("actionSetTcpUdpDstPort")
+ public void setActionSetTcpUdpDstPort(short port) {
+ actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(port);
+ actionType = ActionValues.ACTION_SET_TP_DST;
+ }
+
+ /**
+ * Get the action to output to queue on a port.
+ *
+ * @return the action to output to queue on a port.
+ */
+ @JsonProperty("actionEnqueue")
+ public ActionEnqueue actionEnqueue() { return actionEnqueue; }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Convert the set of actions to a string.
+ *
+ * The string has the following form:
+ * [type=XXX action=XXX]
+ *
+ * @return the set of actions as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "type=" + actionType;
+ switch (actionType) {
+ case ACTION_OUTPUT:
+ ret += " action=" + actionOutput.toString();
+ break;
+ case ACTION_SET_VLAN_VID:
+ ret += " action=" + actionSetVlanId.toString();
+ break;
+ case ACTION_SET_VLAN_PCP:
+ ret += " action=" + actionSetVlanPriority.toString();
+ break;
+ case ACTION_STRIP_VLAN:
+ ret += " action=" + actionStripVlan.toString();
+ break;
+ case ACTION_SET_DL_SRC:
+ ret += " action=" + actionSetEthernetSrcAddr.toString();
+ break;
+ case ACTION_SET_DL_DST:
+ ret += " action=" + actionSetEthernetDstAddr.toString();
+ break;
+ case ACTION_SET_NW_SRC:
+ ret += " action=" + actionSetIPv4SrcAddr.toString();
+ break;
+ case ACTION_SET_NW_DST:
+ ret += " action=" + actionSetIPv4DstAddr.toString();
+ break;
+ case ACTION_SET_NW_TOS:
+ ret += " action=" + actionSetIpToS.toString();
+ break;
+ case ACTION_SET_TP_SRC:
+ ret += " action=" + actionSetTcpUdpSrcPort.toString();
+ break;
+ case ACTION_SET_TP_DST:
+ ret += " action=" + actionSetTcpUdpDstPort.toString();
+ break;
+ case ACTION_ENQUEUE:
+ ret += " action=" + actionEnqueue.toString();
+ break;
+ }
+ ret += "]";
+
+ return ret;
+ }
+}