blob: d269843bc09268fec5f8cc833d40f6bbec729a31 [file] [log] [blame]
Sho SHIMIZUee2aa652015-02-25 18:56:43 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Sho SHIMIZUee2aa652015-02-25 18:56:43 -08003 *
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 */
Yuta HIGUCHId95d5902016-06-27 00:18:45 -070016package org.onosproject.net.optical.intent.impl.compiler;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080017
Marc De Leenheerb6f95e22017-03-15 12:18:59 -070018import com.google.common.collect.ImmutableSet;
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -070019import com.google.common.collect.Lists;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070020import org.osgi.service.component.annotations.Activate;
21import org.osgi.service.component.annotations.Component;
22import org.osgi.service.component.annotations.Deactivate;
23import org.osgi.service.component.annotations.Reference;
24import org.osgi.service.component.annotations.ReferenceCardinality;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080025import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
27import org.onosproject.net.ConnectPoint;
Yuta HIGUCHI09697d02017-03-03 16:53:39 -080028import org.onosproject.net.Device;
29import org.onosproject.net.Device.Type;
30import org.onosproject.net.DeviceId;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080031import org.onosproject.net.Link;
Yuta HIGUCHI09697d02017-03-03 16:53:39 -080032import org.onosproject.net.device.DeviceService;
33import org.onosproject.net.device.DeviceServiceAdapter;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080034import org.onosproject.net.flow.DefaultFlowRule;
35import org.onosproject.net.flow.DefaultTrafficSelector;
36import org.onosproject.net.flow.DefaultTrafficTreatment;
37import org.onosproject.net.flow.FlowRule;
38import org.onosproject.net.flow.TrafficSelector;
39import org.onosproject.net.flow.TrafficTreatment;
Marc De Leenheer1afa2a02015-05-13 09:18:07 -070040import org.onosproject.net.flow.criteria.Criteria;
41import org.onosproject.net.flow.instructions.Instructions;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080042import org.onosproject.net.intent.FlowRuleIntent;
43import org.onosproject.net.intent.Intent;
44import org.onosproject.net.intent.IntentCompiler;
45import org.onosproject.net.intent.IntentExtensionService;
46import org.onosproject.net.intent.OpticalPathIntent;
Luca Prete670ac5d2017-02-03 15:55:43 -080047import org.onosproject.net.intent.PathIntent;
Marc De Leenheer8c2caac2015-05-28 16:37:33 -070048import org.slf4j.Logger;
49import org.slf4j.LoggerFactory;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080050
Sho SHIMIZU98ffca82015-05-11 08:39:24 -070051import java.util.Collections;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080052import java.util.LinkedList;
53import java.util.List;
Yuta HIGUCHI09697d02017-03-03 16:53:39 -080054import java.util.Optional;
Marc De Leenheerb6f95e22017-03-15 12:18:59 -070055import java.util.Set;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080056
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080057@Component(immediate = true)
58public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathIntent> {
59
Marc De Leenheer8c2caac2015-05-28 16:37:33 -070060 private static final Logger log = LoggerFactory.getLogger(OpticalPathIntentCompiler.class);
61
Ray Milkeyd84f89b2018-08-17 14:54:17 -070062 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080063 protected IntentExtensionService intentManager;
64
Ray Milkeyd84f89b2018-08-17 14:54:17 -070065 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080066 protected CoreService coreService;
67
Ray Milkeyd84f89b2018-08-17 14:54:17 -070068 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yuta HIGUCHI09697d02017-03-03 16:53:39 -080069 protected DeviceService deviceService = new DeviceServiceAdapter();
70
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080071 private ApplicationId appId;
Marc De Leenheerb6f95e22017-03-15 12:18:59 -070072 // Devices which are wavelength transparent and thus do not require wavelength-based match/actions
73 private static final Set<Type> TRANSPARENT_DEVICES =
74 ImmutableSet.of(Type.OPTICAL_AMPLIFIER, Type.FIBER_SWITCH);
75 // Devices which don't accept flow rules
76 private static final Set<Type> NO_FLOWRULE_DEVICES =
77 ImmutableSet.of(Type.OPTICAL_AMPLIFIER);
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080078
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080079 @Activate
80 public void activate() {
81 appId = coreService.registerApplication("org.onosproject.net.intent");
82 intentManager.registerCompiler(OpticalPathIntent.class, this);
83 }
84
85 @Deactivate
86 public void deactivate() {
87 intentManager.unregisterCompiler(OpticalPathIntent.class);
88 }
89
90 @Override
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -080091 public List<Intent> compile(OpticalPathIntent intent, List<Intent> installable) {
Marc De Leenheer8c2caac2015-05-28 16:37:33 -070092 log.debug("Compiling optical path intent between {} and {}", intent.src(), intent.dst());
93
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -070094 // Create rules for forward and reverse path
95 List<FlowRule> rules = createRules(intent);
96 if (intent.isBidirectional()) {
97 rules.addAll(createReverseRules(intent));
98 }
99
Luca Prete670ac5d2017-02-03 15:55:43 -0800100 return Collections.singletonList(
101 new FlowRuleIntent(appId,
fahadnaeemkhan0e1b4d92018-02-08 16:40:08 -0800102 intent.key(),
103 rules,
104 intent.resources(),
105 PathIntent.ProtectionType.PRIMARY,
106 intent.resourceGroup()
Luca Prete670ac5d2017-02-03 15:55:43 -0800107 )
108 );
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800109 }
110
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700111 /**
112 * Create rules for the forward path of the intent.
113 *
114 * @param intent the intent
115 * @return list of flow rules
116 */
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700117 private List<FlowRule> createRules(OpticalPathIntent intent) {
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800118 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
119 selectorBuilder.matchInPort(intent.src().port());
120
121 List<FlowRule> rules = new LinkedList<>();
fahadnaeemkhan0e1b4d92018-02-08 16:40:08 -0800122
123 /*
124 * especial case for 0 hop when srcDeviceId = dstDeviceId
125 * and path contain only one fake default path.
126 */
127 if (intent.src().deviceId().equals(intent.dst().deviceId()) &&
128 intent.path().links().size() == 1) {
129 log.debug("handling 0 hop case for intent {}", intent);
130 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
131 if (!isTransparent(intent.src().deviceId())) {
132 treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
133 }
134 treatmentBuilder.setOutput(intent.dst().port());
135
136 FlowRule rule = DefaultFlowRule.builder()
137 .forDevice(intent.src().deviceId())
138 .withSelector(selectorBuilder.build())
139 .withTreatment(treatmentBuilder.build())
140 .withPriority(intent.priority())
141 .fromApp(appId)
142 .makePermanent()
143 .build();
144 rules.add(rule);
145 return rules;
146 }
147
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700148 ConnectPoint current = intent.src();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800149
150 for (Link link : intent.path().links()) {
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800151 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700152 if (!isTransparent(current.deviceId())) {
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700153 treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
154 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800155 treatmentBuilder.setOutput(link.src().port());
156
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700157 FlowRule rule = DefaultFlowRule.builder()
158 .forDevice(current.deviceId())
159 .withSelector(selectorBuilder.build())
160 .withTreatment(treatmentBuilder.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400161 .withPriority(intent.priority())
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700162 .fromApp(appId)
163 .makePermanent()
164 .build();
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700165 selectorBuilder = DefaultTrafficSelector.builder();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800166
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700167 if (!isNoFlowRule(current.deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800168 rules.add(rule);
169 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800170
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700171 current = link.dst();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800172 selectorBuilder.matchInPort(link.dst().port());
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700173 if (!isTransparent(current.deviceId())) {
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700174 selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
175 selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
176 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800177 }
178
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700179 // Build the egress ROADM rule
180 TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800181 treatmentLast.setOutput(intent.dst().port());
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700182
183 FlowRule rule = new DefaultFlowRule.Builder()
184 .forDevice(intent.dst().deviceId())
185 .withSelector(selectorBuilder.build())
186 .withTreatment(treatmentLast.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400187 .withPriority(intent.priority())
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700188 .fromApp(appId)
189 .makePermanent()
190 .build();
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800191
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700192 if (!isNoFlowRule(intent.dst().deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800193 rules.add(rule);
194 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800195
196 return rules;
197 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700198
199 /**
200 * Create rules for the reverse path of the intent.
201 *
202 * @param intent the intent
203 * @return list of flow rules
204 */
205 private List<FlowRule> createReverseRules(OpticalPathIntent intent) {
206 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
207 selectorBuilder.matchInPort(intent.dst().port());
208
209 List<FlowRule> rules = new LinkedList<>();
fahadnaeemkhan0e1b4d92018-02-08 16:40:08 -0800210
211 /*
212 * especial case for 0 hop when srcDeviceId = dstDeviceId
213 * and path contain only one fake default path.
214 */
215 if (intent.src().deviceId().equals(intent.dst().deviceId()) &&
216 intent.path().links().size() == 1) {
217 log.debug("handling 0 hop reverse path case for intent {}", intent);
218 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
219 if (!isTransparent(intent.src().deviceId())) {
220 treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
221 }
222 treatmentBuilder.setOutput(intent.src().port());
223
224 FlowRule rule = DefaultFlowRule.builder()
225 .forDevice(intent.src().deviceId())
226 .withSelector(selectorBuilder.build())
227 .withTreatment(treatmentBuilder.build())
228 .withPriority(intent.priority())
229 .fromApp(appId)
230 .makePermanent()
231 .build();
232 rules.add(rule);
233 return rules;
234 }
235
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700236 ConnectPoint current = intent.dst();
237
238 for (Link link : Lists.reverse(intent.path().links())) {
239 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700240 if (!isTransparent(current.deviceId())) {
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700241 treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
242 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700243 treatmentBuilder.setOutput(link.dst().port());
244
245 FlowRule rule = DefaultFlowRule.builder()
246 .forDevice(current.deviceId())
247 .withSelector(selectorBuilder.build())
248 .withTreatment(treatmentBuilder.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400249 .withPriority(intent.priority())
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700250 .fromApp(appId)
251 .makePermanent()
252 .build();
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700253 selectorBuilder = DefaultTrafficSelector.builder();
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700254
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700255 if (!isNoFlowRule(current.deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800256 rules.add(rule);
257 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700258
259 current = link.src();
260 selectorBuilder.matchInPort(link.src().port());
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700261 if (!isTransparent(current.deviceId())) {
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700262 selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
263 selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
264 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700265 }
266
267 // Build the egress ROADM rule
268 TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
269 treatmentLast.setOutput(intent.src().port());
270
271 FlowRule rule = new DefaultFlowRule.Builder()
272 .forDevice(intent.src().deviceId())
273 .withSelector(selectorBuilder.build())
274 .withTreatment(treatmentLast.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400275 .withPriority(intent.priority())
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700276 .fromApp(appId)
277 .makePermanent()
278 .build();
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800279
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700280 if (!isNoFlowRule(intent.src().deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800281 rules.add(rule);
282 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700283
284 return rules;
285 }
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700286
287 /**
288 * Returns true if device does not accept flow rules, false otherwise.
289 *
290 * @param deviceId the device
291 * @return true if device does not accept flow rule, false otherwise
292 */
293 private boolean isNoFlowRule(DeviceId deviceId) {
294 return NO_FLOWRULE_DEVICES.contains(
295 Optional.ofNullable(deviceService.getDevice(deviceId))
296 .map(Device::type)
297 .orElse(Type.OTHER));
298 }
299
300 /**
301 * Returns true if device is wavelength transparent, false otherwise.
302 *
303 * @param deviceId the device
304 * @return true if wavelength transparent, false otherwise
305 */
306 private boolean isTransparent(DeviceId deviceId) {
307 return TRANSPARENT_DEVICES.contains(
308 Optional.ofNullable(deviceService.getDevice(deviceId))
fahadnaeemkhan0e1b4d92018-02-08 16:40:08 -0800309 .map(Device::type)
310 .orElse(Type.OTHER));
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700311 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800312}