API to return the ECMP learned switches and corresponding paths
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/ECMPShortestPathGraph.java b/src/main/java/net/onrc/onos/apps/segmentrouting/ECMPShortestPathGraph.java
index 2dcc33f..5fa76ca 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/ECMPShortestPathGraph.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/ECMPShortestPathGraph.java
@@ -1,17 +1,16 @@
package net.onrc.onos.apps.segmentrouting;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
-import java.util.ArrayList;
-import org.projectfloodlight.openflow.util.HexString;
-
+import net.onrc.onos.core.intent.Path;
import net.onrc.onos.core.topology.Link;
import net.onrc.onos.core.topology.LinkData;
import net.onrc.onos.core.topology.Switch;
import net.onrc.onos.core.util.Dpid;
-import net.onrc.onos.core.intent.Path;
+import org.projectfloodlight.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,7 +31,7 @@
Switch rootSwitch;
private static final Logger log = LoggerFactory
.getLogger(SegmentRoutingManager.class);
-
+
/**
* Constructor.
*
@@ -66,7 +65,7 @@
{
prevSw = reachedSwitch;
}
-
+
Integer distance = switchSearched.get(reachedSwitch.getDpid());
if ((distance != null) && (distance.intValue() < (currDistance+1))) {
continue;
@@ -76,7 +75,7 @@
switchQueue.add(reachedSwitch);
distanceQueue.add(currDistance+1);
switchSearched.put(reachedSwitch.getDpid(),currDistance+1);
-
+
ArrayList<Switch> distanceSwArray = distanceSwitchMap.get(currDistance+1);
if (distanceSwArray == null)
{
@@ -88,7 +87,7 @@
distanceSwArray.add(reachedSwitch);
}
- ArrayList<LinkData> upstreamLinkArray =
+ ArrayList<LinkData> upstreamLinkArray =
upstreamLinks.get(reachedSwitch.getDpid());
if (upstreamLinkArray == null)
{
@@ -139,20 +138,95 @@
}
/**
- * Return the computed path from the root switch to the leaf switch.
+ * Return the computed ECMP paths from the root switch to a given switch
+ * in the network
*
- * @param leafSwitch the leaf switch
- * @return the Path from the root switch to the leaf switch
+ * @param targetSwitch the target switch
+ * @return the list of ECMP Paths from the root switch to the target switch
*/
- public ArrayList<Path> getPath(Switch leafSwitch) {
- ArrayList<Path> pathArray = paths.get(leafSwitch.getDpid());
- if (pathArray == null && switchSearched.containsKey(leafSwitch.getDpid())) {
+ public ArrayList<Path> getECMPPaths(Switch targetSwitch) {
+ ArrayList<Path> pathArray = paths.get(targetSwitch.getDpid());
+ if (pathArray == null && switchSearched.containsKey(
+ targetSwitch.getDpid())) {
pathArray = new ArrayList<>();
Path path = new Path();
- Dpid sw = leafSwitch.getDpid();
+ Dpid sw = targetSwitch.getDpid();
getDFSPaths(sw, path, pathArray);
- paths.put(leafSwitch.getDpid(), pathArray);
+ paths.put(targetSwitch.getDpid(), pathArray);
}
return pathArray;
}
+
+ /**
+ * Return the complete info of the computed ECMP paths for each switch
+ * learned in multiple iterations from the root switch
+ *
+ * @return the hash table of Switches learned in multiple Dijkstra
+ * iterations and corresponding ECMP paths to it from the root switch
+ */
+ public HashMap<Integer, HashMap<Switch,
+ ArrayList<Path>>> getCompleteLearnedSwitchesAndPaths() {
+
+ HashMap<Integer, HashMap<Switch, ArrayList<Path>>> pathGraph = new
+ HashMap<Integer, HashMap<Switch, ArrayList<Path>>>();
+
+ for (Integer itrIndx : distanceSwitchMap.keySet()) {
+ HashMap<Switch, ArrayList<Path>> swMap = new
+ HashMap<Switch, ArrayList<Path>>();
+ for (Switch sw : distanceSwitchMap.get(itrIndx)) {
+ swMap.put(sw, getECMPPaths(sw));
+ }
+ pathGraph.put(itrIndx, swMap);
+ }
+
+ return pathGraph;
+ }
+
+ /**
+ * Return the complete info of the computed ECMP paths for each switch
+ * learned in multiple iterations from the root switch in the form of
+ * {
+ * Iteration1,
+ * Switch<> via {Switch<>, Switch<>}
+ * Switch<> via {Switch<>, Switch<>}
+ * Iteration2,
+ * Switch<> via {Switch<>, Switch<>, Switch<>}
+ * {Switch<>, Switch<>, Switch<>}
+ * Switch<> via {Switch<>, Switch<>, Switch<>}
+ * }
+ *
+ * @return the hash table of Switches learned in multiple Dijkstra
+ * iterations and corresponding ECMP paths in terms of Switches to be
+ * traversed to it from the root switch
+ */
+ public HashMap<Integer, HashMap<Switch,
+ ArrayList<ArrayList<Dpid>>>> getAllLearnedSwitchesAndVia() {
+
+ HashMap<Integer, HashMap<Switch, ArrayList<ArrayList<Dpid>>>>
+ switchViaMap = new HashMap();
+
+ for (Integer itrIndx : distanceSwitchMap.keySet()) {
+ HashMap<Switch, ArrayList<ArrayList<Dpid>>> swMap = new HashMap();
+
+ for (Switch sw : distanceSwitchMap.get(itrIndx)) {
+ ArrayList<ArrayList<Dpid>> swViaArray = new ArrayList<>();
+ for (Path path:getECMPPaths(sw)){
+ ArrayList<Dpid> swVia = new ArrayList<>();
+ for (LinkData link:path.subList(0, path.size())){
+ if (link.getSrc().getDpid().equals(rootSwitch.getDpid())){
+ /* No need to add the root switch again in
+ * the Via list
+ */
+ continue;
+ }
+ swVia.add(link.getSrc().getDpid());
+ }
+ swViaArray.add(swVia);
+ }
+ swMap.put(sw, swViaArray);
+ }
+ switchViaMap.put(itrIndx, swMap);
+ }
+ return switchViaMap;
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
index b0ae47b..457a626 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
@@ -5,6 +5,7 @@
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -25,6 +26,7 @@
import net.onrc.onos.core.topology.MutableTopology;
import net.onrc.onos.core.topology.Switch;
import net.onrc.onos.core.topology.TopologyEvents;
+import net.onrc.onos.core.util.Dpid;
import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.util.HexString;
@@ -165,16 +167,57 @@
ECMPShortestPathGraph ecmpSPG = new ECMPShortestPathGraph(sw);
log.debug("ECMPShortestPathGraph is computed for switch {}",
HexString.toHexString(sw.getDpid().value()));
+ /*
for (Switch dstSw: mutableTopology.getSwitches()){
if (sw.getDpid().equals(dstSw.getDpid())){
continue;
}
- ArrayList<Path> paths = ecmpSPG.getPath(dstSw);
+ ArrayList<Path> paths = ecmpSPG.getECMPPaths(dstSw);
log.debug("ECMPShortestPathGraph:Paths from switch {} to switch {} is {}",
HexString.toHexString(sw.getDpid().value()),
HexString.toHexString(dstSw.getDpid().value()), paths);
//setSegmentRoutingRule(sw, paths);
}
+ */
+ /*
+ HashMap<Integer, HashMap<Switch,ArrayList<Path>>> pathGraph =
+ ecmpSPG.getCompleteLearnedSwitchesAndPaths();
+ for (Integer itrIdx: pathGraph.keySet()){
+
+ HashMap<Switch, ArrayList<Path>> swPathsMap =
+ pathGraph.get(itrIdx);
+ for (Switch targetSw: swPathsMap.keySet()){
+ log.debug("ECMPShortestPathGraph:Paths in Pass{} from "
+ + " switch {} to switch {}:****",
+ itrIdx,
+ HexString.toHexString(sw.getDpid().value()),
+ HexString.toHexString(targetSw.getDpid().value()));
+ int i=0;
+ for (Path path:swPathsMap.get(targetSw)){
+ log.debug("****ECMPShortestPathGraph:Path{} is {}",i++,path);
+ }
+ }
+ }
+ */
+ HashMap<Integer, HashMap<Switch,ArrayList<ArrayList<Dpid>>>> switchVia =
+ ecmpSPG.getAllLearnedSwitchesAndVia();
+ for (Integer itrIdx: switchVia.keySet()){
+ log.debug("ECMPShortestPathGraph:Switches learned in "
+ + "Iteration{} from switch {}:",
+ itrIdx,
+ HexString.toHexString(sw.getDpid().value()));
+
+ HashMap<Switch, ArrayList<ArrayList<Dpid>>> swViaMap =
+ switchVia.get(itrIdx);
+ for (Switch targetSw: swViaMap.keySet()){
+ log.debug("ECMPShortestPathGraph:****switch {} via:",
+ HexString.toHexString(targetSw.getDpid().value()));
+ int i=0;
+ for (ArrayList<Dpid> via:swViaMap.get(targetSw)){
+ log.debug("ECMPShortestPathGraph:******{}) {}",++i,via);
+ }
+ }
+ }
}
}
}