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/flowcache/FlowManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
index a5f759c..8cf1982 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
@@ -367,7 +367,7 @@
flowEntryObj.setUserState("FE_USER_ADD");
flowEntryObj.setSwitchState("FE_SWITCH_NOT_UPDATED");
//
- // TODO: Take care of the FlowEntryMatch, FlowEntryActions,
+ // TODO: Take care of the FlowEntryMatch, FlowEntryAction set,
// and FlowEntryErrorState.
//
@@ -647,7 +647,7 @@
String switchState = flowEntryObj.getSwitchState();
flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
//
- // TODO: Take care of the FlowEntryMatch, FlowEntryActions,
+ // TODO: Take care of the FlowEntryMatch, FlowEntryAction set,
// and FlowEntryErrorState.
//
flowPath.dataPath().flowEntries().add(flowEntry);
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntry.java b/src/main/java/net/floodlightcontroller/util/FlowEntry.java
index efab0cf..64c32b4 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntry.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntry.java
@@ -1,13 +1,18 @@
package net.floodlightcontroller.util;
+import java.util.ArrayList;
+
import net.floodlightcontroller.util.Dpid;
-import net.floodlightcontroller.util.FlowEntryActions;
+import net.floodlightcontroller.util.FlowEntryAction;
import net.floodlightcontroller.util.FlowEntryId;
import net.floodlightcontroller.util.FlowEntryMatch;
import net.floodlightcontroller.util.FlowEntrySwitchState;
import net.floodlightcontroller.util.FlowEntryUserState;
import net.floodlightcontroller.util.Port;
+import net.floodlightcontroller.util.MACAddress;
+import net.floodlightcontroller.util.IPv4;
+
import org.codehaus.jackson.annotate.JsonProperty;
/**
@@ -19,7 +24,7 @@
public class FlowEntry {
private FlowEntryId flowEntryId; // The Flow Entry ID
private FlowEntryMatch flowEntryMatch; // The Flow Entry Match
- private FlowEntryActions flowEntryActions; // The Flow Entry Actions
+ private ArrayList<FlowEntryAction> flowEntryActions; // The Flow Entry Actions
private Dpid dpid; // The Switch DPID
private Port inPort; // The Switch incoming port
private Port outPort; // The Switch outgoing port
@@ -32,6 +37,85 @@
* Default constructor.
*/
public FlowEntry() {
+ // TODO: Test code
+ /*
+ MACAddress mac = MACAddress.valueOf("01:02:03:04:05:06");
+ IPv4 ipv4 = new IPv4("1.2.3.4");
+ IPv4Net ipv4net = new IPv4Net("5.6.7.0/24");
+
+ flowEntryMatch = new FlowEntryMatch();
+ flowEntryMatch.enableInPort(new Port((short)10));
+ flowEntryMatch.enableSrcMac(mac);
+ flowEntryMatch.enableDstMac(mac);
+ flowEntryMatch.enableVlanId((short)20);
+ flowEntryMatch.enableVlanPriority((byte)30);
+ flowEntryMatch.enableEthernetFrameType((short)40);
+ flowEntryMatch.enableIpToS((byte)50);
+ flowEntryMatch.enableIpProto((byte)60);
+ flowEntryMatch.enableSrcIPv4Net(ipv4net);
+ flowEntryMatch.enableDstIPv4Net(ipv4net);
+ flowEntryMatch.enableSrcTcpUdpPort((short)70);
+ flowEntryMatch.enableDstTcpUdpPort((short)80);
+
+ FlowEntryAction action = null;
+ ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
+
+ action = new FlowEntryAction();
+ action.setActionOutput(new Port((short)12));
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionOutputToController((short)13);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetVlanId((short)14);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetVlanPriority((byte)15);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionStripVlan(true);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetEthernetSrcAddr(mac);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetEthernetDstAddr(mac);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetIPv4SrcAddr(ipv4);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetIPv4DstAddr(ipv4);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetIpToS((byte)16);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetTcpUdpSrcPort((short)17);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetTcpUdpDstPort((short)18);
+ actions.add(action);
+
+ action = new FlowEntryAction();
+ action.setActionEnqueue(new Port((short)19), 20);
+ actions.add(action);
+
+ setFlowEntryActions(actions);
+ */
+
+
flowEntryUserState = FlowEntryUserState.FE_USER_UNKNOWN;
flowEntrySwitchState = FlowEntrySwitchState.FE_SWITCH_UNKNOWN;
}
@@ -78,7 +162,9 @@
* @return the Flow Entry Actions.
*/
@JsonProperty("flowEntryActions")
- public FlowEntryActions flowEntryActions() { return flowEntryActions; }
+ public ArrayList<FlowEntryAction> flowEntryActions() {
+ return flowEntryActions;
+ }
/**
* Set the Flow Entry Actions.
@@ -86,7 +172,7 @@
* @param flowEntryActions the Flow Entry Actions to set.
*/
@JsonProperty("flowEntryActions")
- public void setFlowEntryActions(FlowEntryActions flowEntryActions) {
+ public void setFlowEntryActions(ArrayList<FlowEntryAction> flowEntryActions) {
this.flowEntryActions = flowEntryActions;
}
@@ -214,7 +300,8 @@
* Convert the flow entry to a string.
*
* The string has the following form:
- * [flowEntryId=XXX flowEntryMatch=XXX flowEntryActions=XXX dpid=XXX
+ * [flowEntryId=XXX flowEntryMatch=XXX flowEntryAction=XXX
+ * flowEntryAction=XXX flowEntryAction=XXX dpid=XXX
* inPort=XXX outPort=XXX flowEntryUserState=XXX flowEntrySwitchState=XXX
* flowEntryErrorState=XXX]
* @return the flow entry as a string.
@@ -223,7 +310,9 @@
public String toString() {
String ret = "[flowEntryId=" + this.flowEntryId.toString();
ret += " flowEntryMatch=" + this.flowEntryMatch.toString();
- ret += " flowEntryActions=" + this.flowEntryActions.toString();
+ for (FlowEntryAction fa : flowEntryActions) {
+ ret += " flowEntryAction=" + fa.toString();
+ }
ret += " dpid=" + this.dpid.toString();
ret += " inPort=" + this.inPort.toString();
ret += " outPort=" + this.outPort.toString();
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;
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java b/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java
deleted file mode 100644
index 4d17de8..0000000
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package net.floodlightcontroller.util;
-
-import org.codehaus.jackson.annotate.JsonProperty;
-
-/**
- * The class representing the Flow Entry set of actions.
- *
- * The Flow Entry set of actions need to be applied to each packet.
- *
- * NOTE: This is just an empty placeholder (for now). The implied action is
- * forwarding on a single port.
- */
-public class FlowEntryActions {
-
- /**
- * Default constructor.
- */
- public FlowEntryActions() {
- }
-
- /**
- * Convert the set of actions to a string.
- *
- * @return the set of actions as a string.
- */
- @Override
- public String toString() {
- String ret = "";
- // TODO: Implement it!
- return ret;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java b/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
index 9bd3bea..64527c5 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
@@ -10,18 +10,76 @@
*
* The Flow Entry matching filter that is used to specify
* the network data that would be forwarded on the data path from
- * the source to the destination. Examples: MAC address (of the
- * sender), IP prefix that includes the destination's IP address, etc.
- *
- * NOTE: The FlowEntryMatch specification below is incomplete: we need
- * more matching fields, we need to indicate which fields need to be
- * matched, etc.
+ * the source to the destination. Examples: source or destination MAC address,
+ * IP prefix that includes the destination's IP address, etc.
*/
public class FlowEntryMatch {
- private MACAddress srcMac; // Matching source MAC address
- private MACAddress dstMac; // Matching destination MAC address
- private IPv4Net srcIPv4Net; // Matching source IPv4 prefix
- private IPv4Net dstIPv4Net; // Matching destination IPv4 prefix
+ /**
+ * A class for storing a value to match.
+ */
+ class Field<T> {
+ /**
+ * Default constructor.
+ */
+ public Field() {
+ this.enabled = false;
+ }
+
+ /**
+ * Constructor for a given value to match.
+ */
+ public Field(T value) {
+ this.value = value;
+ this.enabled = true;
+ }
+
+ /**
+ * Get the value.
+ *
+ * @return the value.
+ */
+ public T value() { return this.value; }
+
+ /**
+ * Enable the matching for a given value.
+ *
+ * @param value the value to set.
+ */
+ public void enableMatch(T value) {
+ this.value = value;
+ this.enabled = true;
+ }
+
+ /**
+ * Disable the matching.
+ */
+ public void disableMatch() {
+ this.enabled = false;
+ }
+
+ /**
+ * Test whether matching is enabled.
+ *
+ * @return true if matching is enabled, otherwise false.
+ */
+ public boolean enabled() { return this.enabled; }
+
+ private T value; // The value to match
+ private boolean enabled; // Set to true, if matching is enabled
+ }
+
+ private Field<Port> inPort; // Matching input switch port
+ private Field<MACAddress> srcMac; // Matching source MAC address
+ private Field<MACAddress> dstMac; // Matching destination MAC address
+ private Field<Short> vlanId; // Matching VLAN ID
+ private Field<Byte> vlanPriority; // Matching VLAN priority
+ private Field<Short> ethernetFrameType; // Matching Ethernet frame type
+ private Field<Byte> ipToS; // Matching IP ToS (DSCP field, 6 bits)
+ private Field<Byte> ipProto; // Matching IP protocol
+ private Field<IPv4Net> srcIPv4Net; // Matching source IPv4 prefix
+ private Field<IPv4Net> dstIPv4Net; // Matching destination IPv4 prefix
+ private Field<Short> srcTcpUdpPort; // Matching source TCP/UDP port
+ private Field<Short> dstTcpUdpPort; // Matching destination TCP/UDP port
/**
* Default constructor.
@@ -30,21 +88,85 @@
}
/**
+ * Get the matching input switch port.
+ *
+ * @return the matching input switch port.
+ */
+ @JsonProperty("inPort")
+ public Port inPort() {
+ if (inPort != null)
+ return inPort.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on input switch port.
+ *
+ * @param inPort the input switch port value to enable for matching.
+ */
+ @JsonProperty("inPort")
+ public void enableInPort(Port inPort) {
+ this.inPort = new Field<Port>(inPort);
+ }
+
+ /**
+ * Disable the matching on input switch port.
+ */
+ public void disableInPort() {
+ this.inPort = null;
+ }
+
+ /**
+ * Test if matching on input switch port is enabled.
+ *
+ * @return true if matching on input switch port is enabled.
+ */
+ @JsonProperty("matchInPort")
+ public boolean matchInPort() {
+ if (inPort != null)
+ return inPort.enabled();
+ return false;
+ }
+
+ /**
* Get the matching source MAC address.
*
* @return the matching source MAC address.
*/
@JsonProperty("srcMac")
- public MACAddress srcMac() { return srcMac; }
+ public MACAddress srcMac() {
+ if (srcMac != null)
+ return srcMac.value();
+ return null;
+ }
/**
- * Set the matching source MAC address.
+ * Enable the matching on source MAC address.
*
- * @param srcMac the matching source MAC address to set.
+ * @param srcMac the source MAC address value to enable for matching.
*/
@JsonProperty("srcMac")
- public void setSrcMac(MACAddress srcMac) {
- this.srcMac = srcMac;
+ public void enableSrcMac(MACAddress srcMac) {
+ this.srcMac = new Field<MACAddress>(srcMac);
+ }
+
+ /**
+ * Disable the matching on source MAC address.
+ */
+ public void disableSrcMac() {
+ this.srcMac = null;
+ }
+
+ /**
+ * Test if matching on source MAC address is enabled.
+ *
+ * @return true if matching on source MAC address is enabled.
+ */
+ @JsonProperty("matchSrcMac")
+ public boolean matchSrcMac() {
+ if (srcMac != null)
+ return srcMac.enabled();
+ return false;
}
/**
@@ -53,16 +175,245 @@
* @return the matching destination MAC address.
*/
@JsonProperty("dstMac")
- public MACAddress dstMac() { return dstMac; }
+ public MACAddress dstMac() {
+ if (dstMac != null)
+ return dstMac.value();
+ return null;
+ }
/**
- * Set the matching destination MAC address.
+ * Enable the matching on destination MAC address.
*
- * @param dstMac the matching destination MAC address to set.
+ * @param dstMac the destination MAC address value to enable for matching.
*/
@JsonProperty("dstMac")
- public void setDstMac(MACAddress dstMac) {
- this.dstMac = dstMac;
+ public void enableDstMac(MACAddress dstMac) {
+ this.dstMac = new Field<MACAddress>(dstMac);
+ }
+
+ /**
+ * Disable the matching on destination MAC address.
+ */
+ public void disableDstMac() {
+ this.dstMac = null;
+ }
+
+ /**
+ * Test if matching on destination MAC address is enabled.
+ *
+ * @return true if matching on destination MAC address is enabled.
+ */
+ @JsonProperty("matchDstMac")
+ public boolean matchDstMac() {
+ if (dstMac != null)
+ return dstMac.enabled();
+ return false;
+ }
+
+ /**
+ * Get the matching VLAN ID.
+ *
+ * @return the matching VLAN ID.
+ */
+ @JsonProperty("vlanId")
+ public Short vlanId() {
+ if (vlanId != null)
+ return vlanId.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on VLAN ID.
+ *
+ * @param vlanId the VLAN ID value to enable for matching.
+ */
+ @JsonProperty("vlanId")
+ public void enableVlanId(Short vlanId) {
+ this.vlanId = new Field<Short>(vlanId);
+ }
+
+ /**
+ * Disable the matching on VLAN ID.
+ */
+ public void disableVlanId() {
+ this.vlanId = null;
+ }
+
+ /**
+ * Test if matching on VLAN ID is enabled.
+ *
+ * @return true if matching on VLAN ID is enabled.
+ */
+ @JsonProperty("matchVlanId")
+ public boolean matchVlanId() {
+ if (vlanId != null)
+ return vlanId.enabled();
+ return false;
+ }
+
+ /**
+ * Get the matching VLAN priority.
+ *
+ * @return the matching VLAN priority.
+ */
+ @JsonProperty("vlanPriority")
+ public Byte vlanPriority() {
+ if (vlanPriority != null)
+ return vlanPriority.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on VLAN priority.
+ *
+ * @param vlanPriority the VLAN priority value to enable for matching.
+ */
+ @JsonProperty("vlanPriority")
+ public void enableVlanPriority(Byte vlanPriority) {
+ this.vlanPriority = new Field<Byte>(vlanPriority);
+ }
+
+ /**
+ * Disable the matching on VLAN priority.
+ */
+ public void disableVlanPriority() {
+ this.vlanPriority = null;
+ }
+
+ /**
+ * Test if matching on VLAN priority is enabled.
+ *
+ * @return true if matching on VLAN priority is enabled.
+ */
+ @JsonProperty("matchVlanPriority")
+ public boolean matchVlanPriority() {
+ if (vlanPriority != null)
+ return vlanPriority.enabled();
+ return false;
+ }
+
+ /**
+ * Get the matching Ethernet frame type.
+ *
+ * @return the matching Ethernet frame type.
+ */
+ @JsonProperty("ethernetFrameType")
+ public Short ethernetFrameType() {
+ if (ethernetFrameType != null)
+ return ethernetFrameType.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on Ethernet frame type.
+ *
+ * @param ethernetFrameType the Ethernet frame type value to enable for
+ * matching.
+ */
+ @JsonProperty("ethernetFrameType")
+ public void enableEthernetFrameType(Short ethernetFrameType) {
+ this.ethernetFrameType = new Field<Short>(ethernetFrameType);
+ }
+
+ /**
+ * Disable the matching on Ethernet frame type.
+ */
+ public void disableEthernetFrameType() {
+ this.ethernetFrameType = null;
+ }
+
+ /**
+ * Test if matching on Ethernet frame type is enabled.
+ *
+ * @return true if matching on Ethernet frame type is enabled.
+ */
+ @JsonProperty("matchEthernetFrameType")
+ public boolean matchEthernetFrameType() {
+ if (ethernetFrameType != null)
+ return ethernetFrameType.enabled();
+ return false;
+ }
+
+ /**
+ * Get the matching IP ToS (DSCP field, 6 bits)
+ *
+ * @return the matching IP ToS.
+ */
+ @JsonProperty("ipToS")
+ public Byte ipToS() {
+ if (ipToS != null)
+ return ipToS.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on IP ToS (DSCP field, 6 bits).
+ *
+ * @param ipToS the IP ToS value to enable for matching.
+ */
+ @JsonProperty("ipToS")
+ public void enableIpToS(Byte ipToS) {
+ this.ipToS = new Field<Byte>(ipToS);
+ }
+
+ /**
+ * Disable the matching on IP ToS (DSCP field, 6 bits).
+ */
+ public void disableIpToS() {
+ this.ipToS = null;
+ }
+
+ /**
+ * Test if matching on IP ToS (DSCP field, 6 bits) is enabled.
+ *
+ * @return true if matching on IP ToS is enabled.
+ */
+ @JsonProperty("matchIpToS")
+ public boolean matchIpToS() {
+ if (ipToS != null)
+ return ipToS.enabled();
+ return false;
+ }
+
+ /**
+ * Get the matching IP protocol.
+ *
+ * @return the matching IP protocol.
+ */
+ @JsonProperty("ipProto")
+ public Byte ipProto() {
+ if (ipProto != null)
+ return ipProto.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on IP protocol.
+ *
+ * @param ipProto the IP protocol value to enable for matching.
+ */
+ @JsonProperty("ipProto")
+ public void enableIpProto(Byte ipProto) {
+ this.ipProto = new Field<Byte>(ipProto);
+ }
+
+ /**
+ * Disable the matching on IP protocol.
+ */
+ public void disableIpProto() {
+ this.ipProto = null;
+ }
+
+ /**
+ * Test if matching on IP protocol is enabled.
+ *
+ * @return true if matching on IP protocol is enabled.
+ */
+ @JsonProperty("matchIpProto")
+ public boolean matchIpProto() {
+ if (ipProto != null)
+ return ipProto.enabled();
+ return false;
}
/**
@@ -71,16 +422,39 @@
* @return the matching source IPv4 prefix.
*/
@JsonProperty("srcIPv4Net")
- public IPv4Net srcIPv4Net() { return srcIPv4Net; }
+ public IPv4Net srcIPv4Net() {
+ if (srcIPv4Net != null)
+ return srcIPv4Net.value();
+ return null;
+ }
/**
- * Set the matching source IPv4 prefix.
+ * Enable the matching on source IPv4 prefix.
*
- * @param srcIPv4Net the matching source IPv4 prefix to set.
+ * @param srcIPv4Net the source IPv4 prefix value to enable for matching.
*/
@JsonProperty("srcIPv4Net")
- public void setSrcIPv4Net(IPv4Net srcIPv4Net) {
- this.srcIPv4Net = srcIPv4Net;
+ public void enableSrcIPv4Net(IPv4Net srcIPv4Net) {
+ this.srcIPv4Net = new Field<IPv4Net>(srcIPv4Net);
+ }
+
+ /**
+ * Disable the matching on source IPv4 prefix.
+ */
+ public void disableSrcIPv4Net() {
+ this.srcIPv4Net = null;
+ }
+
+ /**
+ * Test if matching on source IPv4 prefix is enabled.
+ *
+ * @return true if matching on source IPv4 prefix is enabled.
+ */
+ @JsonProperty("matchSrcIPv4Net")
+ public boolean matchSrcIPv4Net() {
+ if (srcIPv4Net != null)
+ return srcIPv4Net.enabled();
+ return false;
}
/**
@@ -89,16 +463,123 @@
* @return the matching destination IPv4 prefix.
*/
@JsonProperty("dstIPv4Net")
- public IPv4Net dstIPv4Net() { return dstIPv4Net; }
+ public IPv4Net dstIPv4Net() {
+ if (dstIPv4Net != null)
+ return dstIPv4Net.value();
+ return null;
+ }
/**
- * Set the matching destination IPv4 prefix.
+ * Enable the matching on destination IPv4 prefix.
*
- * @param srcIPv4Net the matching destination IPv4 prefix to set.
+ * @param dstIPv4Net the destination IPv4 prefix value to enable for
+ * matching.
*/
@JsonProperty("dstIPv4Net")
- public void setDstIPv4Net(IPv4Net dstIPv4Net) {
- this.dstIPv4Net = dstIPv4Net;
+ public void enableDstIPv4Net(IPv4Net dstIPv4Net) {
+ this.dstIPv4Net = new Field<IPv4Net>(dstIPv4Net);
+ }
+
+ /**
+ * Disable the matching on destination IPv4 prefix.
+ */
+ public void disableDstIPv4Net() {
+ this.dstIPv4Net = null;
+ }
+
+ /**
+ * Test if matching on destination IPv4 prefix is enabled.
+ *
+ * @return true if matching on destination IPv4 prefix is enabled.
+ */
+ @JsonProperty("matchDstIPv4Net")
+ public boolean matchDstIPv4Net() {
+ if (dstIPv4Net != null)
+ return dstIPv4Net.enabled();
+ return false;
+ }
+
+ /**
+ * Get the matching source TCP/UDP port.
+ *
+ * @return the matching source TCP/UDP port.
+ */
+ @JsonProperty("srcTcpUdpPort")
+ public Short srcTcpUdpPort() {
+ if (srcTcpUdpPort != null)
+ return srcTcpUdpPort.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on source TCP/UDP port.
+ *
+ * @param srcTcpUdpPort the source TCP/UDP port to enable for matching.
+ */
+ @JsonProperty("srcTcpUdpPort")
+ public void enableSrcTcpUdpPort(Short srcTcpUdpPort) {
+ this.srcTcpUdpPort = new Field<Short>(srcTcpUdpPort);
+ }
+
+ /**
+ * Disable the matching on source TCP/UDP port.
+ */
+ public void disableSrcTcpUdpPort() {
+ this.srcTcpUdpPort = null;
+ }
+
+ /**
+ * Test if matching on source TCP/UDP port is enabled.
+ *
+ * @return true if matching on source TCP/UDP port is enabled.
+ */
+ @JsonProperty("matchSrcTcpUdpPort")
+ public boolean matchSrcTcpUdpPort() {
+ if (srcTcpUdpPort != null)
+ return srcTcpUdpPort.enabled();
+ return false;
+ }
+
+ /**
+ * Get the matching destination TCP/UDP port.
+ *
+ * @return the matching destination TCP/UDP port.
+ */
+ @JsonProperty("dstTcpUdpPort")
+ public Short dstTcpUdpPort() {
+ if (dstTcpUdpPort != null)
+ return dstTcpUdpPort.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on destination TCP/UDP port.
+ *
+ * @param dstTcpUdpPort the destination TCP/UDP port to enable for
+ * matching.
+ */
+ @JsonProperty("dstTcpUdpPort")
+ public void enableDstTcpUdpPort(Short dstTcpUdpPort) {
+ this.dstTcpUdpPort = new Field<Short>(dstTcpUdpPort);
+ }
+
+ /**
+ * Disable the matching on destination TCP/UDP port.
+ */
+ public void disableDstTcpUdpPort() {
+ this.dstTcpUdpPort = null;
+ }
+
+ /**
+ * Test if matching on destination TCP/UDP port is enabled.
+ *
+ * @return true if matching on destination TCP/UDP port is enabled.
+ */
+ @JsonProperty("matchDstTcpUdpPort")
+ public boolean matchDstTcpUdpPort() {
+ if (dstTcpUdpPort != null)
+ return dstTcpUdpPort.enabled();
+ return false;
}
/**
@@ -111,11 +592,87 @@
*/
@Override
public String toString() {
- String ret = "[srcMac=" + this.srcMac.toString();
- ret += " dstMac=" + this.dstMac.toString();
- ret += " srcIPv4Net=" + this.srcIPv4Net.toString();
- ret += " dstIPv4Net=" + this.dstIPv4Net.toString();
+ String ret = "[";
+ boolean addSpace = false;
+
+ //
+ // Conditionally add only those matching fields that are enabled
+ //
+ if (matchInPort()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "inPort=" + this.inPort().toString();
+ }
+ if (matchSrcMac()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "srcMac=" + this.srcMac().toString();
+ }
+ if (matchDstMac()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "dstMac=" + this.dstMac().toString();
+ }
+ if (matchVlanId()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "vlanId=" + this.vlanId().toString();
+ }
+ if (matchVlanPriority()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "vlanPriority=" + this.vlanPriority().toString();
+ }
+ if (matchEthernetFrameType()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "ethernetFrameType=" + this.ethernetFrameType().toString();
+ }
+ if (matchIpToS()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "ipToS=" + this.ipToS().toString();
+ }
+ if (matchIpProto()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "ipProto=" + this.ipProto().toString();
+ }
+ if (matchSrcIPv4Net()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "srcIPv4Net=" + this.srcIPv4Net().toString();
+ }
+ if (matchDstIPv4Net()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "dstIPv4Net=" + this.dstIPv4Net().toString();
+ }
+ if (matchSrcTcpUdpPort()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "srcTcpUdpPort=" + this.srcTcpUdpPort().toString();
+ }
+ if (matchDstTcpUdpPort()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "dstTcpUdpPort=" + this.dstTcpUdpPort().toString();
+ }
+
ret += "]";
+
return ret;
}
}
diff --git a/src/main/java/net/floodlightcontroller/util/MACAddress.java b/src/main/java/net/floodlightcontroller/util/MACAddress.java
index 4ba9dad..743dc5b 100644
--- a/src/main/java/net/floodlightcontroller/util/MACAddress.java
+++ b/src/main/java/net/floodlightcontroller/util/MACAddress.java
@@ -2,11 +2,20 @@
import java.util.Arrays;
+import net.floodlightcontroller.util.serializers.MACAddressDeserializer;
+import net.floodlightcontroller.util.serializers.MACAddressSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
/**
* The class representing MAC address.
*
* @author Sho Shimizu (sho.shimizu@gmail.com)
*/
+@JsonDeserialize(using=MACAddressDeserializer.class)
+@JsonSerialize(using=MACAddressSerializer.class)
public class MACAddress {
public static final int MAC_ADDRESS_LENGTH = 6;
private byte[] address = new byte[MAC_ADDRESS_LENGTH];
diff --git a/src/main/java/net/floodlightcontroller/util/Port.java b/src/main/java/net/floodlightcontroller/util/Port.java
index 19bbf8f..41f0d55 100644
--- a/src/main/java/net/floodlightcontroller/util/Port.java
+++ b/src/main/java/net/floodlightcontroller/util/Port.java
@@ -5,7 +5,69 @@
/**
* The class representing a network port of a switch.
*/
+
public class Port {
+ /**
+ * Special port values.
+ *
+ * Those values are taken as-is from the OpenFlow-v1.0.0 specification
+ * (pp 18-19).
+ */
+ public enum PortValues {
+ /* Maximum number of physical switch ports. */
+ PORT_MAX ((short)0xff00),
+
+ /* Fake output "ports". */
+
+ /* Send the packet out the input port. This
+ virtual port must be explicitly used
+ in order to send back out of the input
+ port. */
+ PORT_IN_PORT ((short)0xfff8),
+
+ /* Perform actions in flow table.
+ NB: This can only be the destination
+ port for packet-out messages. */
+ PORT_TABLE ((short)0xfff9),
+
+ /* Process with normal L2/L3 switching. */
+ PORT_NORMAL ((short)0xfffa),
+
+ /* All physical ports except input port and
+ those disabled by STP. */
+ PORT_FLOOD ((short)0xfffb),
+
+ /* All physical ports except input port. */
+ PORT_ALL ((short)0xfffc),
+
+ /* Send to controller. */
+ PORT_CONTROLLER ((short)0xfffd),
+
+ /* Local openflow "port". */
+ PORT_LOCAL ((short)0xfffe),
+
+ /* Not associated with a physical port. */
+ PORT_NONE ((short)0xffff);
+
+ private final short value; // The value
+
+ /**
+ * Constructor for a given value.
+ *
+ * @param value the value to use for the initialization.
+ */
+ private PortValues(short value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the value as a short integer.
+ *
+ * @return the value as a short integer.
+ */
+ private short value() { return this.value; }
+ }
+
private short value;
/**
@@ -25,7 +87,7 @@
}
/**
- * Constructor from a long value.
+ * Constructor from a short integer value.
*
* @param value the value to use.
*/
@@ -34,6 +96,15 @@
}
/**
+ * Constructor from a PortValues enum value.
+ *
+ * @param value the value to use.
+ */
+ public Port(PortValues value) {
+ this.value = value.value();
+ }
+
+ /**
* Get the value of the port.
*
* @return the value of the port.
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4Deserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv4Deserializer.java
index 7ce7d5c..275f9f0 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv4Deserializer.java
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv4Deserializer.java
@@ -16,7 +16,7 @@
import org.slf4j.LoggerFactory;
/**
- * Deserialize an IPv4 from a string.
+ * Deserialize an IPv4 address from a string.
*/
public class IPv4Deserializer extends JsonDeserializer<IPv4> {
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetDeserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetDeserializer.java
index e35fc80..3c36870 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetDeserializer.java
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetDeserializer.java
@@ -16,7 +16,7 @@
import org.slf4j.LoggerFactory;
/**
- * Deserialize an IPv4Net from a string.
+ * Deserialize an IPv4Net address from a string.
*/
public class IPv4NetDeserializer extends JsonDeserializer<IPv4Net> {
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6Deserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv6Deserializer.java
index 6713f93..818de30 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv6Deserializer.java
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv6Deserializer.java
@@ -16,7 +16,7 @@
import org.slf4j.LoggerFactory;
/**
- * Deserialize an IPv6 from a string.
+ * Deserialize an IPv6 address from a string.
*/
public class IPv6Deserializer extends JsonDeserializer<IPv6> {
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetDeserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetDeserializer.java
index 596ee50..375dc26 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetDeserializer.java
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetDeserializer.java
@@ -16,7 +16,7 @@
import org.slf4j.LoggerFactory;
/**
- * Deserialize an IPv6Net from a string.
+ * Deserialize an IPv6Net address from a string.
*/
public class IPv6NetDeserializer extends JsonDeserializer<IPv6Net> {
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/MACAddressDeserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/MACAddressDeserializer.java
new file mode 100644
index 0000000..35b384d
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/MACAddressDeserializer.java
@@ -0,0 +1,43 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.DeserializationContext;
+
+import net.floodlightcontroller.util.MACAddress;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Deserialize a MAC address from a string.
+ */
+public class MACAddressDeserializer extends JsonDeserializer<MACAddress> {
+
+ protected static Logger log = LoggerFactory.getLogger(MACAddressDeserializer.class);
+
+ @Override
+ public MACAddress deserialize(JsonParser jp,
+ DeserializationContext ctxt)
+ throws IOException, JsonProcessingException {
+
+ MACAddress mac = null;
+
+ jp.nextToken(); // Move to JsonToken.START_OBJECT
+ while (jp.nextToken() != JsonToken.END_OBJECT) {
+ String fieldname = jp.getCurrentName();
+ if ("value".equals(fieldname)) {
+ String value = jp.getText();
+ log.debug("Fieldname: " + fieldname + " Value: " + value);
+ mac = MACAddress.valueOf(value);
+ }
+ }
+ return mac;
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/MACAddressSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/MACAddressSerializer.java
new file mode 100644
index 0000000..dec2596
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/MACAddressSerializer.java
@@ -0,0 +1,25 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.MACAddress;
+
+/**
+ * Serialize a MAC address as a string.
+ */
+public class MACAddressSerializer extends JsonSerializer<MACAddress> {
+
+ @Override
+ public void serialize(MACAddress mac, JsonGenerator jGen,
+ SerializerProvider serializer)
+ throws IOException, JsonProcessingException {
+ jGen.writeStartObject();
+ jGen.writeStringField("value", mac.toString());
+ jGen.writeEndObject();
+ }
+}
diff --git a/web/get_flow.py b/web/get_flow.py
index b20e134..dd6a8b6 100755
--- a/web/get_flow.py
+++ b/web/get_flow.py
@@ -34,23 +34,115 @@
# {"flowId":{"value":"0x5"},"installerId":{"value":"FOOBAR"},"dataPath":{"srcPort":{"dpid":{"value":"00:00:00:00:00:00:00:01"},"port":{"value":0}},"dstPort":{"dpid":{"value":"00:00:00:00:00:00:00:02"},"port":{"value":0}},"flowEntries":[{"flowEntryId":"0x1389","flowEntryMatch":null,"flowEntryActions":null,"dpid":{"value":"00:00:00:00:00:00:00:01"},"inPort":{"value":0},"outPort":{"value":1},"flowEntryUserState":"FE_USER_DELETE","flowEntrySwitchState":"FE_SWITCH_NOT_UPDATED","flowEntryErrorState":null},{"flowEntryId":"0x138a","flowEntryMatch":null,"flowEntryActions":null,"dpid":{"value":"00:00:00:00:00:00:00:02"},"inPort":{"value":9},"outPort":{"value":0},"flowEntryUserState":"FE_USER_DELETE","flowEntrySwitchState":"FE_SWITCH_NOT_UPDATED","flowEntryErrorState":null}]}}
def print_flow_path(parsedResult):
- flowId = parsedResult['flowId']['value'];
- installerId = parsedResult['installerId']['value'];
- srcSwitch = parsedResult['dataPath']['srcPort']['dpid']['value'];
- srcPort = parsedResult['dataPath']['srcPort']['port']['value'];
- dstSwitch = parsedResult['dataPath']['dstPort']['dpid']['value'];
- dstPort = parsedResult['dataPath']['dstPort']['port']['value'];
+ flowId = parsedResult['flowId']['value']
+ installerId = parsedResult['installerId']['value']
+ srcSwitch = parsedResult['dataPath']['srcPort']['dpid']['value']
+ srcPort = parsedResult['dataPath']['srcPort']['port']['value']
+ dstSwitch = parsedResult['dataPath']['dstPort']['dpid']['value']
+ dstPort = parsedResult['dataPath']['dstPort']['port']['value']
print "FlowPath: (flowId = %s installerId = %s src = %s/%s dst = %s/%s)" % (flowId, installerId, srcSwitch, srcPort, dstSwitch, dstPort)
for f in parsedResult['dataPath']['flowEntries']:
- inPort = f['inPort']['value'];
- outPort = f['outPort']['value'];
+ inPort = f['inPort']['value']
+ outPort = f['outPort']['value']
dpid = f['dpid']['value']
userState = f['flowEntryUserState']
switchState = f['flowEntrySwitchState']
+ match = f['flowEntryMatch'];
+ actions = f['flowEntryActions']
print " FlowEntry: (%s, %s, %s, %s, %s)" % (inPort, dpid, outPort, userState, switchState)
+ inPort = match['inPort']
+ matchInPort = match['matchInPort']
+ srcMac = match['srcMac']
+ matchSrcMac = match['matchSrcMac']
+ dstMac = match['dstMac']
+ matchDstMac = match['matchDstMac']
+ vlanId = match['vlanId']
+ matchVlanId = match['matchVlanId']
+ vlanPriority = match['vlanPriority']
+ matchVlanPriority = match['matchVlanPriority']
+ ethernetFrameType = match['ethernetFrameType']
+ matchEthernetFrameType = match['matchEthernetFrameType']
+ ipToS = match['ipToS']
+ matchIpToS = match['matchIpToS']
+ ipProto = match['ipProto']
+ matchIpProto = match['matchIpProto']
+ srcIPv4Net = match['srcIPv4Net']
+ matchSrcIPv4Net = match['matchSrcIPv4Net']
+ dstIPv4Net = match['dstIPv4Net']
+ matchDstIPv4Net = match['matchDstIPv4Net']
+ srcTcpUdpPort = match['srcTcpUdpPort']
+ matchSrcTcpUdpPort = match['matchSrcTcpUdpPort']
+ dstTcpUdpPort = match['dstTcpUdpPort']
+ matchDstTcpUdpPort = match['matchDstTcpUdpPort']
+ if matchInPort == True:
+ print " inPort: %s" % inPort['value']
+ if matchSrcMac == True:
+ print " srcMac: %s" % srcMac['value']
+ if matchDstMac == True:
+ print " dstMac: %s" % dstMac['value']
+ if matchVlanId == True:
+ print " vlanId: %s" % vlanId
+ if matchVlanPriority == True:
+ print " vlanPriority: %s" % vlanPriority
+ if matchEthernetFrameType == True:
+ print " ethernetFrameType: %s" % ethernetFrameType
+ if matchIpToS == True:
+ print " ipToS: %s" % ipToS
+ if matchIpProto == True:
+ print " ipProto: %s" % ipProto
+ if matchSrcIPv4Net == True:
+ print " srcIPv4Net: %s" % srcIPv4Net['value']
+ if matchDstIPv4Net == True:
+ print " dstIPv4Net: %s" % dstIPv4Net['value']
+ if matchSrcTcpUdpPort == True:
+ print " srcTcpUdpPort: %s" % srcTcpUdpPort
+ if matchDstTcpUdpPort == True:
+ print " dstTcpUdpPort: %s" % dstTcpUdpPort
+
+ for a in actions:
+ actionType = a['actionType']
+ if actionType == "ACTION_OUTPUT":
+ port = a['actionOutput']['port']
+ maxLen = a['actionOutput']['maxLen']
+ print " actionType: %s port: %s maxLen: %s" % (actionType, port, maxLen)
+ if actionType == "ACTION_SET_VLAN_VID":
+ vlanId = a['actionSetVlanId']['vlanId']
+ print " actionType: %s vlanId: %s" % (actionType, vlanId)
+ if actionType == "ACTION_SET_VLAN_PCP":
+ vlanPriority = a['actionSetVlanPriority']['vlanPriority']
+ print " actionType: %s vlanPriority: %s" % (actionType, vlanPriority)
+ if actionType == "ACTION_STRIP_VLAN":
+ stripVlan = a['actionStripVlan']['stripVlan']
+ print " actionType: %s stripVlan: %s" % (actionType, stripVlan)
+ if actionType == "ACTION_SET_DL_SRC":
+ setEthernetSrcAddr = a['actionSetEthernetSrcAddr']['addr']['value']
+ print " actionType: %s setEthernetSrcAddr: %s" % (actionType, setEthernetSrcAddr)
+ if actionType == "ACTION_SET_DL_DST":
+ setEthernetDstAddr = a['actionSetEthernetDstAddr']['addr']['value']
+ print " actionType: %s setEthernetDstAddr: %s" % (actionType, setEthernetDstAddr)
+ if actionType == "ACTION_SET_NW_SRC":
+ setIPv4SrcAddr = a['actionSetIPv4SrcAddr']['addr']['value']
+ print " actionType: %s setIPv4SrcAddr: %s" % (actionType, setIPv4SrcAddr)
+ if actionType == "ACTION_SET_NW_DST":
+ setIPv4DstAddr = a['actionSetIPv4DstAddr']['addr']['value']
+ print " actionType: %s setIPv4DstAddr: %s" % (actionType, setIPv4DstAddr)
+ if actionType == "ACTION_SET_NW_TOS":
+ setIpToS = a['actionSetIpToS']['ipToS']
+ print " actionType: %s setIpToS: %s" % (actionType, setIpToS)
+ if actionType == "ACTION_SET_TP_SRC":
+ setTcpUdpSrcPort = a['actionSetTcpUdpSrcPort']['port']
+ print " actionType: %s setTcpUdpSrcPort: %s" % (actionType, setTcpUdpSrcPort)
+ if actionType == "ACTION_SET_TP_DST":
+ setTcpUdpDstPort = a['actionSetTcpUdpDstPort']['port']
+ print " actionType: %s setTcpUdpDstPort: %s" % (actionType, setTcpUdpDstPort)
+ if actionType == "ACTION_ENQUEUE":
+ port = a['actionEnqueue']['port']['value']
+ queueId = a['actionEnqueue']['queueId']
+ print " actionType: %s port: %s queueId: %s" % (actionType, port, queueId)
+
def get_flow_path(flow_id):
try:
command = "curl -s \"http://%s:%s/wm/flow/get/%s/json\"" % (ControllerIP, ControllerPort, flow_id)