Committed by
Gerrit Code Review
ONOS-2846, ONOS-2812 Refactored link discovery pruning to be centralized rather …
…than being with each link discovery helper. This will make it behave properly in a distributed context. Change-Id: I9b9788336468c41d1cf506e388306ad9136d5853
Showing
5 changed files
with
157 additions
and
105 deletions
| ... | @@ -16,13 +16,14 @@ | ... | @@ -16,13 +16,14 @@ |
| 16 | package org.onosproject.provider.lldp.impl; | 16 | package org.onosproject.provider.lldp.impl; |
| 17 | 17 | ||
| 18 | import org.onosproject.mastership.MastershipService; | 18 | import org.onosproject.mastership.MastershipService; |
| 19 | +import org.onosproject.net.LinkKey; | ||
| 19 | import org.onosproject.net.link.LinkProviderService; | 20 | import org.onosproject.net.link.LinkProviderService; |
| 20 | import org.onosproject.net.packet.PacketService; | 21 | import org.onosproject.net.packet.PacketService; |
| 21 | 22 | ||
| 22 | /** | 23 | /** |
| 23 | * Shared context for use by link discovery. | 24 | * Shared context for use by link discovery. |
| 24 | */ | 25 | */ |
| 25 | -public interface DiscoveryContext { | 26 | +interface DiscoveryContext { |
| 26 | 27 | ||
| 27 | /** | 28 | /** |
| 28 | * Returns the shared mastership service reference. | 29 | * Returns the shared mastership service reference. |
| ... | @@ -53,16 +54,16 @@ public interface DiscoveryContext { | ... | @@ -53,16 +54,16 @@ public interface DiscoveryContext { |
| 53 | long probeRate(); | 54 | long probeRate(); |
| 54 | 55 | ||
| 55 | /** | 56 | /** |
| 56 | - * Returns the max stale link age in millis. | 57 | + * Indicates whether to emit BDDP. |
| 57 | * | 58 | * |
| 58 | - * @return stale link age | 59 | + * @return true to emit BDDP |
| 59 | */ | 60 | */ |
| 60 | - long staleLinkAge(); | 61 | + boolean useBDDP(); |
| 61 | 62 | ||
| 62 | /** | 63 | /** |
| 63 | - * Indicates whether to emit BDDP. | 64 | + * Touches the link identified by the given key to indicate that it's active. |
| 64 | * | 65 | * |
| 65 | - * @return true to emit BDDP | 66 | + * @param key link key |
| 66 | */ | 67 | */ |
| 67 | - boolean useBDDP(); | 68 | + void touchLink(LinkKey key); |
| 68 | } | 69 | } | ... | ... |
| ... | @@ -17,6 +17,7 @@ package org.onosproject.provider.lldp.impl; | ... | @@ -17,6 +17,7 @@ package org.onosproject.provider.lldp.impl; |
| 17 | 17 | ||
| 18 | import com.google.common.collect.ImmutableMap; | 18 | import com.google.common.collect.ImmutableMap; |
| 19 | import com.google.common.collect.ImmutableSet; | 19 | import com.google.common.collect.ImmutableSet; |
| 20 | +import com.google.common.collect.Maps; | ||
| 20 | import org.apache.felix.scr.annotations.Activate; | 21 | import org.apache.felix.scr.annotations.Activate; |
| 21 | import org.apache.felix.scr.annotations.Component; | 22 | import org.apache.felix.scr.annotations.Component; |
| 22 | import org.apache.felix.scr.annotations.Deactivate; | 23 | import org.apache.felix.scr.annotations.Deactivate; |
| ... | @@ -34,15 +35,18 @@ import org.onosproject.mastership.MastershipService; | ... | @@ -34,15 +35,18 @@ import org.onosproject.mastership.MastershipService; |
| 34 | import org.onosproject.net.ConnectPoint; | 35 | import org.onosproject.net.ConnectPoint; |
| 35 | import org.onosproject.net.Device; | 36 | import org.onosproject.net.Device; |
| 36 | import org.onosproject.net.DeviceId; | 37 | import org.onosproject.net.DeviceId; |
| 38 | +import org.onosproject.net.LinkKey; | ||
| 37 | import org.onosproject.net.Port; | 39 | import org.onosproject.net.Port; |
| 38 | import org.onosproject.net.device.DeviceEvent; | 40 | import org.onosproject.net.device.DeviceEvent; |
| 39 | import org.onosproject.net.device.DeviceListener; | 41 | import org.onosproject.net.device.DeviceListener; |
| 40 | import org.onosproject.net.device.DeviceService; | 42 | import org.onosproject.net.device.DeviceService; |
| 41 | import org.onosproject.net.flow.DefaultTrafficSelector; | 43 | import org.onosproject.net.flow.DefaultTrafficSelector; |
| 42 | import org.onosproject.net.flow.TrafficSelector; | 44 | import org.onosproject.net.flow.TrafficSelector; |
| 45 | +import org.onosproject.net.link.DefaultLinkDescription; | ||
| 43 | import org.onosproject.net.link.LinkProvider; | 46 | import org.onosproject.net.link.LinkProvider; |
| 44 | import org.onosproject.net.link.LinkProviderRegistry; | 47 | import org.onosproject.net.link.LinkProviderRegistry; |
| 45 | import org.onosproject.net.link.LinkProviderService; | 48 | import org.onosproject.net.link.LinkProviderService; |
| 49 | +import org.onosproject.net.link.LinkService; | ||
| 46 | import org.onosproject.net.packet.PacketContext; | 50 | import org.onosproject.net.packet.PacketContext; |
| 47 | import org.onosproject.net.packet.PacketPriority; | 51 | import org.onosproject.net.packet.PacketPriority; |
| 48 | import org.onosproject.net.packet.PacketProcessor; | 52 | import org.onosproject.net.packet.PacketProcessor; |
| ... | @@ -65,6 +69,7 @@ import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | ... | @@ -65,6 +69,7 @@ import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; |
| 65 | import static java.util.concurrent.TimeUnit.SECONDS; | 69 | import static java.util.concurrent.TimeUnit.SECONDS; |
| 66 | import static org.onlab.util.Tools.get; | 70 | import static org.onlab.util.Tools.get; |
| 67 | import static org.onlab.util.Tools.groupedThreads; | 71 | import static org.onlab.util.Tools.groupedThreads; |
| 72 | +import static org.onosproject.net.Link.Type.DIRECT; | ||
| 68 | import static org.slf4j.LoggerFactory.getLogger; | 73 | import static org.slf4j.LoggerFactory.getLogger; |
| 69 | 74 | ||
| 70 | /** | 75 | /** |
| ... | @@ -91,6 +96,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -91,6 +96,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 91 | protected DeviceService deviceService; | 96 | protected DeviceService deviceService; |
| 92 | 97 | ||
| 93 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 98 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 99 | + protected LinkService linkService; | ||
| 100 | + | ||
| 101 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 94 | protected PacketService packetService; | 102 | protected PacketService packetService; |
| 95 | 103 | ||
| 96 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 104 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| ... | @@ -103,8 +111,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -103,8 +111,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 103 | 111 | ||
| 104 | private ScheduledExecutorService executor; | 112 | private ScheduledExecutorService executor; |
| 105 | 113 | ||
| 106 | - private static final long INIT_DELAY = 5; | 114 | + // TODO: Add sanity checking for the configurable params based on the delays |
| 107 | - private static final long DELAY = 5; | 115 | + private static final long DEVICE_SYNC_DELAY = 5; |
| 116 | + private static final long LINK_PRUNER_DELAY = 3; | ||
| 108 | 117 | ||
| 109 | private static final String PROP_ENABLED = "enabled"; | 118 | private static final String PROP_ENABLED = "enabled"; |
| 110 | @Property(name = PROP_ENABLED, boolValue = true, | 119 | @Property(name = PROP_ENABLED, boolValue = true, |
| ... | @@ -135,13 +144,18 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -135,13 +144,18 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 135 | label = "Path to LLDP suppression configuration file") | 144 | label = "Path to LLDP suppression configuration file") |
| 136 | private String lldpSuppression = DEFAULT_LLDP_SUPPRESSION_CONFIG; | 145 | private String lldpSuppression = DEFAULT_LLDP_SUPPRESSION_CONFIG; |
| 137 | 146 | ||
| 138 | - | ||
| 139 | private final DiscoveryContext context = new InternalDiscoveryContext(); | 147 | private final DiscoveryContext context = new InternalDiscoveryContext(); |
| 140 | - private final InternalLinkProvider listener = new InternalLinkProvider(); | ||
| 141 | private final InternalRoleListener roleListener = new InternalRoleListener(); | 148 | private final InternalRoleListener roleListener = new InternalRoleListener(); |
| 149 | + private final InternalDeviceListener deviceListener = new InternalDeviceListener(); | ||
| 150 | + private final InternalPacketProcessor packetProcessor = new InternalPacketProcessor(); | ||
| 142 | 151 | ||
| 152 | + // Device link discovery helpers. | ||
| 143 | protected final Map<DeviceId, LinkDiscovery> discoverers = new ConcurrentHashMap<>(); | 153 | protected final Map<DeviceId, LinkDiscovery> discoverers = new ConcurrentHashMap<>(); |
| 144 | 154 | ||
| 155 | + // Most recent time a tracked link was seen; links are tracked if their | ||
| 156 | + // destination connection point is mastered by this controller instance. | ||
| 157 | + private final Map<LinkKey, Long> linkTimes = Maps.newConcurrentMap(); | ||
| 158 | + | ||
| 145 | private SuppressionRules rules; | 159 | private SuppressionRules rules; |
| 146 | private ApplicationId appId; | 160 | private ApplicationId appId; |
| 147 | 161 | ||
| ... | @@ -216,28 +230,37 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -216,28 +230,37 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 216 | log.info(FORMAT, enabled, useBDDP, probeRate, staleLinkAge, lldpSuppression); | 230 | log.info(FORMAT, enabled, useBDDP, probeRate, staleLinkAge, lldpSuppression); |
| 217 | } | 231 | } |
| 218 | 232 | ||
| 233 | + /** | ||
| 234 | + * Enables link discovery processing. | ||
| 235 | + */ | ||
| 219 | private void enable() { | 236 | private void enable() { |
| 220 | providerService = providerRegistry.register(this); | 237 | providerService = providerRegistry.register(this); |
| 221 | - deviceService.addListener(listener); | ||
| 222 | - packetService.addProcessor(listener, PacketProcessor.advisor(0)); | ||
| 223 | masterService.addListener(roleListener); | 238 | masterService.addListener(roleListener); |
| 239 | + deviceService.addListener(deviceListener); | ||
| 240 | + packetService.addProcessor(packetProcessor, PacketProcessor.advisor(0)); | ||
| 224 | 241 | ||
| 225 | - processDevices(); | 242 | + loadDevices(); |
| 226 | 243 | ||
| 227 | - executor = newSingleThreadScheduledExecutor(groupedThreads("onos/device", "sync-%d")); | 244 | + executor = newSingleThreadScheduledExecutor(groupedThreads("onos/link", "discovery-%d")); |
| 228 | - executor.scheduleAtFixedRate(new SyncDeviceInfoTask(), INIT_DELAY, DELAY, SECONDS); | 245 | + executor.scheduleAtFixedRate(new SyncDeviceInfoTask(), |
| 246 | + DEVICE_SYNC_DELAY, DEVICE_SYNC_DELAY, SECONDS); | ||
| 247 | + executor.scheduleAtFixedRate(new LinkPrunerTask(), | ||
| 248 | + LINK_PRUNER_DELAY, LINK_PRUNER_DELAY, SECONDS); | ||
| 229 | 249 | ||
| 230 | loadSuppressionRules(); | 250 | loadSuppressionRules(); |
| 231 | requestIntercepts(); | 251 | requestIntercepts(); |
| 232 | } | 252 | } |
| 233 | 253 | ||
| 254 | + /** | ||
| 255 | + * Disables link discovery processing. | ||
| 256 | + */ | ||
| 234 | private void disable() { | 257 | private void disable() { |
| 235 | withdrawIntercepts(); | 258 | withdrawIntercepts(); |
| 236 | 259 | ||
| 237 | providerRegistry.unregister(this); | 260 | providerRegistry.unregister(this); |
| 238 | - deviceService.removeListener(listener); | ||
| 239 | - packetService.removeProcessor(listener); | ||
| 240 | masterService.removeListener(roleListener); | 261 | masterService.removeListener(roleListener); |
| 262 | + deviceService.removeListener(deviceListener); | ||
| 263 | + packetService.removeProcessor(packetProcessor); | ||
| 241 | 264 | ||
| 242 | if (executor != null) { | 265 | if (executor != null) { |
| 243 | executor.shutdownNow(); | 266 | executor.shutdownNow(); |
| ... | @@ -248,7 +271,10 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -248,7 +271,10 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 248 | providerService = null; | 271 | providerService = null; |
| 249 | } | 272 | } |
| 250 | 273 | ||
| 251 | - private void processDevices() { | 274 | + /** |
| 275 | + * Loads available devices and registers their ports to be probed. | ||
| 276 | + */ | ||
| 277 | + private void loadDevices() { | ||
| 252 | for (Device device : deviceService.getAvailableDevices()) { | 278 | for (Device device : deviceService.getAvailableDevices()) { |
| 253 | if (rules.isSuppressed(device)) { | 279 | if (rules.isSuppressed(device)) { |
| 254 | log.debug("LinkDiscovery from {} disabled by configuration", device.id()); | 280 | log.debug("LinkDiscovery from {} disabled by configuration", device.id()); |
| ... | @@ -260,6 +286,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -260,6 +286,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 260 | } | 286 | } |
| 261 | } | 287 | } |
| 262 | 288 | ||
| 289 | + /** | ||
| 290 | + * Adds ports of the specified device to the specified discovery helper. | ||
| 291 | + */ | ||
| 263 | private void addPorts(LinkDiscovery discoverer, DeviceId deviceId) { | 292 | private void addPorts(LinkDiscovery discoverer, DeviceId deviceId) { |
| 264 | for (Port p : deviceService.getPorts(deviceId)) { | 293 | for (Port p : deviceService.getPorts(deviceId)) { |
| 265 | if (rules.isSuppressed(p)) { | 294 | if (rules.isSuppressed(p)) { |
| ... | @@ -271,7 +300,12 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -271,7 +300,12 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 271 | } | 300 | } |
| 272 | } | 301 | } |
| 273 | 302 | ||
| 303 | + | ||
| 304 | + /** | ||
| 305 | + * Loads LLDP suppression rules. | ||
| 306 | + */ | ||
| 274 | private void loadSuppressionRules() { | 307 | private void loadSuppressionRules() { |
| 308 | + // FIXME: convert to use network configuration | ||
| 275 | SuppressionRulesStore store = new SuppressionRulesStore(lldpSuppression); | 309 | SuppressionRulesStore store = new SuppressionRulesStore(lldpSuppression); |
| 276 | try { | 310 | try { |
| 277 | log.info("Reading suppression rules from {}", lldpSuppression); | 311 | log.info("Reading suppression rules from {}", lldpSuppression); |
| ... | @@ -288,7 +322,7 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -288,7 +322,7 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 288 | } | 322 | } |
| 289 | 323 | ||
| 290 | /** | 324 | /** |
| 291 | - * Request packet intercepts. | 325 | + * Requests packet intercepts. |
| 292 | */ | 326 | */ |
| 293 | private void requestIntercepts() { | 327 | private void requestIntercepts() { |
| 294 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 328 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| ... | @@ -304,7 +338,7 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -304,7 +338,7 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 304 | } | 338 | } |
| 305 | 339 | ||
| 306 | /** | 340 | /** |
| 307 | - * Withdraw packet intercepts. | 341 | + * Withdraws packet intercepts. |
| 308 | */ | 342 | */ |
| 309 | private void withdrawIntercepts() { | 343 | private void withdrawIntercepts() { |
| 310 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 344 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| ... | @@ -314,6 +348,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -314,6 +348,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 314 | packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId); | 348 | packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId); |
| 315 | } | 349 | } |
| 316 | 350 | ||
| 351 | + /** | ||
| 352 | + * Processes device mastership role changes. | ||
| 353 | + */ | ||
| 317 | private class InternalRoleListener implements MastershipListener { | 354 | private class InternalRoleListener implements MastershipListener { |
| 318 | @Override | 355 | @Override |
| 319 | public void event(MastershipEvent event) { | 356 | public void event(MastershipEvent event) { |
| ... | @@ -336,7 +373,10 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -336,7 +373,10 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 336 | 373 | ||
| 337 | } | 374 | } |
| 338 | 375 | ||
| 339 | - private class InternalLinkProvider implements PacketProcessor, DeviceListener { | 376 | + /** |
| 377 | + * Processes device events. | ||
| 378 | + */ | ||
| 379 | + private class InternalDeviceListener implements DeviceListener { | ||
| 340 | @Override | 380 | @Override |
| 341 | public void event(DeviceEvent event) { | 381 | public void event(DeviceEvent event) { |
| 342 | LinkDiscovery ld; | 382 | LinkDiscovery ld; |
| ... | @@ -426,7 +466,12 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -426,7 +466,12 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 426 | log.debug("Unknown event {}", event); | 466 | log.debug("Unknown event {}", event); |
| 427 | } | 467 | } |
| 428 | } | 468 | } |
| 469 | + } | ||
| 429 | 470 | ||
| 471 | + /** | ||
| 472 | + * Processes incoming packets. | ||
| 473 | + */ | ||
| 474 | + private class InternalPacketProcessor implements PacketProcessor { | ||
| 430 | @Override | 475 | @Override |
| 431 | public void process(PacketContext context) { | 476 | public void process(PacketContext context) { |
| 432 | if (context == null) { | 477 | if (context == null) { |
| ... | @@ -443,6 +488,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -443,6 +488,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 443 | } | 488 | } |
| 444 | } | 489 | } |
| 445 | 490 | ||
| 491 | + /** | ||
| 492 | + * Auxiliary task to keep device ports up to date. | ||
| 493 | + */ | ||
| 446 | private final class SyncDeviceInfoTask implements Runnable { | 494 | private final class SyncDeviceInfoTask implements Runnable { |
| 447 | @Override | 495 | @Override |
| 448 | public void run() { | 496 | public void run() { |
| ... | @@ -464,12 +512,54 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -464,12 +512,54 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 464 | } | 512 | } |
| 465 | } | 513 | } |
| 466 | } catch (Exception e) { | 514 | } catch (Exception e) { |
| 467 | - // catch all Exception to avoid Scheduled task being suppressed. | 515 | + // Catch all exceptions to avoid task being suppressed |
| 468 | log.error("Exception thrown during synchronization process", e); | 516 | log.error("Exception thrown during synchronization process", e); |
| 469 | } | 517 | } |
| 470 | } | 518 | } |
| 471 | } | 519 | } |
| 472 | 520 | ||
| 521 | + /** | ||
| 522 | + * Auxiliary task for pruning stale links. | ||
| 523 | + */ | ||
| 524 | + private class LinkPrunerTask implements Runnable { | ||
| 525 | + @Override | ||
| 526 | + public void run() { | ||
| 527 | + if (Thread.currentThread().isInterrupted()) { | ||
| 528 | + log.info("Interrupted, quitting"); | ||
| 529 | + return; | ||
| 530 | + } | ||
| 531 | + | ||
| 532 | + try { | ||
| 533 | + // TODO: There is still a slight possibility of mastership | ||
| 534 | + // change occurring right with link going stale. This will | ||
| 535 | + // result in the stale link not being pruned. | ||
| 536 | + Maps.filterEntries(linkTimes, e -> { | ||
| 537 | + if (!masterService.isLocalMaster(e.getKey().dst().deviceId())) { | ||
| 538 | + return true; | ||
| 539 | + } | ||
| 540 | + if (isStale(e.getValue())) { | ||
| 541 | + providerService.linkVanished(new DefaultLinkDescription(e.getKey().src(), | ||
| 542 | + e.getKey().dst(), | ||
| 543 | + DIRECT)); | ||
| 544 | + return true; | ||
| 545 | + } | ||
| 546 | + return false; | ||
| 547 | + }).clear(); | ||
| 548 | + | ||
| 549 | + } catch (Exception e) { | ||
| 550 | + // Catch all exceptions to avoid task being suppressed | ||
| 551 | + log.error("Exception thrown during link pruning process", e); | ||
| 552 | + } | ||
| 553 | + } | ||
| 554 | + | ||
| 555 | + private boolean isStale(long lastSeen) { | ||
| 556 | + return lastSeen < System.currentTimeMillis() - staleLinkAge; | ||
| 557 | + } | ||
| 558 | + } | ||
| 559 | + | ||
| 560 | + /** | ||
| 561 | + * Provides processing context for the device link discovery helpers. | ||
| 562 | + */ | ||
| 473 | private class InternalDiscoveryContext implements DiscoveryContext { | 563 | private class InternalDiscoveryContext implements DiscoveryContext { |
| 474 | @Override | 564 | @Override |
| 475 | public MastershipService mastershipService() { | 565 | public MastershipService mastershipService() { |
| ... | @@ -492,13 +582,14 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -492,13 +582,14 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { |
| 492 | } | 582 | } |
| 493 | 583 | ||
| 494 | @Override | 584 | @Override |
| 495 | - public long staleLinkAge() { | 585 | + public boolean useBDDP() { |
| 496 | - return staleLinkAge; | 586 | + return useBDDP; |
| 497 | } | 587 | } |
| 498 | 588 | ||
| 499 | @Override | 589 | @Override |
| 500 | - public boolean useBDDP() { | 590 | + public void touchLink(LinkKey key) { |
| 501 | - return useBDDP; | 591 | + linkTimes.put(key, System.currentTimeMillis()); |
| 502 | } | 592 | } |
| 503 | } | 593 | } |
| 594 | + | ||
| 504 | } | 595 | } | ... | ... |
| ... | @@ -15,7 +15,6 @@ | ... | @@ -15,7 +15,6 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.provider.lldp.impl; | 16 | package org.onosproject.provider.lldp.impl; |
| 17 | 17 | ||
| 18 | -import com.google.common.collect.Maps; | ||
| 19 | import com.google.common.collect.Sets; | 18 | import com.google.common.collect.Sets; |
| 20 | import org.jboss.netty.util.Timeout; | 19 | import org.jboss.netty.util.Timeout; |
| 21 | import org.jboss.netty.util.TimerTask; | 20 | import org.jboss.netty.util.TimerTask; |
| ... | @@ -37,9 +36,7 @@ import org.onosproject.net.packet.PacketContext; | ... | @@ -37,9 +36,7 @@ import org.onosproject.net.packet.PacketContext; |
| 37 | import org.slf4j.Logger; | 36 | import org.slf4j.Logger; |
| 38 | 37 | ||
| 39 | import java.nio.ByteBuffer; | 38 | import java.nio.ByteBuffer; |
| 40 | -import java.util.Map; | ||
| 41 | import java.util.Set; | 39 | import java.util.Set; |
| 42 | -import java.util.stream.Collectors; | ||
| 43 | 40 | ||
| 44 | import static java.util.concurrent.TimeUnit.MILLISECONDS; | 41 | import static java.util.concurrent.TimeUnit.MILLISECONDS; |
| 45 | import static org.onosproject.net.PortNumber.portNumber; | 42 | import static org.onosproject.net.PortNumber.portNumber; |
| ... | @@ -53,7 +50,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -53,7 +50,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
| 53 | * LLDP, send an LLDP for a single slow port. Based on FlowVisor topology | 50 | * LLDP, send an LLDP for a single slow port. Based on FlowVisor topology |
| 54 | * discovery implementation. | 51 | * discovery implementation. |
| 55 | */ | 52 | */ |
| 56 | -public class LinkDiscovery implements TimerTask { | 53 | +class LinkDiscovery implements TimerTask { |
| 57 | 54 | ||
| 58 | private final Logger log = getLogger(getClass()); | 55 | private final Logger log = getLogger(getClass()); |
| 59 | 56 | ||
| ... | @@ -72,9 +69,6 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -72,9 +69,6 @@ public class LinkDiscovery implements TimerTask { |
| 72 | // Set of ports to be probed | 69 | // Set of ports to be probed |
| 73 | private final Set<Long> ports = Sets.newConcurrentHashSet(); | 70 | private final Set<Long> ports = Sets.newConcurrentHashSet(); |
| 74 | 71 | ||
| 75 | - // Most recent time a link was seen | ||
| 76 | - private final Map<LinkKey, Long> linkTimes = Maps.newConcurrentMap(); | ||
| 77 | - | ||
| 78 | /** | 72 | /** |
| 79 | * Instantiates discovery manager for the given physical switch. Creates a | 73 | * Instantiates discovery manager for the given physical switch. Creates a |
| 80 | * generic LLDP packet that will be customized for the port it is sent out on. | 74 | * generic LLDP packet that will be customized for the port it is sent out on. |
| ... | @@ -83,7 +77,7 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -83,7 +77,7 @@ public class LinkDiscovery implements TimerTask { |
| 83 | * @param device the physical switch | 77 | * @param device the physical switch |
| 84 | * @param context discovery context | 78 | * @param context discovery context |
| 85 | */ | 79 | */ |
| 86 | - public LinkDiscovery(Device device, DiscoveryContext context) { | 80 | + LinkDiscovery(Device device, DiscoveryContext context) { |
| 87 | this.device = device; | 81 | this.device = device; |
| 88 | this.context = context; | 82 | this.context = context; |
| 89 | 83 | ||
| ... | @@ -102,7 +96,6 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -102,7 +96,6 @@ public class LinkDiscovery implements TimerTask { |
| 102 | bddpEth.setEtherType(Ethernet.TYPE_BSN); | 96 | bddpEth.setEtherType(Ethernet.TYPE_BSN); |
| 103 | bddpEth.setDestinationMACAddress(ONOSLLDP.BDDP_MULTICAST); | 97 | bddpEth.setDestinationMACAddress(ONOSLLDP.BDDP_MULTICAST); |
| 104 | bddpEth.setPad(true); | 98 | bddpEth.setPad(true); |
| 105 | - log.info("Using BDDP to discover network"); | ||
| 106 | 99 | ||
| 107 | isStopped = true; | 100 | isStopped = true; |
| 108 | start(); | 101 | start(); |
| ... | @@ -110,46 +103,47 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -110,46 +103,47 @@ public class LinkDiscovery implements TimerTask { |
| 110 | 103 | ||
| 111 | } | 104 | } |
| 112 | 105 | ||
| 106 | + synchronized void stop() { | ||
| 107 | + isStopped = true; | ||
| 108 | + timeout.cancel(); | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + synchronized void start() { | ||
| 112 | + if (isStopped) { | ||
| 113 | + isStopped = false; | ||
| 114 | + timeout = Timer.getTimer().newTimeout(this, 0, MILLISECONDS); | ||
| 115 | + } else { | ||
| 116 | + log.warn("LinkDiscovery started multiple times?"); | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + synchronized boolean isStopped() { | ||
| 121 | + return isStopped || timeout.isCancelled(); | ||
| 122 | + } | ||
| 123 | + | ||
| 113 | /** | 124 | /** |
| 114 | * Add physical port port to discovery process. | 125 | * Add physical port port to discovery process. |
| 115 | * Send out initial LLDP and label it as slow port. | 126 | * Send out initial LLDP and label it as slow port. |
| 116 | * | 127 | * |
| 117 | * @param port the port | 128 | * @param port the port |
| 118 | */ | 129 | */ |
| 119 | - public void addPort(Port port) { | 130 | + void addPort(Port port) { |
| 120 | boolean newPort = ports.add(port.number().toLong()); | 131 | boolean newPort = ports.add(port.number().toLong()); |
| 121 | boolean isMaster = context.mastershipService().isLocalMaster(device.id()); | 132 | boolean isMaster = context.mastershipService().isLocalMaster(device.id()); |
| 122 | if (newPort && isMaster) { | 133 | if (newPort && isMaster) { |
| 123 | - log.debug("Sending init probe to port {}@{}", port.number().toLong(), device.id()); | 134 | + log.debug("Sending initial probe to port {}@{}", port.number().toLong(), device.id()); |
| 124 | sendProbes(port.number().toLong()); | 135 | sendProbes(port.number().toLong()); |
| 125 | } | 136 | } |
| 126 | } | 137 | } |
| 127 | 138 | ||
| 128 | /** | 139 | /** |
| 129 | - * Method called by remote port to acknowledge receipt of LLDP sent by | 140 | + * Handles an incoming LLDP packet. Creates link in topology and adds the |
| 130 | - * this port. If slow port, updates label to fast. If fast port, decrements | 141 | + * link for staleness tracking. |
| 131 | - * number of unacknowledged probes. | ||
| 132 | - * | ||
| 133 | - * @param key link key | ||
| 134 | - */ | ||
| 135 | - private void ackProbe(LinkKey key) { | ||
| 136 | - long portNumber = key.src().port().toLong(); | ||
| 137 | - if (ports.contains(portNumber)) { | ||
| 138 | - linkTimes.put(key, System.currentTimeMillis()); | ||
| 139 | - } else { | ||
| 140 | - log.debug("Got ackProbe for non-existing port: {}", portNumber); | ||
| 141 | - } | ||
| 142 | - } | ||
| 143 | - | ||
| 144 | - | ||
| 145 | - /** | ||
| 146 | - * Handles an incoming LLDP packet. Creates link in topology and sends ACK | ||
| 147 | - * to port where LLDP originated. | ||
| 148 | * | 142 | * |
| 149 | * @param packetContext packet context | 143 | * @param packetContext packet context |
| 150 | * @return true if handled | 144 | * @return true if handled |
| 151 | */ | 145 | */ |
| 152 | - public boolean handleLLDP(PacketContext packetContext) { | 146 | + boolean handleLLDP(PacketContext packetContext) { |
| 153 | Ethernet eth = packetContext.inPacket().parsed(); | 147 | Ethernet eth = packetContext.inPacket().parsed(); |
| 154 | if (eth == null) { | 148 | if (eth == null) { |
| 155 | return false; | 149 | return false; |
| ... | @@ -165,14 +159,13 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -165,14 +159,13 @@ public class LinkDiscovery implements TimerTask { |
| 165 | ConnectPoint src = new ConnectPoint(srcDeviceId, srcPort); | 159 | ConnectPoint src = new ConnectPoint(srcDeviceId, srcPort); |
| 166 | ConnectPoint dst = new ConnectPoint(dstDeviceId, dstPort); | 160 | ConnectPoint dst = new ConnectPoint(dstDeviceId, dstPort); |
| 167 | 161 | ||
| 168 | - ackProbe(LinkKey.linkKey(src, dst)); | ||
| 169 | - | ||
| 170 | LinkDescription ld = eth.getEtherType() == Ethernet.TYPE_LLDP ? | 162 | LinkDescription ld = eth.getEtherType() == Ethernet.TYPE_LLDP ? |
| 171 | new DefaultLinkDescription(src, dst, Type.DIRECT) : | 163 | new DefaultLinkDescription(src, dst, Type.DIRECT) : |
| 172 | new DefaultLinkDescription(src, dst, Type.INDIRECT); | 164 | new DefaultLinkDescription(src, dst, Type.INDIRECT); |
| 173 | 165 | ||
| 174 | try { | 166 | try { |
| 175 | context.providerService().linkDetected(ld); | 167 | context.providerService().linkDetected(ld); |
| 168 | + context.touchLink(LinkKey.linkKey(src, dst)); | ||
| 176 | } catch (IllegalStateException e) { | 169 | } catch (IllegalStateException e) { |
| 177 | return true; | 170 | return true; |
| 178 | } | 171 | } |
| ... | @@ -195,52 +188,16 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -195,52 +188,16 @@ public class LinkDiscovery implements TimerTask { |
| 195 | return; | 188 | return; |
| 196 | } | 189 | } |
| 197 | 190 | ||
| 198 | - if (!context.mastershipService().isLocalMaster(device.id())) { | 191 | + if (context.mastershipService().isLocalMaster(device.id())) { |
| 199 | - if (!isStopped()) { | 192 | + log.trace("Sending probes from {}", device.id()); |
| 200 | - timeout = Timer.getTimer().newTimeout(this, context.probeRate(), MILLISECONDS); | 193 | + ports.forEach(this::sendProbes); |
| 201 | - } | ||
| 202 | - return; | ||
| 203 | } | 194 | } |
| 204 | 195 | ||
| 205 | - // Prune stale links | ||
| 206 | - linkTimes.entrySet().stream() | ||
| 207 | - .filter(e -> isStale(e.getKey(), e.getValue())) | ||
| 208 | - .map(Map.Entry::getKey).collect(Collectors.toSet()) | ||
| 209 | - .forEach(this::pruneLink); | ||
| 210 | - | ||
| 211 | - // Probe ports | ||
| 212 | - log.trace("Sending probes from {}", device.id()); | ||
| 213 | - ports.forEach(this::sendProbes); | ||
| 214 | - | ||
| 215 | if (!isStopped()) { | 196 | if (!isStopped()) { |
| 216 | timeout = Timer.getTimer().newTimeout(this, context.probeRate(), MILLISECONDS); | 197 | timeout = Timer.getTimer().newTimeout(this, context.probeRate(), MILLISECONDS); |
| 217 | } | 198 | } |
| 218 | } | 199 | } |
| 219 | 200 | ||
| 220 | - private void pruneLink(LinkKey key) { | ||
| 221 | - linkTimes.remove(key); | ||
| 222 | - LinkDescription desc = new DefaultLinkDescription(key.src(), key.dst(), Type.DIRECT); | ||
| 223 | - context.providerService().linkVanished(desc); | ||
| 224 | - } | ||
| 225 | - | ||
| 226 | - private boolean isStale(LinkKey key, long lastSeen) { | ||
| 227 | - return lastSeen < (System.currentTimeMillis() - context.staleLinkAge()); | ||
| 228 | - } | ||
| 229 | - | ||
| 230 | - public synchronized void stop() { | ||
| 231 | - isStopped = true; | ||
| 232 | - timeout.cancel(); | ||
| 233 | - } | ||
| 234 | - | ||
| 235 | - public synchronized void start() { | ||
| 236 | - if (isStopped) { | ||
| 237 | - isStopped = false; | ||
| 238 | - timeout = Timer.getTimer().newTimeout(this, 0, MILLISECONDS); | ||
| 239 | - } else { | ||
| 240 | - log.warn("LinkDiscovery started multiple times?"); | ||
| 241 | - } | ||
| 242 | - } | ||
| 243 | - | ||
| 244 | /** | 201 | /** |
| 245 | * Creates packet_out LLDP for specified output port. | 202 | * Creates packet_out LLDP for specified output port. |
| 246 | * | 203 | * |
| ... | @@ -285,11 +242,8 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -285,11 +242,8 @@ public class LinkDiscovery implements TimerTask { |
| 285 | } | 242 | } |
| 286 | } | 243 | } |
| 287 | 244 | ||
| 288 | - public synchronized boolean isStopped() { | ||
| 289 | - return isStopped || timeout.isCancelled(); | ||
| 290 | - } | ||
| 291 | - | ||
| 292 | boolean containsPort(long portNumber) { | 245 | boolean containsPort(long portNumber) { |
| 293 | return ports.contains(portNumber); | 246 | return ports.contains(portNumber); |
| 294 | } | 247 | } |
| 248 | + | ||
| 295 | } | 249 | } | ... | ... |
| ... | @@ -48,6 +48,7 @@ import org.onosproject.net.link.LinkDescription; | ... | @@ -48,6 +48,7 @@ import org.onosproject.net.link.LinkDescription; |
| 48 | import org.onosproject.net.link.LinkProvider; | 48 | import org.onosproject.net.link.LinkProvider; |
| 49 | import org.onosproject.net.link.LinkProviderRegistry; | 49 | import org.onosproject.net.link.LinkProviderRegistry; |
| 50 | import org.onosproject.net.link.LinkProviderService; | 50 | import org.onosproject.net.link.LinkProviderService; |
| 51 | +import org.onosproject.net.link.LinkServiceAdapter; | ||
| 51 | import org.onosproject.net.packet.DefaultInboundPacket; | 52 | import org.onosproject.net.packet.DefaultInboundPacket; |
| 52 | import org.onosproject.net.packet.InboundPacket; | 53 | import org.onosproject.net.packet.InboundPacket; |
| 53 | import org.onosproject.net.packet.OutboundPacket; | 54 | import org.onosproject.net.packet.OutboundPacket; |
| ... | @@ -79,7 +80,8 @@ public class LLDPLinkProviderTest { | ... | @@ -79,7 +80,8 @@ public class LLDPLinkProviderTest { |
| 79 | private static Port pd4; | 80 | private static Port pd4; |
| 80 | 81 | ||
| 81 | private final LLDPLinkProvider provider = new LLDPLinkProvider(); | 82 | private final LLDPLinkProvider provider = new LLDPLinkProvider(); |
| 82 | - private final TestLinkRegistry linkService = new TestLinkRegistry(); | 83 | + private final TestLinkRegistry linkRegistry = new TestLinkRegistry(); |
| 84 | + private final TestLinkService linkService = new TestLinkService(); | ||
| 83 | private final TestPacketService packetService = new TestPacketService(); | 85 | private final TestPacketService packetService = new TestPacketService(); |
| 84 | private final TestDeviceService deviceService = new TestDeviceService(); | 86 | private final TestDeviceService deviceService = new TestDeviceService(); |
| 85 | private final TestMasterShipService masterService = new TestMasterShipService(); | 87 | private final TestMasterShipService masterService = new TestMasterShipService(); |
| ... | @@ -104,8 +106,9 @@ public class LLDPLinkProviderTest { | ... | @@ -104,8 +106,9 @@ public class LLDPLinkProviderTest { |
| 104 | provider.coreService = coreService; | 106 | provider.coreService = coreService; |
| 105 | 107 | ||
| 106 | provider.deviceService = deviceService; | 108 | provider.deviceService = deviceService; |
| 109 | + provider.linkService = linkService; | ||
| 107 | provider.packetService = packetService; | 110 | provider.packetService = packetService; |
| 108 | - provider.providerRegistry = linkService; | 111 | + provider.providerRegistry = linkRegistry; |
| 109 | provider.masterService = masterService; | 112 | provider.masterService = masterService; |
| 110 | 113 | ||
| 111 | provider.activate(null); | 114 | provider.activate(null); |
| ... | @@ -498,4 +501,6 @@ public class LLDPLinkProviderTest { | ... | @@ -498,4 +501,6 @@ public class LLDPLinkProviderTest { |
| 498 | } | 501 | } |
| 499 | 502 | ||
| 500 | 503 | ||
| 504 | + private class TestLinkService extends LinkServiceAdapter { | ||
| 505 | + } | ||
| 501 | } | 506 | } | ... | ... |
| ... | @@ -3,5 +3,6 @@ | ... | @@ -3,5 +3,6 @@ |
| 3 | export ONOS_NIC="10.1.10.*" | 3 | export ONOS_NIC="10.1.10.*" |
| 4 | export OC1="10.1.10.223" | 4 | export OC1="10.1.10.223" |
| 5 | 5 | ||
| 6 | +unset ONOS_USE_SSH | ||
| 6 | export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" | 7 | export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" |
| 7 | 8 | ... | ... |
-
Please register or login to post a comment