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