Reimplement the shortest path computation by using the new DataPath and FlowEntry containers.
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
index a3eb830..b16e4a9 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
@@ -8,6 +8,8 @@
import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.floodlightcontroller.routing.Link;
import net.floodlightcontroller.topology.NodePortTuple;
+import net.floodlightcontroller.util.DataPath;
+import net.floodlightcontroller.util.SwitchPort;
public interface INetMapTopologyService extends INetMapService {
@@ -31,8 +33,8 @@
}
public interface ITopoRouteService extends IFloodlightService {
- List<NodePortTuple> getShortestPath(NodePortTuple src, NodePortTuple dest);
- Boolean routeExists(NodePortTuple src, NodePortTuple dest);
+ DataPath getShortestPath(SwitchPort src, SwitchPort dest);
+ Boolean routeExists(SwitchPort src, SwitchPort dest);
}
public interface ITopoFlowService {
diff --git a/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java b/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
index 6d50602..f979cc7 100644
--- a/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
+++ b/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
@@ -13,7 +13,11 @@
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
-import net.floodlightcontroller.topology.NodePortTuple;
+import net.floodlightcontroller.util.DataPath;
+import net.floodlightcontroller.util.Dpid;
+import net.floodlightcontroller.util.FlowEntry;
+import net.floodlightcontroller.util.Port;
+import net.floodlightcontroller.util.SwitchPort;
import org.openflow.util.HexString;
@@ -87,14 +91,17 @@
SwitchStorageImpl swStore = store.get();
@Override
- public List<NodePortTuple> getShortestPath(NodePortTuple src,
- NodePortTuple dest) {
- List<NodePortTuple> result_list = new ArrayList<NodePortTuple>();
+ public DataPath getShortestPath(SwitchPort src, SwitchPort dest) {
+ DataPath result_data_path = new DataPath();
+
+ // Initialize the source and destination in the data path to return
+ result_data_path.setSrcPort(src);
+ result_data_path.setDstPort(dest);
TitanGraph titanGraph = swStore.graph;
- String dpid_src = HexString.toHexString(src.getNodeId());
- String dpid_dest = HexString.toHexString(dest.getNodeId());
+ String dpid_src = src.dpid().toString();
+ String dpid_dest = dest.dpid().toString();
//
// Implement the Shortest Path between two vertices by using
@@ -120,16 +127,18 @@
//
// Test whether we are computing a path from/to the same DPID.
- // If "yes", then just list the "src" and "dest" in the return
- // result.
+ // If "yes", then just add a single flow entry in the return result.
// NOTE: The return value will change in the future to return
// a single hop/entry instead of two. Currently, we need
// both entries to capture the source and destination ports.
//
if (dpid_src.equals(dpid_dest)) {
- result_list.add(new NodePortTuple(src));
- result_list.add(new NodePortTuple(dest));
- return result_list;
+ FlowEntry flowEntry = new FlowEntry();
+ flowEntry.setDpid(src.dpid());
+ flowEntry.setInPort(src.port());
+ flowEntry.setOutPort(dest.port());
+ result_data_path.flowEntries().add(flowEntry);
+ return result_data_path;
}
//
@@ -151,11 +160,13 @@
}
//
- // Loop through the result and return the list
+ // Loop through the result and collect the list
// of <dpid, port> tuples.
//
long nodeId = 0;
short portId = 0;
+ Port inPort = new Port(src.port().value());
+ Port outPort = new Port();
for (ArrayList<Vertex> lv : results) {
int idx = 0;
for (Vertex v: lv) {
@@ -181,27 +192,48 @@
System.out.println("dpid: " + dpid);
}
- if (idx == 0) {
- idx++;
+ idx++;
+ if (idx == 1) {
continue;
}
- int mod = (idx - 1) % 3;
- if ((mod == 0) || (mod == 2)) {
- result_list.add(new NodePortTuple(nodeId, portId));
+ int mod = idx % 3;
+ if (mod == 0) {
+ // Setup the incoming port
+ inPort = new Port(portId);
+ continue;
}
- idx++;
+ if (mod == 2) {
+ // Setup the outgoing port, and add the Flow Entry
+ outPort = new Port(portId);
+
+ FlowEntry flowEntry = new FlowEntry();
+ flowEntry.setDpid(new Dpid(nodeId));
+ flowEntry.setInPort(inPort);
+ flowEntry.setOutPort(outPort);
+ result_data_path.flowEntries().add(flowEntry);
+ continue;
+ }
+ }
+
+ if (idx > 0) {
+ // Add the last Flow Entry
+ FlowEntry flowEntry = new FlowEntry();
+ flowEntry.setDpid(new Dpid(nodeId));
+ flowEntry.setInPort(inPort);
+ flowEntry.setOutPort(dest.port());
+ result_data_path.flowEntries().add(flowEntry);
}
}
- if (result_list.size() > 0)
- return result_list;
+ if (result_data_path.flowEntries().size() > 0)
+ return result_data_path;
return null;
}
@Override
- public Boolean routeExists(NodePortTuple src, NodePortTuple dest) {
- List<NodePortTuple> route = getShortestPath(src, dest);
- if (route != null)
+ public Boolean routeExists(SwitchPort src, SwitchPort dest) {
+ DataPath dataPath = getShortestPath(src, dest);
+ if (dataPath != null)
return true;
return false;
}
diff --git a/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java b/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
index 3fa7510..20f39d4 100644
--- a/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
+++ b/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
@@ -6,6 +6,10 @@
import net.floodlightcontroller.routing.IRoutingService;
import net.floodlightcontroller.routing.Route;
import net.floodlightcontroller.topology.NodePortTuple;
+import net.floodlightcontroller.util.DataPath;
+import net.floodlightcontroller.util.Dpid;
+import net.floodlightcontroller.util.Port;
+import net.floodlightcontroller.util.SwitchPort;
import org.openflow.util.HexString;
import org.restlet.resource.Get;
@@ -18,7 +22,7 @@
protected static Logger log = LoggerFactory.getLogger(RouteResource.class);
@Get("json")
- public List<NodePortTuple> retrieve() {
+ public DataPath retrieve() {
ITopoRouteService topoRouteService =
(ITopoRouteService)getContext().getAttributes().
get(ITopoRouteService.class.getCanonicalName());
@@ -27,22 +31,22 @@
return null;
}
- String srcDpid = (String) getRequestAttributes().get("src-dpid");
- String srcPort = (String) getRequestAttributes().get("src-port");
- String dstDpid = (String) getRequestAttributes().get("dst-dpid");
- String dstPort = (String) getRequestAttributes().get("dst-port");
+ String srcDpidStr = (String) getRequestAttributes().get("src-dpid");
+ String srcPortStr = (String) getRequestAttributes().get("src-port");
+ String dstDpidStr = (String) getRequestAttributes().get("dst-dpid");
+ String dstPortStr = (String) getRequestAttributes().get("dst-port");
- log.debug( srcDpid + "--" + srcPort + "--" + dstDpid + "--" + dstPort);
+ log.debug( srcDpidStr + "--" + srcPortStr + "--" + dstDpidStr + "--" + dstPortStr);
- long longSrcDpid = HexString.toLong(srcDpid);
- short shortSrcPort = Short.parseShort(srcPort);
- long longDstDpid = HexString.toLong(dstDpid);
- short shortDstPort = Short.parseShort(dstPort);
+ Dpid srcDpid = new Dpid(srcDpidStr);
+ Port srcPort = new Port(Short.parseShort(srcPortStr));
+ Dpid dstDpid = new Dpid(dstDpidStr);
+ Port dstPort = new Port(Short.parseShort(dstPortStr));
- List<NodePortTuple> result =
- topoRouteService.getShortestPath(new NodePortTuple(longSrcDpid, shortSrcPort),
- new NodePortTuple(longDstDpid, shortDstPort));
- if ((result != null) && (result.size() > 0)) {
+ DataPath result =
+ topoRouteService.getShortestPath(new SwitchPort(srcDpid, srcPort),
+ new SwitchPort(dstDpid, dstPort));
+ if (result != null) {
return result;
} else {
log.debug("ERROR! no route found");
diff --git a/src/main/java/net/floodlightcontroller/util/DataPath.java b/src/main/java/net/floodlightcontroller/util/DataPath.java
index 9ec9380..71e0a2f 100644
--- a/src/main/java/net/floodlightcontroller/util/DataPath.java
+++ b/src/main/java/net/floodlightcontroller/util/DataPath.java
@@ -19,6 +19,7 @@
* Default constructor.
*/
public DataPath() {
+ flowEntries = new ArrayList<FlowEntry>();
}
/**
diff --git a/src/main/java/net/floodlightcontroller/util/Port.java b/src/main/java/net/floodlightcontroller/util/Port.java
index 52fdf50..19bbf8f 100644
--- a/src/main/java/net/floodlightcontroller/util/Port.java
+++ b/src/main/java/net/floodlightcontroller/util/Port.java
@@ -16,6 +16,15 @@
}
/**
+ * Constructor from another entry.
+ *
+ * @param other the other entry to use.
+ */
+ public Port(Port other) {
+ this.value = other.value();
+ }
+
+ /**
* Constructor from a long value.
*
* @param value the value to use.
diff --git a/web/shortest_path.py b/web/shortest_path.py
index 5bea182..381d052 100755
--- a/web/shortest_path.py
+++ b/web/shortest_path.py
@@ -34,6 +34,10 @@
print '%s' % (txt)
# @app.route("/wm/topology/route/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
+#
+# Sample output:
+# {'dstPort': {'port': {'value': 0}, 'dpid': {'value': '00:00:00:00:00:00:00:02'}}, 'srcPort': {'port': {'value': 0}, 'dpid': {'value': '00:00:00:00:00:00:00:01'}}, 'flowEntries': [{'outPort': {'value': 1}, 'flowEntryErrorState': None, 'flowEntryMatch': None, 'flowEntryActions': None, 'inPort': {'value': 0}, 'flowEntryId': None, 'flowEntryUserState': 'FE_USER_UNKNOWN', 'dpid': {'value': '00:00:00:00:00:00:00:01'}, 'flowEntrySwitchState': 'FE_SWITCH_UNKNOWN'}, {'outPort': {'value': 0}, 'flowEntryErrorState': None, 'flowEntryMatch': None, 'flowEntryActions': None, 'inPort': {'value': 9}, 'flowEntryId': None, 'flowEntryUserState': 'FE_USER_UNKNOWN', 'dpid': {'value': '00:00:00:00:00:00:00:02'}, 'flowEntrySwitchState': 'FE_SWITCH_UNKNOWN'}]}
+#
def shortest_path(v1, p1, v2, p2):
try:
command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (ControllerIP, ControllerPort, v1, p1, v2, p2)
@@ -46,10 +50,18 @@
debug("shortest_path %s" % command)
debug("parsed %s" % parsedResult)
- for v in parsedResult:
- dpid = v['switch'];
- port = v['port'];
- print "PathEntry: (%s, %s)" % (dpid, port)
+ srcSwitch = parsedResult['srcPort']['dpid']['value'];
+ srcPort = parsedResult['srcPort']['port']['value'];
+ dstSwitch = parsedResult['dstPort']['dpid']['value'];
+ dstPort = parsedResult['dstPort']['port']['value'];
+
+ print "DataPath: (src = %s/%s dst = %s/%s)" % (srcSwitch, srcPort, dstSwitch, dstPort);
+
+ for f in parsedResult['flowEntries']:
+ inPort = f['inPort']['value'];
+ outPort = f['outPort']['value'];
+ dpid = f['dpid']['value']
+ print "FlowEntry: (%s, %s, %s)" % (inPort, dpid, outPort)
if __name__ == "__main__":