blob: ec4a3ffd67cc14d5f5214b290194e089d3f43743 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.lldp.impl;
alshabib7911a052014-10-16 17:49:37 -070017
Thomas Vachuska6f94ded2015-02-21 14:02:38 -080018import com.google.common.base.Strings;
19import com.google.common.collect.ImmutableMap;
20import com.google.common.collect.ImmutableSet;
alshabib7911a052014-10-16 17:49:37 -070021import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
Yuta HIGUCHI41289382014-12-19 17:47:12 -080024import org.apache.felix.scr.annotations.Modified;
25import org.apache.felix.scr.annotations.Property;
alshabib7911a052014-10-16 17:49:37 -070026import org.apache.felix.scr.annotations.Reference;
27import org.apache.felix.scr.annotations.ReferenceCardinality;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080028import org.onlab.packet.Ethernet;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070029import org.onosproject.cfg.ComponentConfigService;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080030import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.mastership.MastershipEvent;
33import org.onosproject.mastership.MastershipListener;
34import org.onosproject.mastership.MastershipService;
35import org.onosproject.net.ConnectPoint;
36import org.onosproject.net.Device;
37import org.onosproject.net.DeviceId;
38import org.onosproject.net.Port;
39import org.onosproject.net.device.DeviceEvent;
40import org.onosproject.net.device.DeviceListener;
41import org.onosproject.net.device.DeviceService;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080042import org.onosproject.net.flow.DefaultTrafficSelector;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080043import org.onosproject.net.flow.TrafficSelector;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.net.link.LinkProvider;
45import org.onosproject.net.link.LinkProviderRegistry;
46import org.onosproject.net.link.LinkProviderService;
47import org.onosproject.net.packet.PacketContext;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080048import org.onosproject.net.packet.PacketPriority;
Brian O'Connorabafb502014-12-02 22:26:20 -080049import org.onosproject.net.packet.PacketProcessor;
50import org.onosproject.net.packet.PacketService;
51import org.onosproject.net.provider.AbstractProvider;
52import org.onosproject.net.provider.ProviderId;
Yuta HIGUCHI41289382014-12-19 17:47:12 -080053import org.osgi.service.component.ComponentContext;
alshabib7911a052014-10-16 17:49:37 -070054import org.slf4j.Logger;
55
Thomas Vachuska6f94ded2015-02-21 14:02:38 -080056import java.io.IOException;
57import java.util.Dictionary;
58import java.util.EnumSet;
59import java.util.Map;
60import java.util.concurrent.ConcurrentHashMap;
61import java.util.concurrent.ScheduledExecutorService;
62
63import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
64import static java.util.concurrent.TimeUnit.SECONDS;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070065import static org.onlab.util.Tools.get;
Thomas Vachuska6f94ded2015-02-21 14:02:38 -080066import static org.onlab.util.Tools.groupedThreads;
67import static org.slf4j.LoggerFactory.getLogger;
Yuta HIGUCHI41289382014-12-19 17:47:12 -080068
alshabib7911a052014-10-16 17:49:37 -070069/**
70 * Provider which uses an OpenFlow controller to detect network
71 * infrastructure links.
72 */
73@Component(immediate = true)
74public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
75
Thomas Vachuskafc52fec2015-05-18 19:13:56 -070076 private static final String PROVIDER_NAME = "org.onosproject.provider.lldp";
77
Yuta HIGUCHI41289382014-12-19 17:47:12 -080078 private static final String PROP_USE_BDDP = "useBDDP";
Saurav Dasc313c402015-02-27 10:09:47 -080079 private static final String PROP_DISABLE_LD = "disableLinkDiscovery";
Yuta HIGUCHI41289382014-12-19 17:47:12 -080080 private static final String PROP_LLDP_SUPPRESSION = "lldpSuppression";
81
82 private static final String DEFAULT_LLDP_SUPPRESSION_CONFIG = "../config/lldp_suppression.json";
83
alshabib7911a052014-10-16 17:49:37 -070084 private final Logger log = getLogger(getClass());
85
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080086 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 protected CoreService coreService;
88
89 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
alshabib7911a052014-10-16 17:49:37 -070090 protected LinkProviderRegistry providerRegistry;
91
92 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
93 protected DeviceService deviceService;
94
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -080096 protected PacketService packetService;
alshabib7911a052014-10-16 17:49:37 -070097
alshabib875d6262014-10-17 16:19:40 -070098 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
99 protected MastershipService masterService;
100
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected ComponentConfigService cfgService;
103
alshabib7911a052014-10-16 17:49:37 -0700104 private LinkProviderService providerService;
105
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800106 private ScheduledExecutorService executor;
107
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700108 @Property(name = PROP_USE_BDDP, boolValue = true,
109 label = "Use BDDP for link discovery")
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800110 private boolean useBDDP = true;
alshabib7911a052014-10-16 17:49:37 -0700111
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700112 @Property(name = PROP_DISABLE_LD, boolValue = false,
113 label = "Permanently disable link discovery")
114 private boolean disableLinkDiscovery = false;
Saurav Dasc313c402015-02-27 10:09:47 -0800115
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800116 private static final long INIT_DELAY = 5;
117 private static final long DELAY = 5;
alshabib7911a052014-10-16 17:49:37 -0700118
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700119 @Property(name = PROP_LLDP_SUPPRESSION, value = DEFAULT_LLDP_SUPPRESSION_CONFIG,
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800120 label = "Path to LLDP suppression configuration file")
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700121 private String lldpSuppression = DEFAULT_LLDP_SUPPRESSION_CONFIG;
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800122
123
alshabib7911a052014-10-16 17:49:37 -0700124 private final InternalLinkProvider listener = new InternalLinkProvider();
125
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800126 private final InternalRoleListener roleListener = new InternalRoleListener();
127
alshabib7911a052014-10-16 17:49:37 -0700128 protected final Map<DeviceId, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
129
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800130 private SuppressionRules rules;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800131 private ApplicationId appId;
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800132
alshabib7911a052014-10-16 17:49:37 -0700133 /**
134 * Creates an OpenFlow link provider.
135 */
136 public LLDPLinkProvider() {
Thomas Vachuskafc52fec2015-05-18 19:13:56 -0700137 super(new ProviderId("lldp", PROVIDER_NAME));
alshabib7911a052014-10-16 17:49:37 -0700138 }
139
140 @Activate
Saurav Dasc313c402015-02-27 10:09:47 -0800141 public void activate(ComponentContext context) {
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700142 cfgService.registerProperties(getClass());
Thomas Vachuskafc52fec2015-05-18 19:13:56 -0700143 appId = coreService.registerApplication(PROVIDER_NAME);
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800144
Saurav Dasc313c402015-02-27 10:09:47 -0800145 // to load configuration at startup
146 modified(context);
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700147 if (disableLinkDiscovery) {
Saurav Dasc313c402015-02-27 10:09:47 -0800148 log.info("Link Discovery has been permanently disabled by configuration");
149 return;
150 }
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800151
alshabib7911a052014-10-16 17:49:37 -0700152 providerService = providerRegistry.register(this);
153 deviceService.addListener(listener);
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800154 packetService.addProcessor(listener, 0);
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800155 masterService.addListener(roleListener);
156
alshabibdfc7afb2014-10-21 20:13:27 -0700157 LinkDiscovery ld;
alshabib5dc5a342014-12-03 14:11:16 -0800158 for (Device device : deviceService.getAvailableDevices()) {
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800159 if (rules.isSuppressed(device)) {
160 log.debug("LinkDiscovery from {} disabled by configuration", device.id());
161 continue;
162 }
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800163 ld = new LinkDiscovery(device, packetService, masterService,
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700164 providerService, useBDDP);
alshabibdfc7afb2014-10-21 20:13:27 -0700165 discoverers.put(device.id(), ld);
166 for (Port p : deviceService.getPorts(device.id())) {
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800167 if (rules.isSuppressed(p)) {
168 log.debug("LinkDiscovery from {}@{} disabled by configuration",
169 p.number(), device.id());
170 continue;
171 }
Yuta HIGUCHI00b476f2014-10-25 21:33:07 -0700172 if (!p.number().isLogical()) {
173 ld.addPort(p);
174 }
alshabibdfc7afb2014-10-21 20:13:27 -0700175 }
176 }
alshabib7911a052014-10-16 17:49:37 -0700177
Thomas Vachuska6f94ded2015-02-21 14:02:38 -0800178 executor = newSingleThreadScheduledExecutor(groupedThreads("onos/device", "sync-%d"));
179 executor.scheduleAtFixedRate(new SyncDeviceInfoTask(), INIT_DELAY, DELAY, SECONDS);
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800180
Thomas Vachuska27bee092015-06-23 19:03:10 -0700181 requestIntercepts();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800182
alshabib7911a052014-10-16 17:49:37 -0700183 log.info("Started");
184 }
185
186 @Deactivate
187 public void deactivate() {
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700188 cfgService.unregisterProperties(getClass(), false);
189 if (disableLinkDiscovery) {
Saurav Dasc313c402015-02-27 10:09:47 -0800190 return;
191 }
Thomas Vachuska27bee092015-06-23 19:03:10 -0700192
193 withdrawIntercepts();
194
alshabib7911a052014-10-16 17:49:37 -0700195 providerRegistry.unregister(this);
196 deviceService.removeListener(listener);
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800197 packetService.removeProcessor(listener);
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800198 masterService.removeListener(roleListener);
Thomas Vachuskafc52fec2015-05-18 19:13:56 -0700199
200 executor.shutdownNow();
201 discoverers.values().forEach(LinkDiscovery::stop);
202 discoverers.clear();
alshabib7911a052014-10-16 17:49:37 -0700203 providerService = null;
204
205 log.info("Stopped");
206 }
207
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800208 @Modified
209 public void modified(ComponentContext context) {
210 if (context == null) {
Saurav Dasc313c402015-02-27 10:09:47 -0800211 loadSuppressionRules();
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800212 return;
213 }
214 @SuppressWarnings("rawtypes")
215 Dictionary properties = context.getProperties();
216
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700217 String s = get(properties, PROP_DISABLE_LD);
Saurav Dasc313c402015-02-27 10:09:47 -0800218 if (!Strings.isNullOrEmpty(s)) {
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700219 disableLinkDiscovery = Boolean.valueOf(s);
Saurav Dasc313c402015-02-27 10:09:47 -0800220 }
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700221 s = get(properties, PROP_USE_BDDP);
Saurav Dasc313c402015-02-27 10:09:47 -0800222 if (!Strings.isNullOrEmpty(s)) {
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800223 useBDDP = Boolean.valueOf(s);
224 }
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700225 s = get(properties, PROP_LLDP_SUPPRESSION);
Saurav Dasc313c402015-02-27 10:09:47 -0800226 if (!Strings.isNullOrEmpty(s)) {
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700227 lldpSuppression = s;
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800228 }
Thomas Vachuska27bee092015-06-23 19:03:10 -0700229 requestIntercepts();
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800230 loadSuppressionRules();
231 }
232
233 private void loadSuppressionRules() {
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700234 SuppressionRulesStore store = new SuppressionRulesStore(lldpSuppression);
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800235 try {
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700236 log.info("Reading suppression rules from {}", lldpSuppression);
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800237 rules = store.read();
238 } catch (IOException e) {
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700239 log.info("Failed to load {}, using built-in rules", lldpSuppression);
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800240 // default rule to suppress ROADM to maintain compatibility
241 rules = new SuppressionRules(ImmutableSet.of(),
242 EnumSet.of(Device.Type.ROADM),
243 ImmutableMap.of());
244 }
245
246 // should refresh discoverers when we need dynamic reconfiguration
247 }
248
Charles M.C. Chane148de82015-05-06 12:38:21 +0800249 /**
Thomas Vachuska27bee092015-06-23 19:03:10 -0700250 * Request packet intercepts.
Charles M.C. Chane148de82015-05-06 12:38:21 +0800251 */
Thomas Vachuska27bee092015-06-23 19:03:10 -0700252 private void requestIntercepts() {
253 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
254 selector.matchEthType(Ethernet.TYPE_LLDP);
255 packetService.requestPackets(selector.build(), PacketPriority.CONTROL, appId);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800256
Thomas Vachuska27bee092015-06-23 19:03:10 -0700257 selector.matchEthType(Ethernet.TYPE_BSN);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800258 if (useBDDP) {
Thomas Vachuska27bee092015-06-23 19:03:10 -0700259 packetService.requestPackets(selector.build(), PacketPriority.CONTROL, appId);
260 } else {
261 packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId);
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800262 }
263 }
264
Thomas Vachuska27bee092015-06-23 19:03:10 -0700265 /**
266 * Withdraw packet intercepts.
267 */
268 private void withdrawIntercepts() {
269 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
270 selector.matchEthType(Ethernet.TYPE_LLDP);
271 packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId);
272 selector.matchEthType(Ethernet.TYPE_BSN);
273 packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId);
274 }
275
276
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800277 private class InternalRoleListener implements MastershipListener {
278
279 @Override
280 public void event(MastershipEvent event) {
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800281 if (MastershipEvent.Type.BACKUPS_CHANGED.equals(event.type())) {
282 // only need new master events
283 return;
284 }
285
286 DeviceId deviceId = event.subject();
287 Device device = deviceService.getDevice(deviceId);
288 if (device == null) {
Thomas Vachuska3358af22015-05-19 18:40:34 -0700289 log.debug("Device {} doesn't exist, or isn't there yet", deviceId);
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800290 return;
291 }
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800292 if (rules.isSuppressed(device)) {
293 return;
294 }
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800295 synchronized (discoverers) {
296 if (!discoverers.containsKey(deviceId)) {
alshabib4785eec2014-12-04 16:45:45 -0800297 // ideally, should never reach here
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800298 log.debug("Device mastership changed ({}) {}",
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700299 event.type(), deviceId);
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800300 discoverers.put(deviceId, new LinkDiscovery(device,
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700301 packetService, masterService, providerService,
302 useBDDP));
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800303 }
304 }
305 }
306
307 }
alshabib7911a052014-10-16 17:49:37 -0700308
309 private class InternalLinkProvider implements PacketProcessor, DeviceListener {
310
311 @Override
312 public void event(DeviceEvent event) {
313 LinkDiscovery ld = null;
314 Device device = event.subject();
alshabibacd91832014-10-17 14:38:41 -0700315 Port port = event.port();
alshabibdfc7afb2014-10-21 20:13:27 -0700316 if (device == null) {
317 log.error("Device is null.");
318 return;
319 }
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700320 log.trace("{} {} {}", event.type(), event.subject(), event);
Yuta HIGUCHId19f6702014-10-31 15:23:25 -0700321 final DeviceId deviceId = device.id();
alshabib7911a052014-10-16 17:49:37 -0700322 switch (event.type()) {
323 case DEVICE_ADDED:
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700324 case DEVICE_UPDATED:
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800325 synchronized (discoverers) {
326 ld = discoverers.get(deviceId);
327 if (ld == null) {
328 if (rules.isSuppressed(device)) {
329 log.debug("LinkDiscovery from {} disabled by configuration", device.id());
330 return;
331 }
332 log.debug("Device added ({}) {}", event.type(),
333 deviceId);
334 discoverers.put(deviceId, new LinkDiscovery(device,
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700335 packetService, masterService,
336 providerService, useBDDP));
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800337 } else {
338 if (ld.isStopped()) {
339 log.debug("Device restarted ({}) {}", event.type(),
340 deviceId);
341 ld.start();
342 }
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800343 }
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700344 }
alshabib7911a052014-10-16 17:49:37 -0700345 break;
346 case PORT_ADDED:
347 case PORT_UPDATED:
Yuta HIGUCHIf6725882014-10-29 15:25:51 -0700348 if (port.isEnabled()) {
Yuta HIGUCHId19f6702014-10-31 15:23:25 -0700349 ld = discoverers.get(deviceId);
alshabib7911a052014-10-16 17:49:37 -0700350 if (ld == null) {
351 return;
352 }
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800353 if (rules.isSuppressed(port)) {
354 log.debug("LinkDiscovery from {}@{} disabled by configuration",
355 port.number(), device.id());
356 return;
357 }
Yuta HIGUCHI00b476f2014-10-25 21:33:07 -0700358 if (!port.number().isLogical()) {
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700359 log.debug("Port added {}", port);
Yuta HIGUCHI00b476f2014-10-25 21:33:07 -0700360 ld.addPort(port);
361 }
alshabib7911a052014-10-16 17:49:37 -0700362 } else {
Yuta HIGUCHIf6725882014-10-29 15:25:51 -0700363 log.debug("Port down {}", port);
Yuta HIGUCHId19f6702014-10-31 15:23:25 -0700364 ConnectPoint point = new ConnectPoint(deviceId,
alshabibacd91832014-10-17 14:38:41 -0700365 port.number());
alshabib7911a052014-10-16 17:49:37 -0700366 providerService.linksVanished(point);
367 }
368 break;
369 case PORT_REMOVED:
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700370 log.debug("Port removed {}", port);
Yuta HIGUCHId19f6702014-10-31 15:23:25 -0700371 ConnectPoint point = new ConnectPoint(deviceId,
alshabibacd91832014-10-17 14:38:41 -0700372 port.number());
alshabib7911a052014-10-16 17:49:37 -0700373 providerService.linksVanished(point);
alshabib4785eec2014-12-04 16:45:45 -0800374
alshabib7911a052014-10-16 17:49:37 -0700375 break;
376 case DEVICE_REMOVED:
377 case DEVICE_SUSPENDED:
Yuta HIGUCHId19f6702014-10-31 15:23:25 -0700378 log.debug("Device removed {}", deviceId);
379 ld = discoverers.get(deviceId);
alshabib7911a052014-10-16 17:49:37 -0700380 if (ld == null) {
381 return;
382 }
383 ld.stop();
Yuta HIGUCHId19f6702014-10-31 15:23:25 -0700384 providerService.linksVanished(deviceId);
alshabib7911a052014-10-16 17:49:37 -0700385 break;
386 case DEVICE_AVAILABILITY_CHANGED:
Yuta HIGUCHId19f6702014-10-31 15:23:25 -0700387 ld = discoverers.get(deviceId);
alshabib7911a052014-10-16 17:49:37 -0700388 if (ld == null) {
389 return;
390 }
Yuta HIGUCHId19f6702014-10-31 15:23:25 -0700391 if (deviceService.isAvailable(deviceId)) {
392 log.debug("Device up {}", deviceId);
alshabib7911a052014-10-16 17:49:37 -0700393 ld.start();
394 } else {
Yuta HIGUCHId19f6702014-10-31 15:23:25 -0700395 providerService.linksVanished(deviceId);
396 log.debug("Device down {}", deviceId);
alshabib7911a052014-10-16 17:49:37 -0700397 ld.stop();
398 }
399 break;
Jonathan Hart9de692c2015-04-23 11:45:47 -0700400 case PORT_STATS_UPDATED:
401 break;
alshabib7911a052014-10-16 17:49:37 -0700402 default:
403 log.debug("Unknown event {}", event);
404 }
405 }
406
407 @Override
408 public void process(PacketContext context) {
alshabib4a179dc2014-10-17 17:17:01 -0700409 if (context == null) {
410 return;
411 }
alshabib7911a052014-10-16 17:49:37 -0700412 LinkDiscovery ld = discoverers.get(
413 context.inPacket().receivedFrom().deviceId());
414 if (ld == null) {
415 return;
416 }
417
418 if (ld.handleLLDP(context)) {
419 context.block();
420 }
421 }
422 }
423
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800424 private final class SyncDeviceInfoTask implements Runnable {
425
426 @Override
427 public void run() {
428 if (Thread.currentThread().isInterrupted()) {
429 log.info("Interrupted, quitting");
430 return;
431 }
432 // check what deviceService sees, to see if we are missing anything
433 try {
434 LinkDiscovery ld = null;
435 for (Device dev : deviceService.getDevices()) {
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800436 if (rules.isSuppressed(dev)) {
437 continue;
438 }
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800439 DeviceId did = dev.id();
440 synchronized (discoverers) {
441 if (!discoverers.containsKey(did)) {
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800442 ld = new LinkDiscovery(dev, packetService,
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700443 masterService, providerService, useBDDP);
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800444 discoverers.put(did, ld);
445 for (Port p : deviceService.getPorts(did)) {
Yuta HIGUCHI41289382014-12-19 17:47:12 -0800446 if (rules.isSuppressed(p)) {
447 continue;
448 }
Ayaka Koshibeccfa94c2014-11-20 11:15:52 -0800449 if (!p.number().isLogical()) {
450 ld.addPort(p);
451 }
452 }
453 }
454 }
455 }
456 } catch (Exception e) {
457 // catch all Exception to avoid Scheduled task being suppressed.
458 log.error("Exception thrown during synchronization process", e);
459 }
460 }
461 }
462
alshabib7911a052014-10-16 17:49:37 -0700463}