blob: be372f3cf5c2518b870b9fb82eedb7e064701670 [file] [log] [blame]
MaoLu819fde22017-04-20 17:17:49 -07001/*
2 * Copyright 2016 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
17package org.onosproject.drivers.oplink;
18
MaoLue00b7422017-05-11 20:27:35 -070019import com.google.common.collect.Range;
MaoLu819fde22017-04-20 17:17:49 -070020import org.onlab.util.Frequency;
21import org.onosproject.core.CoreService;
22import org.onosproject.driver.extensions.OplinkAttenuation;
23import org.onosproject.net.ChannelSpacing;
24import org.onosproject.net.GridType;
25import org.onosproject.net.Lambda;
26import org.onosproject.net.OchSignalType;
27import org.onosproject.net.PortNumber;
28import org.onosproject.net.driver.HandlerBehaviour;
29import org.onosproject.net.flow.DefaultFlowRule;
30import org.onosproject.net.flow.DefaultTrafficSelector;
31import org.onosproject.net.flow.DefaultTrafficTreatment;
32import org.onosproject.net.flow.FlowEntry;
33import org.onosproject.net.flow.FlowRule;
34import org.onosproject.net.flow.FlowRuleService;
35import org.onosproject.net.flow.TrafficSelector;
36import org.onosproject.net.flow.TrafficTreatment;
37import org.onosproject.net.flow.criteria.Criteria;
38import org.onosproject.net.flow.criteria.Criterion;
39import org.onosproject.net.flow.criteria.OchSignalCriterion;
40import org.onosproject.net.flow.criteria.PortCriterion;
41import org.onosproject.net.flow.instructions.Instruction;
42import org.onosproject.net.flow.instructions.Instructions;
43
44import java.util.List;
45import java.util.Set;
46
47/**
48 * Oplink optical utilities.
49 */
50public final class OplinkOpticalUtility {
51
52 // Lambda information supported by device.
53 public static final GridType GRID_TYPE = GridType.DWDM;
54 public static final int SLOT_GRANULARITY = 4;
55 // Channel spacing is 50GHz, 12.5GHz * 4
56 public static final ChannelSpacing CHANNEL_SPACING = ChannelSpacing.CHL_50GHZ;
57 // Start frequency supported by device.
58 public static final Frequency START_CENTER_FREQ = Frequency.ofGHz(191_350);
59 // Stop frequency supported by device.
60 public static final Frequency STOP_CENTER_FREQ = Frequency.ofGHz(196_100);
61
62 // Power multiply factor, the power accuracy supported by device is 0.01dBm.
63 // Transforms the double typed number to long typed power for ONOS.
64 public static final int POWER_MULTIPLIER = 100;
MaoLue00b7422017-05-11 20:27:35 -070065 // Attenuation range supported by device, [0, 25.5dB].
66 public static final Range<Long> RANGE_ATT = Range.closed(0L, 2550L);
67 // General power range for fiber switch, [-60dBm, 60dBm].
68 public static final Range<Long> RANGE_GENERAL = Range.closed(-6000L, 6000L);
MaoLu819fde22017-04-20 17:17:49 -070069
70 // Default attenuation value if the attenuation instruction is not found.
71 private static final int DEFAULT_ATT = 0;
72 // Default flow priority for an extra flow.
73 private static final int DEFAULT_PRIORITY = 88;
74 // Default application name.
75 private static final String DEFAULT_APP = "org.onosproject.drivers.oplink";
76
77 private OplinkOpticalUtility() {
78 }
79
80 /**
81 * Transforms a flow FlowRule object to an OplinkCrossConnect object.
82 * @param behaviour the parent driver handler
83 * @param rule FlowRule object
84 * @return cross connect object
85 */
86 public static OplinkCrossConnect fromFlowRule(HandlerBehaviour behaviour, FlowRule rule) {
87 // TrafficSelector
88 Set<Criterion> criterions = rule.selector().criteria();
89 int channel = criterions.stream()
90 .filter(c -> c instanceof OchSignalCriterion)
91 .map(c -> ((OchSignalCriterion) c).lambda().spacingMultiplier())
92 .findAny()
93 .orElse(null);
94 PortNumber inPort = criterions.stream()
95 .filter(c -> c instanceof PortCriterion)
96 .map(c -> ((PortCriterion) c).port())
97 .findAny()
98 .orElse(null);
99 // TrafficTreatment
100 List<Instruction> instructions = rule.treatment().immediate();
101 PortNumber outPort = instructions.stream()
102 .filter(c -> c instanceof Instructions.OutputInstruction)
103 .map(c -> ((Instructions.OutputInstruction) c).port())
104 .findAny()
105 .orElse(null);
106 int attenuation = instructions.stream()
107 .filter(c -> c instanceof Instructions.ExtensionInstructionWrapper)
108 .map(c -> ((Instructions.ExtensionInstructionWrapper) c).extensionInstruction())
109 .filter(c -> c instanceof OplinkAttenuation)
110 .map(c -> ((OplinkAttenuation) c).getAttenuation())
111 .findAny()
112 .orElse(DEFAULT_ATT);
113 return new OplinkCrossConnect(inPort, outPort, channel, attenuation);
114 }
115
116 /**
117 * Finds the FlowRule from flow rule store by the given cross connect information.
118 * Returns an extra flow to remove the flow by ONOS if not found.
119 * @param behaviour the parent driver handler
120 * @param cfg cross connect information
121 * @return the flow rule
122 */
123 public static FlowRule toFlowRule(HandlerBehaviour behaviour, OplinkCrossConnect cfg) {
124 return toFlowRule(behaviour, cfg.getInPort(), cfg.getOutPort(), cfg.getChannel());
125 }
126
127 /**
128 * Finds the FlowRule from flow rule store by the given ports and channel.
129 * Returns an extra flow to remove the flow by ONOS if not found.
130 * @param behaviour the parent driver handler
131 * @param inPort the input port
132 * @param outPort the output port
133 * @param channel the specified channel
134 * @return the flow rule
135 */
136 public static FlowRule toFlowRule(HandlerBehaviour behaviour, PortNumber inPort,
137 PortNumber outPort, Integer channel) {
138 FlowRuleService service = behaviour.handler().get(FlowRuleService.class);
139 Iterable<FlowEntry> entries = service.getFlowEntries(behaviour.data().deviceId());
140 // Try to Find the flow from flow rule store.
141 for (FlowEntry entry : entries) {
142 Set<Criterion> criterions = entry.selector().criteria();
143 // input port
144 PortNumber ip = criterions.stream()
145 .filter(c -> c instanceof PortCriterion)
146 .map(c -> ((PortCriterion) c).port())
147 .findAny()
148 .orElse(null);
149 // channel
150 Integer ch = criterions.stream()
151 .filter(c -> c instanceof OchSignalCriterion)
152 .map(c -> ((OchSignalCriterion) c).lambda().spacingMultiplier())
153 .findAny()
154 .orElse(null);
155 // output port
156 PortNumber op = entry.treatment().immediate().stream()
157 .filter(c -> c instanceof Instructions.OutputInstruction)
158 .map(c -> ((Instructions.OutputInstruction) c).port())
159 .findAny()
160 .orElse(null);
161 if (inPort.equals(ip) && channel.equals(ch) && outPort.equals(op)) {
162 // Find the flow.
163 return entry;
164 }
165 }
166 // Cannot find the flow from store. So report an extra flow to remove the flow by ONOS.
167 TrafficSelector selector = DefaultTrafficSelector.builder()
168 .matchInPort(inPort)
169 .add(Criteria.matchOchSignalType(OchSignalType.FIXED_GRID))
170 .add(Criteria.matchLambda(Lambda.ochSignal(GRID_TYPE, CHANNEL_SPACING, channel, SLOT_GRANULARITY)))
171 .build();
172 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
173 .setOutput(outPort)
174 .build();
175 return DefaultFlowRule.builder()
176 .forDevice(behaviour.data().deviceId())
177 .withSelector(selector)
178 .withTreatment(treatment)
179 .withPriority(DEFAULT_PRIORITY)
180 .fromApp(behaviour.handler().get(CoreService.class).getAppId(DEFAULT_APP))
181 .build();
182
183 }
184}