Committed by
Gerrit Code Review
Bug fix for route population optimization
Change-Id: Ibdaeaff86a03a64670e08db45b050af93a092df7
Showing
3 changed files
with
59 additions
and
23 deletions
| ... | @@ -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,16 +181,15 @@ public class DefaultRoutingHandler { | ... | @@ -168,16 +181,15 @@ 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 | - } | ||
| 176 | DeviceId src = link.get(0); | 188 | DeviceId src = link.get(0); |
| 177 | DeviceId dst = link.get(1); | 189 | DeviceId dst = link.get(1); |
| 178 | - ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(dst, srManager); | 190 | + log.trace("repopulateRoutingRulesForRoutes: running ECMP graph " |
| 179 | - | 191 | + + "for device {}", dst); |
| 180 | - currentEcmpSpgMap.put(dst, ecmpSpg); | 192 | + ECMPShortestPathGraph ecmpSpg = updatedEcmpSpgMap.get(dst); |
| 181 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = | 193 | HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = |
| 182 | ecmpSpg.getAllLearnedSwitchesAndVia(); | 194 | ecmpSpg.getAllLearnedSwitchesAndVia(); |
| 183 | for (Integer itrIdx : switchVia.keySet()) { | 195 | for (Integer itrIdx : switchVia.keySet()) { |
| ... | @@ -200,6 +212,8 @@ public class DefaultRoutingHandler { | ... | @@ -200,6 +212,8 @@ public class DefaultRoutingHandler { |
| 200 | } | 212 | } |
| 201 | } | 213 | } |
| 202 | } | 214 | } |
| 215 | + currentEcmpSpgMap.put(dst, ecmpSpg); | ||
| 216 | + } | ||
| 203 | } | 217 | } |
| 204 | return true; | 218 | return true; |
| 205 | } | 219 | } |
| ... | @@ -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; | ... | ... |
| ... | @@ -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> | ... | ... |
-
Please register or login to post a comment