Merge pull request #331 from pgreyson/master
Minor improvements
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
index 587b3c2..19addad 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
@@ -1,7 +1,10 @@
package net.floodlightcontroller.core;
+import net.floodlightcontroller.flowcache.web.DatapathSummarySerializer;
+
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.frames.Adjacency;
@@ -155,48 +158,57 @@
}
public interface IFlowPath extends IBaseObject {
+ @JsonProperty("flowId")
@Property("flow_id")
public String getFlowId();
@Property("flow_id")
public void setFlowId(String flowId);
+ @JsonProperty("installerId")
@Property("installer_id")
public String getInstallerId();
@Property("installer_id")
public void setInstallerId(String installerId);
+ @JsonProperty("srcDpid")
@Property("src_switch")
public String getSrcSwitch();
@Property("src_switch")
public void setSrcSwitch(String srcSwitch);
+ @JsonProperty("srcPort")
@Property("src_port")
public Short getSrcPort();
@Property("src_port")
public void setSrcPort(Short srcPort);
+ @JsonProperty("dstDpid")
@Property("dst_switch")
public String getDstSwitch();
@Property("dst_switch")
public void setDstSwitch(String dstSwitch);
+ @JsonProperty("dstPort")
@Property("dst_port")
public Short getDstPort();
@Property("dst_port")
public void setDstPort(Short dstPort);
+ @JsonProperty("dataPath")
+ @JsonSerialize(using=DatapathSummarySerializer.class)
@Property("data_path_summary")
public String getDataPathSummary();
@Property("data_path_summary")
public void setDataPathSummary(String dataPathSummary);
+ @JsonIgnore
@Adjacency(label="flow", direction=Direction.IN)
public Iterable<IFlowEntry> getFlowEntries();
@@ -206,30 +218,35 @@
@Adjacency(label="flow", direction=Direction.IN)
public void removeFlowEntry(final IFlowEntry flowEntry);
+ @JsonIgnore
@Property("matchEthernetFrameType")
public Short getMatchEthernetFrameType();
@Property("matchEthernetFrameType")
public void setMatchEthernetFrameType(Short matchEthernetFrameType);
+ @JsonIgnore
@Property("matchSrcMac")
public String getMatchSrcMac();
@Property("matchSrcMac")
public void setMatchSrcMac(String matchSrcMac);
+ @JsonIgnore
@Property("matchDstMac")
public String getMatchDstMac();
@Property("matchDstMac")
public void setMatchDstMac(String matchDstMac);
+ @JsonIgnore
@Property("matchSrcIPv4Net")
public String getMatchSrcIPv4Net();
@Property("matchSrcIPv4Net")
public void setMatchSrcIPv4Net(String matchSrcIPv4Net);
+ @JsonIgnore
@Property("matchDstIPv4Net")
public String getMatchDstIPv4Net();
@@ -239,6 +256,10 @@
@JsonIgnore
@GremlinGroovy("_().in('flow').out('switch')")
public Iterable<IDeviceObject> getSwitches();
+
+ @JsonIgnore
+ @Property("state")
+ public String getState();
}
public interface IFlowEntry extends IBaseObject {
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
index f9177f2..2b9bf68 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
@@ -3,7 +3,6 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
@@ -12,12 +11,9 @@
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
-import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import net.floodlightcontroller.core.IFloodlightProviderService;
@@ -32,13 +28,12 @@
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.flowcache.IFlowService;
import net.floodlightcontroller.flowcache.web.FlowWebRoutable;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.util.CallerId;
import net.floodlightcontroller.util.DataPath;
-import net.floodlightcontroller.util.Dpid;
import net.floodlightcontroller.util.DataPathEndpoints;
+import net.floodlightcontroller.util.Dpid;
import net.floodlightcontroller.util.FlowEntry;
import net.floodlightcontroller.util.FlowEntryAction;
import net.floodlightcontroller.util.FlowEntryId;
@@ -52,7 +47,6 @@
import net.floodlightcontroller.util.OFMessageDamper;
import net.floodlightcontroller.util.Port;
import net.floodlightcontroller.util.SwitchPort;
-import net.onrc.onos.flow.IFlowManager;
import net.onrc.onos.util.GraphDBConnection;
import net.onrc.onos.util.GraphDBConnection.Transaction;
@@ -63,11 +57,10 @@
import org.openflow.protocol.OFType;
import org.openflow.protocol.action.OFAction;
import org.openflow.protocol.action.OFActionOutput;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class FlowManager implements IFloodlightModule, IFlowService, IFlowManager, INetMapStorage {
+public class FlowManager implements IFloodlightModule, IFlowService, INetMapStorage {
public GraphDBConnection conn;
@@ -102,167 +95,9 @@
private static Logger log = LoggerFactory.getLogger(FlowManager.class);
// The periodic task(s)
- private final ScheduledExecutorService measureShortestPathScheduler =
- Executors.newScheduledThreadPool(1);
- private final ScheduledExecutorService measureMapReaderScheduler =
- Executors.newScheduledThreadPool(1);
private final ScheduledExecutorService mapReaderScheduler =
Executors.newScheduledThreadPool(1);
- private BlockingQueue<Runnable> shortestPathQueue = new LinkedBlockingQueue<Runnable>();
- private ThreadPoolExecutor shortestPathExecutor =
- new ThreadPoolExecutor(10, 10, 5, TimeUnit.SECONDS, shortestPathQueue);
-
- class ShortestPathTask implements Runnable {
- private int hint;
- private ITopoRouteService topoRouteService;
- private ArrayList<DataPath> dpList;
-
- public ShortestPathTask(int hint,
- ITopoRouteService topoRouteService,
- ArrayList<DataPath> dpList) {
- this.hint = hint;
- this.topoRouteService = topoRouteService;
- this.dpList = dpList;
- }
-
- @Override
- public void run() {
- /*
- String logMsg = "MEASUREMENT: Running Thread hint " + this.hint;
- log.debug(logMsg);
- long startTime = System.nanoTime();
- */
- for (DataPath dp : this.dpList) {
- topoRouteService.getTopoShortestPath(dp.srcPort(), dp.dstPort());
- }
- /*
- long estimatedTime = System.nanoTime() - startTime;
- double rate = (estimatedTime > 0)? ((double)dpList.size() * 1000000000) / estimatedTime: 0.0;
- logMsg = "MEASUREMENT: Computed Thread hint " + hint + ": " + dpList.size() + " shortest paths in " + (double)estimatedTime / 1000000000 + " sec: " + rate + " flows/s";
- log.debug(logMsg);
- */
- }
- }
-
- final Runnable measureShortestPath = new Runnable() {
- public void run() {
- log.debug("Recomputing Shortest Paths from the Network Map Flows...");
- if (floodlightProvider == null) {
- log.debug("FloodlightProvider service not found!");
- return;
- }
-
- if (topoRouteService == null) {
- log.debug("Topology Route Service not found");
- return;
- }
-
- int leftoverQueueSize = shortestPathExecutor.getQueue().size();
- if (leftoverQueueSize > 0) {
- String logMsg = "MEASUREMENT: Leftover Shortest Path Queue Size: " + leftoverQueueSize;
- log.debug(logMsg);
- return;
- }
- log.debug("MEASUREMENT: Beginning Shortest Path Computation");
-
- //
- // Recompute the Shortest Paths for all Flows
- //
- int counter = 0;
- int hint = 0;
- ArrayList<DataPath> dpList = new ArrayList<DataPath>();
- long startTime = System.nanoTime();
-
- topoRouteService.prepareShortestPathTopo();
-
- Iterable<IFlowPath> allFlowPaths = conn.utils().getAllFlowPaths(conn);
- for (IFlowPath flowPathObj : allFlowPaths) {
- FlowId flowId = new FlowId(flowPathObj.getFlowId());
-
- // log.debug("Found Path {}", flowId.toString());
- Dpid srcDpid = new Dpid(flowPathObj.getSrcSwitch());
- Port srcPort = new Port(flowPathObj.getSrcPort());
- Dpid dstDpid = new Dpid(flowPathObj.getDstSwitch());
- Port dstPort = new Port(flowPathObj.getDstPort());
- SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
- SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
-
- /*
- DataPath dp = new DataPath();
- dp.setSrcPort(srcSwitchPort);
- dp.setDstPort(dstSwitchPort);
- dpList.add(dp);
- if ((dpList.size() % 10) == 0) {
- shortestPathExecutor.execute(
- new ShortestPathTask(hint, topoRouteService,
- dpList));
- dpList = new ArrayList<DataPath>();
- hint++;
- }
- */
-
- DataPath dataPath =
- topoRouteService.getTopoShortestPath(srcSwitchPort,
- dstSwitchPort);
- counter++;
- }
- if (dpList.size() > 0) {
- shortestPathExecutor.execute(
- new ShortestPathTask(hint, topoRouteService,
- dpList));
- }
-
- /*
- // Wait for all tasks to finish
- try {
- while (shortestPathExecutor.getQueue().size() > 0) {
- Thread.sleep(100);
- }
- } catch (InterruptedException ex) {
- log.debug("MEASUREMENT: Shortest Path Computation interrupted");
- }
- */
-
- conn.endTx(Transaction.COMMIT);
- topoRouteService.dropShortestPathTopo();
-
- long estimatedTime = System.nanoTime() - startTime;
- double rate = (estimatedTime > 0)? ((double)counter * 1000000000) / estimatedTime: 0.0;
- String logMsg = "MEASUREMENT: Computed " + counter + " shortest paths in " + (double)estimatedTime / 1000000000 + " sec: " + rate + " flows/s";
- log.debug(logMsg);
- }
- };
-
- final Runnable measureMapReader = new Runnable() {
- public void run() {
- if (floodlightProvider == null) {
- log.debug("FloodlightProvider service not found!");
- return;
- }
-
- //
- // Fetch all Flow Entries
- //
- int counter = 0;
- long startTime = System.nanoTime();
- Iterable<IFlowEntry> allFlowEntries = conn.utils().getAllFlowEntries(conn);
- for (IFlowEntry flowEntryObj : allFlowEntries) {
- counter++;
- FlowEntryId flowEntryId =
- new FlowEntryId(flowEntryObj.getFlowEntryId());
- String userState = flowEntryObj.getUserState();
- String switchState = flowEntryObj.getSwitchState();
- }
- conn.endTx(Transaction.COMMIT);
-
- long estimatedTime = System.nanoTime() - startTime;
- double rate = (estimatedTime > 0)? ((double)counter * 1000000000) / estimatedTime: 0.0;
- String logMsg = "MEASUREMENT: Fetched " + counter + " flow entries in " + (double)estimatedTime / 1000000000 + " sec: " + rate + " entries/s";
- log.debug(logMsg);
- }
- };
-
final Runnable mapReader = new Runnable() {
public void run() {
long startTime = System.nanoTime();
@@ -305,14 +140,6 @@
FlowEntryId flowEntryId = new FlowEntryId(flowEntryIdStr);
Dpid dpid = new Dpid(dpidStr);
- /*
- log.debug("Found Flow Entry Id = {} {}",
- flowEntryId.toString(),
- "DPID = " + dpid.toString() +
- " User State: " + userState +
- " Switch State: " + switchState);
- */
-
if (! switchState.equals("FE_SWITCH_NOT_UPDATED"))
continue; // Ignore the entry: nothing to do
@@ -321,10 +148,17 @@
continue; // Ignore the entry: not my switch
myFlowEntries.put(flowEntryId.value(), flowEntryObj);
+ if (userState.equals("FE_USER_DELETE")) {
+ // An entry that needs to be deleted.
+ deleteFlowEntries.add(flowEntryObj);
+ }
}
+ log.debug("MEASUREMENT: Found {} My Flow Entries NOT_UPDATED",
+ myFlowEntries.size());
+
//
- // Process my Flow Entries
+ // Process my Flow Entries in the Flow Entry ID order
//
boolean processed_measurement_flow = false;
for (Map.Entry<Long, IFlowEntry> entry : myFlowEntries.entrySet()) {
@@ -337,156 +171,28 @@
continue; // Should NOT happen
// Code for measurement purpose
+ // TODO: Commented-out for now
+ /*
{
if (flowObj.getFlowId().equals(measurementFlowIdStr)) {
processed_measurement_flow = true;
}
}
+ */
- //
- // TODO: Eliminate the re-fetching of flowEntryId,
- // userState, switchState, and dpid from the flowEntryObj.
- //
- FlowEntryId flowEntryId =
- new FlowEntryId(flowEntryObj.getFlowEntryId());
Dpid dpid = new Dpid(flowEntryObj.getSwitchDpid());
- String userState = flowEntryObj.getUserState();
- String switchState = flowEntryObj.getSwitchState();
IOFSwitch mySwitch = mySwitches.get(dpid.value());
if (mySwitch == null)
continue; // Shouldn't happen
-
- //
- // Create the Open Flow Flow Modification Entry to push
- //
- OFFlowMod fm =
- (OFFlowMod) floodlightProvider.getOFMessageFactory()
- .getMessage(OFType.FLOW_MOD);
- long cookie = flowEntryId.value();
-
- short flowModCommand = OFFlowMod.OFPFC_ADD;
- if (userState.equals("FE_USER_ADD")) {
- flowModCommand = OFFlowMod.OFPFC_ADD;
- } else if (userState.equals("FE_USER_MODIFY")) {
- flowModCommand = OFFlowMod.OFPFC_MODIFY_STRICT;
- } else if (userState.equals("FE_USER_DELETE")) {
- flowModCommand = OFFlowMod.OFPFC_DELETE_STRICT;
- } else {
- // Unknown user state. Ignore the entry
- log.debug("Flow Entry ignored (FlowEntryId = {}): unknown user state {}",
- flowEntryId.toString(), userState);
- continue;
- }
-
- //
- // Fetch the match conditions.
- //
- // NOTE: The Flow matching conditions common for all
- // Flow Entries are used ONLY if a Flow Entry does NOT
- // have the corresponding matching condition set.
- //
- OFMatch match = new OFMatch();
- match.setWildcards(OFMatch.OFPFW_ALL);
- //
- Short matchInPort = flowEntryObj.getMatchInPort();
- if (matchInPort != null) {
- match.setInputPort(matchInPort);
- match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
- }
- //
- Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
- if (matchEthernetFrameType == null)
- matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
- if (matchEthernetFrameType != null) {
- match.setDataLayerType(matchEthernetFrameType);
- match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
- }
- //
- String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
- if (matchSrcIPv4Net == null)
- matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
- if (matchSrcIPv4Net != null) {
- match.setFromCIDR(matchSrcIPv4Net, OFMatch.STR_NW_SRC);
- }
- //
- String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
- if (matchDstIPv4Net == null)
- matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
- if (matchDstIPv4Net != null) {
- match.setFromCIDR(matchDstIPv4Net, OFMatch.STR_NW_DST);
- }
- //
- String matchSrcMac = flowEntryObj.getMatchSrcMac();
- if (matchSrcMac == null)
- matchSrcMac = flowObj.getMatchSrcMac();
- if (matchSrcMac != null) {
- match.setDataLayerSource(matchSrcMac);
- match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
- }
- //
- String matchDstMac = flowEntryObj.getMatchDstMac();
- if (matchDstMac == null)
- matchDstMac = flowObj.getMatchDstMac();
- if (matchDstMac != null) {
- match.setDataLayerDestination(matchDstMac);
- match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
- }
-
- //
- // Fetch the actions
- //
- List<OFAction> actions = new ArrayList<OFAction>();
- Short actionOutputPort = flowEntryObj.getActionOutput();
- 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);
- }
-
- fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
- .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
- .setPriority(PRIORITY_DEFAULT)
- .setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setCookie(cookie)
- .setCommand(flowModCommand)
- .setMatch(match)
- .setActions(actions)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
- 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
- // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
- // See method ForwardingBase::pushRoute()
- //
- try {
- messageDamper.write(mySwitch, fm, null);
- mySwitch.flush();
- //
- // TODO: We should use the OpenFlow Barrier mechanism
- // to check for errors, and update the SwitchState
- // for a flow entry after the Barrier message is
- // is received.
- //
- flowEntryObj.setSwitchState("FE_SWITCH_UPDATED");
- if (userState.equals("FE_USER_DELETE")) {
- // An entry that needs to be deleted.
- deleteFlowEntries.add(flowEntryObj);
- }
- } catch (IOException e) {
- log.error("Failure writing flow mod from network map", e);
- }
+ installFlowEntry(mySwitch, flowObj, flowEntryObj);
}
+ log.debug("MEASUREMENT: Found {} Flow Entries to delete",
+ deleteFlowEntries.size());
+
//
- // Delete all entries marked for deletion
+ // Delete all entries marked for deletion from the
+ // Network MAP.
//
// TODO: We should use the OpenFlow Barrier mechanism
// to check for errors, and delete the Flow Entries after the
@@ -502,19 +208,6 @@
}
flowObj.removeFlowEntry(flowEntryObj);
conn.utils().removeFlowEntry(conn, flowEntryObj);
-
- // Test whether the last flow entry
- Iterable<IFlowEntry> tmpflowEntries =
- flowObj.getFlowEntries();
- boolean found = false;
- for (IFlowEntry tmpflowEntryObj : tmpflowEntries) {
- found = true;
- break;
- }
- if (! found) {
- // Remove the Flow Path as well
- conn.utils().removeFlowPath(conn, flowObj);
- }
}
@@ -522,11 +215,6 @@
// Fetch and recompute the Shortest Path for those
// Flow Paths this controller is responsible for.
//
-
- /*
- * TODO: For now, the computation of the reconciliation is
- * commented-out.
- */
topoRouteService.prepareShortestPathTopo();
Iterable<IFlowPath> allFlowPaths = conn.utils().getAllFlowPaths(conn);
HashSet<IFlowPath> flowObjSet = new HashSet<IFlowPath>();
@@ -604,6 +292,8 @@
flowId.toString());
flowObjSet.add(flowPathObj);
}
+ log.debug("MEASUREMENT: Found {} Flows to reconcile",
+ flowObjSet.size());
reconcileFlows(flowObjSet);
topoRouteService.dropShortestPathTopo();
@@ -611,29 +301,28 @@
conn.endTx(Transaction.COMMIT);
if (processed_measurement_flow) {
- long estimatedTime = System.nanoTime() - modifiedMeasurementFlowTime;
+ long estimatedTime =
+ System.nanoTime() - modifiedMeasurementFlowTime;
String logMsg = "MEASUREMENT: Pushed Flow delay: " +
(double)estimatedTime / 1000000000 + " sec";
log.debug(logMsg);
}
long estimatedTime = System.nanoTime() - startTime;
- double rate = (estimatedTime > 0)? ((double)counterAllFlowPaths * 1000000000) / estimatedTime: 0.0;
- String logMsg = "MEASUREMENT: Processed AllFlowEntries: " + counterAllFlowEntries + " MyNotUpdatedFlowEntries: " + counterMyNotUpdatedFlowEntries + " AllFlowPaths: " + counterAllFlowPaths + " MyFlowPaths: " + counterMyFlowPaths + " in " + (double)estimatedTime / 1000000000 + " sec: " + rate + " paths/s";
+ double rate = 0.0;
+ if (estimatedTime > 0)
+ rate = ((double)counterAllFlowPaths * 1000000000) / estimatedTime;
+ String logMsg = "MEASUREMENT: Processed AllFlowEntries: " +
+ counterAllFlowEntries + " MyNotUpdatedFlowEntries: " +
+ counterMyNotUpdatedFlowEntries + " AllFlowPaths: " +
+ counterAllFlowPaths + " MyFlowPaths: " +
+ counterMyFlowPaths + " in " +
+ (double)estimatedTime / 1000000000 + " sec: " +
+ rate + " paths/s";
log.debug(logMsg);
}
};
- /*
- final ScheduledFuture<?> measureShortestPathHandle =
- measureShortestPathScheduler.scheduleAtFixedRate(measureShortestPath, 10, 10, TimeUnit.SECONDS);
- */
-
- /*
- final ScheduledFuture<?> measureMapReaderHandle =
- measureMapReaderScheduler.scheduleAtFixedRate(measureMapReader, 10, 10, TimeUnit.SECONDS);
- */
-
final ScheduledFuture<?> mapReaderHandle =
mapReaderScheduler.scheduleAtFixedRate(mapReader, 3, 3, TimeUnit.SECONDS);
@@ -737,19 +426,12 @@
@Override
public boolean addFlow(FlowPath flowPath, FlowId flowId,
String dataPathSummaryStr) {
+ /*
+ * TODO: Commented-out for now
if (flowPath.flowId().value() == measurementFlowId) {
modifiedMeasurementFlowTime = System.nanoTime();
}
-
- //
- // Assign the FlowEntry IDs
- // Right now every new flow entry gets a new flow entry ID
- // TODO: This needs to be redesigned!
- //
- for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
- long id = getNextFlowEntryId();
- flowEntry.setFlowEntryId(new FlowEntryId(id));
- }
+ */
IFlowPath flowObj = null;
try {
@@ -829,112 +511,10 @@
// flowPath.dataPath().flowEntries()
//
for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
- IFlowEntry flowEntryObj = null;
- boolean found = false;
- try {
- if ((flowEntryObj = conn.utils().searchFlowEntry(conn, flowEntry.flowEntryId())) != null) {
- log.debug("Adding FlowEntry with FlowEntryId {}: found existing FlowEntry",
- flowEntry.flowEntryId().toString());
- found = true;
- } else {
- flowEntryObj = conn.utils().newFlowEntry(conn);
- log.debug("Adding FlowEntry with FlowEntryId {}: creating new FlowEntry",
- flowEntry.flowEntryId().toString());
- }
- } catch (Exception e) {
- // TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
- log.error(":addFlow FlowEntryId:{} failed",
- flowEntry.flowEntryId().toString());
- }
- if (flowEntryObj == null) {
- log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
- flowEntry.flowEntryId().toString());
+ if (addFlowEntry(flowObj, flowEntry) != true) {
conn.endTx(Transaction.ROLLBACK);
return false;
}
-
- //
- // Set the Flow Entry key:
- // - flowEntry.flowEntryId()
- //
- flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
- flowEntryObj.setType("flow_entry");
-
- //
- // Set the Flow Entry Edges and attributes:
- // - Switch edge
- // - InPort edge
- // - OutPort edge
- //
- // - flowEntry.flowEntryMatch()
- // - flowEntry.flowEntryActions()
- // - flowEntry.dpid()
- // - flowEntry.flowEntryUserState()
- // - flowEntry.flowEntrySwitchState()
- // - flowEntry.flowEntryErrorState()
- // - flowEntry.matchInPort()
- // - flowEntry.matchEthernetFrameType()
- // - flowEntry.matchSrcIPv4Net()
- // - flowEntry.matchDstIPv4Net()
- // - flowEntry.matchSrcMac()
- // - flowEntry.matchDstMac()
- // - flowEntry.actionOutput()
- //
- ISwitchObject sw =
- conn.utils().searchSwitch(conn, flowEntry.dpid().toString());
- flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
- flowEntryObj.setSwitch(sw);
- if (flowEntry.flowEntryMatch().matchInPort()) {
- IPortObject inport =
- conn.utils().searchPort(conn, flowEntry.dpid().toString(),
- flowEntry.flowEntryMatch().inPort().value());
- flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
- flowEntryObj.setInPort(inport);
- }
- if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
- flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
- }
- if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
- flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
- }
- if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
- flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
- }
- if (flowEntry.flowEntryMatch().matchSrcMac()) {
- flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
- }
- if (flowEntry.flowEntryMatch().matchDstMac()) {
- flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
- }
-
- for (FlowEntryAction fa : flowEntry.flowEntryActions()) {
- if (fa.actionOutput() != null) {
- IPortObject outport =
- conn.utils().searchPort(conn,
- flowEntry.dpid().toString(),
- fa.actionOutput().port().value());
- flowEntryObj.setActionOutput(fa.actionOutput().port().value());
- flowEntryObj.setOutPort(outport);
- }
- }
- // TODO: Hacks with hard-coded state names!
- if (found)
- flowEntryObj.setUserState("FE_USER_MODIFY");
- else
- flowEntryObj.setUserState("FE_USER_ADD");
- flowEntryObj.setSwitchState("FE_SWITCH_NOT_UPDATED");
- //
- // TODO: Take care of the FlowEntryErrorState.
- //
-
- // Flow Entries edges:
- // Flow
- // NextFE (TODO)
- if (! found) {
- flowObj.addFlowEntry(flowEntryObj);
- flowEntryObj.setFlow(flowObj);
- }
}
conn.endTx(Transaction.COMMIT);
@@ -947,6 +527,135 @@
}
/**
+ * Add a flow entry to the Network MAP.
+ *
+ * @param flowObj the corresponding Flow Path object for the Flow Entry.
+ * @param flowEntry the Flow Entry to install.
+ * @return true on success, otherwise false.
+ */
+ private boolean addFlowEntry(IFlowPath flowObj, FlowEntry flowEntry) {
+ // Flow edges
+ // HeadFE (TODO)
+
+ //
+ // Assign the FlowEntry ID.
+ //
+ if ((flowEntry.flowEntryId() == null) ||
+ (flowEntry.flowEntryId().value() == 0)) {
+ long id = getNextFlowEntryId();
+ flowEntry.setFlowEntryId(new FlowEntryId(id));
+ }
+
+ IFlowEntry flowEntryObj = null;
+ boolean found = false;
+ try {
+ if ((flowEntryObj =
+ conn.utils().searchFlowEntry(conn, flowEntry.flowEntryId())) != null) {
+ log.debug("Adding FlowEntry with FlowEntryId {}: found existing FlowEntry",
+ flowEntry.flowEntryId().toString());
+ found = true;
+ } else {
+ flowEntryObj = conn.utils().newFlowEntry(conn);
+ log.debug("Adding FlowEntry with FlowEntryId {}: creating new FlowEntry",
+ flowEntry.flowEntryId().toString());
+ }
+ } catch (Exception e) {
+ log.error(":addFlow FlowEntryId:{} failed",
+ flowEntry.flowEntryId().toString());
+ return false;
+ }
+ if (flowEntryObj == null) {
+ log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
+ flowEntry.flowEntryId().toString());
+ return false;
+ }
+
+ //
+ // Set the Flow Entry key:
+ // - flowEntry.flowEntryId()
+ //
+ flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
+ flowEntryObj.setType("flow_entry");
+
+ //
+ // Set the Flow Entry Edges and attributes:
+ // - Switch edge
+ // - InPort edge
+ // - OutPort edge
+ //
+ // - flowEntry.flowEntryMatch()
+ // - flowEntry.flowEntryActions()
+ // - flowEntry.dpid()
+ // - flowEntry.flowEntryUserState()
+ // - flowEntry.flowEntrySwitchState()
+ // - flowEntry.flowEntryErrorState()
+ // - flowEntry.matchInPort()
+ // - flowEntry.matchEthernetFrameType()
+ // - flowEntry.matchSrcIPv4Net()
+ // - flowEntry.matchDstIPv4Net()
+ // - flowEntry.matchSrcMac()
+ // - flowEntry.matchDstMac()
+ // - flowEntry.actionOutput()
+ //
+ ISwitchObject sw =
+ conn.utils().searchSwitch(conn, flowEntry.dpid().toString());
+ flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
+ flowEntryObj.setSwitch(sw);
+ if (flowEntry.flowEntryMatch().matchInPort()) {
+ IPortObject inport =
+ conn.utils().searchPort(conn, flowEntry.dpid().toString(),
+ flowEntry.flowEntryMatch().inPort().value());
+ flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
+ flowEntryObj.setInPort(inport);
+ }
+ if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
+ flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+ }
+ if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
+ flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+ }
+ if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
+ flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+ }
+ if (flowEntry.flowEntryMatch().matchSrcMac()) {
+ flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
+ }
+ if (flowEntry.flowEntryMatch().matchDstMac()) {
+ flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
+ }
+
+ for (FlowEntryAction fa : flowEntry.flowEntryActions()) {
+ if (fa.actionOutput() != null) {
+ IPortObject outport =
+ conn.utils().searchPort(conn,
+ flowEntry.dpid().toString(),
+ fa.actionOutput().port().value());
+ flowEntryObj.setActionOutput(fa.actionOutput().port().value());
+ flowEntryObj.setOutPort(outport);
+ }
+ }
+ // TODO: Hacks with hard-coded state names!
+ if (found)
+ flowEntryObj.setUserState("FE_USER_MODIFY");
+ else
+ flowEntryObj.setUserState("FE_USER_ADD");
+ flowEntryObj.setSwitchState("FE_SWITCH_NOT_UPDATED");
+ //
+ // TODO: Take care of the FlowEntryErrorState.
+ //
+
+ // Flow Entries edges:
+ // Flow
+ // NextFE (TODO)
+ if (! found) {
+ flowObj.addFlowEntry(flowEntryObj);
+ flowEntryObj.setFlow(flowObj);
+ }
+
+ return true;
+ }
+
+ /**
* Delete a previously added flow.
*
* @param flowId the Flow ID of the flow to delete.
@@ -954,9 +663,12 @@
*/
@Override
public boolean deleteFlow(FlowId flowId) {
+ /*
+ * TODO: Commented-out for now
if (flowId.value() == measurementFlowId) {
modifiedMeasurementFlowTime = System.nanoTime();
}
+ */
IFlowPath flowObj = null;
//
@@ -1190,7 +902,10 @@
* @return the Flow Paths if found, otherwise null.
*/
@Override
- public ArrayList<FlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows) {
+ public ArrayList<IFlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows) {
+
+
+
//
// TODO: The implementation below is not optimal:
// We fetch all flows, and then return only the subset that match
@@ -1198,10 +913,15 @@
// We should use the appropriate Titan/Gremlin query to filter-out
// the flows as appropriate.
//
- ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+ //ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+ ArrayList<IFlowPath> flowPathsWithoutFlowEntries = getAllFlowsWithoutFlowEntries();
+
+ return flowPathsWithoutFlowEntries;
+
+ /*
ArrayList<FlowPath> allFlows = getAllFlows();
-
+
if (allFlows == null) {
log.debug("Get FlowPathsSummary for {} {}: no FlowPaths found", flowId, maxFlows);
return flowPaths;
@@ -1212,10 +932,10 @@
for (FlowPath flow : allFlows) {
flow.setFlowEntryMatch(null);
- // start from desired flowId
- //if (flow.flowId().value() < flowId.value()) {
- // continue;
- //}
+ // start from desired flowId
+ if (flow.flowId().value() < flowId.value()) {
+ continue;
+ }
// Summarize by making null flow entry fields that are not relevant to report
for (FlowEntry flowEntry : flow.dataPath().flowEntries()) {
@@ -1236,6 +956,7 @@
}
return flowPaths;
+ */
}
/**
@@ -1277,6 +998,45 @@
return flowPaths;
}
+
+ public ArrayList<IFlowPath> getAllFlowsWithoutFlowEntries(){
+ Iterable<IFlowPath> flowPathsObj = null;
+ ArrayList<IFlowPath> flowPathsObjArray = new ArrayList<IFlowPath>();
+ ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+
+ try {
+ if ((flowPathsObj = conn.utils().getAllFlowPaths(conn)) != null) {
+ log.debug("Get all FlowPaths: found FlowPaths");
+ } else {
+ log.debug("Get all FlowPaths: no FlowPaths found");
+ }
+ } catch (Exception e) {
+ // TODO: handle exceptions
+ conn.endTx(Transaction.ROLLBACK);
+ log.error(":getAllFlowPaths failed");
+ }
+ if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
+ return new ArrayList<IFlowPath>(); // No Flows found
+ }
+
+ for (IFlowPath flowObj : flowPathsObj){
+ flowPathsObjArray.add(flowObj);
+ }
+ /*
+ for (IFlowPath flowObj : flowPathsObj) {
+ //
+ // Extract the Flow state
+ //
+ FlowPath flowPath = extractFlowPath(flowObj);
+ if (flowPath != null)
+ flowPaths.add(flowPath);
+ }
+ */
+
+ //conn.endTx(Transaction.COMMIT);
+
+ return flowPathsObjArray;
+ }
/**
* Extract Flow Path State from a Titan Database Object @ref IFlowPath.
@@ -1285,8 +1045,6 @@
* @return the extracted Flow Path State.
*/
private FlowPath extractFlowPath(IFlowPath flowObj) {
- FlowPath flowPath = new FlowPath();
-
//
// Extract the Flow state
//
@@ -1307,6 +1065,7 @@
return null;
}
+ FlowPath flowPath = new FlowPath();
flowPath.setFlowId(new FlowId(flowIdStr));
flowPath.setInstallerId(new CallerId(installerIdStr));
flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
@@ -1341,63 +1100,9 @@
//
Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
for (IFlowEntry flowEntryObj : flowEntries) {
- FlowEntry flowEntry = new FlowEntry();
- String flowEntryIdStr = flowEntryObj.getFlowEntryId();
- String switchDpidStr = flowEntryObj.getSwitchDpid();
- String userState = flowEntryObj.getUserState();
- String switchState = flowEntryObj.getSwitchState();
-
- if ((flowEntryIdStr == null) ||
- (switchDpidStr == null) ||
- (userState == null) ||
- (switchState == null)) {
- // TODO: A work-around, becauuse of some bogus database objects
+ FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
+ if (flowEntry == null)
continue;
- }
- flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
- flowEntry.setDpid(new Dpid(switchDpidStr));
-
- //
- // Extract the match conditions
- //
- FlowEntryMatch match = new FlowEntryMatch();
- Short matchInPort = flowEntryObj.getMatchInPort();
- if (matchInPort != null)
- match.enableInPort(new Port(matchInPort));
- Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
- if (matchEthernetFrameType != null)
- match.enableEthernetFrameType(matchEthernetFrameType);
- String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
- if (matchSrcIPv4Net != null)
- match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
- String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
- if (matchDstIPv4Net != null)
- match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
- String matchSrcMac = flowEntryObj.getMatchSrcMac();
- if (matchSrcMac != null)
- match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
- String matchDstMac = flowEntryObj.getMatchDstMac();
- if (matchDstMac != null)
- match.enableDstMac(MACAddress.valueOf(matchDstMac));
- flowEntry.setFlowEntryMatch(match);
-
- //
- // Extract the actions
- //
- ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
- Short actionOutputPort = flowEntryObj.getActionOutput();
- if (actionOutputPort != null) {
- FlowEntryAction action = new FlowEntryAction();
- action.setActionOutput(new Port(actionOutputPort));
- actions.add(action);
- }
- flowEntry.setFlowEntryActions(actions);
- flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
- flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
- //
- // TODO: Take care of the FlowEntryMatch, FlowEntryAction set,
- // and FlowEntryErrorState.
- //
flowPath.dataPath().flowEntries().add(flowEntry);
}
@@ -1405,6 +1110,74 @@
}
/**
+ * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
+ *
+ * @param flowEntryObj the object to extract the Flow Entry State from.
+ * @return the extracted Flow Entry State.
+ */
+ private FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
+ String flowEntryIdStr = flowEntryObj.getFlowEntryId();
+ String switchDpidStr = flowEntryObj.getSwitchDpid();
+ String userState = flowEntryObj.getUserState();
+ String switchState = flowEntryObj.getSwitchState();
+
+ if ((flowEntryIdStr == null) ||
+ (switchDpidStr == null) ||
+ (userState == null) ||
+ (switchState == null)) {
+ // TODO: A work-around, becauuse of some bogus database objects
+ return null;
+ }
+
+ FlowEntry flowEntry = new FlowEntry();
+ flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
+ flowEntry.setDpid(new Dpid(switchDpidStr));
+
+ //
+ // Extract the match conditions
+ //
+ FlowEntryMatch match = new FlowEntryMatch();
+ Short matchInPort = flowEntryObj.getMatchInPort();
+ if (matchInPort != null)
+ match.enableInPort(new Port(matchInPort));
+ Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType != null)
+ match.enableEthernetFrameType(matchEthernetFrameType);
+ String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net != null)
+ match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
+ String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net != null)
+ match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
+ String matchSrcMac = flowEntryObj.getMatchSrcMac();
+ if (matchSrcMac != null)
+ match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
+ String matchDstMac = flowEntryObj.getMatchDstMac();
+ if (matchDstMac != null)
+ match.enableDstMac(MACAddress.valueOf(matchDstMac));
+ flowEntry.setFlowEntryMatch(match);
+
+ //
+ // Extract the actions
+ //
+ ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
+ Short actionOutputPort = flowEntryObj.getActionOutput();
+ if (actionOutputPort != null) {
+ FlowEntryAction action = new FlowEntryAction();
+ action.setActionOutput(new Port(actionOutputPort));
+ actions.add(action);
+ }
+ flowEntry.setFlowEntryActions(actions);
+ flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
+ flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
+ //
+ // TODO: Take care of the FlowEntryMatch, FlowEntryAction set,
+ // and FlowEntryErrorState.
+ //
+ return flowEntry;
+ }
+
+ /**
* Add and maintain a shortest-path flow.
*
* NOTE: The Flow Path argument does NOT contain flow entries.
@@ -1473,78 +1246,6 @@
}
/**
- * Create a Flow from port to port.
- *
- * TODO: We don't need it for now.
- *
- * @param src_port the source port.
- * @param dest_port the destination port.
- */
- @Override
- public void createFlow(IPortObject src_port, IPortObject dest_port) {
- // TODO: We don't need it for now.
- }
-
- /**
- * Get all Flows matching a source and a destination port.
- *
- * TODO: Pankaj might be implementing it later.
- *
- * @param src_port the source port to match.
- * @param dest_port the destination port to match.
- * @return all flows matching the source and the destination port.
- */
- @Override
- public Iterable<FlowPath> getFlows(IPortObject src_port,
- IPortObject dest_port) {
- // TODO: Pankaj might be implementing it later.
- return null;
- }
-
- /**
- * Get all Flows going out from a port.
- *
- * TODO: We need it now: Pankaj
- *
- * @param port the port to match.
- * @return the list of flows that are going out from the port.
- */
- @Override
- public Iterable<FlowPath> getOutFlows(IPortObject port) {
- // TODO: We need it now: Pankaj
- return null;
- }
-
- /**
- * Reconcile all flows on inactive switch port.
- *
- * @param portObject the port that has become inactive.
- */
- @Override
- public void reconcileFlows(IPortObject portObject) {
- Iterable<IFlowEntry> inFlowEntries = portObject.getInFlowEntries();
- Iterable<IFlowEntry> outFlowEntries = portObject.getOutFlowEntries();
-
- //
- // Collect all affected Flow IDs from the affected flow entries
- //
- HashSet<IFlowPath> flowObjSet = new HashSet<IFlowPath>();
- for (IFlowEntry flowEntryObj: inFlowEntries) {
- IFlowPath flowObj = flowEntryObj.getFlow();
- if (flowObj != null)
- flowObjSet.add(flowObj);
- }
- for (IFlowEntry flowEntryObj: outFlowEntries) {
- IFlowPath flowObj = flowEntryObj.getFlow();
- if (flowObj != null)
- flowObjSet.add(flowObj);
- }
-
- // Reconcile the affected flows
- reconcileFlows(flowObjSet);
- }
-
- /**
* Reconcile all flows in a set.
*
* @param flowObjSet the set of flows that need to be reconciliated.
@@ -1652,96 +1353,156 @@
}
/**
- * Reconcile all flows between a source and a destination port.
+ * Install a Flow Entry on a switch.
*
- * TODO: We don't need it for now.
- *
- * @param src_port the source port.
- * @param dest_port the destination port.
+ * @param mySwitch the switch to install the Flow Entry into.
+ * @param flowObj the flow path object for the flow entry to install.
+ * @param flowEntryObj the flow entry object to install.
+ * @return true on success, otherwise false.
*/
- @Override
- public void reconcileFlow(IPortObject src_port, IPortObject dest_port) {
- // TODO: We don't need it for now.
- }
-
- /**
- * Compute the shortest path between a source and a destination ports.
- *
- * @param src_port the source port.
- * @param dest_port the destination port.
- * @return the computed shortest path between the source and the
- * destination ports. The flow entries in the path itself would
- * contain the incoming port matching and the outgoing port output
- * actions set. However, the path itself will NOT have the Flow ID,
- * Installer ID, and any additional matching conditions for the
- * flow entries (e.g., source or destination MAC address, etc).
- */
- @Override
- public FlowPath computeFlowPath(IPortObject src_port,
- IPortObject dest_port) {
- //
- // Prepare the arguments
- //
- String dpidStr = src_port.getSwitch().getDPID();
- Dpid srcDpid = new Dpid(dpidStr);
- Port srcPort = new Port(src_port.getNumber());
-
- dpidStr = dest_port.getSwitch().getDPID();
- Dpid dstDpid = new Dpid(dpidStr);
- Port dstPort = new Port(dest_port.getNumber());
-
- SwitchPort src = new SwitchPort(srcDpid, srcPort);
- SwitchPort dst = new SwitchPort(dstDpid, dstPort);
+ public boolean installFlowEntry(IOFSwitch mySwitch, IFlowPath flowObj,
+ IFlowEntry flowEntryObj) {
+ FlowEntryId flowEntryId =
+ new FlowEntryId(flowEntryObj.getFlowEntryId());
+ String userState = flowEntryObj.getUserState();
//
- // Do the shortest path computation
+ // Create the Open Flow Flow Modification Entry to push
//
- DataPath dataPath = topoRouteService.getShortestPath(src, dst);
- if (dataPath == null)
- return null;
+ OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory()
+ .getMessage(OFType.FLOW_MOD);
+ long cookie = flowEntryId.value();
- //
- // Set the incoming port matching and the outgoing port output
- // actions for each flow entry.
- //
- for (FlowEntry flowEntry : dataPath.flowEntries()) {
- // Set the incoming port matching
- FlowEntryMatch flowEntryMatch = flowEntry.flowEntryMatch();
- if (flowEntryMatch == null) {
- 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);
- }
- FlowEntryAction flowEntryAction = new FlowEntryAction();
- flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ short flowModCommand = OFFlowMod.OFPFC_ADD;
+ if (userState.equals("FE_USER_ADD")) {
+ flowModCommand = OFFlowMod.OFPFC_ADD;
+ } else if (userState.equals("FE_USER_MODIFY")) {
+ flowModCommand = OFFlowMod.OFPFC_MODIFY_STRICT;
+ } else if (userState.equals("FE_USER_DELETE")) {
+ flowModCommand = OFFlowMod.OFPFC_DELETE_STRICT;
+ } else {
+ // Unknown user state. Ignore the entry
+ log.debug("Flow Entry ignored (FlowEntryId = {}): unknown user state {}",
+ flowEntryId.toString(), userState);
+ return false;
}
//
- // Prepare the return result
+ // Fetch the match conditions.
//
- FlowPath flowPath = new FlowPath();
- flowPath.setDataPath(dataPath);
+ // NOTE: The Flow matching conditions common for all Flow Entries are
+ // used ONLY if a Flow Entry does NOT have the corresponding matching
+ // condition set.
+ //
+ OFMatch match = new OFMatch();
+ match.setWildcards(OFMatch.OFPFW_ALL);
- return flowPath;
- }
+ // Match the Incoming Port
+ Short matchInPort = flowEntryObj.getMatchInPort();
+ if (matchInPort != null) {
+ match.setInputPort(matchInPort);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
+ }
- /**
- * Get all Flow Entries of a Flow.
- *
- * @param flow the flow whose flow entries should be returned.
- * @return the flow entries of the flow.
- */
- @Override
- public Iterable<FlowEntry> getFlowEntries(FlowPath flow) {
- return flow.dataPath().flowEntries();
+ // Match the Ethernet Frame Type
+ Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType == null)
+ matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType != null) {
+ match.setDataLayerType(matchEthernetFrameType);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+ }
+
+ // Match the Source IPv4 Network prefix
+ String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net == null)
+ matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net != null) {
+ match.setFromCIDR(matchSrcIPv4Net, OFMatch.STR_NW_SRC);
+ }
+
+ // Natch the Destination IPv4 Network prefix
+ String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net == null)
+ matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net != null) {
+ match.setFromCIDR(matchDstIPv4Net, OFMatch.STR_NW_DST);
+ }
+
+ // Match the Source MAC address
+ String matchSrcMac = flowEntryObj.getMatchSrcMac();
+ if (matchSrcMac == null)
+ matchSrcMac = flowObj.getMatchSrcMac();
+ if (matchSrcMac != null) {
+ match.setDataLayerSource(matchSrcMac);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
+ }
+
+ // Match the Destination MAC address
+ String matchDstMac = flowEntryObj.getMatchDstMac();
+ if (matchDstMac == null)
+ matchDstMac = flowObj.getMatchDstMac();
+ if (matchDstMac != null) {
+ match.setDataLayerDestination(matchDstMac);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
+ }
+
+ //
+ // Fetch the actions
+ //
+ // TODO: For now we support only the "OUTPUT" actions.
+ //
+ List<OFAction> actions = new ArrayList<OFAction>();
+ Short actionOutputPort = flowEntryObj.getActionOutput();
+ 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);
+ }
+
+ fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
+ .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
+ .setPriority(PRIORITY_DEFAULT)
+ .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+ .setCookie(cookie)
+ .setCommand(flowModCommand)
+ .setMatch(match)
+ .setActions(actions)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+ 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
+ // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
+ // See method ForwardingBase::pushRoute()
+ //
+
+ //
+ // Write the message to the switch
+ //
+ try {
+ messageDamper.write(mySwitch, fm, null);
+ mySwitch.flush();
+ //
+ // TODO: We should use the OpenFlow Barrier mechanism
+ // to check for errors, and update the SwitchState
+ // for a flow entry after the Barrier message is
+ // is received.
+ //
+ flowEntryObj.setSwitchState("FE_SWITCH_UPDATED");
+ } catch (IOException e) {
+ log.error("Failure writing flow mod from network map", e);
+ return false;
+ }
+
+ return true;
}
/**
@@ -1752,7 +1513,6 @@
* @param flowEntry the flow entry to install.
* @return true on success, otherwise false.
*/
- @Override
public boolean installFlowEntry(IOFSwitch mySwitch, FlowPath flowPath,
FlowEntry flowEntry) {
//
@@ -1892,6 +1652,15 @@
try {
messageDamper.write(mySwitch, fm, null);
mySwitch.flush();
+ //
+ // TODO: We should use the OpenFlow Barrier mechanism
+ // to check for errors, and update the SwitchState
+ // for a flow entry after the Barrier message is
+ // is received.
+ //
+ // TODO: The FlowEntry Object in Titan should be set
+ // to FE_SWITCH_UPDATED.
+ //
} catch (IOException e) {
log.error("Failure writing flow mod from network map", e);
return false;
@@ -1907,7 +1676,6 @@
* @param flowEntry the flow entry to remove.
* @return true on success, otherwise false.
*/
- @Override
public boolean removeFlowEntry(IOFSwitch mySwitch, FlowPath flowPath,
FlowEntry flowEntry) {
//
@@ -1928,7 +1696,6 @@
* @param flowEntry the flow entry to install.
* @return true on success, otherwise false.
*/
- @Override
public boolean installRemoteFlowEntry(FlowPath flowPath,
FlowEntry flowEntry) {
// TODO: We need it now: Jono
@@ -1944,7 +1711,6 @@
* @param flowEntry the flow entry to remove.
* @return true on success, otherwise false.
*/
- @Override
public boolean removeRemoteFlowEntry(FlowPath flowPath,
FlowEntry flowEntry) {
//
diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
index 619d36b..855f064 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
@@ -2,6 +2,7 @@
import java.util.ArrayList;
+import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.util.CallerId;
import net.floodlightcontroller.util.DataPathEndpoints;
@@ -77,7 +78,7 @@
* @param maxFlows: number of flows to return
* @return the Flow Paths if found, otherwise null.
*/
- ArrayList<FlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows);
+ ArrayList<IFlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows);
/**
* Get all installed flows by all installers.
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/DatapathSummarySerializer.java b/src/main/java/net/floodlightcontroller/flowcache/web/DatapathSummarySerializer.java
new file mode 100644
index 0000000..b780e5c
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/DatapathSummarySerializer.java
@@ -0,0 +1,82 @@
+package net.floodlightcontroller.flowcache.web;
+
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DatapathSummarySerializer extends JsonSerializer<String>{
+ static Logger log = LoggerFactory.getLogger(DatapathSummarySerializer.class);
+
+ @Override
+ public void serialize(String datapathSummary, JsonGenerator jGen,
+ SerializerProvider serializer) throws IOException,
+ JsonProcessingException {
+
+ String[] flowEntries = datapathSummary.split(";");
+ if (flowEntries.length < 2){
+ log.debug("datapathSummary string to short to parse: {}",
+ datapathSummary);
+ jGen.writeStartObject();
+ jGen.writeEndObject();
+ return;
+ }
+
+ String[] srcFlowEntry = flowEntries[0].split("/");
+ String[] dstFlowEntry = flowEntries[flowEntries.length - 1].split("/");
+ if (srcFlowEntry.length != 3 || dstFlowEntry.length != 3){
+ log.debug("Malformed datapathSummary string: {}", datapathSummary);
+ jGen.writeStartObject();
+ jGen.writeEndObject();
+ return;
+ }
+
+ jGen.writeStartObject();
+
+ /*
+ jGen.writeObjectFieldStart("srcPort");
+ jGen.writeObjectFieldStart("dpid");
+ jGen.writeStringField("value", srcFlowEntry[1]);
+ jGen.writeEndObject();
+ jGen.writeObjectFieldStart("port");
+ jGen.writeStringField("value", srcFlowEntry[0]);
+ jGen.writeEndObject();
+ jGen.writeEndObject();
+
+ jGen.writeObjectFieldStart("dstPort");
+ jGen.writeObjectFieldStart("dpid");
+ jGen.writeStringField("value", srcFlowEntry[1]);
+ jGen.writeEndObject();
+ jGen.writeObjectFieldStart("port");
+ jGen.writeStringField("value", srcFlowEntry[2]);
+ jGen.writeEndObject();
+ jGen.writeEndObject();
+ */
+ jGen.writeArrayFieldStart("flowEntries");
+
+ for (String flowEntryString : flowEntries){
+ String[] flowEntry = flowEntryString.split("/");
+ if (flowEntry.length != 3){
+ log.debug("Malformed datapathSummary string: {}", datapathSummary);
+ jGen.writeStartObject();
+ jGen.writeEndObject();
+ continue;
+ }
+
+ jGen.writeStartObject();
+ jGen.writeObjectFieldStart("dpid");
+ jGen.writeStringField("value", flowEntry[1]);
+ jGen.writeEndObject();
+ jGen.writeEndObject();
+ }
+
+ jGen.writeEndArray();
+
+ jGen.writeEndObject();
+ }
+
+}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java
index 7a928c9..5f63222 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java
@@ -2,9 +2,10 @@
import java.util.ArrayList;
+import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowPath;
import net.floodlightcontroller.util.FlowId;
+import net.floodlightcontroller.util.FlowPath;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
@@ -15,8 +16,8 @@
protected static Logger log = LoggerFactory.getLogger(GetSummaryFlowsResource.class);
@Get("json")
- public ArrayList<FlowPath> retrieve() {
- ArrayList<FlowPath> result = null;
+ public ArrayList<IFlowPath> retrieve() {
+ ArrayList<IFlowPath> result = null;
FlowId flowId;
int maxFlows = 0;
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
index ec8051f..634f7eb 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -82,10 +82,7 @@
import net.floodlightcontroller.topology.NodePortTuple;
import net.floodlightcontroller.util.EventHistory;
import net.floodlightcontroller.util.EventHistory.EvAction;
-
import net.onrc.onos.registry.controller.IControllerRegistryService;
-import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
-import net.onrc.onos.registry.controller.RegistryException;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFPacketIn;
@@ -130,6 +127,12 @@
IStorageSourceListener, ILinkDiscoveryService,
IFloodlightModule, IInfoProvider, IHAListener {
protected static Logger log = LoggerFactory.getLogger(LinkDiscoveryManager.class);
+
+ protected enum NetworkMapOperation {
+ NONE,
+ INSERT,
+ UPDATE
+ }
// Names of table/fields for links in the storage API
private static final String LINK_TABLE_NAME = "controller_link";
@@ -1025,6 +1028,7 @@
NodePortTuple srcNpt, dstNpt;
boolean linkChanged = false;
+ NetworkMapOperation operation = NetworkMapOperation.NONE;
lock.writeLock().lock();
try {
@@ -1073,7 +1077,8 @@
writeLinkToStorage(lt, newInfo);
// Write link to network map
- linkStore.update(lt, newInfo, DM_OPERATION.INSERT);
+ operation = NetworkMapOperation.INSERT;
+ //linkStore.update(lt, newInfo, DM_OPERATION.INSERT);
updateOperation = UpdateOperation.LINK_UPDATED;
linkChanged = true;
@@ -1132,7 +1137,8 @@
writeLinkToStorage(lt, newInfo);
// Write link to network map
- linkStore.update(lt, newInfo, DM_OPERATION.UPDATE);
+ operation = NetworkMapOperation.UPDATE;
+ //linkStore.update(lt, newInfo, DM_OPERATION.UPDATE);
if (linkChanged) {
updateOperation = getUpdateOperation(newInfo.getSrcPortState(),
@@ -1162,6 +1168,18 @@
} finally {
lock.writeLock().unlock();
}
+
+ switch (operation){
+ case INSERT:
+ linkStore.update(lt, newInfo, DM_OPERATION.INSERT);
+ break;
+ case UPDATE:
+ linkStore.update(lt, newInfo, DM_OPERATION.UPDATE);
+ break;
+ case NONE:
+ default:
+ break;
+ }
return linkChanged;
}
diff --git a/start-rest.sh b/start-rest.sh
index 564eccf..01e7638 100755
--- a/start-rest.sh
+++ b/start-rest.sh
@@ -11,6 +11,16 @@
REST_LOG="${LOGDIR}/rest.`hostname`.log"
#######################
+dokill() {
+ for cpid in $(ps -o pid= --ppid $1)
+ do
+ dokill $cpid
+ done
+ echo "killing: $(ps -p $1 -o cmd=)"
+ kill -9 $1 > /dev/null 2>&1
+}
+
+
function lotate {
logfile=$1
nr_max=${2:-10}
@@ -28,15 +38,16 @@
pids=`ps -edalf |grep ${script_name} | grep python | grep -v grep | awk '{print $4}'`
for p in ${pids}; do
if [ x$p != "x" ]; then
- sudo kill -KILL $p
- echo "Killed existing prosess (pid: $p)"
+ dokill $p
+# sudo kill -KILL $p
+# echo "Killed existing prosess (pid: $p)"
fi
done
}
function status {
nr_process=`ps -edalf |grep ${script_name} | grep python | grep -v grep | wc -l`
- if [ x${nr_process} != "x" ] ; then
+ if [ ${nr_process} != 0 ] ; then
echo "rest server is running"
else
echo "rest server is not running"
diff --git a/web/ons-demo/js/app.js b/web/ons-demo/js/app.js
index 6176c3a..bc3cc6d 100644
--- a/web/ons-demo/js/app.js
+++ b/web/ons-demo/js/app.js
@@ -98,8 +98,8 @@
var pts = [];
if (!d.dataPath.flowEntries) {
// create a temporary vector to indicate the pending flow
- var s1 = d3.select(document.getElementById(d.dataPath.srcPort.dpid.value));
- var s2 = d3.select(document.getElementById(d.dataPath.dstPort.dpid.value));
+ var s1 = d3.select(document.getElementById(d.srcDpid));
+ var s2 = d3.select(document.getElementById(d.dstDpid));
var pt1 = document.querySelector('svg').createSVGPoint();
pt1.x = s1.attr('x');
@@ -199,7 +199,7 @@
});
row.on('dblclick', function () {
if (d) {
- var prompt = 'Delete flow ' + d.flowId.value + '?';
+ var prompt = 'Delete flow ' + d.flowId + '?';
if (confirm(prompt)) {
deleteFlow(d);
d.deletePending = true;
@@ -217,7 +217,7 @@
.text(function (d) {
if (d) {
if (d.flowId) {
- return d.flowId.value;
+ return d.flowId;
} else {
return '0x--';
}
@@ -230,14 +230,14 @@
row.select('.srcDPID')
.text(function (d) {
if (d) {
- return d.dataPath.srcPort.dpid.value;
+ return d.srcDpid;
}
});
row.select('.dstDPID')
.text(function (d) {
if (d) {
- return d.dataPath.dstPort.dpid.value;
+ return d.dstDpid;
}
});
}
@@ -280,7 +280,7 @@
}
if (flow.flowId) {
- console.log('starting iperf for: ' + flow.flowId.value);
+ console.log('starting iperf for: ' + flow.flowId);
startIPerf(flow, duration, updateRate/interval);
flow.iperfDisplayInterval = setInterval(function () {
if (flow.iperfData) {
@@ -386,7 +386,7 @@
}
function clearIPerf(flow) {
- console.log('clearing iperf interval for: ' + flow.flowId.value);
+ console.log('clearing iperf interval for: ' + flow.flowId);
clearInterval(flow.iperfFetchInterval);
delete flow.iperfFetchInterval;
clearInterval(flow.iperfDisplayInterval);
@@ -433,20 +433,20 @@
row.append('div')
.classed('flowId', true)
.text(function (d) {
- return d.flowId.value;
+ return d.flowId;
});
row.append('div')
.classed('srcDPID', true)
.text(function (d) {
- return d.dataPath.srcPort.dpid.value;
+ return d.srcDpid;
});
row.append('div')
.classed('dstDPID', true)
.text(function (d) {
- return d.dataPath.dstPort.dpid.value;
+ return d.dstDpid;
});
}
@@ -589,7 +589,7 @@
}
function makeFlowKey(flow) {
- return flow.dataPath.srcPort.dpid.value + '=>' + flow.dataPath.dstPort.dpid.value;
+ return flow.srcDpid + '=>' + flow.dstDpid;
}
function makeSelectedFlowKey(flow) {
@@ -935,6 +935,8 @@
}
}
},
+ srcDpid: srcData.dpid,
+ dstDpid: dstData.dpid,
createPending: true
};
diff --git a/web/ons-demo/js/controller.js b/web/ons-demo/js/controller.js
index a6c7843..fbc381e 100644
--- a/web/ons-demo/js/controller.js
+++ b/web/ons-demo/js/controller.js
@@ -38,16 +38,16 @@
callURL(url);
},
delFlowCmd: function (flow) {
- var url = '/proxy/gui/delflow/' + flow.flowId.value;
+ var url = '/proxy/gui/delflow/' + flow.flowId;
callURL(url);
},
startIPerfCmd: function (flow, duration, numSamples) {
- var flowId = parseInt(flow.flowId.value, 16);
+ var flowId = parseInt(flow.flowId, 16);
var url = '/proxy/gui/iperf/start/' + [flowId, duration, numSamples].join('/');
callURL(url)
},
getIPerfDataCmd: function (flow, cb) {
- var flowId = parseInt(flow.flowId.value, 16);
+ var flowId = parseInt(flow.flowId, 16);
var url = '/proxy/gui/iperf/rate/' + flowId;
callURL(url, cb);
}
@@ -91,4 +91,4 @@
function getIPerfData(flow, cb) {
controllerFunctions.getIPerfDataCmd(flow, cb);
-}
\ No newline at end of file
+}
diff --git a/web/topology_rest.py b/web/topology_rest.py
index 4ed3ae5..d55bf7f 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -7,18 +7,17 @@
import argparse
import io
import time
+import random
import re
from flask import Flask, json, Response, render_template, make_response, request
-## Global Var ##
+## Global Var for ON.Lab local REST ##
RestIP="localhost"
RestPort=8080
-#DBName="onos-network-map"
## Uncomment the desired block based on your testbed environment
-
# Settings for running on production
controllers=["onosgui1", "onosgui2", "onosgui3", "onosgui4", "onosgui5", "onosgui6", "onosgui7", "onosgui8"]
core_switches=["00:00:00:00:ba:5e:ba:11", "00:00:00:00:00:00:ba:12", "00:00:20:4e:7f:51:8a:35", "00:00:00:00:ba:5e:ba:13", "00:00:00:08:a2:08:f9:01", "00:00:00:16:97:08:9a:46"]
@@ -27,17 +26,18 @@
# Settings for running on dev testbed. Replace dev
#controllers=["onosdevb1", "onosdevb2", "onosdevb3", "onosdevb4"]
+#controllers=["onosdevt1", "onosdevt2", "onosdevt3", "onosdevt4", "onosdevt5", "onosdevt6", "onosdevt7", "onosdevt8"]
#core_switches=["00:00:00:00:00:00:01:01", "00:00:00:00:00:00:01:02", "00:00:00:00:00:00:01:03", "00:00:00:00:00:00:01:04", "00:00:00:00:00:00:01:05", "00:00:00:00:00:00:01:06"]
-#ONOS_GUI3_HOST="http://devb-gui.onlab.us:8080"
-#ONOS_GUI3_CONTROL_HOST="http://devb-gui.onlab.us:8080"
-ONOS_LOCAL_HOST="http://localhost:8080" ;# for Amazon EC2
+#ONOS_GUI3_HOST="http://devt-gui.onlab.us:8080"
+#ONOS_GUI3_CONTROL_HOST="http://devt-gui.onlab.us:8080"
-nr_flow=0
+LB=True #; True or False
+ONOS_DEFAULT_HOST="localhost" ;# Has to set if LB=False
DEBUG=1
-pp = pprint.PrettyPrinter(indent=4)
+pp = pprint.PrettyPrinter(indent=4)
app = Flask(__name__)
## Worker Functions ##
@@ -48,7 +48,6 @@
if DEBUG:
print '%s' % (txt)
-## Rest APIs ##
### File Fetch ###
@app.route('/ui/img/<filename>', methods=['GET'])
@app.route('/img/<filename>', methods=['GET'])
@@ -88,7 +87,7 @@
return response
-
+## Proxy ##
@app.route("/proxy/gui/link/<cmd>/<src_dpid>/<src_port>/<dst_dpid>/<dst_port>")
def proxy_link_change(cmd, src_dpid, src_port, dst_dpid, dst_port):
try:
@@ -181,98 +180,103 @@
return resp
+###### ONOS RESET API ##############################
+## Worker Func ###
+def get_json(url):
+ code = 200
+ try:
+ command = "curl -s %s" % (url)
+ result = os.popen(command).read()
+ parsedResult = json.loads(result)
+ if type(parsedResult) == 'dict' and parsedResult.has_key('code'):
+ print "REST %s returned code %s" % (command, parsedResult['code'])
+ code=500
+ except:
+ print "REST IF %s has issue" % command
+ result = ""
+ code = 500
+
+ return (code, result)
+
+def pick_host():
+ if LB == True:
+ nr_host=len(controllers)
+ r=random.randint(0, nr_host - 1)
+ host=controllers[r]
+ else:
+ host=ONOS_DEFAULT_HOST
+
+ return "http://" + host + ":8080"
+
+## Switch ##
@app.route("/wm/core/topology/switches/all/json")
def switches():
if request.args.get('proxy') == None:
- host = ONOS_LOCAL_HOST
+ host = pick_host()
else:
host = ONOS_GUI3_HOST
- try:
- command = "curl -s %s/wm/core/topology/switches/all/json" % (host)
-# print command
- result = os.popen(command).read()
- except:
- print "REST IF has issue"
- exit
+ url ="%s/wm/core/topology/switches/all/json" % (host)
+ (code, result) = get_json(url)
- resp = Response(result, status=200, mimetype='application/json')
+ resp = Response(result, status=code, mimetype='application/json')
return resp
+## Link ##
@app.route("/wm/core/topology/links/json")
def links():
if request.args.get('proxy') == None:
- host = ONOS_LOCAL_HOST
+ host = pick_host()
else:
host = ONOS_GUI3_HOST
- try:
- command = "curl -s %s/wm/core/topology/links/json" % (host)
- print command
- result = os.popen(command).read()
- except:
- print "REST IF has issue"
- exit
+ url ="%s/wm/core/topology/links/json" % (host)
+ (code, result) = get_json(url)
- resp = Response(result, status=200, mimetype='application/json')
+ resp = Response(result, status=code, mimetype='application/json')
return resp
-@app.route("/wm/flow/getsummary/0/0/json")
-def flows():
+## FlowSummary ##
+@app.route("/wm/flow/getsummary/<start>/<range>/json")
+def flows(start, range):
if request.args.get('proxy') == None:
- host = ONOS_LOCAL_HOST
+ host = pick_host()
else:
host = ONOS_GUI3_HOST
- try:
- command = "curl -s %s/wm/flow/getsummary/0/0/json" % (host)
-# print command
- result = os.popen(command).read()
- except:
- print "REST IF has issue"
- exit
+ url ="%s/wm/flow/getsummary/%s/%s/json" % (host, start, range)
+ (code, result) = get_json(url)
-
- resp = Response(result, status=200, mimetype='application/json')
+ resp = Response(result, status=code, mimetype='application/json')
return resp
@app.route("/wm/registry/controllers/json")
def registry_controllers():
if request.args.get('proxy') == None:
- host = ONOS_LOCAL_HOST
+ host = pick_host()
else:
host = ONOS_GUI3_HOST
- try:
- command = "curl -s %s/wm/registry/controllers/json" % (host)
-# print command
- result = os.popen(command).read()
- except:
- print "REST IF has issue"
- exit
+ url= "%s/wm/registry/controllers/json" % (host)
+ (code, result) = get_json(url)
- resp = Response(result, status=200, mimetype='application/json')
+ resp = Response(result, status=code, mimetype='application/json')
return resp
+
@app.route("/wm/registry/switches/json")
def registry_switches():
if request.args.get('proxy') == None:
- host = ONOS_LOCAL_HOST
+ host = pick_host()
else:
host = ONOS_GUI3_HOST
- try:
- command = "curl -s %s/wm/registry/switches/json" % (host)
-# print command
- result = os.popen(command).read()
- except:
- print "REST IF has issue"
- exit
+ url="%s/wm/registry/switches/json" % (host)
+ (code, result) = get_json(url)
- resp = Response(result, status=200, mimetype='application/json')
+ resp = Response(result, status=code, mimetype='application/json')
return resp
-
def node_id(switch_array, dpid):
id = -1
for i, val in enumerate(switch_array):
@@ -312,39 +316,6 @@
sw['group']=0
switches.append(sw)
-## Comment in if we need devies
-# sw_index = len(switches) - 1
-# for p in v['ports']:
-# for d in p['devices']:
-# device = {}
-# device['attached_switch']=dpid
-# device['name']=d['mac']
-# if d['state'] == "ACTIVE":
-# device['group']=1000
-# else:
-# device['group']=1001
-#
-# switches.append(device)
-# device_index = len (switches) -1
-# link = {}
-# link['source'] = device_index
-# link['target'] = sw_index
-# link['type'] = -1
-# links.append(link)
-# link = {}
-# link['source'] = sw_index
-# link['target'] = device_index
-# link['type'] = -1
-# links.append(link)
-
-# try:
-# command = "curl -s \'http://%s:%s/wm/registry/controllers/json\'" % (RestIP, RestPort)
-# result = os.popen(command).read()
-# controllers = json.loads(result)
-# except:
-# log_error("xx REST IF has issue: %s" % command)
-# log_error("%s" % result)
-
try:
command = "curl -s \'http://%s:%s/wm/registry/switches/json\'" % (RestIP, RestPort)
result = os.popen(command).read()
@@ -416,7 +387,6 @@
topo['nodes'] = switches
topo['links'] = links
- pp.pprint(topo)
js = json.dumps(topo)
resp = Response(js, status=200, mimetype='application/json')
return resp
@@ -503,7 +473,6 @@
topo['nodes'] = switches
topo['links'] = links
-# pp.pprint(topo)
js = json.dumps(topo)
resp = Response(js, status=200, mimetype='application/json')
return resp
@@ -575,7 +544,6 @@
device['attachmentPoint']=attachpoints
devices.append(device)
- print devices
js = json.dumps(devices)
resp = Response(js, status=200, mimetype='application/json')
return resp
@@ -649,82 +617,6 @@
resp = Response(js, status=200, mimetype='application/json')
return resp
-topo_less = {
- "nodes" : [
- {"name" : "00:a0", "group" : 1},
- {"name" : "00:a1", "group" : 1},
- {"name" : "00:a2", "group" : 1},
- ],
- "links" : [
- {"source" :0, "target": 1},
- {"source" :1, "target": 0},
- {"source" :0, "target": 2},
- {"source" :2, "target": 0},
- {"source" :1, "target": 2},
- {"source" :2, "target": 1},
- ]
-}
-
-topo_more = {
- "nodes" : [
- {"name" : "00:a3", "group" : 2},
- {"name" : "00:a0", "group" : 1},
- {"name" : "00:a1", "group" : 1},
- {"name" : "00:a2", "group" : 1},
- ],
- "links" : [
- {"source" :1, "target": 2},
- {"source" :2, "target": 1},
- {"source" :1, "target": 3},
- {"source" :3, "target": 1},
- {"source" :2, "target": 3},
- {"source" :3, "target": 2},
- {"source" :0, "target": 2},
- ]
-}
-
-@app.route("/topology_more")
-def topology_more():
- topo = topo_more
- js = json.dumps(topo)
- resp = Response(js, status=200, mimetype='application/json')
- return resp
-
-@app.route("/topology_less")
-def topology_less():
- topo = topo_less
- js = json.dumps(topo)
- resp = Response(js, status=200, mimetype='application/json')
- return resp
-
-cont_status1 = [
- {"name":"onos9vpc", "onos": 1, "cassandra": 1},
- {"name":"onos10vpc", "onos": 0, "cassandra": 1},
- {"name":"onos11vpc", "onos": 1, "cassandra": 0},
- {"name":"onos12vpc", "onos": 1, "cassandra": 0}]
-
-cont_status2 = [
- {"name":"onos9vpc", "onos": 0, "cassandra": 1},
- {"name":"onos10vpc", "onos": 0, "cassandra": 1},
- {"name":"onos11vpc", "onos": 0, "cassandra": 1},
- {"name":"onos12vpc", "onos": 0, "cassandra": 1}]
-
-@app.route("/controller_status1")
-def controller_status1():
- status = cont_status1
- js = json.dumps(status)
- resp = Response(js, status=200, mimetype='application/json')
- pp.pprint(resp)
- return resp
-
-@app.route("/controller_status2")
-def controller_status2():
- status = cont_status2
- js = json.dumps(status)
- resp = Response(js, status=200, mimetype='application/json')
- pp.pprint(resp)
- return resp
-
@app.route("/controller_status")
def controller_status():
onos_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh status | awk '{print $1}'"
@@ -741,20 +633,18 @@
js = json.dumps(cont_status)
resp = Response(js, status=200, mimetype='application/json')
- pp.pprint(js)
return resp
+### Command ###
@app.route("/gui/controller/<cmd>/<controller_name>")
def controller_status_change(cmd, controller_name):
start_onos="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh start" % (controller_name)
stop_onos="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh stop" % (controller_name)
if cmd == "up":
- print start_onos
result=os.popen(start_onos).read()
ret = "controller %s is up" % (controller_name)
elif cmd == "down":
- print stop_onos
result=os.popen(stop_onos).read()
ret = "controller %s is down" % (controller_name)
@@ -838,9 +728,11 @@
flow_nr += 1
command = "/home/ubuntu/ONOS/web/add_flow.py -m onos %d %s %s %s %s %s matchSrcMac %s matchDstMac %s" % (flow_nr, "dummy", src_dpid, src_port, dst_dpid, dst_port, srcMAC, dstMAC)
+ command1 = "/home/ubuntu/ONOS/web/add_flow.py -m onos %d %s %s %s %s %s matchSrcMac %s matchDstMac %s" % (flow_nr, "dummy", dst_dpid, dst_port, src_dpid, src_port, dstMAC, srcMAC)
print command
errcode = os.popen(command).read()
- return errcode
+ errcode1 = os.popen(command1).read()
+ return errcode+" "+errcode1
#* Delete Flow
#http://localhost:9000/gui/delflow/<flow_id>
@@ -886,7 +778,7 @@
print cmd_string
os.popen(cmd_string)
- return
+ return cmd_string
#* Get Iperf Throughput
#http://localhost:9000/gui/iperf/rate/<flow_id>
@@ -897,8 +789,8 @@
print command
result = os.popen(command).read()
if len(result) == 0:
- print "No Flow found"
- return;
+ resp = Response(result, status=400, mimetype='text/html')
+ return "no such iperf flow (flowid %s)" % flow_id;
except:
print "REST IF has issue"
exit
@@ -922,14 +814,18 @@
print command
result = os.popen(command).read()
except:
- print "REST IF has issue"
exit
- resp = Response(result, status=200, mimetype='application/json')
- return resp
+ if len(result) == 0:
+ resp = Response(result, status=400, mimetype='text/html')
+ return "no iperf file found (flowid %s)" % flow_id;
+ else:
+ resp = Response(result, status=200, mimetype='application/json')
+ return resp
if __name__ == "__main__":
+ random.seed()
if len(sys.argv) > 1 and sys.argv[1] == "-d":
# add_flow("00:00:00:00:00:00:02:02", 1, "00:00:00:00:00:00:03:02", 1, "00:00:00:00:02:02", "00:00:00:00:03:0c")
# link_change("up", "00:00:00:00:ba:5e:ba:11", 1, "00:00:00:00:00:00:00:00", 1)
@@ -945,8 +841,9 @@
# query_links()
# print "-- query all devices --"
# devices()
- iperf_start(1,10,15)
- iperf_rate(1)
+# iperf_start(1,10,15)
+# iperf_rate(1)
+ switches()
else:
app.debug = True
app.run(threaded=True, host="0.0.0.0", port=9000)