aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of')
-rw-r--r--framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java227
-rw-r--r--framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceValueMapper.java73
2 files changed, 251 insertions, 49 deletions
diff --git a/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java b/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
index cb19dc52..4fa961f8 100644
--- a/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
+++ b/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
@@ -15,10 +15,24 @@
*/
package org.onosproject.provider.of.device.impl;
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.onlab.util.Tools.get;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.Port.Type.COPPER;
+import static org.onosproject.net.Port.Type.FIBER;
+import static org.onosproject.openflow.controller.Dpid.dpid;
+import static org.onosproject.openflow.controller.Dpid.uri;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -28,15 +42,17 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.ChassisId;
import org.onlab.util.Frequency;
-import org.onosproject.cfg.ComponentConfigService;
import org.onlab.util.Spectrum;
+import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.GridType;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.OchSignal;
+import org.onosproject.net.OduCltPort;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
@@ -49,6 +65,7 @@ import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.OchPortDescription;
+import org.onosproject.net.device.OduCltPortDescription;
import org.onosproject.net.device.OmsPortDescription;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
@@ -64,13 +81,19 @@ import org.onosproject.openflow.controller.PortDescPropertyType;
import org.onosproject.openflow.controller.RoleState;
import org.osgi.service.component.ComponentContext;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescStatsEntry;
+import org.projectfloodlight.openflow.protocol.OFExpPort;
+import org.projectfloodlight.openflow.protocol.OFExpPortDescPropOpticalTransport;
+import org.projectfloodlight.openflow.protocol.OFExpPortOpticalTransportLayerEntry;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFObject;
import org.projectfloodlight.openflow.protocol.OFPortConfig;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescPropOpticalTransport;
import org.projectfloodlight.openflow.protocol.OFPortFeatures;
import org.projectfloodlight.openflow.protocol.OFPortOptical;
+import org.projectfloodlight.openflow.protocol.OFPortOpticalTransportLayerClass;
+import org.projectfloodlight.openflow.protocol.OFPortOpticalTransportSignalType;
import org.projectfloodlight.openflow.protocol.OFPortReason;
import org.projectfloodlight.openflow.protocol.OFPortState;
import org.projectfloodlight.openflow.protocol.OFPortStatsEntry;
@@ -83,23 +106,10 @@ import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.types.PortSpeed;
import org.slf4j.Logger;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static org.onlab.util.Tools.get;
-import static org.onosproject.net.DeviceId.deviceId;
-import static org.onosproject.net.Port.Type.COPPER;
-import static org.onosproject.net.Port.Type.FIBER;
-import static org.onosproject.openflow.controller.Dpid.dpid;
-import static org.onosproject.openflow.controller.Dpid.uri;
-import static org.slf4j.LoggerFactory.getLogger;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
/**
* Provider which uses an OpenFlow controller to detect network
@@ -109,7 +119,11 @@ import static org.slf4j.LoggerFactory.getLogger;
public class OpenFlowDeviceProvider extends AbstractProvider implements DeviceProvider {
private static final Logger LOG = getLogger(OpenFlowDeviceProvider.class);
+
private static final long MBPS = 1_000 * 1_000;
+ private static final Frequency FREQ100 = Frequency.ofGHz(100);
+ private static final Frequency FREQ193_1 = Frequency.ofTHz(193.1);
+ private static final Frequency FREQ4_4 = Frequency.ofTHz(4.4);
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceProviderRegistry providerRegistry;
@@ -145,27 +159,16 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
providerService = providerRegistry.register(this);
controller.addListener(listener);
controller.addEventListener(listener);
- for (OpenFlowSwitch sw : controller.getSwitches()) {
- try {
- listener.switchAdded(new Dpid(sw.getId()));
- } catch (Exception e) {
- LOG.warn("Failed initially adding {} : {}", sw.getStringId(), e.getMessage());
- LOG.debug("Error details:", e);
- // disconnect to trigger switch-add later
- sw.disconnectSwitch();
- }
- PortStatsCollector psc = new PortStatsCollector(sw, portStatsPollFrequency);
- psc.start();
- collectors.put(new Dpid(sw.getId()), psc);
- }
+ connectInitialDevices();
LOG.info("Started");
}
@Deactivate
public void deactivate(ComponentContext context) {
cfgService.unregisterProperties(getClass(), false);
- providerRegistry.unregister(this);
controller.removeListener(listener);
+ disconnectDevices();
+ providerRegistry.unregister(this);
collectors.values().forEach(PortStatsCollector::stop);
providerService = null;
LOG.info("Stopped");
@@ -191,13 +194,31 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
LOG.info("Settings: portStatsPollFrequency={}", portStatsPollFrequency);
}
+ private void connectInitialDevices() {
+ for (OpenFlowSwitch sw : controller.getSwitches()) {
+ try {
+ listener.switchAdded(new Dpid(sw.getId()));
+ } catch (Exception e) {
+ LOG.warn("Failed initially adding {} : {}", sw.getStringId(), e.getMessage());
+ LOG.debug("Error details:", e);
+ // disconnect to trigger switch-add later
+ sw.disconnectSwitch();
+ }
+ PortStatsCollector psc = new PortStatsCollector(sw, portStatsPollFrequency);
+ psc.start();
+ collectors.put(new Dpid(sw.getId()), psc);
+ }
+ }
+
+ private void disconnectDevices() {
+ // Only disconnect the devices for which we are currently master.
+ controller.getMasterSwitches().forEach(sw -> listener.switchRemoved(new Dpid(sw.getId())));
+ }
+
@Override
public boolean isReachable(DeviceId deviceId) {
OpenFlowSwitch sw = controller.getSwitch(dpid(deviceId.uri()));
- if (sw == null || !sw.isConnected()) {
- return false;
- }
- return true;
+ return sw != null && sw.isConnected();
}
@Override
@@ -302,8 +323,9 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
ChassisId cId = new ChassisId(dpid.value());
SparseAnnotations annotations = DefaultAnnotations.builder()
- .set("protocol", sw.factory().getVersion().toString())
- .set("channelId", sw.channelId())
+ .set(AnnotationKeys.PROTOCOL, sw.factory().getVersion().toString())
+ .set(AnnotationKeys.CHANNEL_ID, sw.channelId())
+ .set(AnnotationKeys.MANAGEMENT_ADDRESS, sw.channelId().split(":")[0])
.build();
DeviceDescription description =
@@ -386,18 +408,27 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
*/
private List<PortDescription> buildPortDescriptions(OpenFlowSwitch sw) {
final List<PortDescription> portDescs = new ArrayList<>(sw.getPorts().size());
- sw.getPorts().forEach(port -> portDescs.add(buildPortDescription(port)));
+ if (!(Device.Type.ROADM.equals(sw.deviceType()))) {
+ sw.getPorts().forEach(port -> portDescs.add(buildPortDescription(port)));
+ }
OpenFlowOpticalSwitch opsw;
switch (sw.deviceType()) {
case ROADM:
opsw = (OpenFlowOpticalSwitch) sw;
+ List<OFPortDesc> ports = opsw.getPorts();
+ LOG.debug("SW ID {} , ETH- ODU CLT Ports {}", opsw.getId(), ports);
+ // ODU client ports are reported as ETH
+ ports.forEach(port -> portDescs.add(buildOduCltPortDescription(port)));
+
opsw.getPortTypes().forEach(type -> {
- opsw.getPortsOf(type).forEach(
- op -> {
- portDescs.add(buildPortDescription(type, (OFPortOptical) op));
- }
- );
+ List<? extends OFObject> portsOf = opsw.getPortsOf(type);
+ LOG.debug("Ports Of{}", portsOf);
+ portsOf.forEach(
+ op -> {
+ portDescs.add(buildPortDescription(type, (OFObject) op));
+ }
+ );
});
break;
case FIBER_SWITCH:
@@ -417,6 +448,105 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
return portDescs;
}
+ private PortDescription buildOduCltPortDescription(OFPortDesc port) {
+ PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
+ boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN) &&
+ !port.getConfig().contains(OFPortConfig.PORT_DOWN);
+ Long portSpeed = portSpeed(port);
+ OduCltPort.SignalType sigType = null;
+
+ switch (portSpeed.toString()) {
+ case "1":
+ sigType = OduCltPort.SignalType.CLT_1GBE;
+ break;
+ case "10":
+ sigType = OduCltPort.SignalType.CLT_10GBE;
+ break;
+ case "40":
+ sigType = OduCltPort.SignalType.CLT_40GBE;
+ break;
+ case "100":
+ sigType = OduCltPort.SignalType.CLT_100GBE;
+ break;
+ default:
+ throw new RuntimeException("Un recognize OduClt speed: " + portSpeed.toString());
+ }
+
+ SparseAnnotations annotations = buildOduCltAnnotation(port);
+ return new OduCltPortDescription(portNo, enabled, sigType, annotations);
+ }
+
+ private SparseAnnotations buildOduCltAnnotation(OFPortDesc port) {
+ SparseAnnotations annotations = null;
+ String portName = Strings.emptyToNull(port.getName());
+ if (portName != null) {
+ annotations = DefaultAnnotations.builder()
+ .set(AnnotationKeys.PORT_NAME, portName)
+ .set(AnnotationKeys.STATIC_PORT, Boolean.TRUE.toString()).build();
+ }
+ return annotations;
+ }
+
+ private PortDescription buildPortDescription(PortDescPropertyType ptype, OFObject port) {
+ if (port instanceof OFPortOptical) {
+ return buildPortDescription(ptype, (OFPortOptical) port);
+ }
+ return buildPortDescription(ptype, (OFExpPort) port);
+ }
+
+ /**
+ * Build a portDescription from a given a port description describing some
+ * Optical port.
+ *
+ * @param ptype description property type.
+ * @param port the port to build from.
+ * @return portDescription for the port.
+ */
+ private PortDescription buildPortDescription(PortDescPropertyType ptype, OFExpPort port) {
+ PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
+ boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN)
+ && !port.getConfig().contains(OFPortConfig.PORT_DOWN);
+ SparseAnnotations annotations = makePortNameAnnotation(port.getName());
+
+ OFExpPortDescPropOpticalTransport firstProp = port.getProperties().get(0);
+ OFPortOpticalTransportSignalType sigType = firstProp.getPortSignalType();
+
+ DefaultPortDescription portDes = null;
+ switch (sigType) {
+ case OMSN:
+ portDes = new OmsPortDescription(portNo, enabled, FREQ193_1, FREQ193_1.add(FREQ4_4),
+ FREQ100, annotations);
+ break;
+ case OCH:
+ OFExpPortOpticalTransportLayerEntry entry = firstProp.getFeatures().get(0).getValue().get(0);
+ OFPortOpticalTransportLayerClass layerClass = entry.getLayerClass();
+ if (!OFPortOpticalTransportLayerClass.ODU.equals(layerClass)) {
+ LOG.error("Unsupported layer Class {} ", layerClass);
+ return null;
+ }
+
+ // convert to ONOS OduSignalType
+ OduSignalType oduSignalType = OpenFlowDeviceValueMapper.
+ lookupOduSignalType((byte) entry.getSignalType());
+ //OchSignal is needed for OchPortDescription constructor,
+ //yet not relevant for tunable OCH port, creating with default parameters
+ OchSignal signalId = new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 1, 1);
+
+ portDes = new OchPortDescription(portNo, enabled,
+ oduSignalType, true, signalId, annotations);
+
+ break;
+ case OTU2:
+ case OTU4:
+ LOG.error("Signal tpye OTU2/4 not supported yet ", port.toString());
+ break;
+ default:
+ break;
+ }
+
+ return portDes;
+ }
+
/**
* Creates an annotation for the port name if one is available.
*
@@ -565,5 +695,4 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
}
}
}
-
}
diff --git a/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceValueMapper.java b/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceValueMapper.java
new file mode 100644
index 00000000..7bdf06fd
--- /dev/null
+++ b/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceValueMapper.java
@@ -0,0 +1,73 @@
+/*
+ * 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.of.device.impl;
+
+import org.onosproject.net.OduSignalType;
+
+import com.google.common.collect.BiMap;
+import com.google.common.collect.EnumHashBiMap;
+
+/**
+ * Collection of helper methods to convert protocol agnostic models to values used in OpenFlow spec.
+ */
+final class OpenFlowDeviceValueMapper {
+
+ // prohibit instantiation
+ private OpenFlowDeviceValueMapper() {}
+
+ private static final BiMap<OduSignalType, Byte> ODU_SIGNAL_TYPES = EnumHashBiMap.create(OduSignalType.class);
+ static {
+ // See ONF "Optical Transport Protocol Extensions Version 1.0" for the following values
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU1, (byte) 1); // OFPODUT_ODU1 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU2, (byte) 2); // OFPODUT_ODU2 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU3, (byte) 3); // OFPODUT_ODU3 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU4, (byte) 4); // OFPODUT_ODU4 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU0, (byte) 10); // OFPODUT_ODU0 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU2e, (byte) 11); // OFPODUT_ODU2E of enum ofp_odu_signal_type
+ }
+
+ /**
+ * Looks up the specified input value to the corresponding value with the specified map.
+ *
+ * @param map bidirectional mapping
+ * @param input input value
+ * @param cls class of output value
+ * @param <I> type of input value
+ * @param <O> type of output value
+ * @return the corresponding value stored in the specified map
+ */
+ private static <I, O> O lookup(BiMap<I, O> map, I input, Class<O> cls) {
+ if (!map.containsKey(input)) {
+ throw new RuntimeException(
+ String.format("No mapping found for %s when converting to %s", input, cls.getName()));
+ }
+
+ return map.get(input);
+ }
+
+ /**
+ * Looks up the the corresponding {@link OduSignalType} instance
+ * from the specified byte value for ODU signal type defined in
+ * ONF "Optical Transport Protocol Extensions Version 1.0".
+ *
+ * @param signalType byte value as ODU (Optical channel Data Unit) signal type defined the spec
+ * @return the corresponding OchSignalType instance
+ */
+ static OduSignalType lookupOduSignalType(byte signalType) {
+ return lookup(ODU_SIGNAL_TYPES.inverse(), signalType, OduSignalType.class);
+ }
+
+}