Committed by
Gerrit Code Review
Bug fix for route population optimization
Change-Id: Ibdaeaff86a03a64670e08db45b050af93a092df7
Showing
3 changed files
with
82 additions
and
46 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,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> | ... | ... |
-
Please register or login to post a comment