Implementation of lambda query behaviour for LINC and Calient drivers.
ONOS-3431 Change-Id: I03b7e7c9d2b0ba7e55d09745cfc6ceb57cc6eb5e
Showing
6 changed files
with
129 additions
and
13 deletions
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.net; | ||
17 | + | ||
18 | +import java.util.Comparator; | ||
19 | + | ||
20 | +import static com.google.common.base.Preconditions.checkArgument; | ||
21 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
22 | + | ||
23 | +/** | ||
24 | + * Comparator implementation for OchSignal. Assumes identical grid type and channel spacing. | ||
25 | + */ | ||
26 | +public class DefaultOchSignalComparator implements Comparator<OchSignal> { | ||
27 | + @Override | ||
28 | + public int compare(OchSignal o1, OchSignal o2) { | ||
29 | + checkNotNull(o1.gridType()); | ||
30 | + checkNotNull(o1.channelSpacing()); | ||
31 | + | ||
32 | + checkArgument(o1.gridType().equals(o2.gridType())); | ||
33 | + checkArgument(o1.channelSpacing().equals(o2.channelSpacing())); | ||
34 | + | ||
35 | + return o1.spacingMultiplier() * o1.slotGranularity() - o2.spacingMultiplier() * o2.slotGranularity(); | ||
36 | + } | ||
37 | +} |
... | @@ -17,6 +17,7 @@ package org.onosproject.net; | ... | @@ -17,6 +17,7 @@ package org.onosproject.net; |
17 | 17 | ||
18 | import com.google.common.base.MoreObjects; | 18 | import com.google.common.base.MoreObjects; |
19 | import org.onlab.util.Frequency; | 19 | import org.onlab.util.Frequency; |
20 | +import org.onlab.util.Spectrum; | ||
20 | 21 | ||
21 | import java.util.Objects; | 22 | import java.util.Objects; |
22 | 23 | ||
... | @@ -32,7 +33,6 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -32,7 +33,6 @@ import static com.google.common.base.Preconditions.checkNotNull; |
32 | */ | 33 | */ |
33 | public class OchSignal implements Lambda { | 34 | public class OchSignal implements Lambda { |
34 | 35 | ||
35 | - public static final Frequency CENTER_FREQUENCY = Frequency.ofTHz(193.1); | ||
36 | public static final Frequency FLEX_GRID_SLOT = Frequency.ofGHz(12.5); | 36 | public static final Frequency FLEX_GRID_SLOT = Frequency.ofGHz(12.5); |
37 | private static final GridType DEFAULT_OCH_GRIDTYPE = GridType.DWDM; | 37 | private static final GridType DEFAULT_OCH_GRIDTYPE = GridType.DWDM; |
38 | private static final ChannelSpacing DEFAULT_CHANNEL_SPACING = ChannelSpacing.CHL_50GHZ; | 38 | private static final ChannelSpacing DEFAULT_CHANNEL_SPACING = ChannelSpacing.CHL_50GHZ; |
... | @@ -78,7 +78,7 @@ public class OchSignal implements Lambda { | ... | @@ -78,7 +78,7 @@ public class OchSignal implements Lambda { |
78 | 78 | ||
79 | this.gridType = DEFAULT_OCH_GRIDTYPE; | 79 | this.gridType = DEFAULT_OCH_GRIDTYPE; |
80 | this.channelSpacing = DEFAULT_CHANNEL_SPACING; | 80 | this.channelSpacing = DEFAULT_CHANNEL_SPACING; |
81 | - this.spacingMultiplier = (int) (centerFrequency.subtract(OchSignal.CENTER_FREQUENCY).asHz() / grid.asHz()); | 81 | + this.spacingMultiplier = (int) (centerFrequency.subtract(Spectrum.CENTER_FREQUENCY).asHz() / grid.asHz()); |
82 | this.slotGranularity = (int) Math.round((double) grid.asHz() / ChannelSpacing.CHL_12P5GHZ.frequency().asHz()); | 82 | this.slotGranularity = (int) Math.round((double) grid.asHz() / ChannelSpacing.CHL_12P5GHZ.frequency().asHz()); |
83 | } | 83 | } |
84 | 84 | ||
... | @@ -86,7 +86,7 @@ public class OchSignal implements Lambda { | ... | @@ -86,7 +86,7 @@ public class OchSignal implements Lambda { |
86 | this.gridType = DEFAULT_OCH_GRIDTYPE; | 86 | this.gridType = DEFAULT_OCH_GRIDTYPE; |
87 | this.channelSpacing = channelSpacing; | 87 | this.channelSpacing = channelSpacing; |
88 | this.spacingMultiplier = (int) Math.round((double) centerFrequency. | 88 | this.spacingMultiplier = (int) Math.round((double) centerFrequency. |
89 | - subtract(OchSignal.CENTER_FREQUENCY).asHz() / channelSpacing().frequency().asHz()); | 89 | + subtract(Spectrum.CENTER_FREQUENCY).asHz() / channelSpacing().frequency().asHz()); |
90 | this.slotGranularity = slotGranularity; | 90 | this.slotGranularity = slotGranularity; |
91 | } | 91 | } |
92 | 92 | ||
... | @@ -132,7 +132,7 @@ public class OchSignal implements Lambda { | ... | @@ -132,7 +132,7 @@ public class OchSignal implements Lambda { |
132 | * @return frequency in MHz | 132 | * @return frequency in MHz |
133 | */ | 133 | */ |
134 | public Frequency centralFrequency() { | 134 | public Frequency centralFrequency() { |
135 | - return CENTER_FREQUENCY.add(channelSpacing().frequency().multiply(spacingMultiplier)); | 135 | + return Spectrum.CENTER_FREQUENCY.add(channelSpacing().frequency().multiply(spacingMultiplier)); |
136 | } | 136 | } |
137 | 137 | ||
138 | /** | 138 | /** | ... | ... |
... | @@ -17,7 +17,14 @@ package org.onosproject.driver.handshaker; | ... | @@ -17,7 +17,14 @@ package org.onosproject.driver.handshaker; |
17 | 17 | ||
18 | import com.google.common.collect.ImmutableList; | 18 | import com.google.common.collect.ImmutableList; |
19 | import com.google.common.collect.ImmutableSet; | 19 | import com.google.common.collect.ImmutableSet; |
20 | +import org.onlab.util.Spectrum; | ||
21 | +import org.onosproject.net.ChannelSpacing; | ||
22 | +import org.onosproject.net.DefaultOchSignalComparator; | ||
20 | import org.onosproject.net.Device; | 23 | import org.onosproject.net.Device; |
24 | +import org.onosproject.net.GridType; | ||
25 | +import org.onosproject.net.OchSignal; | ||
26 | +import org.onosproject.net.PortNumber; | ||
27 | +import org.onosproject.net.behaviour.LambdaQuery; | ||
21 | import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; | 28 | import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; |
22 | import org.onosproject.openflow.controller.PortDescPropertyType; | 29 | import org.onosproject.openflow.controller.PortDescPropertyType; |
23 | import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; | 30 | import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; |
... | @@ -41,9 +48,24 @@ import java.io.IOException; | ... | @@ -41,9 +48,24 @@ import java.io.IOException; |
41 | import java.util.ArrayList; | 48 | import java.util.ArrayList; |
42 | import java.util.List; | 49 | import java.util.List; |
43 | import java.util.Set; | 50 | import java.util.Set; |
51 | +import java.util.SortedSet; | ||
52 | +import java.util.TreeSet; | ||
44 | import java.util.concurrent.atomic.AtomicBoolean; | 53 | import java.util.concurrent.atomic.AtomicBoolean; |
54 | +import java.util.stream.Collectors; | ||
55 | +import java.util.stream.IntStream; | ||
45 | 56 | ||
46 | -public class CalientFiberSwitchHandshaker extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch { | 57 | +/** |
58 | + * Driver for Calient S160 Optical Circuit Switch. Untested on Calient S320 but probably works ok. | ||
59 | + * | ||
60 | + * Driver implements custom handshaker, and rewrites flow stats as expected by the device. Port stats are currently | ||
61 | + * not supported. | ||
62 | + * | ||
63 | + * The device consists of OMS ports only, and each port exposes lambda resources covering the whole | ||
64 | + * usable optical spectrum (U to O band, see {@link Spectrum} for spectrum definitions). | ||
65 | + */ | ||
66 | +public class CalientFiberSwitchHandshaker | ||
67 | + extends AbstractOpenFlowSwitch | ||
68 | + implements OpenFlowOpticalSwitch, LambdaQuery { | ||
47 | 69 | ||
48 | private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false); | 70 | private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false); |
49 | private List<OFCalientPortDescStatsEntry> fiberPorts = new ArrayList<>(); | 71 | private List<OFCalientPortDescStatsEntry> fiberPorts = new ArrayList<>(); |
... | @@ -178,4 +200,22 @@ public class CalientFiberSwitchHandshaker extends AbstractOpenFlowSwitch impleme | ... | @@ -178,4 +200,22 @@ public class CalientFiberSwitchHandshaker extends AbstractOpenFlowSwitch impleme |
178 | 200 | ||
179 | super.sendMsg(newMsg); | 201 | super.sendMsg(newMsg); |
180 | } | 202 | } |
203 | + | ||
204 | + @Override | ||
205 | + public SortedSet<OchSignal> queryLambdas(PortNumber port) { | ||
206 | + // S160 data sheet | ||
207 | + // Wavelength range: 1260 - 1630 nm | ||
208 | + long startSpacingMultiplier = Spectrum.U_BAND_MIN.subtract(Spectrum.CENTER_FREQUENCY).asHz() / | ||
209 | + ChannelSpacing.CHL_12P5GHZ.frequency().asHz(); | ||
210 | + long stopSpacingMultiplier = Spectrum.O_BAND_MAX.subtract(Spectrum.CENTER_FREQUENCY).asHz() / | ||
211 | + ChannelSpacing.CHL_12P5GHZ.frequency().asHz(); | ||
212 | + List<OchSignal> lambdas = IntStream.rangeClosed((int) startSpacingMultiplier, (int) stopSpacingMultiplier) | ||
213 | + .mapToObj(x -> new OchSignal(GridType.FLEX, ChannelSpacing.CHL_12P5GHZ, x, 1)) | ||
214 | + .collect(Collectors.toList()); | ||
215 | + | ||
216 | + SortedSet<OchSignal> result = new TreeSet<>(new DefaultOchSignalComparator()); | ||
217 | + result.addAll(lambdas); | ||
218 | + | ||
219 | + return result; | ||
220 | + } | ||
181 | } | 221 | } | ... | ... |
... | @@ -16,7 +16,13 @@ | ... | @@ -16,7 +16,13 @@ |
16 | package org.onosproject.driver.handshaker; | 16 | package org.onosproject.driver.handshaker; |
17 | 17 | ||
18 | import com.google.common.collect.ImmutableSet; | 18 | import com.google.common.collect.ImmutableSet; |
19 | +import org.onosproject.net.ChannelSpacing; | ||
20 | +import org.onosproject.net.DefaultOchSignalComparator; | ||
19 | import org.onosproject.net.Device; | 21 | import org.onosproject.net.Device; |
22 | +import org.onosproject.net.GridType; | ||
23 | +import org.onosproject.net.OchSignal; | ||
24 | +import org.onosproject.net.PortNumber; | ||
25 | +import org.onosproject.net.behaviour.LambdaQuery; | ||
20 | import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; | 26 | import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; |
21 | import org.onosproject.openflow.controller.PortDescPropertyType; | 27 | import org.onosproject.openflow.controller.PortDescPropertyType; |
22 | import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; | 28 | import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; |
... | @@ -42,7 +48,6 @@ import org.projectfloodlight.openflow.protocol.match.Match; | ... | @@ -42,7 +48,6 @@ import org.projectfloodlight.openflow.protocol.match.Match; |
42 | import org.projectfloodlight.openflow.protocol.match.MatchField; | 48 | import org.projectfloodlight.openflow.protocol.match.MatchField; |
43 | import org.projectfloodlight.openflow.protocol.oxm.OFOxmExpOchSigId; | 49 | import org.projectfloodlight.openflow.protocol.oxm.OFOxmExpOchSigId; |
44 | import org.projectfloodlight.openflow.types.CircuitSignalID; | 50 | import org.projectfloodlight.openflow.types.CircuitSignalID; |
45 | -import org.projectfloodlight.openflow.types.OFPort; | ||
46 | import org.projectfloodlight.openflow.types.U8; | 51 | import org.projectfloodlight.openflow.types.U8; |
47 | 52 | ||
48 | import java.io.IOException; | 53 | import java.io.IOException; |
... | @@ -51,7 +56,11 @@ import java.util.Collections; | ... | @@ -51,7 +56,11 @@ import java.util.Collections; |
51 | import java.util.LinkedList; | 56 | import java.util.LinkedList; |
52 | import java.util.List; | 57 | import java.util.List; |
53 | import java.util.Set; | 58 | import java.util.Set; |
59 | +import java.util.SortedSet; | ||
60 | +import java.util.TreeSet; | ||
54 | import java.util.concurrent.atomic.AtomicBoolean; | 61 | import java.util.concurrent.atomic.AtomicBoolean; |
62 | +import java.util.stream.Collectors; | ||
63 | +import java.util.stream.IntStream; | ||
55 | 64 | ||
56 | /** | 65 | /** |
57 | * LINC-OE Optical Emulator switch class. | 66 | * LINC-OE Optical Emulator switch class. |
... | @@ -65,10 +74,13 @@ import java.util.concurrent.atomic.AtomicBoolean; | ... | @@ -65,10 +74,13 @@ import java.util.concurrent.atomic.AtomicBoolean; |
65 | * As LINC implements custom OF optical extensions (in contrast to the final standard as specified in | 74 | * As LINC implements custom OF optical extensions (in contrast to the final standard as specified in |
66 | * ONF TS-022 (March 15, 2015), we need to rewrite flow stat requests and flow mods in {@link #sendMsg(OFMessage)}. | 75 | * ONF TS-022 (March 15, 2015), we need to rewrite flow stat requests and flow mods in {@link #sendMsg(OFMessage)}. |
67 | * | 76 | * |
77 | + * LINC exposes OchSignal resources: 80 lambdas of 50 GHz around ITU-T G.694.1 center frequency 193.1 GHz. | ||
78 | + * | ||
68 | */ | 79 | */ |
69 | public class OfOpticalSwitchImplLinc13 | 80 | public class OfOpticalSwitchImplLinc13 |
70 | - extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch { | 81 | + extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch, LambdaQuery { |
71 | 82 | ||
83 | + private static final int LAMBDA_COUNT = 80; | ||
72 | private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false); | 84 | private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false); |
73 | private long barrierXidToWaitFor = -1; | 85 | private long barrierXidToWaitFor = -1; |
74 | 86 | ||
... | @@ -267,13 +279,13 @@ public class OfOpticalSwitchImplLinc13 | ... | @@ -267,13 +279,13 @@ public class OfOpticalSwitchImplLinc13 |
267 | /** | 279 | /** |
268 | * Checks if given port is also part of the regular port desc stats, i.e., is the port a tap port. | 280 | * Checks if given port is also part of the regular port desc stats, i.e., is the port a tap port. |
269 | * | 281 | * |
270 | - * @param port given OF port | 282 | + * @param port given port number |
271 | * @return true if the port is a tap (OCh), false otherwise (OMS port) | 283 | * @return true if the port is a tap (OCh), false otherwise (OMS port) |
272 | */ | 284 | */ |
273 | - private boolean hasPort(OFPort port) { | 285 | + private boolean isOChPort(long port) { |
274 | for (OFPortDescStatsReply reply : this.ports) { | 286 | for (OFPortDescStatsReply reply : this.ports) { |
275 | for (OFPortDesc p : reply.getEntries()) { | 287 | for (OFPortDesc p : reply.getEntries()) { |
276 | - if (p.getPortNo().equals(port)) { | 288 | + if (p.getPortNo().getPortNumber() == port) { |
277 | return true; | 289 | return true; |
278 | } | 290 | } |
279 | } | 291 | } |
... | @@ -328,7 +340,7 @@ public class OfOpticalSwitchImplLinc13 | ... | @@ -328,7 +340,7 @@ public class OfOpticalSwitchImplLinc13 |
328 | short signalType; | 340 | short signalType; |
329 | 341 | ||
330 | // FIXME: use constants once loxi has full optical extensions | 342 | // FIXME: use constants once loxi has full optical extensions |
331 | - if (hasPort(p.getPortNo())) { | 343 | + if (isOChPort(p.getPortNo().getPortNumber())) { |
332 | signalType = 5; // OCH port | 344 | signalType = 5; // OCH port |
333 | } else { | 345 | } else { |
334 | signalType = 2; // OMS port | 346 | signalType = 2; // OMS port |
... | @@ -351,4 +363,23 @@ public class OfOpticalSwitchImplLinc13 | ... | @@ -351,4 +363,23 @@ public class OfOpticalSwitchImplLinc13 |
351 | public Set<PortDescPropertyType> getPortTypes() { | 363 | public Set<PortDescPropertyType> getPortTypes() { |
352 | return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT); | 364 | return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT); |
353 | } | 365 | } |
366 | + | ||
367 | + @Override | ||
368 | + public SortedSet<OchSignal> queryLambdas(PortNumber port) { | ||
369 | + // OCh ports don't have lambdas | ||
370 | + if (isOChPort(port.toLong())) { | ||
371 | + return Collections.emptySortedSet(); | ||
372 | + } | ||
373 | + | ||
374 | + // OMS ports expose 80 lambdas of 50GHz width, centered around the ITU-T center frequency. | ||
375 | + // We report these with a spacing of 12.5 GHz. | ||
376 | + List<OchSignal> lambdas = IntStream.range(0, LAMBDA_COUNT) | ||
377 | + .mapToObj(x -> new OchSignal(GridType.FLEX, ChannelSpacing.CHL_12P5GHZ, x - (LAMBDA_COUNT / 2), 1)) | ||
378 | + .collect(Collectors.toList()); | ||
379 | + | ||
380 | + SortedSet<OchSignal> result = new TreeSet<>(new DefaultOchSignalComparator()); | ||
381 | + result.addAll(lambdas); | ||
382 | + | ||
383 | + return result; | ||
384 | + } | ||
354 | } | 385 | } | ... | ... |
... | @@ -74,6 +74,8 @@ | ... | @@ -74,6 +74,8 @@ |
74 | swVersion="LINC-OE OpenFlow Software Switch 1.1"> | 74 | swVersion="LINC-OE OpenFlow Software Switch 1.1"> |
75 | <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | 75 | <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" |
76 | impl="org.onosproject.driver.handshaker.OfOpticalSwitchImplLinc13"/> | 76 | impl="org.onosproject.driver.handshaker.OfOpticalSwitchImplLinc13"/> |
77 | + <behaviour api="org.onosproject.net.behaviour.LambdaQuery" | ||
78 | + impl="org.onosproject.driver.handshaker.OfOpticalSwitchImplLinc13"/> | ||
77 | </driver> | 79 | </driver> |
78 | <driver name="corsa" | 80 | <driver name="corsa" |
79 | manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1"> | 81 | manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1"> |
... | @@ -135,6 +137,8 @@ | ... | @@ -135,6 +137,8 @@ |
135 | swVersion="ocs switch"> | 137 | swVersion="ocs switch"> |
136 | <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | 138 | <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" |
137 | impl="org.onosproject.driver.handshaker.CalientFiberSwitchHandshaker"/> | 139 | impl="org.onosproject.driver.handshaker.CalientFiberSwitchHandshaker"/> |
140 | + <behaviour api="org.onosproject.net.behaviour.LambdaQuery" | ||
141 | + impl="org.onosproject.driver.handshaker.CalientFiberSwitchHandshaker"/> | ||
138 | </driver> | 142 | </driver> |
139 | <driver name="onosfw" extends="ovs" | 143 | <driver name="onosfw" extends="ovs" |
140 | manufacturer="" hwVersion="" swVersion=""> | 144 | manufacturer="" hwVersion="" swVersion=""> | ... | ... |
... | @@ -19,11 +19,12 @@ package org.onlab.util; | ... | @@ -19,11 +19,12 @@ package org.onlab.util; |
19 | * Telecom optical wavelength bands: O, E, S, C, L and U bands. | 19 | * Telecom optical wavelength bands: O, E, S, C, L and U bands. |
20 | * | 20 | * |
21 | * See ITU-T G-Series Recommendations, Supplement 39 | 21 | * See ITU-T G-Series Recommendations, Supplement 39 |
22 | + * See ITU-T G.694.1 for center frequency definition. | ||
22 | */ | 23 | */ |
23 | public final class Spectrum { | 24 | public final class Spectrum { |
24 | 25 | ||
25 | - private Spectrum() { | 26 | + // Center frequency |
26 | - } | 27 | + public static final Frequency CENTER_FREQUENCY = Frequency.ofTHz(193.1); |
27 | 28 | ||
28 | // O band (original): 1260 to 1360 nm | 29 | // O band (original): 1260 to 1360 nm |
29 | public static final Frequency O_BAND_MIN = Frequency.ofTHz(220.436); | 30 | public static final Frequency O_BAND_MIN = Frequency.ofTHz(220.436); |
... | @@ -48,4 +49,7 @@ public final class Spectrum { | ... | @@ -48,4 +49,7 @@ public final class Spectrum { |
48 | // U band (ultra-long wavelength): 1625 to 1675 nm | 49 | // U band (ultra-long wavelength): 1625 to 1675 nm |
49 | public static final Frequency U_BAND_MIN = Frequency.ofTHz(178.981); | 50 | public static final Frequency U_BAND_MIN = Frequency.ofTHz(178.981); |
50 | public static final Frequency U_BAND_MAX = Frequency.ofTHz(184.488); | 51 | public static final Frequency U_BAND_MAX = Frequency.ofTHz(184.488); |
52 | + | ||
53 | + private Spectrum() { | ||
54 | + } | ||
51 | } | 55 | } | ... | ... |
-
Please register or login to post a comment