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