Ayaka Koshibe
Committed by Gerrit Code Review

Interfaces for passing port information from OF switch drivers to DeviceProviders.

Change-Id: I14039f5999c930a211c30138caf81c0513d398e2
Reference: ONOS-1911
......@@ -15,6 +15,8 @@
*/
package org.onosproject.driver.handshaker;
import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
import org.onosproject.openflow.controller.PortDescPropertyType;
import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
......@@ -23,28 +25,29 @@ import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus;
import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
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.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 java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* LINC-OE Optical Emulator switch class.
*/
public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
public class OFOpticalSwitchImplLINC13
extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {
private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
private long barrierXidToWaitFor = -1;
private OFPortDescStatsReply wPorts;
private OFCircuitPortsReply wPorts;
@Override
public void startDriverHandshake() {
......@@ -105,8 +108,7 @@ public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
OFStatsReply stats = (OFStatsReply) m;
if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
log.warn("LINC-OE : Received stats reply message {}", m);
processHandshakeOFExperimenterPortDescRequest(
(OFCircuitPortsReply) m);
wPorts = (OFCircuitPortsReply) m;
driverHandshakeComplete.set(true);
}
break;
......@@ -124,30 +126,6 @@ public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
}
private void processHandshakeOFExperimenterPortDescRequest(
OFCircuitPortsReply sr) {
Collection<OFPortOptical> entries = sr.getEntries();
List<OFPortDesc> ofPortDescList = new ArrayList<>(entries.size());
for (OFPortOptical entry : entries) {
log.warn("LINC:OE port message {}", entry.toString());
ofPortDescList.add(factory().buildPortDesc().
setPortNo(entry.getPortNo())
.setConfig(entry.getConfig())
.setState(entry.getState())
.setHwAddr(entry.getHwAddr())
.setName(entry.getName())
.build());
}
setExperimenterPortDescReply(factory().buildPortDescStatsReply().
setEntries(ofPortDescList).build());
}
private void setExperimenterPortDescReply(OFPortDescStatsReply reply) {
wPorts = reply;
}
private void sendHandshakeOFExperimenterPortDescRequest() throws
IOException {
// send multi part message for port description for optical switches
......@@ -162,13 +140,13 @@ public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
}
@Override
/**
* Returns a list of standard (Ethernet) ports.
*
* @return List of ports
*/
public List<OFPortDesc> getPorts() {
List<OFPortDesc> portEntries = new ArrayList<>();
portEntries.addAll(super.getPorts());
if (wPorts != null) {
portEntries.addAll(wPorts.getEntries());
}
return Collections.unmodifiableList(portEntries);
return ImmutableList.copyOf(super.getPorts());
}
......@@ -182,4 +160,14 @@ public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
return true;
}
@Override
public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
return ImmutableList.copyOf(wPorts.getEntries());
}
@Override
public Set<PortDescPropertyType> getPortTypes() {
return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT);
}
}
......
package org.onosproject.openflow.controller;
/**
* A marker interface for optical switches, which require the ability to pass
* port information to a Device provider.
*/
public interface OpenFlowOpticalSwitch extends OpenFlowSwitch, WithTypedPorts {
}
package org.onosproject.openflow.controller;
/**
* Port description property types (OFPPDPT enums) in OF 1.3 &lt;.
*/
public enum PortDescPropertyType {
ETHERNET(0), /* Ethernet port */
OPTICAL(1), /* Optical port */
OPTICAL_TRANSPORT(2), /* OF1.3 Optical transport extension */
PIPELINE_INPUT(2), /* Ingress pipeline */
PIPELINE_OUTPUT(3), /* Egress pipeline */
RECIRCULATE(4), /* Recirculation */
EXPERIMENTER(0xffff); /* Experimenter-implemented */
private final int value;
PortDescPropertyType(int v) {
value = v;
}
public int valueOf() {
return value;
}
}
package org.onosproject.openflow.controller;
import java.util.List;
import java.util.Set;
import org.projectfloodlight.openflow.protocol.OFObject;
/**
* An interface implemented by OpenFlow devices that enables providers to
* retrieve ports based on port property.
*/
public interface WithTypedPorts {
/**
* Return a list of interfaces (ports) of the type associated with this
* OpenFlow switch.
*
* @param type The port description property type of requested ports
* @return A potentially empty list of ports.
*/
List<? extends OFObject> getPortsOf(PortDescPropertyType type);
/**
* Returns the port property types supported by the driver implementing this
* interface.
*
* @return A set of port property types
*/
Set<PortDescPropertyType> getPortTypes();
}
......@@ -17,6 +17,7 @@ package org.onosproject.provider.of.device.impl;
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;
......@@ -44,8 +45,10 @@ import org.onosproject.net.provider.ProviderId;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowController;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.PortDescPropertyType;
import org.onosproject.openflow.controller.RoleState;
import org.onlab.packet.ChassisId;
import org.projectfloodlight.openflow.protocol.OFFactory;
......@@ -53,6 +56,7 @@ import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortConfig;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortFeatures;
import org.projectfloodlight.openflow.protocol.OFPortOptical;
import org.projectfloodlight.openflow.protocol.OFPortReason;
import org.projectfloodlight.openflow.protocol.OFPortState;
import org.projectfloodlight.openflow.protocol.OFPortStatsEntry;
......@@ -262,7 +266,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
sw.serialNumber(),
cId, annotations);
providerService.deviceConnected(did, description);
providerService.updatePorts(did, buildPortDescriptions(sw.getPorts()));
providerService.updatePorts(did, buildPortDescriptions(sw));
PortStatsCollector psc = new PortStatsCollector(
controller.getSwitch(dpid), POLL_INTERVAL);
......@@ -290,7 +294,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
}
DeviceId did = deviceId(uri(dpid));
OpenFlowSwitch sw = controller.getSwitch(dpid);
providerService.updatePorts(did, buildPortDescriptions(sw.getPorts()));
providerService.updatePorts(did, buildPortDescriptions(sw));
}
@Override
......@@ -333,10 +337,19 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
* @param ports the list of ports
* @return list of portdescriptions
*/
private List<PortDescription> buildPortDescriptions(List<OFPortDesc> ports) {
final List<PortDescription> portDescs = new ArrayList<>(ports.size());
for (OFPortDesc port : ports) {
portDescs.add(buildPortDescription(port));
private List<PortDescription> buildPortDescriptions(OpenFlowSwitch sw) {
final List<PortDescription> portDescs = new ArrayList<>(sw.getPorts().size());
sw.getPorts().forEach(port -> portDescs.add(buildPortDescription(port)));
if (sw.isOptical()) {
OpenFlowOpticalSwitch opsw = (OpenFlowOpticalSwitch) sw;
opsw.getPortTypes().forEach(type -> {
LOG.info("ports: {}", opsw.getPortsOf(type));
opsw.getPortsOf(type).forEach(
op -> {
portDescs.add(buildPortDescription(type, (OFPortOptical) op));
}
);
});
}
return portDescs;
}
......@@ -348,9 +361,9 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
* @return annotation containing the port name if one is found,
* null otherwise
*/
private SparseAnnotations makePortNameAnnotation(OFPortDesc port) {
private SparseAnnotations makePortNameAnnotation(String port) {
SparseAnnotations annotations = null;
String portName = Strings.emptyToNull(port.getName());
String portName = Strings.emptyToNull(port);
if (portName != null) {
annotations = DefaultAnnotations.builder()
.set(AnnotationKeys.PORT_NAME, portName).build();
......@@ -359,7 +372,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
}
/**
* Build a portDescription from a given port.
* Build a portDescription from a given Ethernet port description.
*
* @param port the port to build from.
* @return portDescription for the port.
......@@ -370,11 +383,38 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
!port.getState().contains(OFPortState.LINK_DOWN) &&
!port.getConfig().contains(OFPortConfig.PORT_DOWN);
Port.Type type = port.getCurr().contains(OFPortFeatures.PF_FIBER) ? FIBER : COPPER;
SparseAnnotations annotations = makePortNameAnnotation(port);
SparseAnnotations annotations = makePortNameAnnotation(port.getName());
return new DefaultPortDescription(portNo, enabled, type,
portSpeed(port), annotations);
}
/**
* Build a portDescription from a given a port description describing some
* Optical port.
*
* @param port description property type.
* @param port the port to build from.
* @return portDescription for the port.
*/
private PortDescription buildPortDescription(PortDescPropertyType ptype, OFPortOptical port) {
// Minimally functional fixture. This needs to be fixed as we add better support.
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());
Port.Type type = FIBER;
if (port.getVersion() == OFVersion.OF_13
&& ptype == PortDescPropertyType.OPTICAL_TRANSPORT) {
// At this point, not much is carried in the optical port message.
LOG.info("Optical transport port message {}", port.toString());
} else {
// removable once 1.4+ support complete.
LOG.warn("Unsupported optical port properties");
}
return new DefaultPortDescription(portNo, enabled, type, 0, annotations);
}
private PortDescription buildPortDescription(OFPortStatus status) {
OFPortDesc port = status.getDesc();
if (status.getReason() != OFPortReason.DELETE) {
......@@ -382,7 +422,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
} else {
PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
Port.Type type = port.getCurr().contains(OFPortFeatures.PF_FIBER) ? FIBER : COPPER;
SparseAnnotations annotations = makePortNameAnnotation(port);
SparseAnnotations annotations = makePortNameAnnotation(port.getName());
return new DefaultPortDescription(portNo, false, type,
portSpeed(port), annotations);
}
......