ONOS-3461 Disable LinkDiscovery on specific device/port.
- Configuration moved from "apps" -> "devices", "ports"
in network configuration tree
Change-Id: I030bab489939ce5326a6ebea14f246726ca024f0
diff --git a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
index 1b16e51..94abeba 100644
--- a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
+++ b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
@@ -15,9 +15,28 @@
*/
package org.onosproject.provider.lldp.impl;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.onlab.packet.Ethernet.TYPE_BSN;
+import static org.onlab.packet.Ethernet.TYPE_LLDP;
+import static org.onlab.util.Tools.get;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.Link.Type.DIRECT;
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
+import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
+import static org.onosproject.net.config.basics.SubjectFactories.DEVICE_SUBJECT_FACTORY;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledExecutorService;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -61,25 +80,9 @@
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
-import java.util.Dictionary;
-import java.util.EnumSet;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledExecutorService;
-
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.onlab.packet.Ethernet.TYPE_BSN;
-import static org.onlab.packet.Ethernet.TYPE_LLDP;
-import static org.onlab.util.Tools.get;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.Link.Type.DIRECT;
-import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
-import static org.slf4j.LoggerFactory.getLogger;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
/**
* Provider which uses LLDP and BDDP packets to detect network infrastructure links.
@@ -170,15 +173,15 @@
private ApplicationId appId;
static final SuppressionRules DEFAULT_RULES
- = new SuppressionRules(ImmutableSet.of(),
- EnumSet.of(Device.Type.ROADM),
+ = new SuppressionRules(EnumSet.of(Device.Type.ROADM),
ImmutableMap.of(NO_LLDP, SuppressionRules.ANY_VALUE));
private SuppressionRules rules = LldpLinkProvider.DEFAULT_RULES;
public static final String CONFIG_KEY = "suppression";
+ public static final String FEATURE_NAME = "linkDiscovery";
- private final Set<ConfigFactory> factories = ImmutableSet.of(
+ private final Set<ConfigFactory<?, ?>> factories = ImmutableSet.of(
new ConfigFactory<ApplicationId, SuppressionConfig>(APP_SUBJECT_FACTORY,
SuppressionConfig.class,
CONFIG_KEY) {
@@ -186,6 +189,20 @@
public SuppressionConfig createConfig() {
return new SuppressionConfig();
}
+ },
+ new ConfigFactory<DeviceId, LinkDiscoveryFromDevice>(DEVICE_SUBJECT_FACTORY,
+ LinkDiscoveryFromDevice.class, FEATURE_NAME) {
+ @Override
+ public LinkDiscoveryFromDevice createConfig() {
+ return new LinkDiscoveryFromDevice();
+ }
+ },
+ new ConfigFactory<ConnectPoint, LinkDiscoveryFromPort>(CONNECT_POINT_SUBJECT_FACTORY,
+ LinkDiscoveryFromPort.class, FEATURE_NAME) {
+ @Override
+ public LinkDiscoveryFromPort createConfig() {
+ return new LinkDiscoveryFromPort();
+ }
}
);
@@ -211,8 +228,7 @@
if (cfg == null) {
// If no configuration is found, register default.
cfg = cfgRegistry.addConfig(appId, SuppressionConfig.class);
- cfg.deviceIds(DEFAULT_RULES.getSuppressedDevice())
- .deviceTypes(DEFAULT_RULES.getSuppressedDeviceType())
+ cfg.deviceTypes(DEFAULT_RULES.getSuppressedDeviceType())
.annotation(DEFAULT_RULES.getSuppressedAnnotation())
.apply();
}
@@ -333,6 +349,30 @@
.ifPresent(ld -> updatePorts(ld, d.id())));
}
+ private boolean isBlacklisted(DeviceId did) {
+ LinkDiscoveryFromDevice cfg = cfgRegistry.getConfig(did, LinkDiscoveryFromDevice.class);
+ if (cfg == null) {
+ return false;
+ }
+ return !cfg.enabled();
+ }
+
+ private boolean isBlacklisted(ConnectPoint cp) {
+ // if parent device is blacklisted, so is the port
+ if (isBlacklisted(cp.deviceId())) {
+ return true;
+ }
+ LinkDiscoveryFromPort cfg = cfgRegistry.getConfig(cp, LinkDiscoveryFromPort.class);
+ if (cfg == null) {
+ return false;
+ }
+ return !cfg.enabled();
+ }
+
+ private boolean isBlacklisted(Port port) {
+ return isBlacklisted(new ConnectPoint(port.element().id(), port.number()));
+ }
+
/**
* Updates discovery helper for specified device.
*
@@ -343,7 +383,10 @@
* @return discovery helper if discovery is enabled for the device
*/
private Optional<LinkDiscovery> updateDevice(Device device) {
- if (rules.isSuppressed(device)) {
+ if (device == null) {
+ return Optional.empty();
+ }
+ if (rules.isSuppressed(device) || isBlacklisted(device.id())) {
log.trace("LinkDiscovery from {} disabled by configuration", device.id());
removeDevice(device.id());
return Optional.empty();
@@ -382,12 +425,15 @@
* or calls {@link #removePort(Port)} otherwise.
*/
private void updatePort(LinkDiscovery discoverer, Port port) {
+ if (port == null) {
+ return;
+ }
if (port.number().isLogical()) {
// silently ignore logical ports
return;
}
- if (rules.isSuppressed(port)) {
+ if (rules.isSuppressed(port) || isBlacklisted(port)) {
log.trace("LinkDiscovery from {} disabled by configuration", port);
removePort(port);
return;
@@ -659,6 +705,11 @@
}
}
+ static final EnumSet<NetworkConfigEvent.Type> CONFIG_CHANGED
+ = EnumSet.of(NetworkConfigEvent.Type.CONFIG_ADDED,
+ NetworkConfigEvent.Type.CONFIG_UPDATED,
+ NetworkConfigEvent.Type.CONFIG_REMOVED);
+
private class InternalConfigListener implements NetworkConfigListener {
private synchronized void reconfigureSuppressionRules(SuppressionConfig cfg) {
@@ -667,8 +718,7 @@
return;
}
- SuppressionRules newRules = new SuppressionRules(cfg.deviceIds(),
- cfg.deviceTypes(),
+ SuppressionRules newRules = new SuppressionRules(cfg.deviceTypes(),
cfg.annotation());
updateRules(newRules);
@@ -676,7 +726,29 @@
@Override
public void event(NetworkConfigEvent event) {
- if (event.configClass().equals(SuppressionConfig.class) &&
+ if (event.configClass() == LinkDiscoveryFromDevice.class &&
+ CONFIG_CHANGED.contains(event.type())) {
+
+ if (event.subject() instanceof DeviceId) {
+ final DeviceId did = (DeviceId) event.subject();
+ Device device = deviceService.getDevice(did);
+ updateDevice(device).ifPresent(ld -> updatePorts(ld, did));
+ }
+
+ } else if (event.configClass() == LinkDiscoveryFromPort.class &&
+ CONFIG_CHANGED.contains(event.type())) {
+
+ if (event.subject() instanceof ConnectPoint) {
+ ConnectPoint cp = (ConnectPoint) event.subject();
+ if (cp.elementId() instanceof DeviceId) {
+ final DeviceId did = (DeviceId) cp.elementId();
+ Device device = deviceService.getDevice(did);
+ Port port = deviceService.getPort(did, cp.port());
+ updateDevice(device).ifPresent(ld -> updatePort(ld, port));
+ }
+ }
+
+ } else if (event.configClass().equals(SuppressionConfig.class) &&
(event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) {
SuppressionConfig cfg = cfgRegistry.getConfig(appId, SuppressionConfig.class);