blob: e126b379264f698d62c465410878d530a43bbde7 [file] [log] [blame]
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -07001package net.onrc.onos.apps.segmentrouting;
2
3import java.util.HashMap;
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -07004import java.util.LinkedList;
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -07005import java.util.ArrayList;
6
7import org.projectfloodlight.openflow.util.HexString;
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -07008
9import net.onrc.onos.core.topology.Link;
10import net.onrc.onos.core.topology.LinkData;
11import net.onrc.onos.core.topology.Switch;
12import net.onrc.onos.core.util.Dpid;
13import net.onrc.onos.core.intent.Path;
14
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -070015import org.slf4j.Logger;
16import org.slf4j.LoggerFactory;
17
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -070018/**
19 * This class creates bandwidth constrained breadth first tree and returns paths
20 * from root switch to leaf switches which satisfies the bandwidth condition. If
21 * bandwidth parameter is not specified, the normal breadth first tree will be
22 * calculated. The paths are snapshot paths at the point of the class
23 * instantiation.
24 */
25public class ECMPShortestPathGraph {
26 LinkedList<Switch> switchQueue = new LinkedList<>();
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -070027 LinkedList<Integer> distanceQueue = new LinkedList<>();
28 HashMap<Dpid, Integer> switchSearched = new HashMap<>();
29 HashMap<Dpid, ArrayList<LinkData>> upstreamLinks = new HashMap<>();
30 HashMap<Dpid, ArrayList<Path>> paths = new HashMap<>();
31 HashMap<Integer, ArrayList<Switch>> distanceSwitchMap = new HashMap<>();
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -070032 Switch rootSwitch;
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -070033 private static final Logger log = LoggerFactory
34 .getLogger(SegmentRoutingManager.class);
35
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -070036 /**
37 * Constructor.
38 *
39 * @param rootSwitch root of the BFS tree
40 */
41 public ECMPShortestPathGraph(Switch rootSwitch) {
42 this.rootSwitch = rootSwitch;
43 calcECMPShortestPathGraph();
44 }
45
46 /**
47 * Calculates the BFS tree using any provided constraints and Intents.
48 */
49 private void calcECMPShortestPathGraph() {
50 switchQueue.add(rootSwitch);
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -070051 int currDistance = 0;
52 distanceQueue.add(currDistance);
53 switchSearched.put(rootSwitch.getDpid(),currDistance);
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -070054 while (!switchQueue.isEmpty()) {
55 Switch sw = switchQueue.poll();
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -070056 Switch prevSw = null;
57 currDistance = distanceQueue.poll();
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -070058 for (Link link : sw.getOutgoingLinks()) {
59 Switch reachedSwitch = link.getDstPort().getSwitch();
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -070060 if (prevSw == null)
61 {
62 prevSw = reachedSwitch;
63 }
64 else if (prevSw.getDpid().equals(reachedSwitch.getDpid()))
65 {
66 /* Ignore LAG links between the same set of switches */
67 continue;
68 }
69 Integer distance = switchSearched.get(reachedSwitch.getDpid());
70 if ((distance != null) && (distance.intValue() < (currDistance+1))) {
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -070071 continue;
72 }
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -070073 if (distance == null){
74 switchQueue.add(reachedSwitch);
75 distanceQueue.add(currDistance+1);
76 switchSearched.put(reachedSwitch.getDpid(),currDistance+1);
77 ArrayList<LinkData> upstreamLinkArray = new ArrayList<>();
78 upstreamLinkArray.add(new LinkData(link));
79 upstreamLinks.put(reachedSwitch.getDpid(), upstreamLinkArray);
80 ArrayList<Switch> distanceSwArray = distanceSwitchMap.get(currDistance+1);
81 if (distanceSwArray == null)
82 {
83 distanceSwArray = new ArrayList<Switch>();
84 distanceSwArray.add(reachedSwitch);
85 distanceSwitchMap.put(currDistance+1, distanceSwArray);
86 }
87 else
88 distanceSwArray.add(reachedSwitch);
89 }
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -070090 }
91 }
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -070092
93 log.debug("ECMPShortestPathGraph:switchSearched for switch {} is {}",
94 HexString.toHexString(rootSwitch.getDpid().value()), switchSearched);
95 log.debug("ECMPShortestPathGraph:upstreamLinks for switch {} is {}",
96 HexString.toHexString(rootSwitch.getDpid().value()), upstreamLinks);
97 log.debug("ECMPShortestPathGraph:distanceSwitchMap for switch {} is {}",
98 HexString.toHexString(rootSwitch.getDpid().value()), distanceSwitchMap);
99 /*
100 for (Integer distance: distanceSwitchMap.keySet()){
101 for (Switch sw: distanceSwitchMap.get(distance)){
102 ArrayList<Path> path = getPath(sw);
103 log.debug("ECMPShortestPathGraph:Paths in Pass{} from switch {} to switch {} is {}",
104 distance,
105 HexString.toHexString(rootSwitch.getDpid().value()),
106 HexString.toHexString(sw.getDpid().value()), path);
107 }
108 }*/
109 }
110
111 private void getDFSPaths(Dpid dstSwitchDpid, Path path, ArrayList<Path> paths) {
112 Dpid rootSwitchDpid = rootSwitch.getDpid();
113 for (LinkData upstreamLink : upstreamLinks.get(dstSwitchDpid)) {
114 Path sofarPath = path;
115 sofarPath.add(upstreamLink);
116 if (upstreamLink.getSrc().getDpid().equals(rootSwitchDpid))
117 {
118 paths.add(sofarPath);
119 return;
120 }
121 else
122 getDFSPaths(upstreamLink.getSrc().getDpid(),sofarPath, paths);
123 }
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -0700124 }
125
126 /**
127 * Return the computed path from the root switch to the leaf switch.
128 *
129 * @param leafSwitch the leaf switch
130 * @return the Path from the root switch to the leaf switch
131 */
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -0700132 public ArrayList<Path> getPath(Switch leafSwitch) {
133 ArrayList<Path> pathArray = paths.get(leafSwitch.getDpid());
134 if (pathArray == null && switchSearched.containsKey(leafSwitch.getDpid())) {
135 pathArray = new ArrayList<>();
136 Path path = new Path();
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -0700137 Dpid sw = leafSwitch.getDpid();
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -0700138 getDFSPaths(sw, path, pathArray);
139 paths.put(leafSwitch.getDpid(), pathArray);
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -0700140 }
Srikanth Vavilapalli174e67c2014-09-19 07:27:17 -0700141 return pathArray;
Srikanth Vavilapalli9338f9d2014-09-18 07:37:09 -0700142 }
143}