LINC driver and OF device provider report correct optical port types
Change-Id: I501ce5f6f53136254024ad7122a4fec0d17504e0
diff --git a/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitchImplLINC13.java b/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitchImplLINC13.java
index 1e270b0..7faee37 100644
--- a/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitchImplLINC13.java
+++ b/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitchImplLINC13.java
@@ -16,6 +16,7 @@
package org.onosproject.driver.handshaker;
import org.onosproject.net.Device;
+import com.google.common.collect.ImmutableSet;
import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
import org.onosproject.openflow.controller.PortDescPropertyType;
import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
@@ -28,19 +29,29 @@
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFObject;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortDescPropOpticalTransport;
+import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFPortOptical;
import org.projectfloodlight.openflow.protocol.OFStatsReply;
import org.projectfloodlight.openflow.protocol.OFStatsType;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
+import org.projectfloodlight.openflow.types.OFPort;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* LINC-OE Optical Emulator switch class.
+ *
+ * The LINC ROADM emulator exposes two types of ports: OCh ports connect to ports in the packet layer,
+ * while OMS ports connect to an OMS port on a neighbouring ROADM.
+ *
+ * LINC sends the tap ports (OCh for our purposes) in the regular port desc stats reply,
+ * while it sends *all* ports (both tap and WDM ports, i.e., OCh and OMS) in the experimenter port desc stats reply.
+ *
*/
public class OFOpticalSwitchImplLINC13
extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {
@@ -48,7 +59,7 @@
private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
private long barrierXidToWaitFor = -1;
- private OFCircuitPortsReply wPorts;
+ private List<OFPortOptical> opticalPorts;
@Override
public void startDriverHandshake() {
@@ -109,7 +120,7 @@
OFStatsReply stats = (OFStatsReply) m;
if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
log.warn("LINC-OE : Received stats reply message {}", m);
- wPorts = (OFCircuitPortsReply) m;
+ createOpticalPortList((OFCircuitPortsReply) m);
driverHandshakeComplete.set(true);
}
break;
@@ -124,7 +135,6 @@
public void processOFPortStatus(OFCircuitPortStatus ps) {
log.debug("LINC-OE ..OF Port Status :", ps);
-
}
private void sendHandshakeOFExperimenterPortDescRequest() throws
@@ -147,7 +157,7 @@
* @return List of ports
*/
public List<OFPortDesc> getPorts() {
- return ImmutableList.copyOf(super.getPorts());
+ return Collections.EMPTY_LIST;
}
@@ -161,9 +171,87 @@
return Device.Type.ROADM;
}
+ /**
+ * Checks if given port is also part of the regular port desc stats, i.e., is the port a tap port.
+ *
+ * @param port given OF port
+ * @return true if the port is a tap (OCh), false otherwise (OMS port)
+ */
+ private boolean hasPort(OFPort port) {
+ for (OFPortDescStatsReply reply : this.ports) {
+ for (OFPortDesc p : reply.getEntries()) {
+ if (p.getPortNo().equals(port)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Creates an OpenFlow optical port based on the given port and transport type.
+ *
+ * @param port OpenFlow optical port
+ * @param type transport type
+ * @return OpenFlow optical port
+ */
+ private OFPortOptical createOpticalPort(OFPortOptical port, short type) {
+ List<OFPortDescPropOpticalTransport> descList = new ArrayList<>(port.getDesc().size());
+
+ for (OFPortDescPropOpticalTransport desc : port.getDesc()) {
+ OFPortDescPropOpticalTransport newDesc = desc.createBuilder()
+ .setType(desc.getType())
+ .setPortSignalType(type)
+ .setPortType(desc.getPortType())
+ .setReserved(desc.getReserved())
+ .build();
+ descList.add(newDesc);
+ }
+
+ OFPortOptical newPort = port.createBuilder()
+ .setConfig(port.getConfig())
+ .setDesc(descList)
+ .setHwAddr(port.getHwAddr())
+ .setName(port.getName())
+ .setPortNo(port.getPortNo())
+ .setState(port.getState())
+ .build();
+
+ return newPort;
+ }
+
+ /**
+ * Builds list of OFPortOptical ports based on the multi-part circuit ports reply.
+ *
+ * Ensure the optical transport port's signal type is configured correctly.
+ *
+ * @param wPorts OF reply with circuit ports
+ */
+ private void createOpticalPortList(OFCircuitPortsReply wPorts) {
+ opticalPorts = new ArrayList<>(wPorts.getEntries().size());
+
+ for (OFPortOptical p : wPorts.getEntries()) {
+ short signalType;
+
+ // FIXME: use constants once loxi has full optical extensions
+ if (hasPort(p.getPortNo())) {
+ signalType = 5; // OCH port
+ } else {
+ signalType = 2; // OMS port
+ }
+
+ opticalPorts.add(createOpticalPort(p, signalType));
+ }
+ }
+
@Override
public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
- return ImmutableList.copyOf(wPorts.getEntries());
+ if (!type.equals(PortDescPropertyType.OPTICAL_TRANSPORT)) {
+ return Collections.EMPTY_LIST;
+ }
+
+ return opticalPorts;
}
@Override
diff --git a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
index 9177e70..cb19dc5 100644
--- a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
+++ b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
@@ -19,7 +19,6 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -28,13 +27,17 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.ChassisId;
-import org.onosproject.cfg.ComponentConfigService;
import org.onlab.util.Frequency;
+import org.onosproject.cfg.ComponentConfigService;
import org.onlab.util.Spectrum;
import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.GridType;
import org.onosproject.net.MastershipRole;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.OduSignalType;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
@@ -45,6 +48,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.OmsPortDescription;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
@@ -64,6 +68,7 @@
import org.projectfloodlight.openflow.protocol.OFMessage;
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.OFPortReason;
@@ -86,6 +91,7 @@
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;
@@ -454,6 +460,8 @@
* @return portDescription for the port.
*/
private PortDescription buildPortDescription(PortDescPropertyType ptype, OFPortOptical port) {
+ checkArgument(port.getDesc().size() >= 1);
+
// Minimally functional fixture. This needs to be fixed as we add better support.
PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
@@ -469,6 +477,23 @@
// removable once 1.4+ support complete.
LOG.debug("Unsupported optical port properties");
}
+
+ OFPortDescPropOpticalTransport desc = port.getDesc().get(0);
+ switch (desc.getPortSignalType()) {
+ // FIXME: use constants once loxi has full optical extensions
+ case 2: // OMS port
+ // Assume complete optical spectrum and 50 GHz grid
+ // LINC-OE is only supported optical OF device for now
+ return new OmsPortDescription(portNo, enabled,
+ Spectrum.U_BAND_MIN, Spectrum.O_BAND_MAX, Frequency.ofGHz(50), annotations);
+ case 5: // OCH port
+ OchSignal signal = new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 0, 4);
+ return new OchPortDescription(portNo, enabled, OduSignalType.ODU4,
+ true, signal, annotations);
+ default:
+ break;
+ }
+
return new DefaultPortDescription(portNo, enabled, FIBER, 0, annotations);
}
@@ -486,12 +511,10 @@
boolean enabled = true;
SparseAnnotations annotations = makePortNameAnnotation(port.getName());
- // Wavelength range: 1260 - 1630 nm (S160 data sheet)
- // Grid is irrelevant for this type of switch
- Frequency minFreq = Spectrum.O_BAND_MAX;
- Frequency maxFreq = Spectrum.U_BAND_MIN;
- Frequency grid = Frequency.ofGHz(100);
- return new OmsPortDescription(portNo, enabled, minFreq, maxFreq, grid, annotations);
+ // S160 data sheet
+ // Wavelength range: 1260 - 1630 nm, grid is irrelevant for this type of switch
+ return new OmsPortDescription(portNo, enabled,
+ Spectrum.U_BAND_MIN, Spectrum.O_BAND_MAX, Frequency.ofGHz(100), annotations);
}
private PortDescription buildPortDescription(OFPortStatus status) {
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/ConfigProvider.java b/web/api/src/main/java/org/onosproject/rest/resources/ConfigProvider.java
index cc05bff..dbd80cc 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/ConfigProvider.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/ConfigProvider.java
@@ -254,6 +254,7 @@
annotations);
case FIBER:
// Currently, assume OMS when FIBER. Provide sane defaults.
+ annotations = annotations(node.get("annotations"));
return new OmsPortDescription(port, node.path("enabled").asBoolean(true),
CENTER, CENTER.add(TOTAL),
Frequency.ofGHz(100), annotations);