Marc De Leenheer
Committed by Gerrit Code Review

LINC driver and OF device provider report correct optical port types

Change-Id: I501ce5f6f53136254024ad7122a4fec0d17504e0
......@@ -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.OFCircuitPortsRequest;
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 @@ public class OFOpticalSwitchImplLINC13
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 @@ public class OFOpticalSwitchImplLINC13
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 class OFOpticalSwitchImplLINC13
public void processOFPortStatus(OFCircuitPortStatus ps) {
log.debug("LINC-OE ..OF Port Status :", ps);
}
private void sendHandshakeOFExperimenterPortDescRequest() throws
......@@ -147,7 +157,7 @@ public class OFOpticalSwitchImplLINC13
* @return List of ports
*/
public List<OFPortDesc> getPorts() {
return ImmutableList.copyOf(super.getPorts());
return Collections.EMPTY_LIST;
}
......@@ -161,9 +171,87 @@ public class OFOpticalSwitchImplLINC13
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
......
......@@ -19,7 +19,6 @@ 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 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.Property;
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.DeviceDescription;
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.OFFactory;
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.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;
......@@ -454,6 +460,8 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
* @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 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
// 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 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
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) {
......
......@@ -254,6 +254,7 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider {
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);
......