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/LinkDiscoveryFromDevice.java b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LinkDiscoveryFromDevice.java
new file mode 100644
index 0000000..32b12d4
--- /dev/null
+++ b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LinkDiscoveryFromDevice.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.lldp.impl;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.basics.BasicFeatureConfig;
+
+/**
+ * Configuration to see LinkDiscovery should be enabled on Device.
+ */
+public class LinkDiscoveryFromDevice extends BasicFeatureConfig<DeviceId> {
+
+ public LinkDiscoveryFromDevice() {
+ // default: enabled
+ super(true);
+ }
+
+}
diff --git a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LinkDiscoveryFromPort.java b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LinkDiscoveryFromPort.java
new file mode 100644
index 0000000..b9a502f
--- /dev/null
+++ b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LinkDiscoveryFromPort.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.lldp.impl;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.basics.BasicFeatureConfig;
+
+/**
+ * Configuration to see LinkDiscovery should be enabled on a Port.
+ */
+public class LinkDiscoveryFromPort extends BasicFeatureConfig<ConnectPoint> {
+
+ public LinkDiscoveryFromPort() {
+ // default: enabled
+ super(true);
+ }
+
+}
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);
diff --git a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionConfig.java b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionConfig.java
index 20bafb3..5b10f6d 100644
--- a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionConfig.java
+++ b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionConfig.java
@@ -26,7 +26,6 @@
import org.onosproject.core.ApplicationId;
import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
import org.onosproject.net.config.Config;
import org.slf4j.Logger;
@@ -39,44 +38,22 @@
import static org.slf4j.LoggerFactory.getLogger;
/**
- * LLDP suppression config class.
+ * LinkDiscovery suppression config class.
*/
public class SuppressionConfig extends Config<ApplicationId> {
- private static final String DEVICE_IDS = "deviceIds";
+
private static final String DEVICE_TYPES = "deviceTypes";
private static final String ANNOTATION = "annotation";
private static final ObjectMapper MAPPER = new ObjectMapper();
- private static final List<DeviceId> DEFAULT_DEVICE_IDS
- = ImmutableList.copyOf(DEFAULT_RULES.getSuppressedDevice());
+
private static final List<Device.Type> DEFAULT_DEVICE_TYPES
= ImmutableList.copyOf(DEFAULT_RULES.getSuppressedDeviceType());
private final Logger log = getLogger(getClass());
/**
- * Returns device IDs on which LLDP is suppressed.
- *
- * @return Set of DeviceId objects
- */
- @Deprecated
- public Set<DeviceId> deviceIds() {
- return ImmutableSet.copyOf(getList(DEVICE_IDS, DeviceId::deviceId, DEFAULT_DEVICE_IDS));
- }
-
- /**
- * Sets device IDs on which LLDP is suppressed.
- *
- * @param deviceIds new set of device IDs; null to clear
- * @return self
- */
- @Deprecated
- public SuppressionConfig deviceIds(Set<DeviceId> deviceIds) {
- return (SuppressionConfig) setOrClear(DEVICE_IDS, deviceIds);
- }
-
- /**
- * Returns types of devices on which LLDP is suppressed.
+ * Returns types of devices on which LinkDiscovery is suppressed.
*
* @return set of device types
*/
@@ -85,7 +62,7 @@
}
/**
- * Sets types of devices on which LLDP is suppressed.
+ * Sets types of devices on which LinkDiscovery is suppressed.
*
* @param deviceTypes new set of device types; null to clear
* @return self
@@ -95,7 +72,7 @@
}
/**
- * Returns annotation of Ports on which LLDP is suppressed.
+ * Returns annotation of Ports on which LinkDiscovery is suppressed.
*
* @return key-value pairs of annotation
*/
@@ -142,7 +119,7 @@
}
/**
- * Sets annotation of Ports on which LLDP is suppressed.
+ * Sets annotation of Ports on which LinkDiscovery is suppressed.
*
* @param annotation new key-value pair of annotation; null to clear
* @return self
diff --git a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionRules.java b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionRules.java
index 9cda07c..14bc220 100644
--- a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionRules.java
+++ b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionRules.java
@@ -23,7 +23,6 @@
import org.onosproject.net.Annotations;
import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
import org.onosproject.net.Element;
import org.onosproject.net.Port;
@@ -35,23 +34,17 @@
public static final String ANY_VALUE = "(any)";
- private final Set<DeviceId> suppressedDevice;
private final Set<Device.Type> suppressedDeviceType;
private final Map<String, String> suppressedAnnotation;
- public SuppressionRules(Set<DeviceId> suppressedDevice,
- Set<Device.Type> suppressedType,
- Map<String, String> suppressedAnnotation) {
+ public SuppressionRules(Set<Device.Type> suppressedType,
+ Map<String, String> suppressedAnnotation) {
- this.suppressedDevice = ImmutableSet.copyOf(suppressedDevice);
this.suppressedDeviceType = ImmutableSet.copyOf(suppressedType);
this.suppressedAnnotation = ImmutableMap.copyOf(suppressedAnnotation);
}
public boolean isSuppressed(Device device) {
- if (suppressedDevice.contains(device.id())) {
- return true;
- }
if (suppressedDeviceType.contains(device.type())) {
return true;
}
@@ -94,10 +87,6 @@
return false;
}
- Set<DeviceId> getSuppressedDevice() {
- return suppressedDevice;
- }
-
Set<Device.Type> getSuppressedDeviceType() {
return suppressedDeviceType;
}
@@ -108,8 +97,7 @@
@Override
public int hashCode() {
- return Objects.hash(suppressedDevice,
- suppressedDeviceType,
+ return Objects.hash(suppressedDeviceType,
suppressedAnnotation);
}
@@ -117,9 +105,7 @@
public boolean equals(Object object) {
if (object != null && getClass() == object.getClass()) {
SuppressionRules that = (SuppressionRules) object;
- return Objects.equals(this.suppressedDevice,
- that.suppressedDevice)
- && Objects.equals(this.suppressedDeviceType,
+ return Objects.equals(this.suppressedDeviceType,
that.suppressedDeviceType)
&& Objects.equals(this.suppressedAnnotation,
that.suppressedAnnotation);
@@ -130,7 +116,6 @@
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
- .add("suppressedDevice", suppressedDevice)
.add("suppressedDeviceType", suppressedDeviceType)
.add("suppressedAnnotation", suppressedAnnotation)
.toString();