sangho
Committed by Gerrit Code Review

Bug fix for route population optimization

Change-Id: Ibdaeaff86a03a64670e08db45b050af93a092df7
...@@ -43,6 +43,7 @@ public class DefaultRoutingHandler { ...@@ -43,6 +43,7 @@ public class DefaultRoutingHandler {
43 private SegmentRoutingManager srManager; 43 private SegmentRoutingManager srManager;
44 private RoutingRulePopulator rulePopulator; 44 private RoutingRulePopulator rulePopulator;
45 private HashMap<DeviceId, ECMPShortestPathGraph> currentEcmpSpgMap; 45 private HashMap<DeviceId, ECMPShortestPathGraph> currentEcmpSpgMap;
46 + private HashMap<DeviceId, ECMPShortestPathGraph> updatedEcmpSpgMap;
46 private DeviceConfiguration config; 47 private DeviceConfiguration config;
47 private Status populationStatus; 48 private Status populationStatus;
48 49
...@@ -128,6 +129,18 @@ public class DefaultRoutingHandler { ...@@ -128,6 +129,18 @@ public class DefaultRoutingHandler {
128 return true; 129 return true;
129 } 130 }
130 131
132 + // Take the snapshots of the links
133 + updatedEcmpSpgMap = new HashMap<>();
134 + for (Device sw : srManager.deviceService.getDevices()) {
135 + if (srManager.mastershipService.
136 + getLocalRole(sw.id()) != MastershipRole.MASTER) {
137 + continue;
138 + }
139 + ECMPShortestPathGraph ecmpSpgUpdated =
140 + new ECMPShortestPathGraph(sw.id(), srManager);
141 + updatedEcmpSpgMap.put(sw.id(), ecmpSpgUpdated);
142 + }
143 +
131 log.info("Starts rule population from link change"); 144 log.info("Starts rule population from link change");
132 145
133 Set<ArrayList<DeviceId>> routeChanges; 146 Set<ArrayList<DeviceId>> routeChanges;
...@@ -168,37 +181,38 @@ public class DefaultRoutingHandler { ...@@ -168,37 +181,38 @@ public class DefaultRoutingHandler {
168 if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) { 181 if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) {
169 currentEcmpSpgMap.put(link.get(0), ecmpSpg); 182 currentEcmpSpgMap.put(link.get(0), ecmpSpg);
170 } else { 183 } else {
171 - log.warn("Failed to populate the flow ruls from {} to all", link.get(0)); 184 + log.warn("Failed to populate the flow rules from {} to all", link.get(0));
172 return false; 185 return false;
173 } 186 }
174 - continue; 187 + } else {
175 - } 188 + DeviceId src = link.get(0);
176 - DeviceId src = link.get(0); 189 + DeviceId dst = link.get(1);
177 - DeviceId dst = link.get(1); 190 + log.trace("repopulateRoutingRulesForRoutes: running ECMP graph "
178 - ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(dst, srManager); 191 + + "for device {}", dst);
179 - 192 + ECMPShortestPathGraph ecmpSpg = updatedEcmpSpgMap.get(dst);
180 - currentEcmpSpgMap.put(dst, ecmpSpg); 193 + HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia =
181 - HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = 194 + ecmpSpg.getAllLearnedSwitchesAndVia();
182 - ecmpSpg.getAllLearnedSwitchesAndVia(); 195 + for (Integer itrIdx : switchVia.keySet()) {
183 - for (Integer itrIdx : switchVia.keySet()) { 196 + HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap =
184 - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap = 197 + switchVia.get(itrIdx);
185 - switchVia.get(itrIdx); 198 + for (DeviceId targetSw : swViaMap.keySet()) {
186 - for (DeviceId targetSw : swViaMap.keySet()) { 199 + if (!targetSw.equals(src)) {
187 - if (!targetSw.equals(src)) { 200 + continue;
188 - continue; 201 + }
189 - } 202 + Set<DeviceId> nextHops = new HashSet<>();
190 - Set<DeviceId> nextHops = new HashSet<>(); 203 + for (ArrayList<DeviceId> via : swViaMap.get(targetSw)) {
191 - for (ArrayList<DeviceId> via : swViaMap.get(targetSw)) { 204 + if (via.isEmpty()) {
192 - if (via.isEmpty()) { 205 + nextHops.add(dst);
193 - nextHops.add(dst); 206 + } else {
194 - } else { 207 + nextHops.add(via.get(0));
195 - nextHops.add(via.get(0)); 208 + }
209 + }
210 + if (!populateEcmpRoutingRulePartial(targetSw, dst, nextHops)) {
211 + return false;
196 } 212 }
197 - }
198 - if (!populateEcmpRoutingRulePartial(targetSw, dst, nextHops)) {
199 - return false;
200 } 213 }
201 } 214 }
215 + currentEcmpSpgMap.put(dst, ecmpSpg);
202 } 216 }
203 } 217 }
204 return true; 218 return true;
...@@ -239,6 +253,7 @@ public class DefaultRoutingHandler { ...@@ -239,6 +253,7 @@ public class DefaultRoutingHandler {
239 } 253 }
240 } 254 }
241 } 255 }
256 +
242 } 257 }
243 258
244 return routes; 259 return routes;
...@@ -251,8 +266,16 @@ public class DefaultRoutingHandler { ...@@ -251,8 +266,16 @@ public class DefaultRoutingHandler {
251 for (Device sw : srManager.deviceService.getDevices()) { 266 for (Device sw : srManager.deviceService.getDevices()) {
252 if (srManager.mastershipService. 267 if (srManager.mastershipService.
253 getLocalRole(sw.id()) != MastershipRole.MASTER) { 268 getLocalRole(sw.id()) != MastershipRole.MASTER) {
269 + log.warn("No mastership for {} and skip route optimization");
254 continue; 270 continue;
255 } 271 }
272 +
273 + log.trace("link of {} - ", sw.id());
274 + for (Link link: srManager.linkService.getDeviceLinks(sw.id())) {
275 + log.trace("{} -> {} ", link.src().deviceId(), link.dst().deviceId());
276 + }
277 +
278 + log.debug("Checking route change for switch {}", sw.id());
256 ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); 279 ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id());
257 if (ecmpSpg == null) { 280 if (ecmpSpg == null) {
258 log.debug("No existing ECMP path for Switch {}", sw.id()); 281 log.debug("No existing ECMP path for Switch {}", sw.id());
...@@ -261,20 +284,22 @@ public class DefaultRoutingHandler { ...@@ -261,20 +284,22 @@ public class DefaultRoutingHandler {
261 routes.add(route); 284 routes.add(route);
262 continue; 285 continue;
263 } 286 }
264 - ECMPShortestPathGraph newEcmpSpg = 287 + log.debug("computeRouteChange: running ECMP graph "
265 - new ECMPShortestPathGraph(sw.id(), srManager); 288 + + "for device {}", sw.id());
289 + ECMPShortestPathGraph newEcmpSpg = updatedEcmpSpgMap.get(sw.id());
290 + currentEcmpSpgMap.put(sw.id(), newEcmpSpg);
266 HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = 291 HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia =
267 ecmpSpg.getAllLearnedSwitchesAndVia(); 292 ecmpSpg.getAllLearnedSwitchesAndVia();
268 HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchViaUpdated = 293 HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchViaUpdated =
269 newEcmpSpg.getAllLearnedSwitchesAndVia(); 294 newEcmpSpg.getAllLearnedSwitchesAndVia();
270 295
271 - for (Integer itrIdx : switchVia.keySet()) { 296 + for (Integer itrIdx : switchViaUpdated.keySet()) {
272 - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap = 297 + HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMapUpdated =
273 - switchVia.get(itrIdx); 298 + switchViaUpdated.get(itrIdx);
274 - for (DeviceId srcSw : swViaMap.keySet()) { 299 + for (DeviceId srcSw : swViaMapUpdated.keySet()) {
275 - ArrayList<ArrayList<DeviceId>> via1 = swViaMap.get(srcSw); 300 + ArrayList<ArrayList<DeviceId>> viaUpdated = swViaMapUpdated.get(srcSw);
276 - ArrayList<ArrayList<DeviceId>> via2 = getVia(switchViaUpdated, srcSw); 301 + ArrayList<ArrayList<DeviceId>> via = getVia(switchVia, srcSw);
277 - if (!via1.equals(via2)) { 302 + if (via.isEmpty() || !viaUpdated.equals(via)) {
278 ArrayList<DeviceId> route = new ArrayList<>(); 303 ArrayList<DeviceId> route = new ArrayList<>();
279 route.add(srcSw); 304 route.add(srcSw);
280 route.add(sw.id()); 305 route.add(sw.id());
...@@ -282,7 +307,15 @@ public class DefaultRoutingHandler { ...@@ -282,7 +307,15 @@ public class DefaultRoutingHandler {
282 } 307 }
283 } 308 }
284 } 309 }
310 + }
285 311
312 + for (ArrayList<DeviceId> link: routes) {
313 + log.trace("Link changes - ");
314 + if (link.size() == 1) {
315 + log.trace(" : {} - all", link.get(0));
316 + } else {
317 + log.trace(" : {} - {}", link.get(0), link.get(1));
318 + }
286 } 319 }
287 320
288 return routes; 321 return routes;
......
...@@ -265,7 +265,7 @@ public class RoutingRulePopulator { ...@@ -265,7 +265,7 @@ public class RoutingRulePopulator {
265 .withPriority(100)) 265 .withPriority(100))
266 .withFlag(ForwardingObjective.Flag.SPECIFIC); 266 .withFlag(ForwardingObjective.Flag.SPECIFIC);
267 log.debug("Installing MPLS forwarding objective in switch {}", 267 log.debug("Installing MPLS forwarding objective in switch {}",
268 - deviceId); 268 + deviceId);
269 srManager.flowObjectiveService.forward(deviceId, 269 srManager.flowObjectiveService.forward(deviceId,
270 fwdObjBuilder.add()); 270 fwdObjBuilder.add());
271 rulePopulationCounter.incrementAndGet(); 271 rulePopulationCounter.incrementAndGet();
...@@ -299,15 +299,15 @@ public class RoutingRulePopulator { ...@@ -299,15 +299,15 @@ public class RoutingRulePopulator {
299 } 299 }
300 300
301 if (!isECMPSupportedInTransitRouter() && !config.isEdgeDevice(deviceId)) { 301 if (!isECMPSupportedInTransitRouter() && !config.isEdgeDevice(deviceId)) {
302 - Link link = selectOneLink(deviceId, nextHops); 302 + PortNumber port = selectOnePort(deviceId, nextHops);
303 DeviceId nextHop = (DeviceId) nextHops.toArray()[0]; 303 DeviceId nextHop = (DeviceId) nextHops.toArray()[0];
304 - if (link == null) { 304 + if (port == null) {
305 log.warn("No link from {} to {}", deviceId, nextHops); 305 log.warn("No link from {} to {}", deviceId, nextHops);
306 return null; 306 return null;
307 } 307 }
308 tbuilder.setEthSrc(config.getDeviceMac(deviceId)) 308 tbuilder.setEthSrc(config.getDeviceMac(deviceId))
309 .setEthDst(config.getDeviceMac(nextHop)) 309 .setEthDst(config.getDeviceMac(nextHop))
310 - .setOutput(link.src().port()); 310 + .setOutput(port);
311 fwdBuilder.withTreatment(tbuilder.build()); 311 fwdBuilder.withTreatment(tbuilder.build());
312 } else { 312 } else {
313 NeighborSet ns = new NeighborSet(nextHops); 313 NeighborSet ns = new NeighborSet(nextHops);
...@@ -356,13 +356,16 @@ public class RoutingRulePopulator { ...@@ -356,13 +356,16 @@ public class RoutingRulePopulator {
356 srManager.flowObjectiveService.filter(deviceId, fob.add()); 356 srManager.flowObjectiveService.filter(deviceId, fob.add());
357 } 357 }
358 358
359 - private Link selectOneLink(DeviceId srcId, Set<DeviceId> destIds) { 359 + private PortNumber selectOnePort(DeviceId srcId, Set<DeviceId> destIds) {
360 360
361 - Set<Link> links = srManager.linkService.getDeviceEgressLinks(srcId); 361 + Set<Link> links = srManager.linkService.getDeviceLinks(srcId);
362 - DeviceId destId = (DeviceId) destIds.toArray()[0]; 362 + for (DeviceId destId: destIds) {
363 - for (Link link : links) { 363 + for (Link link : links) {
364 - if (link.dst().deviceId().equals(destId)) { 364 + if (link.dst().deviceId().equals(destId)) {
365 - return link; 365 + return link.src().port();
366 + } else if (link.src().deviceId().equals(destId)) {
367 + return link.dst().port();
368 + }
366 } 369 }
367 } 370 }
368 371
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
38 <driver name="cpqd" manufacturer="Stanford University, Ericsson Research and CPqD Research" 38 <driver name="cpqd" manufacturer="Stanford University, Ericsson Research and CPqD Research"
39 hwVersion="OpenFlow 1.3 Reference Userspace Switch" swVersion=".*"> 39 hwVersion="OpenFlow 1.3 Reference Userspace Switch" swVersion=".*">
40 <behaviour api="org.onosproject.net.behaviour.Pipeliner" 40 <behaviour api="org.onosproject.net.behaviour.Pipeliner"
41 - impl="org.onosproject.driver.pipeline.DefaultSingleTablePipeline"/> 41 + impl="org.onosproject.driver.pipeline.SpringOpenTTP"/>
42 <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" 42 <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
43 impl="org.onosproject.driver.handshaker.OFSwitchImplSpringOpenTTP"/> 43 impl="org.onosproject.driver.handshaker.OFSwitchImplSpringOpenTTP"/>
44 </driver> 44 </driver>
......