Merge branch 'master' of https://github.com/OPENNETWORKINGLAB/ONOS
diff --git a/pom.xml b/pom.xml
index 52fe30a..44b7f07 100644
--- a/pom.xml
+++ b/pom.xml
@@ -121,6 +121,30 @@
<locale>en</locale>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <version>0.6.3.201306030806</version>
+ <configuration>
+ <destfile>${basedir}/target/jacoco/jacoco.exec</destfile>
+ <datafile>${basedir}/target/jacoco/jacoco.exec</datafile>
+ </configuration>
+ <executions>
+ <execution>
+ <id>jacoco-initialize</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>jacoco-site</id>
+ <phase>package</phase>
+ <goals>
+ <goal>report</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
<!-- for getting visualization reporting -->
@@ -145,6 +169,7 @@
<reportSet>
<reports>
<report>dependencies</report>
+ <report>maven-emma-plugin</report>
<report>scm</report>
</reports>
</reportSet>
diff --git a/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java b/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java
index 1f041e6..2e2706c 100644
--- a/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java
+++ b/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java
@@ -28,6 +28,7 @@
import net.onrc.onos.ofcontroller.util.Dpid;
import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowEntryAction;
+import net.onrc.onos.ofcontroller.util.FlowEntryActions;
import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
import net.onrc.onos.ofcontroller.util.FlowPath;
import net.onrc.onos.ofcontroller.util.Port;
@@ -132,16 +133,12 @@
flowEntry.setOutPort(new Port(src_port.getNumber()));
flowEntry.setFlowEntryMatch(new FlowEntryMatch());
flowEntry.flowEntryMatch().enableInPort(flowEntry.inPort());
-
+
// Set the outgoing port output action
- ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
- if (flowEntryActions == null) {
- flowEntryActions = new ArrayList<FlowEntryAction>();
- flowEntry.setFlowEntryActions(flowEntryActions);
- }
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
FlowEntryAction flowEntryAction = new FlowEntryAction();
flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ flowEntryActions.addAction(flowEntryAction);
dataPath.flowEntries().add(flowEntry);
FlowPath flowPath = new FlowPath();
@@ -254,14 +251,10 @@
flowEntry.flowEntryMatch().enableInPort(flowEntry.inPort());
// Set the outgoing port output action
- ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
- if (flowEntryActions == null) {
- flowEntryActions = new ArrayList<FlowEntryAction>();
- flowEntry.setFlowEntryActions(flowEntryActions);
- }
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
FlowEntryAction flowEntryAction = new FlowEntryAction();
flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ flowEntryActions.addAction(flowEntryAction);
dataPath.flowEntries().add(flowEntry);
continue;
}
@@ -276,14 +269,10 @@
flowEntry.flowEntryMatch().enableInPort(flowEntry.inPort());
// Set the outgoing port output action
- ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
- if (flowEntryActions == null) {
- flowEntryActions = new ArrayList<FlowEntryAction>();
- flowEntry.setFlowEntryActions(flowEntryActions);
- }
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
FlowEntryAction flowEntryAction = new FlowEntryAction();
flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ flowEntryActions.addAction(flowEntryAction);
dataPath.flowEntries().add(flowEntry);
dataPath.flowEntries().add(flowEntry);
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
index 0d52171..9a96638 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
@@ -253,6 +253,9 @@
@Adjacency(label="flow", direction=Direction.IN)
public void removeFlowEntry(final IFlowEntry flowEntry);
+ //
+ // Matching fields
+ //
@JsonIgnore
@Property("matchSrcMac")
public String getMatchSrcMac();
@@ -330,6 +333,18 @@
@Property("matchDstTcpUdpPort")
public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort);
+ //
+ // Action-related fields
+ //
+ @Property("actions")
+ public String getActions();
+
+ @Property("actions")
+ public void setActions(String actionsStr);
+
+ //
+ // Other fields
+ //
@JsonIgnore
@GremlinGroovy("it.in('flow').out('switch')")
public Iterable<ISwitchObject> getSwitches();
@@ -383,6 +398,9 @@
@Property("error_state_code")
public void setErrorStateCode(String errorStateCode);
+ //
+ // Matching fields
+ //
@Property("matchInPort")
public Short getMatchInPort();
@@ -455,12 +473,24 @@
@Property("matchDstTcpUdpPort")
public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort);
+ //
+ // Action-related fields
+ //
@Property("actionOutputPort")
public Short getActionOutputPort();
@Property("actionOutputPort")
public void setActionOutputPort(Short actionOutputPort);
+ @Property("actions")
+ public String getActions();
+
+ @Property("actions")
+ public void setActions(String actionsStr);
+
+ //
+ // Other fields
+ //
@Adjacency(label="flow")
public IFlowPath getFlow();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index 1784540..a072882 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -42,6 +42,8 @@
import net.onrc.onos.ofcontroller.util.Dpid;
import net.onrc.onos.ofcontroller.util.FlowEntry;
import net.onrc.onos.ofcontroller.util.FlowEntryAction;
+import net.onrc.onos.ofcontroller.util.FlowEntryAction.*;
+import net.onrc.onos.ofcontroller.util.FlowEntryActions;
import net.onrc.onos.ofcontroller.util.FlowEntryId;
import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
import net.onrc.onos.ofcontroller.util.FlowEntrySwitchState;
@@ -58,8 +60,7 @@
import org.openflow.protocol.OFPacketOut;
import org.openflow.protocol.OFPort;
import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
+import org.openflow.protocol.action.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -587,6 +588,7 @@
// - flowPath.matchIpToS()
// - flowPath.matchSrcTcpUdpPort()
// - flowPath.matchDstTcpUdpPort()
+ // - flowPath.flowEntryActions()
//
flowObj.setInstallerId(flowPath.installerId().toString());
flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
@@ -627,6 +629,9 @@
if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
}
+ if (! flowPath.flowEntryActions().actions().isEmpty()) {
+ flowObj.setActions(flowPath.flowEntryActions().toString());
+ }
if (dataPathSummaryStr != null) {
flowObj.setDataPathSummary(dataPathSummaryStr);
@@ -720,8 +725,6 @@
// - InPort edge
// - OutPort edge
//
- // - flowEntry.flowEntryMatch()
- // - flowEntry.flowEntryActions()
// - flowEntry.dpid()
// - flowEntry.flowEntryUserState()
// - flowEntry.flowEntrySwitchState()
@@ -739,6 +742,7 @@
// - flowEntry.matchSrcTcpUdpPort()
// - flowEntry.matchDstTcpUdpPort()
// - flowEntry.actionOutputPort()
+ // - flowEntry.actions()
//
ISwitchObject sw =
op.searchSwitch(flowEntry.dpid().toString());
@@ -785,7 +789,7 @@
flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
}
- for (FlowEntryAction fa : flowEntry.flowEntryActions()) {
+ for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
if (fa.actionOutput() != null) {
IPortObject outport =
op.searchPort(flowEntry.dpid().toString(),
@@ -794,6 +798,10 @@
flowEntryObj.setOutPort(outport);
}
}
+ if (! flowEntry.flowEntryActions().isEmpty()) {
+ flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
+ }
+
// TODO: Hacks with hard-coded state names!
if (found)
flowEntryObj.setUserState("FE_USER_MODIFY");
@@ -1387,6 +1395,16 @@
flowPath.setFlowEntryMatch(match);
}
+ //
+ // Extract the actions for the first Flow Entry
+ //
+ {
+ String actionsStr = flowObj.getActions();
+ if (actionsStr != null) {
+ FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
+ flowPath.setFlowEntryActions(flowEntryActions);
+ }
+ }
//
// Extract all Flow Entries
@@ -1471,19 +1489,15 @@
//
// Extract the actions
//
- ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
- Short actionOutputPort = flowEntryObj.getActionOutputPort();
- if (actionOutputPort != null) {
- FlowEntryAction action = new FlowEntryAction();
- action.setActionOutput(new Port(actionOutputPort));
- actions.add(action);
- }
+ FlowEntryActions actions = new FlowEntryActions();
+ String actionsStr = flowEntryObj.getActions();
+ if (actionsStr != null)
+ actions = new FlowEntryActions(actionsStr);
flowEntry.setFlowEntryActions(actions);
flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
//
- // TODO: Take care of the FlowEntryMatch, FlowEntryAction set,
- // and FlowEntryErrorState.
+ // TODO: Take care of FlowEntryErrorState.
//
return flowEntry;
}
@@ -1518,6 +1532,7 @@
computedFlowPath.setFlowPathFlags(new FlowPathFlags(flowPath.flowPathFlags().flags()));
computedFlowPath.setDataPath(dataPath);
computedFlowPath.setFlowEntryMatch(new FlowEntryMatch(flowPath.flowEntryMatch()));
+ computedFlowPath.setFlowEntryActions(new FlowEntryActions(flowPath.flowEntryActions()));
FlowId flowId = new FlowId();
String dataPathSummaryStr = dataPath.dataPathSummary();
@@ -1543,21 +1558,35 @@
// Set the incoming port matching and the outgoing port output
// actions for each flow entry.
//
+ int idx = 0;
for (FlowEntry flowEntry : newDataPath.flowEntries()) {
// Set the incoming port matching
FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
flowEntry.setFlowEntryMatch(flowEntryMatch);
flowEntryMatch.enableInPort(flowEntry.inPort());
- // Set the outgoing port output action
- ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
- if (flowEntryActions == null) {
- flowEntryActions = new ArrayList<FlowEntryAction>();
- flowEntry.setFlowEntryActions(flowEntryActions);
+ //
+ // Set the actions
+ //
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
+ //
+ // If the first Flow Entry, copy the Flow Path actions to it
+ //
+ if (idx == 0) {
+ String actionsStr = flowObj.getActions();
+ if (actionsStr != null) {
+ FlowEntryActions flowActions = new FlowEntryActions(actionsStr);
+ for (FlowEntryAction action : flowActions.actions())
+ flowEntryActions.addAction(action);
+ }
}
+ idx++;
+ //
+ // Add the outgoing port output action
+ //
FlowEntryAction flowEntryAction = new FlowEntryAction();
flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ flowEntryActions.addAction(flowEntryAction);
}
//
@@ -1749,16 +1778,115 @@
//
// Fetch the actions
//
- // TODO: For now we support only the "OUTPUT" actions.
- //
- List<OFAction> actions = new ArrayList<OFAction>();
- Short actionOutputPort = flowEntryObj.getActionOutputPort();
- if (actionOutputPort != null) {
- OFActionOutput action = new OFActionOutput();
- // XXX: The max length is hard-coded for now
- action.setMaxLength((short)0xffff);
- action.setPort(actionOutputPort);
- actions.add(action);
+ Short actionOutputPort = null;
+ List<OFAction> openFlowActions = new ArrayList<OFAction>();
+ int actionsLen = 0;
+ FlowEntryActions flowEntryActions = null;
+ String actionsStr = flowEntryObj.getActions();
+ if (actionsStr != null)
+ flowEntryActions = new FlowEntryActions(actionsStr);
+ for (FlowEntryAction action : flowEntryActions.actions()) {
+ ActionOutput actionOutput = action.actionOutput();
+ ActionSetVlanId actionSetVlanId = action.actionSetVlanId();
+ ActionSetVlanPriority actionSetVlanPriority = action.actionSetVlanPriority();
+ ActionStripVlan actionStripVlan = action.actionStripVlan();
+ ActionSetEthernetAddr actionSetEthernetSrcAddr = action.actionSetEthernetSrcAddr();
+ ActionSetEthernetAddr actionSetEthernetDstAddr = action.actionSetEthernetDstAddr();
+ ActionSetIPv4Addr actionSetIPv4SrcAddr = action.actionSetIPv4SrcAddr();
+ ActionSetIPv4Addr actionSetIPv4DstAddr = action.actionSetIPv4DstAddr();
+ ActionSetIpToS actionSetIpToS = action.actionSetIpToS();
+ ActionSetTcpUdpPort actionSetTcpUdpSrcPort = action.actionSetTcpUdpSrcPort();
+ ActionSetTcpUdpPort actionSetTcpUdpDstPort = action.actionSetTcpUdpDstPort();
+ ActionEnqueue actionEnqueue = action.actionEnqueue();
+
+ if (actionOutput != null) {
+ actionOutputPort = actionOutput.port().value();
+ // XXX: The max length is hard-coded for now
+ OFActionOutput ofa =
+ new OFActionOutput(actionOutput.port().value(),
+ (short)0xffff);
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetVlanId != null) {
+ OFActionVirtualLanIdentifier ofa =
+ new OFActionVirtualLanIdentifier(actionSetVlanId.vlanId());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetVlanPriority != null) {
+ OFActionVirtualLanPriorityCodePoint ofa =
+ new OFActionVirtualLanPriorityCodePoint(actionSetVlanPriority.vlanPriority());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionStripVlan != null) {
+ if (actionStripVlan.stripVlan() == true) {
+ OFActionStripVirtualLan ofa = new OFActionStripVirtualLan();
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+ }
+
+ if (actionSetEthernetSrcAddr != null) {
+ OFActionDataLayerSource ofa =
+ new OFActionDataLayerSource(actionSetEthernetSrcAddr.addr().toBytes());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetEthernetDstAddr != null) {
+ OFActionDataLayerDestination ofa =
+ new OFActionDataLayerDestination(actionSetEthernetDstAddr.addr().toBytes());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIPv4SrcAddr != null) {
+ OFActionNetworkLayerSource ofa =
+ new OFActionNetworkLayerSource(actionSetIPv4SrcAddr.addr().value());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIPv4DstAddr != null) {
+ OFActionNetworkLayerDestination ofa =
+ new OFActionNetworkLayerDestination(actionSetIPv4DstAddr.addr().value());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIpToS != null) {
+ OFActionNetworkTypeOfService ofa =
+ new OFActionNetworkTypeOfService(actionSetIpToS.ipToS());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetTcpUdpSrcPort != null) {
+ OFActionTransportLayerSource ofa =
+ new OFActionTransportLayerSource(actionSetTcpUdpSrcPort.port());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetTcpUdpDstPort != null) {
+ OFActionTransportLayerDestination ofa =
+ new OFActionTransportLayerDestination(actionSetTcpUdpDstPort.port());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionEnqueue != null) {
+ OFActionEnqueue ofa =
+ new OFActionEnqueue(actionEnqueue.port().value(),
+ actionEnqueue.queueId());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
}
fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
@@ -1768,8 +1896,8 @@
.setCookie(cookie)
.setCommand(flowModCommand)
.setMatch(match)
- .setActions(actions)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+ .setActions(openFlowActions)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLen);
fm.setOutPort(OFPort.OFPP_NONE.getValue());
if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
(flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
@@ -1973,27 +2101,113 @@
//
// Fetch the actions
//
- // TODO: For now we support only the "OUTPUT" actions.
+ Short actionOutputPort = null;
+ List<OFAction> openFlowActions = new ArrayList<OFAction>();
+ int actionsLen = 0;
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
//
- fm.setOutPort(OFPort.OFPP_NONE.getValue());
- List<OFAction> actions = new ArrayList<OFAction>();
- ArrayList<FlowEntryAction> flowEntryActions =
- flowEntry.flowEntryActions();
- for (FlowEntryAction flowEntryAction : flowEntryActions) {
- FlowEntryAction.ActionOutput actionOutput =
- flowEntryAction.actionOutput();
+ for (FlowEntryAction action : flowEntryActions.actions()) {
+ ActionOutput actionOutput = action.actionOutput();
+ ActionSetVlanId actionSetVlanId = action.actionSetVlanId();
+ ActionSetVlanPriority actionSetVlanPriority = action.actionSetVlanPriority();
+ ActionStripVlan actionStripVlan = action.actionStripVlan();
+ ActionSetEthernetAddr actionSetEthernetSrcAddr = action.actionSetEthernetSrcAddr();
+ ActionSetEthernetAddr actionSetEthernetDstAddr = action.actionSetEthernetDstAddr();
+ ActionSetIPv4Addr actionSetIPv4SrcAddr = action.actionSetIPv4SrcAddr();
+ ActionSetIPv4Addr actionSetIPv4DstAddr = action.actionSetIPv4DstAddr();
+ ActionSetIpToS actionSetIpToS = action.actionSetIpToS();
+ ActionSetTcpUdpPort actionSetTcpUdpSrcPort = action.actionSetTcpUdpSrcPort();
+ ActionSetTcpUdpPort actionSetTcpUdpDstPort = action.actionSetTcpUdpDstPort();
+ ActionEnqueue actionEnqueue = action.actionEnqueue();
+
if (actionOutput != null) {
- short actionOutputPort = actionOutput.port().value();
- OFActionOutput action = new OFActionOutput();
+ actionOutputPort = actionOutput.port().value();
// XXX: The max length is hard-coded for now
- action.setMaxLength((short)0xffff);
- action.setPort(actionOutputPort);
- actions.add(action);
- if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
- (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
- fm.setOutPort(actionOutputPort);
+ OFActionOutput ofa =
+ new OFActionOutput(actionOutput.port().value(),
+ (short)0xffff);
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetVlanId != null) {
+ OFActionVirtualLanIdentifier ofa =
+ new OFActionVirtualLanIdentifier(actionSetVlanId.vlanId());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetVlanPriority != null) {
+ OFActionVirtualLanPriorityCodePoint ofa =
+ new OFActionVirtualLanPriorityCodePoint(actionSetVlanPriority.vlanPriority());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionStripVlan != null) {
+ if (actionStripVlan.stripVlan() == true) {
+ OFActionStripVirtualLan ofa = new OFActionStripVirtualLan();
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
}
}
+
+ if (actionSetEthernetSrcAddr != null) {
+ OFActionDataLayerSource ofa =
+ new OFActionDataLayerSource(actionSetEthernetSrcAddr.addr().toBytes());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetEthernetDstAddr != null) {
+ OFActionDataLayerDestination ofa =
+ new OFActionDataLayerDestination(actionSetEthernetDstAddr.addr().toBytes());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIPv4SrcAddr != null) {
+ OFActionNetworkLayerSource ofa =
+ new OFActionNetworkLayerSource(actionSetIPv4SrcAddr.addr().value());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIPv4DstAddr != null) {
+ OFActionNetworkLayerDestination ofa =
+ new OFActionNetworkLayerDestination(actionSetIPv4DstAddr.addr().value());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIpToS != null) {
+ OFActionNetworkTypeOfService ofa =
+ new OFActionNetworkTypeOfService(actionSetIpToS.ipToS());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetTcpUdpSrcPort != null) {
+ OFActionTransportLayerSource ofa =
+ new OFActionTransportLayerSource(actionSetTcpUdpSrcPort.port());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetTcpUdpDstPort != null) {
+ OFActionTransportLayerDestination ofa =
+ new OFActionTransportLayerDestination(actionSetTcpUdpDstPort.port());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionEnqueue != null) {
+ OFActionEnqueue ofa =
+ new OFActionEnqueue(actionEnqueue.port().value(),
+ actionEnqueue.queueId());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
}
fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
@@ -2003,8 +2217,14 @@
.setCookie(cookie)
.setCommand(flowModCommand)
.setMatch(match)
- .setActions(actions)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+ .setActions(openFlowActions)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLen);
+ fm.setOutPort(OFPort.OFPP_NONE.getValue());
+ if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
+ (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
+ if (actionOutputPort != null)
+ fm.setOutPort(actionOutputPort);
+ }
//
// TODO: Set the following flag
@@ -2131,14 +2351,10 @@
flowEntryMatch.enableInPort(flowEntry.inPort());
// Set the outgoing port output action
- ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
- if (flowEntryActions == null) {
- flowEntryActions = new ArrayList<FlowEntryAction>();
- flowEntry.setFlowEntryActions(flowEntryActions);
- }
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
FlowEntryAction flowEntryAction = new FlowEntryAction();
flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ flowEntryActions.addAction(flowEntryAction);
}
//
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java
index 7dd0699..87d08ce 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java
@@ -15,7 +15,7 @@
private FlowId flowId; // FlowID of flowEntry
private FlowEntryId flowEntryId; // The Flow Entry ID
private FlowEntryMatch flowEntryMatch; // The Flow Entry Match
- private ArrayList<FlowEntryAction> flowEntryActions; // The Flow Entry Actions
+ private FlowEntryActions flowEntryActions; // The Flow Entry Actions
private Dpid dpid; // The Switch DPID
private Port inPort; // The Switch incoming port. Used only
// when the entry is used to return
@@ -53,64 +53,64 @@
flowEntryMatch.enableDstTcpUdpPort((short)80);
FlowEntryAction action = null;
- ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
+ FlowEntryActions actions = new FlowEntryActions();
action = new FlowEntryAction();
action.setActionOutput(new Port((short)12));
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionOutputToController((short)13);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetVlanId((short)14);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetVlanPriority((byte)15);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionStripVlan(true);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetEthernetSrcAddr(mac);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetEthernetDstAddr(mac);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetIPv4SrcAddr(ipv4);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetIPv4DstAddr(ipv4);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetIpToS((byte)16);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetTcpUdpSrcPort((short)17);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetTcpUdpDstPort((short)18);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionEnqueue(new Port((short)19), 20);
- actions.add(action);
+ actions.addAction(action);
setFlowEntryActions(actions);
*/
-
+ flowEntryActions = new FlowEntryActions();
flowEntryUserState = FlowEntryUserState.FE_USER_UNKNOWN;
flowEntrySwitchState = FlowEntrySwitchState.FE_SWITCH_UNKNOWN;
}
@@ -173,7 +173,7 @@
* @return the Flow Entry Actions.
*/
@JsonProperty("flowEntryActions")
- public ArrayList<FlowEntryAction> flowEntryActions() {
+ public FlowEntryActions flowEntryActions() {
return flowEntryActions;
}
@@ -183,7 +183,7 @@
* @param flowEntryActions the Flow Entry Actions to set.
*/
@JsonProperty("flowEntryActions")
- public void setFlowEntryActions(ArrayList<FlowEntryAction> flowEntryActions) {
+ public void setFlowEntryActions(FlowEntryActions flowEntryActions) {
this.flowEntryActions = flowEntryActions;
}
@@ -319,8 +319,7 @@
* Convert the flow entry to a string.
*
* The string has the following form:
- * [flowEntryId=XXX flowEntryMatch=XXX flowEntryAction=XXX
- * flowEntryAction=XXX flowEntryAction=XXX dpid=XXX
+ * [flowEntryId=XXX flowEntryMatch=XXX flowEntryActions=XXX dpid=XXX
* inPort=XXX outPort=XXX flowEntryUserState=XXX flowEntrySwitchState=XXX
* flowEntryErrorState=XXX]
* @return the flow entry as a string.
@@ -329,9 +328,7 @@
public String toString() {
String ret = "[flowEntryId=" + this.flowEntryId.toString();
ret += " flowEntryMatch=" + this.flowEntryMatch.toString();
- for (FlowEntryAction fa : flowEntryActions) {
- ret += " flowEntryAction=" + fa.toString();
- }
+ ret += " flowEntryActions=" + this.flowEntryActions.toString();
ret += " dpid=" + this.dpid.toString();
ret += " inPort=" + this.inPort.toString();
ret += " outPort=" + this.outPort.toString();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java
index 22aef98..b9c41ff 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java
@@ -59,6 +59,28 @@
this.maxLen = 0;
}
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionOutput(ActionOutput other) {
+ if (other.port != null)
+ this.port = new Port(other.port);
+ this.maxLen = other.maxLen;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [port=XXX maxLen=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionOutput(String actionStr) {
+ this.fromString(actionStr);
+ }
/**
* Constructor for a given output port and maximum length.
@@ -121,6 +143,54 @@
return ret;
}
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [port=XXX maxLen=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split(" ");
+ String decode = null;
+
+ // Decode the "port=XXX" part
+ if (parts.length > 0)
+ decode = parts[0];
+ if (decode != null) {
+ String[] tokens = decode.split("port=");
+ if (tokens.length > 1 && tokens[1] != null) {
+ try {
+ Short valueShort = Short.valueOf(tokens[1]);
+ port = new Port(valueShort);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+
+ // Decode the "maxLen=XXX" part
+ decode = null;
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ String[] tokens = decode.split("maxLen=");
+ if (tokens.length > 1 && tokens[1] != null) {
+ try {
+ maxLen = Short.valueOf(tokens[1]);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
}
/**
@@ -137,6 +207,27 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetVlanId(ActionSetVlanId other) {
+ this.vlanId = other.vlanId;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [vlanId=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetVlanId(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
* Constructor for a given VLAN ID.
*
* @param vlanId the VLAN ID to set.
@@ -171,6 +262,33 @@
return ret;
}
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [vlanId=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("vlanId=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ vlanId = Short.valueOf(decode);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
}
/**
@@ -187,6 +305,27 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetVlanPriority(ActionSetVlanPriority other) {
+ this.vlanPriority = other.vlanPriority;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [vlanPriority=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetVlanPriority(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
* Constructor for a given VLAN priority.
*
* @param vlanPriority the VLAN priority to set.
@@ -221,6 +360,33 @@
return ret;
}
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [vlanPriority=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("vlanPriority=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ vlanPriority = Byte.valueOf(decode);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
}
/**
@@ -237,6 +403,27 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionStripVlan(ActionStripVlan other) {
+ this.stripVlan = other.stripVlan;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [stripVlan=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionStripVlan(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
* Constructor for a given boolean flag.
*
* @param stripVlan if true, strip the VLAN header.
@@ -271,6 +458,29 @@
return ret;
}
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [stripVlan=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("stripVlan=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ stripVlan = Boolean.valueOf(decode);
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
}
/**
@@ -288,6 +498,28 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetEthernetAddr(ActionSetEthernetAddr other) {
+ if (other.addr != null)
+ this.addr = MACAddress.valueOf(other.addr.toLong());
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetEthernetAddr(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
* Constructor for a given MAC address.
*
* @param addr the MAC address to set.
@@ -322,6 +554,33 @@
return ret;
}
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("addr=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ addr = MACAddress.valueOf(decode);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
}
/**
@@ -339,6 +598,28 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetIPv4Addr(ActionSetIPv4Addr other) {
+ if (other.addr != null)
+ this.addr = new IPv4(other.addr);
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetIPv4Addr(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
* Constructor for a given IPv4 address.
*
* @param addr the IPv4 address to set.
@@ -373,6 +654,33 @@
return ret;
}
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("addr=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ addr = new IPv4(decode);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
}
/**
@@ -390,6 +698,27 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetIpToS(ActionSetIpToS other) {
+ this.ipToS = other.ipToS;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [ipToS=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetIpToS(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
* Constructor for a given IP ToS (DSCP field, 6 bits).
*
* @param ipToS the IP ToS (DSCP field, 6 bits) to set.
@@ -424,6 +753,33 @@
return ret;
}
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [ipToS=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("ipToS=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ ipToS = Byte.valueOf(decode);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
}
/**
@@ -441,6 +797,27 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetTcpUdpPort(ActionSetTcpUdpPort other) {
+ this.port = other.port;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [port=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetTcpUdpPort(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
* Constructor for a given TCP/UDP port.
*
* @param port the TCP/UDP port to set.
@@ -475,6 +852,33 @@
return ret;
}
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [port=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("port=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ port = Short.valueOf(decode);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
}
/**
@@ -495,6 +899,29 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionEnqueue(ActionEnqueue other) {
+ if (other.port != null)
+ this.port = new Port(other.port);
+ this.queueId = other.queueId;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [port=XXX queueId=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionEnqueue(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
* Constructor for a given port and queue ID.
*
* @param port the port to set.
@@ -542,6 +969,54 @@
return ret;
}
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [port=XXX queueId=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split(" ");
+ String decode = null;
+
+ // Decode the "port=XXX" part
+ if (parts.length > 0)
+ decode = parts[0];
+ if (decode != null) {
+ String[] tokens = decode.split("port=");
+ if (tokens.length > 1 && tokens[1] != null) {
+ try {
+ Short valueShort = Short.valueOf(tokens[1]);
+ port = new Port(valueShort);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+
+ // Decode the "queueId=XXX" part
+ decode = null;
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ String[] tokens = decode.split("queueId=");
+ if (tokens.length > 1 && tokens[1] != null) {
+ try {
+ queueId = Short.valueOf(tokens[1]);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
}
private ActionValues actionType; // The action type
@@ -571,6 +1046,88 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public FlowEntryAction(FlowEntryAction other) {
+ this.actionType = other.actionType;
+
+ //
+ if (other.actionOutput != null)
+ this.actionOutput = new ActionOutput(other.actionOutput);
+ else
+ this.actionOutput = null;
+ //
+ if (other.actionSetVlanId != null)
+ this.actionSetVlanId = new ActionSetVlanId(other.actionSetVlanId);
+ else
+ this.actionSetVlanId = null;
+ //
+ if (other.actionSetVlanPriority != null)
+ this.actionSetVlanPriority = new ActionSetVlanPriority(other.actionSetVlanPriority);
+ else
+ this.actionSetVlanPriority = null;
+ //
+ if (other.actionStripVlan != null)
+ this.actionStripVlan = new ActionStripVlan(other.actionStripVlan);
+ else
+ this.actionStripVlan = null;
+ //
+ if (other.actionSetEthernetSrcAddr != null)
+ this.actionSetEthernetSrcAddr = new ActionSetEthernetAddr(other.actionSetEthernetSrcAddr);
+ else
+ this.actionSetEthernetSrcAddr = null;
+ //
+ if (other.actionSetEthernetDstAddr != null)
+ this.actionSetEthernetDstAddr = new ActionSetEthernetAddr(other.actionSetEthernetDstAddr);
+ else
+ this.actionSetEthernetDstAddr = null;
+ //
+ if (other.actionSetIPv4SrcAddr != null)
+ this.actionSetIPv4SrcAddr = new ActionSetIPv4Addr(other.actionSetIPv4SrcAddr);
+ else
+ this.actionSetIPv4SrcAddr = null;
+ //
+ if (other.actionSetIPv4DstAddr != null)
+ this.actionSetIPv4DstAddr = new ActionSetIPv4Addr(other.actionSetIPv4DstAddr);
+ else
+ this.actionSetIPv4DstAddr = null;
+ //
+ if (other.actionSetIpToS != null)
+ this.actionSetIpToS = new ActionSetIpToS(other.actionSetIpToS);
+ else
+ this.actionSetIpToS = null;
+ //
+ if (other.actionSetTcpUdpSrcPort != null)
+ this.actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(other.actionSetTcpUdpSrcPort);
+ else
+ this.actionSetTcpUdpSrcPort = null;
+ //
+ if (other.actionSetTcpUdpDstPort != null)
+ this.actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(other.actionSetTcpUdpDstPort);
+ else
+ this.actionSetTcpUdpDstPort = null;
+ //
+ if (other.actionEnqueue != null)
+ this.actionEnqueue = new ActionEnqueue(other.actionEnqueue);
+ else
+ this.actionEnqueue = null;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [type=XXX action=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public FlowEntryAction(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
* Get the action type.
*
* @return the action type.
@@ -957,12 +1514,12 @@
}
/**
- * Convert the set of actions to a string.
+ * Convert the action to a string.
*
* The string has the following form:
* [type=XXX action=XXX]
*
- * @return the set of actions as a string.
+ * @return the action as a string.
*/
@Override
public String toString() {
@@ -1010,4 +1567,96 @@
return ret;
}
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [type=XXX action=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("type=");
+ String decode = null;
+
+ // Extract the string after the "type="
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode == null)
+ throw new IllegalArgumentException("Invalid action string");
+
+ // Remove the trailing ']'
+ if ((decode.length() > 0) && (decode.charAt(decode.length() - 1) == ']')) {
+ decode = decode.substring(0, decode.length() - 1);
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+
+ // Extract the type value and the action value
+ parts = decode.split(" action=");
+
+ // Decode the "type=XXX" payload
+ if (parts.length > 0)
+ decode = parts[0];
+ if (decode != null) {
+ try {
+ actionType = Enum.valueOf(ActionValues.class, decode);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+
+ // Decode the "action=XXX" payload
+ decode = null;
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode == null)
+ throw new IllegalArgumentException("Invalid action string");
+ //
+ try {
+ switch (actionType) {
+ case ACTION_OUTPUT:
+ actionOutput = new ActionOutput(decode);
+ break;
+ case ACTION_SET_VLAN_VID:
+ actionSetVlanId = new ActionSetVlanId(decode);
+ break;
+ case ACTION_SET_VLAN_PCP:
+ actionSetVlanPriority = new ActionSetVlanPriority(decode);
+ break;
+ case ACTION_STRIP_VLAN:
+ actionStripVlan = new ActionStripVlan(decode);
+ break;
+ case ACTION_SET_DL_SRC:
+ actionSetEthernetSrcAddr = new ActionSetEthernetAddr(decode);
+ break;
+ case ACTION_SET_DL_DST:
+ actionSetEthernetDstAddr = new ActionSetEthernetAddr(decode);
+ break;
+ case ACTION_SET_NW_SRC:
+ actionSetIPv4SrcAddr = new ActionSetIPv4Addr(decode);
+ break;
+ case ACTION_SET_NW_DST:
+ actionSetIPv4DstAddr = new ActionSetIPv4Addr(decode);
+ break;
+ case ACTION_SET_NW_TOS:
+ actionSetIpToS = new ActionSetIpToS(decode);
+ break;
+ case ACTION_SET_TP_SRC:
+ actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(decode);
+ break;
+ case ACTION_SET_TP_DST:
+ actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(decode);
+ break;
+ case ACTION_ENQUEUE:
+ actionEnqueue = new ActionEnqueue(decode);
+ break;
+ }
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryActions.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryActions.java
new file mode 100644
index 0000000..46f638d
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryActions.java
@@ -0,0 +1,146 @@
+package net.onrc.onos.ofcontroller.util;
+
+import java.util.ArrayList;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * The class representing multiple Flow Entry actions.
+ *
+ * A set of Flow Entry actions need to be applied to each packet.
+ */
+public class FlowEntryActions {
+ private ArrayList<FlowEntryAction> actions; // The Flow Entry Actions
+
+ /**
+ * Default constructor.
+ */
+ public FlowEntryActions() {
+ actions = new ArrayList<FlowEntryAction>();
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [[type=XXX action=XXX];[type=XXX action=XXX];...;]
+ *
+ * @param actionsStr the set of actions as a string.
+ */
+ public FlowEntryActions(String actionsStr) {
+ this.fromString(actionsStr);
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public FlowEntryActions(FlowEntryActions other) {
+ actions = new ArrayList<FlowEntryAction>();
+
+ for (FlowEntryAction action : other.actions) {
+ FlowEntryAction newAction = new FlowEntryAction(action);
+ actions.add(newAction);
+ }
+ }
+
+ /**
+ * Get the Flow Entry Actions.
+ *
+ * @return the Flow Entry Actions.
+ */
+ @JsonProperty("actions")
+ public ArrayList<FlowEntryAction> actions() {
+ return actions;
+ }
+
+ /**
+ * Set the Flow Entry Actions.
+ *
+ * @param actions the Flow Entry Actions to set.
+ */
+ @JsonProperty("actions")
+ public void setActions(ArrayList<FlowEntryAction> actions) {
+ this.actions = actions;
+ }
+
+ /**
+ * Add a Flow Entry Action.
+ *
+ * @param FlowEntryAction the Flow Entry Action to add.
+ */
+ public void addAction(FlowEntryAction flowEntryAction) {
+ actions.add(flowEntryAction);
+ }
+
+ /**
+ * Test whether the set of actions is empty.
+ *
+ * @return true if the set of actions is empty, otherwise false.
+ */
+ public Boolean isEmpty() {
+ return actions.isEmpty();
+ }
+
+ /**
+ * Convert the set of actions to a string.
+ *
+ * The string has the following form:
+ * [[type=XXX action=XXX];[type=XXX action=XXX];...;]
+ *
+ * @return the set of actions as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ for (FlowEntryAction action : actions) {
+ ret += action.toString() + ";";
+ }
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to a set of actions.
+ *
+ * The string has the following form:
+ * [[type=XXX action=XXX];[type=XXX action=XXX];...;]
+ *
+ * @param actionsStr the set of actions as a string.
+ */
+ public void fromString(String actionsStr) {
+ String decode = actionsStr;
+
+ actions = new ArrayList<FlowEntryAction>();
+
+ if (decode.isEmpty())
+ return; // Nothing to do
+
+ // Remove the '[' and ']' in the beginning and the end of the string
+ if ((decode.length() > 1) && (decode.charAt(0) == '[') &&
+ (decode.charAt(decode.length() - 1) == ']')) {
+ decode = decode.substring(1, decode.length() - 1);
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+
+ // Split the string, and decode each action
+ String[] parts = decode.split(";");
+ for (int i = 0; i < parts.length; i++) {
+ decode = parts[i];
+ if ((decode == null) || decode.isEmpty())
+ continue;
+ FlowEntryAction flowEntryAction = null;
+ try {
+ flowEntryAction = new FlowEntryAction(decode);
+ } catch (IllegalArgumentException e) {
+ // TODO: Ignore invalid actions for now
+ continue;
+ }
+ if (flowEntryAction != null)
+ actions.add(flowEntryAction);
+ }
+ }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java
index 8acc2e9..153e184 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java
@@ -19,6 +19,8 @@
private DataPath dataPath; // The data path
private FlowEntryMatch flowEntryMatch; // Common Flow Entry Match for all
// Flow Entries
+ private FlowEntryActions flowEntryActions; // The Flow Entry Actions for
+ // the first Flow Entry
/**
* Default constructor.
@@ -26,6 +28,7 @@
public FlowPath() {
flowPathFlags = new FlowPathFlags();
dataPath = new DataPath();
+ flowEntryActions = new FlowEntryActions();
}
/**
@@ -82,6 +85,19 @@
this.setFlowEntryMatch(match);
}
+ //
+ // Extract the actions for the first Flow Entry
+ //
+ {
+ FlowEntryActions actions = new FlowEntryActions();
+
+ String actionsStr = flowObj.getActions();
+ if (actions != null)
+ actions = new FlowEntryActions(actionsStr);
+
+ this.setFlowEntryActions(actions);
+ }
+
//
// Extract all Flow Entries
//
@@ -95,64 +111,77 @@
// Extract the match conditions
//
FlowEntryMatch match = new FlowEntryMatch();
+ //
Short matchInPort = flowEntryObj.getMatchInPort();
if (matchInPort != null)
match.enableInPort(new Port(matchInPort));
+ //
String matchSrcMac = flowEntryObj.getMatchSrcMac();
if (matchSrcMac != null)
match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
+ //
String matchDstMac = flowEntryObj.getMatchDstMac();
if (matchDstMac != null)
match.enableDstMac(MACAddress.valueOf(matchDstMac));
+ //
Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
if (matchEthernetFrameType != null)
match.enableEthernetFrameType(matchEthernetFrameType);
+ //
Short matchVlanId = flowEntryObj.getMatchVlanId();
if (matchVlanId != null)
match.enableVlanId(matchVlanId);
+ //
Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
if (matchVlanPriority != null)
match.enableVlanPriority(matchVlanPriority);
+ //
String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
if (matchSrcIPv4Net != null)
match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
+ //
String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
if (matchDstIPv4Net != null)
match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
+ //
Byte matchIpProto = flowEntryObj.getMatchIpProto();
if (matchIpProto != null)
match.enableIpProto(matchIpProto);
+ //
Byte matchIpToS = flowEntryObj.getMatchIpToS();
if (matchIpToS != null)
match.enableIpToS(matchIpToS);
+ //
Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
if (matchSrcTcpUdpPort != null)
match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
+ //
Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
if (matchDstTcpUdpPort != null)
match.enableDstTcpUdpPort(matchDstTcpUdpPort);
+ //
flowEntry.setFlowEntryMatch(match);
- //
- // Extract the actions
- //
- ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
- Short actionOutputPort = flowEntryObj.getActionOutputPort();
- if (actionOutputPort != null) {
- FlowEntryAction action = new FlowEntryAction();
- action.setActionOutput(new Port(actionOutputPort));
- actions.add(action);
- }
- flowEntry.setFlowEntryActions(actions);
+ //
+ // Extract the actions
+ //
+ {
+ FlowEntryActions actions = new FlowEntryActions();
+
+ String actionsStr = flowObj.getActions();
+ if (actions != null)
+ actions = new FlowEntryActions(actionsStr);
+
+ flowEntry.setFlowEntryActions(actions);
+ }
String userState = flowEntryObj.getUserState();
flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
String switchState = flowEntryObj.getSwitchState();
flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
- //
- // TODO: Take care of the FlowEntryMatch, FlowEntryAction set,
- // and FlowEntryErrorState.
- //
+ //
+ // TODO: Take care of the FlowEntryErrorState.
+ //
this.dataPath().flowEntries().add(flowEntry);
}
}
@@ -249,10 +278,32 @@
}
/**
+ * Get the flow path's flow entry actions for the first Flow Entry.
+ *
+ * @return the flow path's flow entry actions for the first Flow Entry.
+ */
+ @JsonProperty("flowEntryActions")
+ public FlowEntryActions flowEntryActions() {
+ return flowEntryActions;
+ }
+
+ /**
+ * Set the flow path's flow entry actions for the first Flow Entry.
+ *
+ * @param flowEntryActions the flow path's flow entry actions for the first
+ * Flow Entry.
+ */
+ @JsonProperty("flowEntryActions")
+ public void setFlowEntryActions(FlowEntryActions flowEntryActions) {
+ this.flowEntryActions = flowEntryActions;
+ }
+
+ /**
* Convert the flow path to a string.
*
* The string has the following form:
- * [flowId=XXX installerId=XXX flowPathFlags=XXX dataPath=XXX]
+ * [flowId=XXX installerId=XXX flowPathFlags=XXX dataPath=XXX
+ * flowEntryMatch=XXX flowEntryActions=XXX]
*
* @return the flow path as a string.
*/
@@ -265,6 +316,8 @@
ret += " dataPath=" + this.dataPath.toString();
if (flowEntryMatch != null)
ret += " flowEntryMatch=" + this.flowEntryMatch.toString();
+ if (flowEntryActions != null)
+ ret += " flowEntryActions=" + this.flowEntryActions.toString();
ret += "]";
return ret;
}
@@ -276,5 +329,4 @@
public int compareTo(FlowPath f) {
return (int) (this.flowId.value() - f.flowId.value());
}
-
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/IPv4.java b/src/main/java/net/onrc/onos/ofcontroller/util/IPv4.java
index 2081bbe..119165c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/IPv4.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/IPv4.java
@@ -22,6 +22,15 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public IPv4(IPv4 other) {
+ this.value = other.value;
+ }
+
+ /**
* Constructor from an integer value.
*
* @param value the value to use.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/IPv4Net.java b/src/main/java/net/onrc/onos/ofcontroller/util/IPv4Net.java
index 52e6535..9ce247c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/IPv4Net.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/IPv4Net.java
@@ -23,6 +23,17 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public IPv4Net(IPv4Net other) {
+ if (other.address != null)
+ this.address = new IPv4(other.address);
+ this.prefixLen = other.prefixLen;
+ }
+
+ /**
* Constructor for a given address and prefix length.
*
* @param address the address to use.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/IPv6.java b/src/main/java/net/onrc/onos/ofcontroller/util/IPv6.java
index 2d28db8..f5dae11 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/IPv6.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/IPv6.java
@@ -25,6 +25,16 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public IPv6(IPv6 other) {
+ this.valueHigh = other.valueHigh;
+ this.valueLow = other.valueLow;
+ }
+
+ /**
* Constructor from integer values.
*
* @param valueHigh the higher (more significant) 64 bits of the address.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/IPv6Net.java b/src/main/java/net/onrc/onos/ofcontroller/util/IPv6Net.java
index bafff24..65ffe54 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/IPv6Net.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/IPv6Net.java
@@ -23,6 +23,17 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public IPv6Net(IPv6Net other) {
+ if (other.address != null)
+ this.address = new IPv6(other.address);
+ this.prefixLen = other.prefixLen;
+ }
+
+ /**
* Constructor for a given address and prefix length.
*
* @param address the address to use.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/Port.java b/src/main/java/net/onrc/onos/ofcontroller/util/Port.java
index 34c807d..bb4851c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/Port.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/Port.java
@@ -78,9 +78,9 @@
}
/**
- * Constructor from another entry.
+ * Copy constructor.
*
- * @param other the other entry to use.
+ * @param other the object to copy from.
*/
public Port(Port other) {
this.value = other.value();
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
index dd21a26..bcff36a 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
@@ -425,6 +425,7 @@
private String matchSrcIpaddr,matchDstIpaddr;
private Byte matchIpProto, matchIpToS;
private Short matchSrcTcpUdpPort, matchDstTcpUdpPort;
+ private String actions;
private List<IFlowEntry> entries;
private List<ISwitchObject> switches;
@@ -440,6 +441,7 @@
private String matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
private Byte matchIpProtoToUpdate, matchIpToSToUpdate;
private Short matchSrcTcpUdpPortToUpdate, matchDstTcpUdpPortToUpdate;
+ private String actionsToUpdate;
private List<IFlowEntry> flowsToAdd;
private List<IFlowEntry> flowsToRemove;
@@ -485,6 +487,7 @@
if(matchIpToSToUpdate != null) { matchIpToS = matchIpToSToUpdate; }
if(matchSrcTcpUdpPortToUpdate != null) { matchSrcTcpUdpPort = matchSrcTcpUdpPortToUpdate; }
if(matchDstTcpUdpPortToUpdate != null) { matchDstTcpUdpPort = matchDstTcpUdpPortToUpdate; }
+ if(actionsToUpdate != null) { actions = actionsToUpdate; }
}
public void rollback() {
@@ -506,6 +509,7 @@
matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
matchIpProtoToUpdate = matchIpToSToUpdate = null;
matchSrcTcpUdpPortToUpdate = matchDstTcpUdpPortToUpdate = null;
+ actionsToUpdate = null;
}
// Setter methods for test
@@ -531,6 +535,7 @@
public void setMatchIpToSForTest(Byte matchIpToS) { this.matchIpToS = matchIpToS; }
public void setMatchSrcTcpUdpPortForTest(Short matchSrcTcpUdpPort) { this.matchSrcTcpUdpPort = matchSrcTcpUdpPort; }
public void setMatchDstTcpUdpPortForTest(Short matchDstTcpUdpPort) { this.matchDstTcpUdpPort = matchDstTcpUdpPort; }
+ public void setActionsForTest(String actions) { this.actions = actions; }
public void addFlowEntryForTest(IFlowEntry entry) { entries.add(entry); }
public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
@@ -693,6 +698,13 @@
matchDstTcpUdpPortToUpdate = matchDstTcpUdpPort; }
@Override
+ public String getActions() { return actions; }
+
+ @Override
+ public void setActions(String actions) {
+ actionsToUpdate = actions; }
+
+ @Override
public Iterable<ISwitchObject> getSwitches() { return switches; }
@Override
@@ -713,6 +725,7 @@
private Byte matchIpProto, matchIpToS;
private Short matchSrcTcpUdpPort, matchDstTcpUdpPort;
private Short actionOutputPort;
+ private String actions;
private IFlowPath flowPath;
private ISwitchObject sw;
@@ -729,6 +742,7 @@
private Byte matchIpProtoToUpdate, matchIpToSToUpdate;
private Short matchSrcTcpUdpPortToUpdate, matchDstTcpUdpPortToUpdate;
private Short actionOutputPortToUpdate;
+ private String actionsToUpdate;
private IFlowPath flowPathToUpdate;
private ISwitchObject swToUpdate;
@@ -762,6 +776,7 @@
if(matchSrcTcpUdpPortToUpdate != null) { matchSrcTcpUdpPort = matchSrcTcpUdpPortToUpdate; }
if(matchDstTcpUdpPortToUpdate != null) { matchDstTcpUdpPort = matchDstTcpUdpPortToUpdate; }
if(actionOutputPortToUpdate != null) { actionOutputPort = actionOutputPortToUpdate; }
+ if(actionsToUpdate != null) { actions = actionsToUpdate; }
if(flowPathToUpdate != null) { flowPath = flowPathToUpdate; }
if(swToUpdate != null) { sw = swToUpdate; }
@@ -787,6 +802,7 @@
matchIpProtoToUpdate = matchIpToSToUpdate = null;
matchSrcTcpUdpPortToUpdate = matchDstTcpUdpPortToUpdate = null;
actionOutputPortToUpdate = null;
+ actionsToUpdate = null;
flowPathToUpdate = null;
swToUpdate = null;
inportToUpdate = outportToUpdate = null;
@@ -814,6 +830,7 @@
public void setMatchSrcTcpUdpPortForTest(Short matchSrcTcpUdpPort) { this.matchSrcTcpUdpPort = matchSrcTcpUdpPort; }
public void setMatchDstTcpUdpPortForTest(Short matchDstTcpUdpPort) { this.matchDstTcpUdpPort = matchDstTcpUdpPort; }
public void setActionOutputPortForTest(Short actionOutputPort) { this.actionOutputPort = actionOutputPort; }
+ public void setActionsForTest(String actions) { this.actions = actions; }
public void setFlowPathForTest(IFlowPath flowPath) { this.flowPath = flowPath; }
public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
public void setInportForTest(IPortObject inport) { this.inport = inport; }
@@ -950,6 +967,12 @@
@Override
public void setActionOutputPort(Short actionOutputPort) { actionOutputPortToUpdate = actionOutputPort; }
+
+ @Override
+ public String getActions() { return actions; }
+
+ @Override
+ public void setActions(String actions) { actionsToUpdate = actions; }
@Override
public IFlowPath getFlow() { return flowPath; }
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
index 9f197a7..7bc0aac 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
@@ -1086,7 +1086,7 @@
flowEntry1.setOutPort(new Port((short) 11));
flowEntry1.setFlowEntryId(new FlowEntryId(1));
flowEntry1.setFlowEntryMatch(new FlowEntryMatch());
- flowEntry1.setFlowEntryActions(new ArrayList<FlowEntryAction>());
+ flowEntry1.setFlowEntryActions(new FlowEntryActions());
flowEntry1.setFlowEntryErrorState(new FlowEntryErrorState());
FlowEntry flowEntry2 = new FlowEntry();
@@ -1096,7 +1096,7 @@
flowEntry2.setOutPort(new Port((short) 2));
flowEntry2.setFlowEntryId(new FlowEntryId(2));
flowEntry2.setFlowEntryMatch(new FlowEntryMatch());
- flowEntry2.setFlowEntryActions(new ArrayList<FlowEntryAction>());
+ flowEntry2.setFlowEntryActions(new FlowEntryActions());
flowEntry2.setFlowEntryErrorState(new FlowEntryErrorState());
DataPath dataPath = new DataPath();
@@ -1147,6 +1147,11 @@
// instantiate required objects
FlowManager fm = new FlowManager();
+ FlowEntryAction action = new FlowEntryAction();
+ action.setActionOutput(new Port((short)2));
+ FlowEntryActions actions = new FlowEntryActions();
+ actions.addAction(action);
+
// setup expectations
expectInitWithContext();
expect(iFlowEntry.getFlowEntryId()).andReturn(new FlowEntryId(123).toString());
@@ -1164,7 +1169,7 @@
expect(iFlowEntry.getMatchIpToS()).andReturn(new Byte((byte)0x3));
expect(iFlowEntry.getMatchSrcTcpUdpPort()).andReturn(new Short((short)40000));
expect(iFlowEntry.getMatchDstTcpUdpPort()).andReturn(new Short((short)80));
- expect(iFlowEntry.getActionOutputPort()).andReturn(new Short((short) 2));
+ expect(iFlowEntry.getActions()).andReturn(actions.toString());
expect(floodlightProvider.getOFMessageFactory()).andReturn(basicFactory);
expect(basicFactory.getMessage(OFType.FLOW_MOD)).andReturn(new OFFlowMod());
expect(iofSwitch.getStringId()).andReturn(new Dpid(100).toString());
diff --git a/start-onos.sh b/start-onos.sh
index 13ea0ac..a35d181 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -16,6 +16,8 @@
# Set JVM options
JVM_OPTS=""
+## If you want JaCoCo Code Coverage reports... uncomment line below
+JVM_OPTS="$JVM_OPTS -javaagent:${ONOS_HOME}/lib/jacocoagent.jar=dumponexit=true,output=file,destfile=${LOGDIR}/jacoco.exec"
JVM_OPTS="$JVM_OPTS -server -d64"
#JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
@@ -134,7 +136,7 @@
pids="$flpid $tdpid"
for p in ${pids}; do
if [ x$p != "x" ]; then
- kill -KILL $p
+ kill -TERM $p
echo "Killed existing process (pid: $p)"
fi
done
diff --git a/web/add_flow.py b/web/add_flow.py
index 9ecb102..8100f22 100755
--- a/web/add_flow.py
+++ b/web/add_flow.py
@@ -204,18 +204,19 @@
match['dstTcpUdpPort'] = int(arg2, 0)
# match['matchDstTcpUdpPort'] = True
elif arg1 == "actionOutput":
- # Just mark whether ACTION_OUTPUT action is enabled
+ # Mark whether ACTION_OUTPUT action is enabled
actionOutputEnabled = arg2 in ['True', 'true']
- #
- # TODO: Complete the implementation for ACTION_OUTPUT
- # actionOutput = {}
- # outPort = {}
- # outPort['value'] = int(arg2, 0)
- # actionOutput['port'] = outPort
- # actionOutput['maxLen'] = int(arg3, 0)
- # action['actionOutput'] = actionOutput
- # # action['actionType'] = 'ACTION_OUTPUT'
- # actions.append(action)
+ # If ACTION_OUTPUT is explicitly enabled, add an entry with a fake
+ # port number. We need this entry to preserve the action ordering.
+ if actionOutputEnabled == True:
+ actionOutput = {}
+ outPort = {}
+ outPort['value'] = 0xffff
+ actionOutput['port'] = outPort
+ actionOutput['maxLen'] = 0
+ action['actionOutput'] = actionOutput
+ # action['actionType'] = 'ACTION_OUTPUT'
+ actions.append(action)
#
elif arg1 == "actionSetVlanId":
vlanId = {}
@@ -346,6 +347,8 @@
flowPathFlags = {}
flowPathFlags['flags'] = myFlowPathFlags
+ flowEntryActions = {}
+
flow_path = {}
flow_path['flowId'] = flow_id
flow_path['installerId'] = installer_id
@@ -367,6 +370,11 @@
my_data_path['flowEntries'][idx]['flowEntryMatch'] = copy.deepcopy(match)
idx = idx + 1
+
+ if (len(actions) > 0):
+ flowEntryActions['actions'] = copy.deepcopy(actions)
+ flow_path['flowEntryActions'] = flowEntryActions
+
#
# Set the actions for each flow entry
# NOTE: The actions from the command line are aplied
@@ -388,11 +396,12 @@
action['actionOutput'] = copy.deepcopy(actionOutput)
# action['actionType'] = 'ACTION_OUTPUT'
actions.append(copy.deepcopy(action))
+ flowEntryActions = {}
+ flowEntryActions['actions'] = copy.deepcopy(actions)
- my_data_path['flowEntries'][idx]['flowEntryActions'] = copy.deepcopy(actions)
+ my_data_path['flowEntries'][idx]['flowEntryActions'] = flowEntryActions
idx = idx + 1
-
flow_path['dataPath'] = my_data_path
debug("Flow Path: %s" % flow_path)
return flow_path
@@ -516,6 +525,7 @@
usage_msg = usage_msg + " actionSetIpToS <IP ToS (DSCP field, 6 bits)>\n"
usage_msg = usage_msg + " actionSetTcpUdpSrcPort <source TCP/UDP port>\n"
usage_msg = usage_msg + " actionSetTcpUdpDstPort <destination TCP/UDP port>\n"
+ usage_msg = usage_msg + " Actions (not implemented yet):\n"
usage_msg = usage_msg + " actionEnqueue <dummy argument>\n"
# app.debug = False;
diff --git a/web/get_flow.py b/web/get_flow.py
index 6599360..9ab55da 100755
--- a/web/get_flow.py
+++ b/web/get_flow.py
@@ -33,6 +33,131 @@
# Sample output:
# {"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 parse_match(match):
+ result = []
+
+ inPort = match['inPort']
+ matchInPort = match['matchInPort']
+ srcMac = match['srcMac']
+ matchSrcMac = match['matchSrcMac']
+ dstMac = match['dstMac']
+ matchDstMac = match['matchDstMac']
+ ethernetFrameType = match['ethernetFrameType']
+ matchEthernetFrameType = match['matchEthernetFrameType']
+ vlanId = match['vlanId']
+ matchVlanId = match['matchVlanId']
+ vlanPriority = match['vlanPriority']
+ matchVlanPriority = match['matchVlanPriority']
+ srcIPv4Net = match['srcIPv4Net']
+ matchSrcIPv4Net = match['matchSrcIPv4Net']
+ dstIPv4Net = match['dstIPv4Net']
+ matchDstIPv4Net = match['matchDstIPv4Net']
+ ipProto = match['ipProto']
+ matchIpProto = match['matchIpProto']
+ ipToS = match['ipToS']
+ matchIpToS = match['matchIpToS']
+ srcTcpUdpPort = match['srcTcpUdpPort']
+ matchSrcTcpUdpPort = match['matchSrcTcpUdpPort']
+ dstTcpUdpPort = match['dstTcpUdpPort']
+ matchDstTcpUdpPort = match['matchDstTcpUdpPort']
+ if matchInPort == True:
+ r = "inPort: %s" % inPort['value']
+ result.append(r)
+ if matchSrcMac == True:
+ r = "srcMac: %s" % srcMac['value']
+ result.append(r)
+ if matchDstMac == True:
+ r = "dstMac: %s" % dstMac['value']
+ result.append(r)
+ if matchEthernetFrameType == True:
+ r = "ethernetFrameType: %s" % hex(ethernetFrameType)
+ result.append(r)
+ if matchVlanId == True:
+ r = "vlanId: %s" % vlanId
+ result.append(r)
+ if matchVlanPriority == True:
+ r = "vlanPriority: %s" % vlanPriority
+ result.append(r)
+ if matchSrcIPv4Net == True:
+ r = "srcIPv4Net: %s" % srcIPv4Net['value']
+ result.append(r)
+ if matchDstIPv4Net == True:
+ r = "dstIPv4Net: %s" % dstIPv4Net['value']
+ result.append(r)
+ if matchIpProto == True:
+ r = "ipProto: %s" % ipProto
+ result.append(r)
+ if matchIpToS == True:
+ r = "ipToS: %s" % ipToS
+ result.append(r)
+ if matchSrcTcpUdpPort == True:
+ r = "srcTcpUdpPort: %s" % srcTcpUdpPort
+ result.append(r)
+ if matchDstTcpUdpPort == True:
+ r = "dstTcpUdpPort: %s" % dstTcpUdpPort
+ result.append(r)
+
+ return result
+
+
+def parse_actions(actions):
+ result = []
+ for a in actions:
+ actionType = a['actionType']
+ if actionType == "ACTION_OUTPUT":
+ port = a['actionOutput']['port']['value']
+ maxLen = a['actionOutput']['maxLen']
+ r = "actionType: %s port: %s maxLen: %s" % (actionType, port, maxLen)
+ result.append(r)
+ if actionType == "ACTION_SET_VLAN_VID":
+ vlanId = a['actionSetVlanId']['vlanId']
+ r = "actionType: %s vlanId: %s" % (actionType, vlanId)
+ result.append(r)
+ if actionType == "ACTION_SET_VLAN_PCP":
+ vlanPriority = a['actionSetVlanPriority']['vlanPriority']
+ r = "actionType: %s vlanPriority: %s" % (actionType, vlanPriority)
+ result.append(r)
+ if actionType == "ACTION_STRIP_VLAN":
+ stripVlan = a['actionStripVlan']['stripVlan']
+ r = "actionType: %s stripVlan: %s" % (actionType, stripVlan)
+ result.append(r)
+ if actionType == "ACTION_SET_DL_SRC":
+ setEthernetSrcAddr = a['actionSetEthernetSrcAddr']['addr']['value']
+ r = "actionType: %s setEthernetSrcAddr: %s" % (actionType, setEthernetSrcAddr)
+ result.append(r)
+ if actionType == "ACTION_SET_DL_DST":
+ setEthernetDstAddr = a['actionSetEthernetDstAddr']['addr']['value']
+ r = "actionType: %s setEthernetDstAddr: %s" % (actionType, setEthernetDstAddr)
+ result.append(r)
+ if actionType == "ACTION_SET_NW_SRC":
+ setIPv4SrcAddr = a['actionSetIPv4SrcAddr']['addr']['value']
+ r = "actionType: %s setIPv4SrcAddr: %s" % (actionType, setIPv4SrcAddr)
+ result.append(r)
+ if actionType == "ACTION_SET_NW_DST":
+ setIPv4DstAddr = a['actionSetIPv4DstAddr']['addr']['value']
+ r = "actionType: %s setIPv4DstAddr: %s" % (actionType, setIPv4DstAddr)
+ result.append(r)
+ if actionType == "ACTION_SET_NW_TOS":
+ setIpToS = a['actionSetIpToS']['ipToS']
+ r = "actionType: %s setIpToS: %s" % (actionType, setIpToS)
+ result.append(r)
+ if actionType == "ACTION_SET_TP_SRC":
+ setTcpUdpSrcPort = a['actionSetTcpUdpSrcPort']['port']
+ r = "actionType: %s setTcpUdpSrcPort: %s" % (actionType, setTcpUdpSrcPort)
+ result.append(r)
+ if actionType == "ACTION_SET_TP_DST":
+ setTcpUdpDstPort = a['actionSetTcpUdpDstPort']['port']
+ r = "actionType: %s setTcpUdpDstPort: %s" % (actionType, setTcpUdpDstPort)
+ result.append(r)
+ if actionType == "ACTION_ENQUEUE":
+ port = a['actionEnqueue']['port']['value']
+ queueId = a['actionEnqueue']['queueId']
+ r = "actionType: %s port: %s queueId: %s" % (actionType, port, queueId)
+ result.append(r)
+
+ return result
+
+
def print_flow_path(parsedResult):
flowId = parsedResult['flowId']['value']
installerId = parsedResult['installerId']['value']
@@ -41,6 +166,8 @@
srcPort = parsedResult['dataPath']['srcPort']['port']['value']
dstSwitch = parsedResult['dataPath']['dstPort']['dpid']['value']
dstPort = parsedResult['dataPath']['dstPort']['port']['value']
+ match = parsedResult['flowEntryMatch'];
+ actions = parsedResult['flowEntryActions']['actions']
flowPathFlagsStr = ""
if (flowPathFlags & 0x1):
@@ -53,69 +180,35 @@
flowPathFlagsStr += "KEEP_ONLY_FIRST_HOP_ENTRY"
print "FlowPath: (flowId = %s installerId = %s flowPathFlags = 0x%x(%s) src = %s/%s dst = %s/%s)" % (flowId, installerId, flowPathFlags, flowPathFlagsStr, srcSwitch, srcPort, dstSwitch, dstPort)
- match = parsedResult['flowEntryMatch'];
+
#
- # Print the common conditions
+ # Print the common match conditions
#
if match == None:
print " Match: %s" % (match)
else:
- # inPort = match['inPort']
- # matchInPort = match['matchInPort']
- srcMac = match['srcMac']
- matchSrcMac = match['matchSrcMac']
- dstMac = match['dstMac']
- matchDstMac = match['matchDstMac']
- ethernetFrameType = match['ethernetFrameType']
- matchEthernetFrameType = match['matchEthernetFrameType']
- vlanId = match['vlanId']
- matchVlanId = match['matchVlanId']
- vlanPriority = match['vlanPriority']
- matchVlanPriority = match['matchVlanPriority']
- srcIPv4Net = match['srcIPv4Net']
- matchSrcIPv4Net = match['matchSrcIPv4Net']
- dstIPv4Net = match['dstIPv4Net']
- matchDstIPv4Net = match['matchDstIPv4Net']
- ipProto = match['ipProto']
- matchIpProto = match['matchIpProto']
- ipToS = match['ipToS']
- matchIpToS = match['matchIpToS']
- 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 matchEthernetFrameType == True:
- print " ethernetFrameType: %s" % hex(ethernetFrameType)
- if matchVlanId == True:
- print " vlanId: %s" % vlanId
- if matchVlanPriority == True:
- print " vlanPriority: %s" % vlanPriority
- if matchSrcIPv4Net == True:
- print " srcIPv4Net: %s" % srcIPv4Net['value']
- if matchDstIPv4Net == True:
- print " dstIPv4Net: %s" % dstIPv4Net['value']
- if matchIpProto == True:
- print " ipProto: %s" % ipProto
- if matchIpToS == True:
- print " ipToS: %s" % ipToS
- if matchSrcTcpUdpPort == True:
- print " srcTcpUdpPort: %s" % srcTcpUdpPort
- if matchDstTcpUdpPort == True:
- print " dstTcpUdpPort: %s" % dstTcpUdpPort
+ parsedMatch = parse_match(match)
+ for l in parsedMatch:
+ print " %s" % l
+ #
+ # Print the actions
+ #
+ parsedActions = parse_actions(actions)
+ for l in parsedActions:
+ print " %s" % l
+
+ #
+ # Print each Flow Entry
+ #
for f in parsedResult['dataPath']['flowEntries']:
flowEntryId = f['flowEntryId']
dpid = f['dpid']['value']
userState = f['flowEntryUserState']
switchState = f['flowEntrySwitchState']
match = f['flowEntryMatch'];
- actions = f['flowEntryActions']
+ actions = f['flowEntryActions']['actions']
+
print " FlowEntry: (%s, %s, %s, %s)" % (flowEntryId, dpid, userState, switchState)
#
@@ -124,101 +217,16 @@
if match == None:
print " Match: %s" % (match)
else:
- inPort = match['inPort']
- matchInPort = match['matchInPort']
- srcMac = match['srcMac']
- matchSrcMac = match['matchSrcMac']
- dstMac = match['dstMac']
- matchDstMac = match['matchDstMac']
- ethernetFrameType = match['ethernetFrameType']
- matchEthernetFrameType = match['matchEthernetFrameType']
- vlanId = match['vlanId']
- matchVlanId = match['matchVlanId']
- vlanPriority = match['vlanPriority']
- matchVlanPriority = match['matchVlanPriority']
- srcIPv4Net = match['srcIPv4Net']
- matchSrcIPv4Net = match['matchSrcIPv4Net']
- dstIPv4Net = match['dstIPv4Net']
- matchDstIPv4Net = match['matchDstIPv4Net']
- ipProto = match['ipProto']
- matchIpProto = match['matchIpProto']
- ipToS = match['ipToS']
- matchIpToS = match['matchIpToS']
- 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 matchEthernetFrameType == True:
- print " ethernetFrameType: %s" % hex(ethernetFrameType)
- if matchVlanId == True:
- print " vlanId: %s" % vlanId
- if matchVlanPriority == True:
- print " vlanPriority: %s" % vlanPriority
- if matchSrcIPv4Net == True:
- print " srcIPv4Net: %s" % srcIPv4Net['value']
- if matchDstIPv4Net == True:
- print " dstIPv4Net: %s" % dstIPv4Net['value']
- if matchIpProto == True:
- print " ipProto: %s" % ipProto
- if matchIpToS == True:
- print " ipToS: %s" % ipToS
- if matchSrcTcpUdpPort == True:
- print " srcTcpUdpPort: %s" % srcTcpUdpPort
- if matchDstTcpUdpPort == True:
- print " dstTcpUdpPort: %s" % dstTcpUdpPort
-
+ parsedMatch = parse_match(match)
+ for l in parsedMatch:
+ print " %s" % l
#
# Print the actions
#
- if actions == None:
- print " Actions: %s" % (actions)
- else:
- for a in actions:
- actionType = a['actionType']
- if actionType == "ACTION_OUTPUT":
- port = a['actionOutput']['port']['value']
- 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)
+ parsedActions = parse_actions(actions)
+ for l in parsedActions:
+ print " %s" % l
+
def get_flow_path(flow_id):
try:
diff --git a/web/measurement_store_flow.py b/web/measurement_store_flow.py
index ad0eadf..0e39465 100755
--- a/web/measurement_store_flow.py
+++ b/web/measurement_store_flow.py
@@ -87,7 +87,7 @@
if "KEEP_ONLY_FIRST_HOP_ENTRY" in arg2:
flowPathFlags = flowPathFlags + 0x2
elif arg1 == "matchInPort":
- # Just mark whether inPort matching is enabled
+ # Mark whether ACTION_OUTPUT action is enabled
matchInPortEnabled = arg2 in ['True', 'true']
# inPort = {}
# inPort['value'] = int(arg2, 0)
@@ -135,18 +135,19 @@
match['dstTcpUdpPort'] = int(arg2, 0)
# match['matchDstTcpUdpPort'] = True
elif arg1 == "actionOutput":
- # Just mark whether ACTION_OUTPUT action is enabled
+ # Mark whether ACTION_OUTPUT action is enabled
actionOutputEnabled = arg2 in ['True', 'true']
- #
- # TODO: Complete the implementation for ACTION_OUTPUT
- # actionOutput = {}
- # outPort = {}
- # outPort['value'] = int(arg2, 0)
- # actionOutput['port'] = outPort
- # actionOutput['maxLen'] = int(arg3, 0)
- # action['actionOutput'] = actionOutput
- # # action['actionType'] = 'ACTION_OUTPUT'
- # actions.append(action)
+ # If ACTION_OUTPUT is explicitly enabled, add an entry with a fake
+ # port number. We need this entry to preserve the action ordering.
+ if actionOutputEnabled == True:
+ actionOutput = {}
+ outPort = {}
+ outPort['value'] = 0xffff
+ actionOutput['port'] = outPort
+ actionOutput['maxLen'] = 0
+ action['actionOutput'] = actionOutput
+ # action['actionType'] = 'ACTION_OUTPUT'
+ actions.append(action)
#
elif arg1 == "actionSetVlanId":
vlanId = {}
@@ -264,6 +265,8 @@
flowPathFlags = {}
flowPathFlags['flags'] = myFlowPathFlags
+ flowEntryActions = {}
+
flow_path = {}
flow_path['flowId'] = flow_id
flow_path['installerId'] = installer_id
@@ -285,6 +288,11 @@
my_data_path['flowEntries'][idx]['flowEntryMatch'] = copy.deepcopy(match)
idx = idx + 1
+
+ if (len(actions) > 0):
+ flowEntryActions['actions'] = copy.deepcopy(actions)
+ flow_path['flowEntryActions'] = flowEntryActions
+
#
# Set the actions for each flow entry
# NOTE: The actions from the command line are aplied
@@ -306,11 +314,12 @@
action['actionOutput'] = copy.deepcopy(actionOutput)
# action['actionType'] = 'ACTION_OUTPUT'
actions.append(copy.deepcopy(action))
+ flowEntryActions = {}
+ flowEntryActions['actions'] = copy.deepcopy(actions)
- my_data_path['flowEntries'][idx]['flowEntryActions'] = copy.deepcopy(actions)
+ my_data_path['flowEntries'][idx]['flowEntryActions'] = flowEntryActions
idx = idx + 1
-
flow_path['dataPath'] = my_data_path
debug("Flow Path: %s" % flow_path)
return flow_path
@@ -396,6 +405,7 @@
usage_msg = usage_msg + " actionSetIpToS <IP ToS (DSCP field, 6 bits)>\n"
usage_msg = usage_msg + " actionSetTcpUdpSrcPort <source TCP/UDP port>\n"
usage_msg = usage_msg + " actionSetTcpUdpDstPort <destination TCP/UDP port>\n"
+ usage_msg = usage_msg + " Actions (not implemented yet):\n"
usage_msg = usage_msg + " actionEnqueue <dummy argument>\n"
# app.debug = False;
diff --git a/web/topology_rest.py b/web/topology_rest.py
index 53f46bc..ea33a00 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -216,19 +216,6 @@
resp = Response(result, status=200, mimetype='application/json')
return resp
-@app.route("/proxy/gui/switchctrl/<cmd>")
-def proxy_switch_controller_setting(cmd):
- try:
- command = "curl -s %s/gui/switchctrl/%s" % (ONOS_GUI3_CONTROL_HOST, cmd)
- print command
- result = os.popen(command).read()
- except:
- print "REST IF has issue"
- exit
-
- resp = Response(result, status=200, mimetype='application/json')
- return resp
-
@app.route("/proxy/gui/reset")
def proxy_gui_reset():
result = ""