Thomas Vachuska
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
...@@ -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
......