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 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.driver.handshaker; 16 package org.onosproject.driver.handshaker;
17 17
18 import org.onosproject.net.Device; 18 import org.onosproject.net.Device;
19 +import com.google.common.collect.ImmutableSet;
19 import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; 20 import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
20 import org.onosproject.openflow.controller.PortDescPropertyType; 21 import org.onosproject.openflow.controller.PortDescPropertyType;
21 import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; 22 import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
...@@ -28,19 +29,29 @@ import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest; ...@@ -28,19 +29,29 @@ import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
28 import org.projectfloodlight.openflow.protocol.OFMessage; 29 import org.projectfloodlight.openflow.protocol.OFMessage;
29 import org.projectfloodlight.openflow.protocol.OFObject; 30 import org.projectfloodlight.openflow.protocol.OFObject;
30 import org.projectfloodlight.openflow.protocol.OFPortDesc; 31 import org.projectfloodlight.openflow.protocol.OFPortDesc;
32 +import org.projectfloodlight.openflow.protocol.OFPortDescPropOpticalTransport;
33 +import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
34 +import org.projectfloodlight.openflow.protocol.OFPortOptical;
31 import org.projectfloodlight.openflow.protocol.OFStatsReply; 35 import org.projectfloodlight.openflow.protocol.OFStatsReply;
32 import org.projectfloodlight.openflow.protocol.OFStatsType; 36 import org.projectfloodlight.openflow.protocol.OFStatsType;
33 - 37 +import org.projectfloodlight.openflow.types.OFPort;
34 -import com.google.common.collect.ImmutableList;
35 -import com.google.common.collect.ImmutableSet;
36 38
37 import java.io.IOException; 39 import java.io.IOException;
40 +import java.util.ArrayList;
41 +import java.util.Collections;
38 import java.util.List; 42 import java.util.List;
39 import java.util.Set; 43 import java.util.Set;
40 import java.util.concurrent.atomic.AtomicBoolean; 44 import java.util.concurrent.atomic.AtomicBoolean;
41 45
42 /** 46 /**
43 * LINC-OE Optical Emulator switch class. 47 * LINC-OE Optical Emulator switch class.
48 + *
49 + * The LINC ROADM emulator exposes two types of ports: OCh ports connect to ports in the packet layer,
50 + * while OMS ports connect to an OMS port on a neighbouring ROADM.
51 + *
52 + * LINC sends the tap ports (OCh for our purposes) in the regular port desc stats reply,
53 + * while it sends *all* ports (both tap and WDM ports, i.e., OCh and OMS) in the experimenter port desc stats reply.
54 + *
44 */ 55 */
45 public class OFOpticalSwitchImplLINC13 56 public class OFOpticalSwitchImplLINC13
46 extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch { 57 extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {
...@@ -48,7 +59,7 @@ public class OFOpticalSwitchImplLINC13 ...@@ -48,7 +59,7 @@ public class OFOpticalSwitchImplLINC13
48 private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false); 59 private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
49 private long barrierXidToWaitFor = -1; 60 private long barrierXidToWaitFor = -1;
50 61
51 - private OFCircuitPortsReply wPorts; 62 + private List<OFPortOptical> opticalPorts;
52 63
53 @Override 64 @Override
54 public void startDriverHandshake() { 65 public void startDriverHandshake() {
...@@ -109,7 +120,7 @@ public class OFOpticalSwitchImplLINC13 ...@@ -109,7 +120,7 @@ public class OFOpticalSwitchImplLINC13
109 OFStatsReply stats = (OFStatsReply) m; 120 OFStatsReply stats = (OFStatsReply) m;
110 if (stats.getStatsType() == OFStatsType.EXPERIMENTER) { 121 if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
111 log.warn("LINC-OE : Received stats reply message {}", m); 122 log.warn("LINC-OE : Received stats reply message {}", m);
112 - wPorts = (OFCircuitPortsReply) m; 123 + createOpticalPortList((OFCircuitPortsReply) m);
113 driverHandshakeComplete.set(true); 124 driverHandshakeComplete.set(true);
114 } 125 }
115 break; 126 break;
...@@ -124,7 +135,6 @@ public class OFOpticalSwitchImplLINC13 ...@@ -124,7 +135,6 @@ public class OFOpticalSwitchImplLINC13
124 135
125 public void processOFPortStatus(OFCircuitPortStatus ps) { 136 public void processOFPortStatus(OFCircuitPortStatus ps) {
126 log.debug("LINC-OE ..OF Port Status :", ps); 137 log.debug("LINC-OE ..OF Port Status :", ps);
127 -
128 } 138 }
129 139
130 private void sendHandshakeOFExperimenterPortDescRequest() throws 140 private void sendHandshakeOFExperimenterPortDescRequest() throws
...@@ -147,7 +157,7 @@ public class OFOpticalSwitchImplLINC13 ...@@ -147,7 +157,7 @@ public class OFOpticalSwitchImplLINC13
147 * @return List of ports 157 * @return List of ports
148 */ 158 */
149 public List<OFPortDesc> getPorts() { 159 public List<OFPortDesc> getPorts() {
150 - return ImmutableList.copyOf(super.getPorts()); 160 + return Collections.EMPTY_LIST;
151 } 161 }
152 162
153 163
...@@ -161,9 +171,87 @@ public class OFOpticalSwitchImplLINC13 ...@@ -161,9 +171,87 @@ public class OFOpticalSwitchImplLINC13
161 return Device.Type.ROADM; 171 return Device.Type.ROADM;
162 } 172 }
163 173
174 + /**
175 + * Checks if given port is also part of the regular port desc stats, i.e., is the port a tap port.
176 + *
177 + * @param port given OF port
178 + * @return true if the port is a tap (OCh), false otherwise (OMS port)
179 + */
180 + private boolean hasPort(OFPort port) {
181 + for (OFPortDescStatsReply reply : this.ports) {
182 + for (OFPortDesc p : reply.getEntries()) {
183 + if (p.getPortNo().equals(port)) {
184 + return true;
185 + }
186 + }
187 + }
188 +
189 + return false;
190 + }
191 +
192 + /**
193 + * Creates an OpenFlow optical port based on the given port and transport type.
194 + *
195 + * @param port OpenFlow optical port
196 + * @param type transport type
197 + * @return OpenFlow optical port
198 + */
199 + private OFPortOptical createOpticalPort(OFPortOptical port, short type) {
200 + List<OFPortDescPropOpticalTransport> descList = new ArrayList<>(port.getDesc().size());
201 +
202 + for (OFPortDescPropOpticalTransport desc : port.getDesc()) {
203 + OFPortDescPropOpticalTransport newDesc = desc.createBuilder()
204 + .setType(desc.getType())
205 + .setPortSignalType(type)
206 + .setPortType(desc.getPortType())
207 + .setReserved(desc.getReserved())
208 + .build();
209 + descList.add(newDesc);
210 + }
211 +
212 + OFPortOptical newPort = port.createBuilder()
213 + .setConfig(port.getConfig())
214 + .setDesc(descList)
215 + .setHwAddr(port.getHwAddr())
216 + .setName(port.getName())
217 + .setPortNo(port.getPortNo())
218 + .setState(port.getState())
219 + .build();
220 +
221 + return newPort;
222 + }
223 +
224 + /**
225 + * Builds list of OFPortOptical ports based on the multi-part circuit ports reply.
226 + *
227 + * Ensure the optical transport port's signal type is configured correctly.
228 + *
229 + * @param wPorts OF reply with circuit ports
230 + */
231 + private void createOpticalPortList(OFCircuitPortsReply wPorts) {
232 + opticalPorts = new ArrayList<>(wPorts.getEntries().size());
233 +
234 + for (OFPortOptical p : wPorts.getEntries()) {
235 + short signalType;
236 +
237 + // FIXME: use constants once loxi has full optical extensions
238 + if (hasPort(p.getPortNo())) {
239 + signalType = 5; // OCH port
240 + } else {
241 + signalType = 2; // OMS port
242 + }
243 +
244 + opticalPorts.add(createOpticalPort(p, signalType));
245 + }
246 + }
247 +
164 @Override 248 @Override
165 public List<? extends OFObject> getPortsOf(PortDescPropertyType type) { 249 public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
166 - return ImmutableList.copyOf(wPorts.getEntries()); 250 + if (!type.equals(PortDescPropertyType.OPTICAL_TRANSPORT)) {
251 + return Collections.EMPTY_LIST;
252 + }
253 +
254 + return opticalPorts;
167 } 255 }
168 256
169 @Override 257 @Override
......
...@@ -19,7 +19,6 @@ import com.google.common.base.Strings; ...@@ -19,7 +19,6 @@ import com.google.common.base.Strings;
19 import com.google.common.collect.Lists; 19 import com.google.common.collect.Lists;
20 import com.google.common.collect.Maps; 20 import com.google.common.collect.Maps;
21 import com.google.common.collect.Sets; 21 import com.google.common.collect.Sets;
22 -
23 import org.apache.felix.scr.annotations.Activate; 22 import org.apache.felix.scr.annotations.Activate;
24 import org.apache.felix.scr.annotations.Component; 23 import org.apache.felix.scr.annotations.Component;
25 import org.apache.felix.scr.annotations.Deactivate; 24 import org.apache.felix.scr.annotations.Deactivate;
...@@ -28,13 +27,17 @@ import org.apache.felix.scr.annotations.Property; ...@@ -28,13 +27,17 @@ import org.apache.felix.scr.annotations.Property;
28 import org.apache.felix.scr.annotations.Reference; 27 import org.apache.felix.scr.annotations.Reference;
29 import org.apache.felix.scr.annotations.ReferenceCardinality; 28 import org.apache.felix.scr.annotations.ReferenceCardinality;
30 import org.onlab.packet.ChassisId; 29 import org.onlab.packet.ChassisId;
31 -import org.onosproject.cfg.ComponentConfigService;
32 import org.onlab.util.Frequency; 30 import org.onlab.util.Frequency;
31 +import org.onosproject.cfg.ComponentConfigService;
33 import org.onlab.util.Spectrum; 32 import org.onlab.util.Spectrum;
34 import org.onosproject.net.AnnotationKeys; 33 import org.onosproject.net.AnnotationKeys;
34 +import org.onosproject.net.ChannelSpacing;
35 import org.onosproject.net.DefaultAnnotations; 35 import org.onosproject.net.DefaultAnnotations;
36 import org.onosproject.net.DeviceId; 36 import org.onosproject.net.DeviceId;
37 +import org.onosproject.net.GridType;
37 import org.onosproject.net.MastershipRole; 38 import org.onosproject.net.MastershipRole;
39 +import org.onosproject.net.OchSignal;
40 +import org.onosproject.net.OduSignalType;
38 import org.onosproject.net.Port; 41 import org.onosproject.net.Port;
39 import org.onosproject.net.PortNumber; 42 import org.onosproject.net.PortNumber;
40 import org.onosproject.net.SparseAnnotations; 43 import org.onosproject.net.SparseAnnotations;
...@@ -45,6 +48,7 @@ import org.onosproject.net.device.DeviceDescription; ...@@ -45,6 +48,7 @@ import org.onosproject.net.device.DeviceDescription;
45 import org.onosproject.net.device.DeviceProvider; 48 import org.onosproject.net.device.DeviceProvider;
46 import org.onosproject.net.device.DeviceProviderRegistry; 49 import org.onosproject.net.device.DeviceProviderRegistry;
47 import org.onosproject.net.device.DeviceProviderService; 50 import org.onosproject.net.device.DeviceProviderService;
51 +import org.onosproject.net.device.OchPortDescription;
48 import org.onosproject.net.device.OmsPortDescription; 52 import org.onosproject.net.device.OmsPortDescription;
49 import org.onosproject.net.device.PortDescription; 53 import org.onosproject.net.device.PortDescription;
50 import org.onosproject.net.device.PortStatistics; 54 import org.onosproject.net.device.PortStatistics;
...@@ -64,6 +68,7 @@ import org.projectfloodlight.openflow.protocol.OFFactory; ...@@ -64,6 +68,7 @@ import org.projectfloodlight.openflow.protocol.OFFactory;
64 import org.projectfloodlight.openflow.protocol.OFMessage; 68 import org.projectfloodlight.openflow.protocol.OFMessage;
65 import org.projectfloodlight.openflow.protocol.OFPortConfig; 69 import org.projectfloodlight.openflow.protocol.OFPortConfig;
66 import org.projectfloodlight.openflow.protocol.OFPortDesc; 70 import org.projectfloodlight.openflow.protocol.OFPortDesc;
71 +import org.projectfloodlight.openflow.protocol.OFPortDescPropOpticalTransport;
67 import org.projectfloodlight.openflow.protocol.OFPortFeatures; 72 import org.projectfloodlight.openflow.protocol.OFPortFeatures;
68 import org.projectfloodlight.openflow.protocol.OFPortOptical; 73 import org.projectfloodlight.openflow.protocol.OFPortOptical;
69 import org.projectfloodlight.openflow.protocol.OFPortReason; 74 import org.projectfloodlight.openflow.protocol.OFPortReason;
...@@ -86,6 +91,7 @@ import java.util.HashMap; ...@@ -86,6 +91,7 @@ import java.util.HashMap;
86 import java.util.HashSet; 91 import java.util.HashSet;
87 import java.util.List; 92 import java.util.List;
88 93
94 +import static com.google.common.base.Preconditions.checkArgument;
89 import static com.google.common.base.Strings.isNullOrEmpty; 95 import static com.google.common.base.Strings.isNullOrEmpty;
90 import static org.onlab.util.Tools.get; 96 import static org.onlab.util.Tools.get;
91 import static org.onosproject.net.DeviceId.deviceId; 97 import static org.onosproject.net.DeviceId.deviceId;
...@@ -454,6 +460,8 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -454,6 +460,8 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
454 * @return portDescription for the port. 460 * @return portDescription for the port.
455 */ 461 */
456 private PortDescription buildPortDescription(PortDescPropertyType ptype, OFPortOptical port) { 462 private PortDescription buildPortDescription(PortDescPropertyType ptype, OFPortOptical port) {
463 + checkArgument(port.getDesc().size() >= 1);
464 +
457 // Minimally functional fixture. This needs to be fixed as we add better support. 465 // Minimally functional fixture. This needs to be fixed as we add better support.
458 PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber()); 466 PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
459 467
...@@ -469,6 +477,23 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -469,6 +477,23 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
469 // removable once 1.4+ support complete. 477 // removable once 1.4+ support complete.
470 LOG.debug("Unsupported optical port properties"); 478 LOG.debug("Unsupported optical port properties");
471 } 479 }
480 +
481 + OFPortDescPropOpticalTransport desc = port.getDesc().get(0);
482 + switch (desc.getPortSignalType()) {
483 + // FIXME: use constants once loxi has full optical extensions
484 + case 2: // OMS port
485 + // Assume complete optical spectrum and 50 GHz grid
486 + // LINC-OE is only supported optical OF device for now
487 + return new OmsPortDescription(portNo, enabled,
488 + Spectrum.U_BAND_MIN, Spectrum.O_BAND_MAX, Frequency.ofGHz(50), annotations);
489 + case 5: // OCH port
490 + OchSignal signal = new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 0, 4);
491 + return new OchPortDescription(portNo, enabled, OduSignalType.ODU4,
492 + true, signal, annotations);
493 + default:
494 + break;
495 + }
496 +
472 return new DefaultPortDescription(portNo, enabled, FIBER, 0, annotations); 497 return new DefaultPortDescription(portNo, enabled, FIBER, 0, annotations);
473 } 498 }
474 499
...@@ -486,12 +511,10 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -486,12 +511,10 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
486 boolean enabled = true; 511 boolean enabled = true;
487 SparseAnnotations annotations = makePortNameAnnotation(port.getName()); 512 SparseAnnotations annotations = makePortNameAnnotation(port.getName());
488 513
489 - // Wavelength range: 1260 - 1630 nm (S160 data sheet) 514 + // S160 data sheet
490 - // Grid is irrelevant for this type of switch 515 + // Wavelength range: 1260 - 1630 nm, grid is irrelevant for this type of switch
491 - Frequency minFreq = Spectrum.O_BAND_MAX; 516 + return new OmsPortDescription(portNo, enabled,
492 - Frequency maxFreq = Spectrum.U_BAND_MIN; 517 + Spectrum.U_BAND_MIN, Spectrum.O_BAND_MAX, Frequency.ofGHz(100), annotations);
493 - Frequency grid = Frequency.ofGHz(100);
494 - return new OmsPortDescription(portNo, enabled, minFreq, maxFreq, grid, annotations);
495 } 518 }
496 519
497 private PortDescription buildPortDescription(OFPortStatus status) { 520 private PortDescription buildPortDescription(OFPortStatus status) {
......
...@@ -254,6 +254,7 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider { ...@@ -254,6 +254,7 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider {
254 annotations); 254 annotations);
255 case FIBER: 255 case FIBER:
256 // Currently, assume OMS when FIBER. Provide sane defaults. 256 // Currently, assume OMS when FIBER. Provide sane defaults.
257 + annotations = annotations(node.get("annotations"));
257 return new OmsPortDescription(port, node.path("enabled").asBoolean(true), 258 return new OmsPortDescription(port, node.path("enabled").asBoolean(true),
258 CENTER, CENTER.add(TOTAL), 259 CENTER, CENTER.add(TOTAL),
259 Frequency.ofGHz(100), annotations); 260 Frequency.ofGHz(100), annotations);
......