Yafit Hadar
Committed by Gerrit Code Review

[Emu] Open Flow Optical Port Description

Change-Id: I8da4d7a1e1dea18d56cba9673f70b1ec69a5adcf
1 /* 1 /*
2 - * Copyright 2014 Open Networking Laboratory 2 + * Copyright 2015 Open Networking Laboratory
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
...@@ -22,8 +22,12 @@ import com.fasterxml.jackson.databind.node.ObjectNode; ...@@ -22,8 +22,12 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
22 import org.apache.karaf.shell.commands.Argument; 22 import org.apache.karaf.shell.commands.Argument;
23 import org.apache.karaf.shell.commands.Command; 23 import org.apache.karaf.shell.commands.Command;
24 import org.apache.karaf.shell.commands.Option; 24 import org.apache.karaf.shell.commands.Option;
25 +import org.onlab.util.Frequency;
25 import org.onosproject.cli.Comparators; 26 import org.onosproject.cli.Comparators;
26 import org.onosproject.net.Device; 27 import org.onosproject.net.Device;
28 +import org.onosproject.net.OchPort;
29 +import org.onosproject.net.OduCltPort;
30 +import org.onosproject.net.OmsPort;
27 import org.onosproject.net.Port; 31 import org.onosproject.net.Port;
28 import org.onosproject.net.PortNumber; 32 import org.onosproject.net.PortNumber;
29 import org.onosproject.net.device.DeviceService; 33 import org.onosproject.net.device.DeviceService;
...@@ -41,7 +45,10 @@ import static org.onosproject.net.DeviceId.deviceId; ...@@ -41,7 +45,10 @@ import static org.onosproject.net.DeviceId.deviceId;
41 description = "Lists all ports or all ports of a device") 45 description = "Lists all ports or all ports of a device")
42 public class DevicePortsListCommand extends DevicesListCommand { 46 public class DevicePortsListCommand extends DevicesListCommand {
43 47
44 - private static final String FMT = " port=%s, state=%s, type=%s, speed=%s%s"; 48 + private static final String FMT = " port=%s, state=%s, type=%s, speed=%s %s";
49 + private static final String FMT_OCH = " port=%s, state=%s, type=%s, signalType=%s, isTunable=%s %s";
50 + private static final String FMT_ODUCLT = " port=%s, state=%s, type=%s, signalType=%s %s";
51 + private static final String FMT_OMS = " port=%s, state=%s, type=%s, Freqs= %s / %s / %s GHz, totalChannels=%s %s";
45 52
46 @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports", 53 @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports",
47 required = false, multiValued = false) 54 required = false, multiValued = false)
...@@ -137,13 +144,34 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -137,13 +144,34 @@ public class DevicePortsListCommand extends DevicesListCommand {
137 List<Port> ports = new ArrayList<>(service.getPorts(device.id())); 144 List<Port> ports = new ArrayList<>(service.getPorts(device.id()));
138 Collections.sort(ports, Comparators.PORT_COMPARATOR); 145 Collections.sort(ports, Comparators.PORT_COMPARATOR);
139 for (Port port : ports) { 146 for (Port port : ports) {
140 - if (isIncluded(port)) { 147 + if (!isIncluded(port)) {
141 - print(FMT, portName(port.number()), 148 + continue;
142 - port.isEnabled() ? "enabled" : "disabled", 149 + }
143 - port.type().toString().toLowerCase(), port.portSpeed(), 150 + String portName = portName(port.number());
144 - annotations(port.annotations())); 151 + Object portIsEnabled = port.isEnabled() ? "enabled" : "disabled";
152 + String portType = port.type().toString().toLowerCase();
153 + String annotations = annotations(port.annotations());
154 + switch (port.type()) {
155 + case OCH:
156 + print(FMT_OCH, portName, portIsEnabled, portType,
157 + ((OchPort) port).signalType().toString(),
158 + ((OchPort) port).isTunable() ? "yes" : "no", annotations);
159 + break;
160 + case ODUCLT:
161 + print(FMT_ODUCLT, portName, portIsEnabled, portType,
162 + ((OduCltPort) port).signalType().toString(), annotations);
163 + break;
164 + case OMS:
165 + print(FMT_OMS, portName, portIsEnabled, portType,
166 + ((OmsPort) port).minFrequency().asHz() / Frequency.ofGHz(1).asHz(),
167 + ((OmsPort) port).maxFrequency().asHz() / Frequency.ofGHz(1).asHz(),
168 + ((OmsPort) port).grid().asHz() / Frequency.ofGHz(1).asHz(),
169 + ((OmsPort) port).totalChannels(), annotations);
170 + break;
171 + default:
172 + print(FMT, portName, portIsEnabled, portType, port.portSpeed(), annotations);
173 + break;
145 } 174 }
146 } 175 }
147 } 176 }
148 -
149 } 177 }
......
...@@ -15,8 +15,26 @@ ...@@ -15,8 +15,26 @@
15 */ 15 */
16 package org.onosproject.net.device.impl; 16 package org.onosproject.net.device.impl;
17 17
18 -import com.google.common.collect.Lists; 18 +import static com.google.common.base.Preconditions.checkNotNull;
19 -import com.google.common.util.concurrent.Futures; 19 +import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
20 +import static org.onlab.util.Tools.groupedThreads;
21 +import static org.onosproject.net.MastershipRole.MASTER;
22 +import static org.onosproject.net.MastershipRole.NONE;
23 +import static org.onosproject.net.MastershipRole.STANDBY;
24 +import static org.onosproject.security.AppGuard.checkPermission;
25 +import static org.onosproject.security.AppPermission.Type.DEVICE_READ;
26 +import static org.slf4j.LoggerFactory.getLogger;
27 +
28 +import java.util.Collection;
29 +import java.util.HashSet;
30 +import java.util.List;
31 +import java.util.Objects;
32 +import java.util.Set;
33 +import java.util.concurrent.CompletableFuture;
34 +import java.util.concurrent.ExecutionException;
35 +import java.util.concurrent.ScheduledExecutorService;
36 +import java.util.concurrent.TimeUnit;
37 +import java.util.stream.Collectors;
20 38
21 import org.apache.felix.scr.annotations.Activate; 39 import org.apache.felix.scr.annotations.Activate;
22 import org.apache.felix.scr.annotations.Component; 40 import org.apache.felix.scr.annotations.Component;
...@@ -26,12 +44,6 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -26,12 +44,6 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
26 import org.apache.felix.scr.annotations.Service; 44 import org.apache.felix.scr.annotations.Service;
27 import org.onosproject.cluster.ClusterService; 45 import org.onosproject.cluster.ClusterService;
28 import org.onosproject.cluster.NodeId; 46 import org.onosproject.cluster.NodeId;
29 -import org.onosproject.net.provider.AbstractListenerProviderRegistry;
30 -import org.onosproject.net.config.NetworkConfigEvent;
31 -import org.onosproject.net.config.NetworkConfigListener;
32 -import org.onosproject.net.config.NetworkConfigService;
33 -import org.onosproject.net.config.basics.BasicDeviceConfig;
34 -import org.onosproject.net.config.basics.OpticalPortConfig;
35 import org.onosproject.mastership.MastershipEvent; 47 import org.onosproject.mastership.MastershipEvent;
36 import org.onosproject.mastership.MastershipListener; 48 import org.onosproject.mastership.MastershipListener;
37 import org.onosproject.mastership.MastershipService; 49 import org.onosproject.mastership.MastershipService;
...@@ -44,6 +56,11 @@ import org.onosproject.net.DeviceId; ...@@ -44,6 +56,11 @@ import org.onosproject.net.DeviceId;
44 import org.onosproject.net.MastershipRole; 56 import org.onosproject.net.MastershipRole;
45 import org.onosproject.net.Port; 57 import org.onosproject.net.Port;
46 import org.onosproject.net.PortNumber; 58 import org.onosproject.net.PortNumber;
59 +import org.onosproject.net.config.NetworkConfigEvent;
60 +import org.onosproject.net.config.NetworkConfigListener;
61 +import org.onosproject.net.config.NetworkConfigService;
62 +import org.onosproject.net.config.basics.BasicDeviceConfig;
63 +import org.onosproject.net.config.basics.OpticalPortConfig;
47 import org.onosproject.net.device.DefaultDeviceDescription; 64 import org.onosproject.net.device.DefaultDeviceDescription;
48 import org.onosproject.net.device.DefaultPortDescription; 65 import org.onosproject.net.device.DefaultPortDescription;
49 import org.onosproject.net.device.DeviceAdminService; 66 import org.onosproject.net.device.DeviceAdminService;
...@@ -58,27 +75,11 @@ import org.onosproject.net.device.DeviceStore; ...@@ -58,27 +75,11 @@ import org.onosproject.net.device.DeviceStore;
58 import org.onosproject.net.device.DeviceStoreDelegate; 75 import org.onosproject.net.device.DeviceStoreDelegate;
59 import org.onosproject.net.device.PortDescription; 76 import org.onosproject.net.device.PortDescription;
60 import org.onosproject.net.device.PortStatistics; 77 import org.onosproject.net.device.PortStatistics;
78 +import org.onosproject.net.provider.AbstractListenerProviderRegistry;
61 import org.onosproject.net.provider.AbstractProviderService; 79 import org.onosproject.net.provider.AbstractProviderService;
62 import org.slf4j.Logger; 80 import org.slf4j.Logger;
63 81
64 -import java.util.Collection; 82 +import com.google.common.util.concurrent.Futures;
65 -import java.util.HashSet;
66 -import java.util.List;
67 -import java.util.Objects;
68 -import java.util.Set;
69 -import java.util.stream.Collectors;
70 -import java.util.concurrent.CompletableFuture;
71 -import java.util.concurrent.ExecutionException;
72 -import java.util.concurrent.ScheduledExecutorService;
73 -import java.util.concurrent.TimeUnit;
74 -
75 -import static com.google.common.base.Preconditions.checkNotNull;
76 -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
77 -import static org.onlab.util.Tools.groupedThreads;
78 -import static org.onosproject.net.MastershipRole.*;
79 -import static org.onosproject.security.AppGuard.checkPermission;
80 -import static org.slf4j.LoggerFactory.getLogger;
81 -import static org.onosproject.security.AppPermission.Type.*;
82 83
83 /** 84 /**
84 * Provides implementation of the device SB &amp; NB APIs. 85 * Provides implementation of the device SB &amp; NB APIs.
...@@ -347,11 +348,15 @@ public class DeviceManager ...@@ -347,11 +348,15 @@ public class DeviceManager
347 log.info("Device {} disconnected from this node", deviceId); 348 log.info("Device {} disconnected from this node", deviceId);
348 349
349 List<Port> ports = store.getPorts(deviceId); 350 List<Port> ports = store.getPorts(deviceId);
350 - List<PortDescription> descs = Lists.newArrayList(); 351 + final Device device = getDevice(deviceId);
351 - ports.forEach(port -> 352 +
352 - descs.add(new DefaultPortDescription(port.number(), 353 + List<PortDescription> descs = ports.stream().map(
353 - false, port.type(), 354 + port -> (!(Device.Type.ROADM.equals(device.type()))) ?
354 - port.portSpeed()))); 355 + new DefaultPortDescription(port.number(), false,
356 + port.type(), port.portSpeed()) :
357 + OpticalPortOperator.descriptionOf(port, false)
358 + ).collect(Collectors.toList());
359 +
355 store.updatePorts(this.provider().id(), deviceId, descs); 360 store.updatePorts(this.provider().id(), deviceId, descs);
356 try { 361 try {
357 if (mastershipService.isLocalMaster(deviceId)) { 362 if (mastershipService.isLocalMaster(deviceId)) {
...@@ -430,6 +435,12 @@ public class DeviceManager ...@@ -430,6 +435,12 @@ public class DeviceManager
430 portDescription); 435 portDescription);
431 return; 436 return;
432 } 437 }
438 + final Device device = getDevice(deviceId);
439 + if ((Device.Type.ROADM.equals(device.type()))) {
440 + Port port = getPort(deviceId, portDescription.portNumber());
441 + portDescription = OpticalPortOperator.descriptionOf(port, portDescription.isEnabled());
442 + }
443 +
433 portDescription = consolidate(deviceId, portDescription); 444 portDescription = consolidate(deviceId, portDescription);
434 final DeviceEvent event = store.updatePortStatus(this.provider().id(), 445 final DeviceEvent event = store.updatePortStatus(this.provider().id(),
435 deviceId, portDescription); 446 deviceId, portDescription);
......
...@@ -151,8 +151,25 @@ public final class OpticalPortOperator implements ConfigOperator { ...@@ -151,8 +151,25 @@ public final class OpticalPortOperator implements ConfigOperator {
151 */ 151 */
152 public static PortDescription descriptionOf(Port port) { 152 public static PortDescription descriptionOf(Port port) {
153 checkNotNull(port, "Must supply non-null Port"); 153 checkNotNull(port, "Must supply non-null Port");
154 + final boolean isUp = port.isEnabled();
155 + return descriptionOfPort(port, isUp);
156 + }
157 +
158 + /**
159 + * Returns a description built from an existing port and reported status.
160 + *
161 + * @param port
162 + * @param isEnabled
163 + * @return a PortDescription based on the port
164 + */
165 + static PortDescription descriptionOf(Port port, boolean isEnabled) {
166 + checkNotNull(port, "Must supply non-null Port");
167 + final boolean isup = isEnabled;
168 + return descriptionOfPort(port, isup);
169 + }
170 +
171 + private static PortDescription descriptionOfPort(Port port, final boolean isup) {
154 final PortNumber ptn = port.number(); 172 final PortNumber ptn = port.number();
155 - final boolean isup = port.isEnabled();
156 final SparseAnnotations an = (SparseAnnotations) port.annotations(); 173 final SparseAnnotations an = (SparseAnnotations) port.annotations();
157 switch (port.type()) { 174 switch (port.type()) {
158 case OMS: 175 case OMS:
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.driver.handshaker;
17 +
18 +import org.projectfloodlight.openflow.protocol.OFExpPort;
19 +import org.projectfloodlight.openflow.protocol.OFExpPortDescReply;
20 +import org.projectfloodlight.openflow.protocol.OFExpPortDescRequest;
21 +import org.projectfloodlight.openflow.protocol.OFMessage;
22 +import org.projectfloodlight.openflow.protocol.OFPortDesc;
23 +import org.projectfloodlight.openflow.protocol.OFStatsReply;
24 +import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
25 +import org.projectfloodlight.openflow.protocol.OFStatsType;
26 +
27 +import java.io.IOException;
28 +import java.util.ArrayList;
29 +import java.util.List;
30 +import java.util.Set;
31 +import java.util.concurrent.atomic.AtomicBoolean;
32 +import java.util.stream.Collectors;
33 +
34 +import org.onosproject.net.Device;
35 +import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
36 +import org.onosproject.openflow.controller.PortDescPropertyType;
37 +import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
38 +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
39 +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
40 +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
41 +import org.projectfloodlight.openflow.protocol.OFObject;
42 +
43 +import com.google.common.collect.ImmutableList;
44 +import com.google.common.collect.ImmutableSet;
45 +
46 +
47 +/**
48 + * Open Flow Optical Switch handshaker - for Open Flow 13.
49 + */
50 +public class OFOpticalSwitch13 extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {
51 +
52 + private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
53 + private List<OFExpPort> expPortDes = new ArrayList<>();
54 +
55 + @Override
56 + public Boolean supportNxRole() {
57 + return false;
58 + }
59 +
60 + @Override
61 + public void startDriverHandshake() {
62 + log.info("Starting driver handshake for sw {}", getStringId());
63 + if (startDriverHandshakeCalled) {
64 + throw new SwitchDriverSubHandshakeAlreadyStarted();
65 + }
66 + startDriverHandshakeCalled = true;
67 +
68 + log.debug("sendHandshakeOFExperimenterPortDescRequest for sw {}", getStringId());
69 +
70 + try {
71 + sendHandshakeOFExperimenterPortDescRequest();
72 + } catch (IOException e) {
73 + log.error("Failed to send handshaker message OFExperimenterPortDescRequestfor sw {}, {}",
74 + getStringId(), e.getMessage());
75 + e.printStackTrace();
76 + }
77 + }
78 +
79 + @Override
80 + public void processDriverHandshakeMessage(OFMessage m) {
81 + if (!startDriverHandshakeCalled) {
82 + throw new SwitchDriverSubHandshakeNotStarted();
83 + }
84 + if (driverHandshakeComplete.get()) {
85 + throw new SwitchDriverSubHandshakeCompleted(m);
86 + }
87 +
88 + log.debug("processDriverHandshakeMessage for sw {}", getStringId());
89 +
90 + switch (m.getType()) {
91 + case STATS_REPLY: // multipart message is reported as STAT
92 + processOFMultipartReply((OFStatsReply) m);
93 + break;
94 + default:
95 + log.warn("Received message {} during switch-driver " +
96 + "subhandshake " + "from switch {} ... " +
97 + "Ignoring message", m,
98 + getStringId());
99 + }
100 + }
101 +
102 + private void processOFMultipartReply(OFStatsReply stats) {
103 + log.debug("Received message {} during switch-driver " +
104 + "subhandshake " + "from switch {} ... " +
105 + stats,
106 + getStringId());
107 +
108 + if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
109 + try {
110 + OFExpPortDescReply expPortDescReply = (OFExpPortDescReply) stats;
111 + expPortDes.addAll(expPortDescReply.getEntries());
112 + if (!expPortDescReply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
113 + driverHandshakeComplete.set(true);
114 + return;
115 + }
116 + } catch (ClassCastException e) {
117 + log.error("Unexspected Experimenter Multipart message type {} "
118 + , stats.getClass().getName());
119 + }
120 + }
121 + }
122 +
123 +
124 + @Override
125 + public boolean isDriverHandshakeComplete() {
126 + return driverHandshakeComplete.get();
127 + }
128 +
129 + private void sendHandshakeOFExperimenterPortDescRequest() throws
130 + IOException {
131 +
132 + OFExpPortDescRequest preq = factory()
133 + .buildExpPortDescRequest()
134 + .setXid(getNextTransactionId())
135 + .build();
136 +
137 + log.debug("Sending experimented port description " +
138 + "message " +
139 + "{}",
140 + preq.toString());
141 +
142 + this.sendHandshakeMessage(preq);
143 + }
144 +
145 + @Override
146 + public Device.Type deviceType() {
147 + return Device.Type.ROADM;
148 + }
149 +
150 + /*
151 + * OduClt ports are reported as regular ETH ports.
152 + */
153 + @Override
154 + public List<OFPortDesc> getPorts() {
155 + return ImmutableList.copyOf(
156 + ports.stream().flatMap(p -> p.getEntries().stream())
157 + .collect(Collectors.toList()));
158 + }
159 +
160 + @Override
161 + public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
162 + return ImmutableList.copyOf(expPortDes);
163 + }
164 +
165 + @Override
166 + public Set<PortDescPropertyType> getPortTypes() {
167 + return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT);
168 + }
169 +
170 +}
...@@ -120,5 +120,10 @@ ...@@ -120,5 +120,10 @@
120 <behaviour api="org.onosproject.net.behaviour.Pipeliner" 120 <behaviour api="org.onosproject.net.behaviour.Pipeliner"
121 impl="org.onosproject.driver.pipeline.OpenVSwitchPipeline"/> 121 impl="org.onosproject.driver.pipeline.OpenVSwitchPipeline"/>
122 </driver> 122 </driver>
123 + <driver name="eci" extends="default"
124 + manufacturer="ECI Telecom" hwVersion="optical" swVersion="V_1_0">
125 + <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
126 + impl="org.onosproject.driver.handshaker.OFOpticalSwitch13"/>
127 + </driver>
123 </drivers> 128 </drivers>
124 129
......
...@@ -15,10 +15,24 @@ ...@@ -15,10 +15,24 @@
15 */ 15 */
16 package org.onosproject.provider.of.device.impl; 16 package org.onosproject.provider.of.device.impl;
17 17
18 -import com.google.common.base.Strings; 18 +import static com.google.common.base.Preconditions.checkArgument;
19 -import com.google.common.collect.Lists; 19 +import static com.google.common.base.Strings.isNullOrEmpty;
20 -import com.google.common.collect.Maps; 20 +import static org.onlab.util.Tools.get;
21 -import com.google.common.collect.Sets; 21 +import static org.onosproject.net.DeviceId.deviceId;
22 +import static org.onosproject.net.Port.Type.COPPER;
23 +import static org.onosproject.net.Port.Type.FIBER;
24 +import static org.onosproject.openflow.controller.Dpid.dpid;
25 +import static org.onosproject.openflow.controller.Dpid.uri;
26 +import static org.slf4j.LoggerFactory.getLogger;
27 +
28 +import java.util.ArrayList;
29 +import java.util.Collection;
30 +import java.util.Collections;
31 +import java.util.Dictionary;
32 +import java.util.HashMap;
33 +import java.util.HashSet;
34 +import java.util.List;
35 +
22 import org.apache.felix.scr.annotations.Activate; 36 import org.apache.felix.scr.annotations.Activate;
23 import org.apache.felix.scr.annotations.Component; 37 import org.apache.felix.scr.annotations.Component;
24 import org.apache.felix.scr.annotations.Deactivate; 38 import org.apache.felix.scr.annotations.Deactivate;
...@@ -28,15 +42,17 @@ import org.apache.felix.scr.annotations.Reference; ...@@ -28,15 +42,17 @@ import org.apache.felix.scr.annotations.Reference;
28 import org.apache.felix.scr.annotations.ReferenceCardinality; 42 import org.apache.felix.scr.annotations.ReferenceCardinality;
29 import org.onlab.packet.ChassisId; 43 import org.onlab.packet.ChassisId;
30 import org.onlab.util.Frequency; 44 import org.onlab.util.Frequency;
31 -import org.onosproject.cfg.ComponentConfigService;
32 import org.onlab.util.Spectrum; 45 import org.onlab.util.Spectrum;
46 +import org.onosproject.cfg.ComponentConfigService;
33 import org.onosproject.net.AnnotationKeys; 47 import org.onosproject.net.AnnotationKeys;
34 import org.onosproject.net.ChannelSpacing; 48 import org.onosproject.net.ChannelSpacing;
35 import org.onosproject.net.DefaultAnnotations; 49 import org.onosproject.net.DefaultAnnotations;
50 +import org.onosproject.net.Device;
36 import org.onosproject.net.DeviceId; 51 import org.onosproject.net.DeviceId;
37 import org.onosproject.net.GridType; 52 import org.onosproject.net.GridType;
38 import org.onosproject.net.MastershipRole; 53 import org.onosproject.net.MastershipRole;
39 import org.onosproject.net.OchSignal; 54 import org.onosproject.net.OchSignal;
55 +import org.onosproject.net.OduCltPort;
40 import org.onosproject.net.OduSignalType; 56 import org.onosproject.net.OduSignalType;
41 import org.onosproject.net.Port; 57 import org.onosproject.net.Port;
42 import org.onosproject.net.PortNumber; 58 import org.onosproject.net.PortNumber;
...@@ -49,6 +65,7 @@ import org.onosproject.net.device.DeviceProvider; ...@@ -49,6 +65,7 @@ import org.onosproject.net.device.DeviceProvider;
49 import org.onosproject.net.device.DeviceProviderRegistry; 65 import org.onosproject.net.device.DeviceProviderRegistry;
50 import org.onosproject.net.device.DeviceProviderService; 66 import org.onosproject.net.device.DeviceProviderService;
51 import org.onosproject.net.device.OchPortDescription; 67 import org.onosproject.net.device.OchPortDescription;
68 +import org.onosproject.net.device.OduCltPortDescription;
52 import org.onosproject.net.device.OmsPortDescription; 69 import org.onosproject.net.device.OmsPortDescription;
53 import org.onosproject.net.device.PortDescription; 70 import org.onosproject.net.device.PortDescription;
54 import org.onosproject.net.device.PortStatistics; 71 import org.onosproject.net.device.PortStatistics;
...@@ -64,13 +81,19 @@ import org.onosproject.openflow.controller.PortDescPropertyType; ...@@ -64,13 +81,19 @@ import org.onosproject.openflow.controller.PortDescPropertyType;
64 import org.onosproject.openflow.controller.RoleState; 81 import org.onosproject.openflow.controller.RoleState;
65 import org.osgi.service.component.ComponentContext; 82 import org.osgi.service.component.ComponentContext;
66 import org.projectfloodlight.openflow.protocol.OFCalientPortDescStatsEntry; 83 import org.projectfloodlight.openflow.protocol.OFCalientPortDescStatsEntry;
84 +import org.projectfloodlight.openflow.protocol.OFExpPort;
85 +import org.projectfloodlight.openflow.protocol.OFExpPortDescPropOpticalTransport;
86 +import org.projectfloodlight.openflow.protocol.OFExpPortOpticalTransportLayerEntry;
67 import org.projectfloodlight.openflow.protocol.OFFactory; 87 import org.projectfloodlight.openflow.protocol.OFFactory;
68 import org.projectfloodlight.openflow.protocol.OFMessage; 88 import org.projectfloodlight.openflow.protocol.OFMessage;
89 +import org.projectfloodlight.openflow.protocol.OFObject;
69 import org.projectfloodlight.openflow.protocol.OFPortConfig; 90 import org.projectfloodlight.openflow.protocol.OFPortConfig;
70 import org.projectfloodlight.openflow.protocol.OFPortDesc; 91 import org.projectfloodlight.openflow.protocol.OFPortDesc;
71 import org.projectfloodlight.openflow.protocol.OFPortDescPropOpticalTransport; 92 import org.projectfloodlight.openflow.protocol.OFPortDescPropOpticalTransport;
72 import org.projectfloodlight.openflow.protocol.OFPortFeatures; 93 import org.projectfloodlight.openflow.protocol.OFPortFeatures;
73 import org.projectfloodlight.openflow.protocol.OFPortOptical; 94 import org.projectfloodlight.openflow.protocol.OFPortOptical;
95 +import org.projectfloodlight.openflow.protocol.OFPortOpticalTransportLayerClass;
96 +import org.projectfloodlight.openflow.protocol.OFPortOpticalTransportSignalType;
74 import org.projectfloodlight.openflow.protocol.OFPortReason; 97 import org.projectfloodlight.openflow.protocol.OFPortReason;
75 import org.projectfloodlight.openflow.protocol.OFPortState; 98 import org.projectfloodlight.openflow.protocol.OFPortState;
76 import org.projectfloodlight.openflow.protocol.OFPortStatsEntry; 99 import org.projectfloodlight.openflow.protocol.OFPortStatsEntry;
...@@ -83,23 +106,10 @@ import org.projectfloodlight.openflow.protocol.OFVersion; ...@@ -83,23 +106,10 @@ import org.projectfloodlight.openflow.protocol.OFVersion;
83 import org.projectfloodlight.openflow.types.PortSpeed; 106 import org.projectfloodlight.openflow.types.PortSpeed;
84 import org.slf4j.Logger; 107 import org.slf4j.Logger;
85 108
86 -import java.util.ArrayList; 109 +import com.google.common.base.Strings;
87 -import java.util.Collection; 110 +import com.google.common.collect.Lists;
88 -import java.util.Collections; 111 +import com.google.common.collect.Maps;
89 -import java.util.Dictionary; 112 +import com.google.common.collect.Sets;
90 -import java.util.HashMap;
91 -import java.util.HashSet;
92 -import java.util.List;
93 -
94 -import static com.google.common.base.Preconditions.checkArgument;
95 -import static com.google.common.base.Strings.isNullOrEmpty;
96 -import static org.onlab.util.Tools.get;
97 -import static org.onosproject.net.DeviceId.deviceId;
98 -import static org.onosproject.net.Port.Type.COPPER;
99 -import static org.onosproject.net.Port.Type.FIBER;
100 -import static org.onosproject.openflow.controller.Dpid.dpid;
101 -import static org.onosproject.openflow.controller.Dpid.uri;
102 -import static org.slf4j.LoggerFactory.getLogger;
103 113
104 /** 114 /**
105 * Provider which uses an OpenFlow controller to detect network 115 * Provider which uses an OpenFlow controller to detect network
...@@ -110,6 +120,9 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -110,6 +120,9 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
110 120
111 private static final Logger LOG = getLogger(OpenFlowDeviceProvider.class); 121 private static final Logger LOG = getLogger(OpenFlowDeviceProvider.class);
112 private static final long MBPS = 1_000 * 1_000; 122 private static final long MBPS = 1_000 * 1_000;
123 + private static final Frequency FREQ100 = Frequency.ofGHz(100);
124 + private static final Frequency FREQ193_1 = Frequency.ofTHz(193.1);
125 + private static final Frequency FREQ4_4 = Frequency.ofTHz(4.4);
113 126
114 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 127 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
115 protected DeviceProviderRegistry providerRegistry; 128 protected DeviceProviderRegistry providerRegistry;
...@@ -386,16 +399,25 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -386,16 +399,25 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
386 */ 399 */
387 private List<PortDescription> buildPortDescriptions(OpenFlowSwitch sw) { 400 private List<PortDescription> buildPortDescriptions(OpenFlowSwitch sw) {
388 final List<PortDescription> portDescs = new ArrayList<>(sw.getPorts().size()); 401 final List<PortDescription> portDescs = new ArrayList<>(sw.getPorts().size());
402 + if (!(Device.Type.ROADM.equals(sw.deviceType()))) {
389 sw.getPorts().forEach(port -> portDescs.add(buildPortDescription(port))); 403 sw.getPorts().forEach(port -> portDescs.add(buildPortDescription(port)));
404 + }
390 405
391 OpenFlowOpticalSwitch opsw; 406 OpenFlowOpticalSwitch opsw;
392 switch (sw.deviceType()) { 407 switch (sw.deviceType()) {
393 case ROADM: 408 case ROADM:
394 opsw = (OpenFlowOpticalSwitch) sw; 409 opsw = (OpenFlowOpticalSwitch) sw;
410 + List<OFPortDesc> ports = opsw.getPorts();
411 + LOG.debug("SW ID {} , ETH- ODU CLT Ports {}", opsw.getId(), ports);
412 + // ODU client ports are reported as ETH
413 + ports.forEach(port -> portDescs.add(buildOduCltPortDescription(port)));
414 +
395 opsw.getPortTypes().forEach(type -> { 415 opsw.getPortTypes().forEach(type -> {
396 - opsw.getPortsOf(type).forEach( 416 + List<? extends OFObject> portsOf = opsw.getPortsOf(type);
417 + LOG.debug("Ports Of{}", portsOf);
418 + portsOf.forEach(
397 op -> { 419 op -> {
398 - portDescs.add(buildPortDescription(type, (OFPortOptical) op)); 420 + portDescs.add(buildPortDescription(type, (OFObject) op));
399 } 421 }
400 ); 422 );
401 }); 423 });
...@@ -417,6 +439,105 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -417,6 +439,105 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
417 return portDescs; 439 return portDescs;
418 } 440 }
419 441
442 + private PortDescription buildOduCltPortDescription(OFPortDesc port) {
443 + PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
444 + boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN) &&
445 + !port.getConfig().contains(OFPortConfig.PORT_DOWN);
446 + Long portSpeed = portSpeed(port);
447 + OduCltPort.SignalType sigType = null;
448 +
449 + switch (portSpeed.toString()) {
450 + case "1":
451 + sigType = OduCltPort.SignalType.CLT_1GBE;
452 + break;
453 + case "10":
454 + sigType = OduCltPort.SignalType.CLT_10GBE;
455 + break;
456 + case "40":
457 + sigType = OduCltPort.SignalType.CLT_40GBE;
458 + break;
459 + case "100":
460 + sigType = OduCltPort.SignalType.CLT_100GBE;
461 + break;
462 + default:
463 + throw new RuntimeException("Un recognize OduClt speed: " + portSpeed.toString());
464 + }
465 +
466 + SparseAnnotations annotations = buildOduCltAnnotation(port);
467 + return new OduCltPortDescription(portNo, enabled, sigType, annotations);
468 + }
469 +
470 + private SparseAnnotations buildOduCltAnnotation(OFPortDesc port) {
471 + SparseAnnotations annotations = null;
472 + String portName = Strings.emptyToNull(port.getName());
473 + if (portName != null) {
474 + annotations = DefaultAnnotations.builder()
475 + .set(AnnotationKeys.PORT_NAME, portName)
476 + .set(AnnotationKeys.STATIC_PORT, Boolean.TRUE.toString()).build();
477 + }
478 + return annotations;
479 + }
480 +
481 + private PortDescription buildPortDescription(PortDescPropertyType ptype, OFObject port) {
482 + if (port instanceof OFPortOptical) {
483 + return buildPortDescription(ptype, (OFPortOptical) port);
484 + }
485 + return buildPortDescription(ptype, (OFExpPort) port);
486 + }
487 +
488 + /**
489 + * Build a portDescription from a given a port description describing some
490 + * Optical port.
491 + *
492 + * @param ptype description property type.
493 + * @param port the port to build from.
494 + * @return portDescription for the port.
495 + */
496 + private PortDescription buildPortDescription(PortDescPropertyType ptype, OFExpPort port) {
497 + PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
498 + boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN)
499 + && !port.getConfig().contains(OFPortConfig.PORT_DOWN);
500 + SparseAnnotations annotations = makePortNameAnnotation(port.getName());
501 +
502 + OFExpPortDescPropOpticalTransport firstProp = port.getProperties().get(0);
503 + OFPortOpticalTransportSignalType sigType = firstProp.getPortSignalType();
504 +
505 + DefaultPortDescription portDes = null;
506 + switch (sigType) {
507 + case OMSN:
508 + portDes = new OmsPortDescription(portNo, enabled, FREQ193_1, FREQ193_1.add(FREQ4_4),
509 + FREQ100, annotations);
510 + break;
511 + case OCH:
512 + OFExpPortOpticalTransportLayerEntry entry = firstProp.getFeatures().get(0).getValue().get(0);
513 + OFPortOpticalTransportLayerClass layerClass = entry.getLayerClass();
514 + if (!OFPortOpticalTransportLayerClass.ODU.equals(layerClass)) {
515 + LOG.error("Unsupported layer Class {} ", layerClass);
516 + return null;
517 + }
518 +
519 + // convert to ONOS OduSignalType
520 + OduSignalType oduSignalType = OpenFlowDeviceValueMapper.
521 + lookupOduSignalType((byte) entry.getSignalType());
522 + //OchSignal is needed for OchPortDescription constructor,
523 + //yet not relevant for tunable OCH port, creating with default parameters
524 + OchSignal signalId = new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 1, 1);
525 +
526 + portDes = new OchPortDescription(portNo, enabled,
527 + oduSignalType, true, signalId, annotations);
528 +
529 + break;
530 + case OTU2:
531 + case OTU4:
532 + LOG.error("Signal tpye OTU2/4 not supported yet ", port.toString());
533 + break;
534 + default:
535 + break;
536 + }
537 +
538 + return portDes;
539 + }
540 +
420 /** 541 /**
421 * Creates an annotation for the port name if one is available. 542 * Creates an annotation for the port name if one is available.
422 * 543 *
...@@ -565,5 +686,4 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -565,5 +686,4 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
565 } 686 }
566 } 687 }
567 } 688 }
568 -
569 } 689 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.provider.of.device.impl;
17 +
18 +import org.onosproject.net.OduSignalType;
19 +
20 +import com.google.common.collect.BiMap;
21 +import com.google.common.collect.EnumHashBiMap;
22 +
23 +/**
24 + * Collection of helper methods to convert protocol agnostic models to values used in OpenFlow spec.
25 + */
26 +final class OpenFlowDeviceValueMapper {
27 +
28 + // prohibit instantiation
29 + private OpenFlowDeviceValueMapper() {}
30 +
31 + private static final BiMap<OduSignalType, Byte> ODU_SIGNAL_TYPES = EnumHashBiMap.create(OduSignalType.class);
32 + static {
33 + // See ONF "Optical Transport Protocol Extensions Version 1.0" for the following values
34 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU1, (byte) 1); // OFPODUT_ODU1 of enum ofp_odu_signal_type
35 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU2, (byte) 2); // OFPODUT_ODU2 of enum ofp_odu_signal_type
36 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU3, (byte) 3); // OFPODUT_ODU3 of enum ofp_odu_signal_type
37 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU4, (byte) 4); // OFPODUT_ODU4 of enum ofp_odu_signal_type
38 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU0, (byte) 10); // OFPODUT_ODU0 of enum ofp_odu_signal_type
39 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU2e, (byte) 11); // OFPODUT_ODU2E of enum ofp_odu_signal_type
40 + }
41 +
42 + /**
43 + * Looks up the specified input value to the corresponding value with the specified map.
44 + *
45 + * @param map bidirectional mapping
46 + * @param input input value
47 + * @param cls class of output value
48 + * @param <I> type of input value
49 + * @param <O> type of output value
50 + * @return the corresponding value stored in the specified map
51 + */
52 + private static <I, O> O lookup(BiMap<I, O> map, I input, Class<O> cls) {
53 + if (!map.containsKey(input)) {
54 + throw new RuntimeException(
55 + String.format("No mapping found for %s when converting to %s", input, cls.getName()));
56 + }
57 +
58 + return map.get(input);
59 + }
60 +
61 + /**
62 + * Looks up the the corresponding {@link OduSignalType} instance
63 + * from the specified byte value for ODU signal type defined in
64 + * ONF "Optical Transport Protocol Extensions Version 1.0".
65 + *
66 + * @param signalType byte value as ODU (Optical channel Data Unit) signal type defined the spec
67 + * @return the corresponding OchSignalType instance
68 + */
69 + static OduSignalType lookupOduSignalType(byte signalType) {
70 + return lookup(ODU_SIGNAL_TYPES.inverse(), signalType, OduSignalType.class);
71 + }
72 +
73 +}