blob: ed2c06786a860d99847689bda1a9a42d33ad6b01 [file] [log] [blame]
Pier Ventre6b19e482016-11-07 16:21:04 -08001/*
Brian O'Connor0947d7e2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Pier Ventre6b19e482016-11-07 16:21:04 -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 */
16
17package org.onosproject.segmentrouting.config;
18
19import com.fasterxml.jackson.databind.JsonNode;
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -070020import com.fasterxml.jackson.databind.node.JsonNodeFactory;
Pier Ventre6b19e482016-11-07 16:21:04 -080021import com.fasterxml.jackson.databind.node.ObjectNode;
22import com.google.common.collect.ImmutableSet;
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -070023import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
Pier Ventre6b19e482016-11-07 16:21:04 -080025import org.onlab.packet.MplsLabel;
26import org.onlab.packet.VlanId;
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -070027import org.onosproject.cli.AbstractShellCommand;
Pier Ventre6b19e482016-11-07 16:21:04 -080028import org.onosproject.core.ApplicationId;
29import org.onosproject.net.ConnectPoint;
30import org.onosproject.net.config.Config;
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -070031import org.onosproject.net.device.DeviceService;
32import org.onosproject.net.intf.InterfaceService;
Pier Ventre6b19e482016-11-07 16:21:04 -080033import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
34import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
35import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
36import org.onosproject.segmentrouting.pwaas.L2Mode;
37import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -070040import java.util.HashMap;
41import java.util.HashSet;
42import java.util.Map;
Pier Ventre6b19e482016-11-07 16:21:04 -080043import java.util.Set;
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -070044import java.util.stream.Collectors;
Pier Ventre6b19e482016-11-07 16:21:04 -080045
46/**
47 * App configuration object for Pwaas.
48 */
49public class PwaasConfig extends Config<ApplicationId> {
50
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -070051 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 public DeviceService deviceService;
53
54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 public InterfaceService intfService;
56
Pier Ventre6b19e482016-11-07 16:21:04 -080057 private static Logger log = LoggerFactory
58 .getLogger(PwaasConfig.class);
59
60 private static final String SRC_CP = "cP1";
61 private static final String DST_CP = "cP2";
62 private static final String SRC_OUTER_TAG = "cP1OuterTag";
63 private static final String DST_OUTER_TAG = "cP2OuterTag";
64 private static final String SRC_INNER_TAG = "cP1InnerTag";
65 private static final String DST_INNER_TAG = "cP2InnerTag";
66 private static final String MODE = "mode";
Pier Ventre6b19e482016-11-07 16:21:04 -080067 private static final String SD_TAG = "sdTag";
68 private static final String PW_LABEL = "pwLabel";
69
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -070070 public PwaasConfig(DeviceService devS, InterfaceService intfS) {
71
72 super();
73
74 deviceService = devS;
75 intfService = intfS;
76 }
77
78 public PwaasConfig() {
79
80 super();
81
82 deviceService = AbstractShellCommand.get(DeviceService.class);
83 intfService = AbstractShellCommand.get(InterfaceService.class);
84 }
Pier Ventre6b19e482016-11-07 16:21:04 -080085 /**
86 * Error message for missing parameters.
87 */
88 private static final String MISSING_PARAMS = "Missing parameters in pseudo wire description";
89
90 /**
91 * Error message for invalid l2 mode.
92 */
93 private static final String INVALID_L2_MODE = "Invalid pseudo wire mode";
94
95 /**
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -070096 * Error message for invalid VLAN.
97 */
98 private static final String INVALID_VLAN = "Vlan should be either int or */-";
99
100 /**
101 * Error message for invalid PW label.
102 */
103 private static final String INVALID_PW_LABEL = "Pseudowire label should be an integer";
104
105 /**
Pier Ventre6b19e482016-11-07 16:21:04 -0800106 * Verify if the pwaas configuration block is valid.
107 *
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700108 * Here we try to ensure that the provided pseudowires will get instantiated
109 * correctly in the network. We also check for any collisions with already used
110 * interfaces and also between different pseudowires. Most of the restrictions stem
111 * from the fact that all vlan matching is done in table 10 of ofdpa.
112 *
Pier Ventre6b19e482016-11-07 16:21:04 -0800113 * @return true, if the configuration block is valid.
114 * False otherwise.
115 */
116 @Override
117 public boolean isValid() {
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700118
119 Set<DefaultL2TunnelDescription> pseudowires;
Pier Ventre6b19e482016-11-07 16:21:04 -0800120 try {
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700121 pseudowires = getPwIds().stream()
122 .map(this::getPwDescription)
123 .collect(Collectors.toSet());
124
Pier Ventre6b19e482016-11-07 16:21:04 -0800125 } catch (IllegalArgumentException e) {
126 log.warn("{}", e.getMessage());
127 return false;
128 }
Pier Ventre6b19e482016-11-07 16:21:04 -0800129
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700130 // check semantics now and return
131 return configurationValidity(pseudowires);
132 }
133
134 /**
135 * Helper method to verify if the tunnel is whether or not
136 * supported.
137 *
138 * @param l2Tunnel the tunnel to verify
139 * @return the result of the verification
140 */
141 private void verifyTunnel(DefaultL2Tunnel l2Tunnel) {
142
143 // Service delimiting tag not supported yet.
144 if (!l2Tunnel.sdTag().equals(VlanId.NONE)) {
145 throw new IllegalArgumentException(String.format("Service delimiting tag not supported yet for " +
146 "pseudowire %d.", l2Tunnel.tunnelId()));
147 }
148
149 // Tag mode not supported yet.
150 if (l2Tunnel.pwMode() == L2Mode.TAGGED) {
151 throw new IllegalArgumentException(String.format("Tagged mode not supported yet for pseudowire %d.",
152 l2Tunnel.tunnelId()));
153 }
154
155 // Raw mode without service delimiting tag
156 // is the only mode supported for now.
157 }
158
159 /**
160 * Helper method to verify if the policy is whether or not
161 * supported and if policy will be successfully instantiated in the
162 * network.
163 *
164 * @param ingressInner the ingress inner tag
165 * @param ingressOuter the ingress outer tag
166 * @param egressInner the egress inner tag
167 * @param egressOuter the egress outer tag
168 * @return the result of verification
169 */
170 private void verifyPolicy(ConnectPoint cP1,
171 ConnectPoint cP2,
172 VlanId ingressInner,
173 VlanId ingressOuter,
174 VlanId egressInner,
175 VlanId egressOuter,
176 Long tunnelId) {
177
178 if (cP1.deviceId().equals(cP2.deviceId())) {
179 throw new IllegalArgumentException(String.format("Pseudowire connection points can not reside in the " +
180 "same node, in pseudowire %d.", tunnelId));
181 }
182
183 // We can have multiple tags, all of them can be NONE,
184 // indicating untagged traffic, however, the outer tag can
185 // not have value if the inner tag is None
186 if (ingressInner.equals(VlanId.NONE) && !ingressOuter.equals(VlanId.NONE)) {
187 throw new IllegalArgumentException(String.format("Inner tag should not be empty when " +
188 "outer tag is set for pseudowire %d for cP1.",
189 tunnelId));
190 }
191
192 if (egressInner.equals(VlanId.NONE) && !egressOuter.equals(VlanId.NONE)) {
193 throw new IllegalArgumentException(String.valueOf(String.format("Inner tag should not be empty when" +
194 " outer tag is set for pseudowire %d " +
195 "for cP2.", tunnelId)));
196 }
197
198 if (ingressInner.equals(VlanId.ANY) ||
199 ingressOuter.equals(VlanId.ANY) ||
200 egressInner.equals(VlanId.ANY) ||
201 egressOuter.equals(VlanId.ANY)) {
202 throw new IllegalArgumentException(String.valueOf(String.format("Wildcard VLAN matching not yet " +
203 "supported for pseudowire %d.",
204 tunnelId)));
205 }
206
207 if (((!ingressOuter.equals(VlanId.NONE) && !ingressOuter.equals(VlanId.NONE)) &&
208 (egressOuter.equals(VlanId.NONE) && egressInner.equals(VlanId.NONE)))
209 || ((ingressOuter.equals(VlanId.NONE) && ingressOuter.equals(VlanId.NONE)) &&
210 (!egressOuter.equals(VlanId.NONE) && !egressInner.equals(VlanId.NONE)))) {
211 throw new IllegalArgumentException(String.valueOf(String.format("Support for double tag <-> untag is not" +
212 "supported for pseudowire %d.",
213 tunnelId)));
214 }
215 if ((!ingressInner.equals(VlanId.NONE) &&
216 ingressOuter.equals(VlanId.NONE) &&
217 !egressOuter.equals(VlanId.NONE))
218 || (!ingressOuter.equals(VlanId.NONE) &&
219 egressOuter.equals(VlanId.NONE) &&
220 !ingressOuter.equals(VlanId.NONE))) {
221 throw new IllegalArgumentException(String.valueOf(String.format("Support for double-tag<->" +
222 "single-tag is not supported" +
223 " for pseudowire %d.", tunnelId)));
224 }
225
226 if ((ingressInner.equals(VlanId.NONE) && !egressInner.equals(VlanId.NONE))
227 || (!ingressInner.equals(VlanId.NONE) && egressInner.equals(VlanId.NONE))) {
228 throw new IllegalArgumentException(String.valueOf(String.format("single-tag <-> untag is not supported" +
229 " for pseudowire %d.", tunnelId)));
230 }
231
232
233 if (!ingressInner.equals(egressInner) && !ingressOuter.equals(egressOuter)) {
234 throw new IllegalArgumentException(String.valueOf(String.format("We do not support changing both tags " +
235 "in double tagged pws, only the outer," +
236 " for pseudowire %d.", tunnelId)));
237 }
238
239 // check if cp1 and port of cp1 exist
240 if (deviceService.getDevice(cP1.deviceId()) == null) {
241 throw new IllegalArgumentException(String.valueOf(String.format("cP1 device %s does not exist for" +
242 " pseudowire %d.", cP1.deviceId(),
243 tunnelId)));
244 }
245
246 if (deviceService.getPort(cP1) == null) {
247 throw new IllegalArgumentException(String.valueOf(String.format("Port %s for cP1 device %s does not" +
248 " exist for pseudowire %d.", cP1.port(),
249 cP1.deviceId(), tunnelId)));
250 }
251
252 // check if cp2 and port of cp2 exist
253 if (deviceService.getDevice(cP2.deviceId()) == null) {
254 throw new IllegalArgumentException(String.valueOf(String.format("cP2 device %s does not exist for" +
255 " pseudowire %d.", cP2.deviceId(),
256 tunnelId)));
257 }
258
259 if (deviceService.getPort(cP2) == null) {
260 throw new IllegalArgumentException(String.valueOf(String.format("Port %s for cP2 device %s does " +
261 "not exist for pseudowire %d.",
262 cP2.port(), cP2.deviceId(), tunnelId)));
263 }
264 }
265
266 /**
267 * Verifies that the pseudowires will not conflict with each other.
268 *
269 * Further, check if vlans for connect points are already used.
270 *
271 * @param tunnel Tunnel for pw
272 * @param policy Policy for pw
273 * @param labelSet Label set used so far with this configuration
274 * @param vlanSet Vlan set used with this configuration
275 * @param tunnelSet Tunnel set used with this configuration
276 */
277 private void verifyGlobalValidity(DefaultL2Tunnel tunnel,
278 DefaultL2TunnelPolicy policy,
279 Set<MplsLabel> labelSet,
280 Map<ConnectPoint, Set<VlanId>> vlanSet,
281 Set<Long> tunnelSet) {
282
283 if (tunnelSet.contains(tunnel.tunnelId())) {
284 throw new IllegalArgumentException(String.valueOf(String.format("Tunnel Id %d already used by" +
285 " another pseudowire, in " +
286 "pseudowire %d!", tunnel.tunnelId(),
287 tunnel.tunnelId())));
288 }
289 tunnelSet.add(tunnel.tunnelId());
290
291 // check if tunnel id is used again
292 ConnectPoint cP1 = policy.cP1();
293 ConnectPoint cP2 = policy.cP2();
294
295 // insert cps to hashmap if this is the first time seen
296 if (!vlanSet.containsKey(cP1)) {
297 vlanSet.put(cP1, new HashSet<VlanId>());
298 }
299 if (!vlanSet.containsKey(cP2)) {
300 vlanSet.put(cP2, new HashSet<VlanId>());
301 }
302
303 // if single tagged or untagged vlan is the inner
304 // if double tagged vlan is the outer
305 VlanId vlanToCheckCP1;
306 if (policy.cP1OuterTag().equals(VlanId.NONE)) {
307 vlanToCheckCP1 = policy.cP1InnerTag();
308 } else {
309 vlanToCheckCP1 = policy.cP1OuterTag();
310 }
311
312 VlanId vlanToCheckCP2;
313 if (policy.cP2OuterTag().equals(VlanId.NONE)) {
314 vlanToCheckCP2 = policy.cP2InnerTag();
315 } else {
316 vlanToCheckCP2 = policy.cP2OuterTag();
317 }
318
319 if (labelSet.contains(tunnel.pwLabel())) {
320 throw new IllegalArgumentException(String.valueOf(String.format("Label %s already used by another" +
321 " pseudowire, in pseudowire %d!",
322 tunnel.pwLabel(), tunnel.tunnelId())));
323 }
324 labelSet.add(tunnel.pwLabel());
325
326 if (vlanSet.get(cP1).contains(vlanToCheckCP1)) {
327 throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP1 %s already used " +
328 "by another pseudowire, in pseudowire" +
329 " %d!", vlanToCheckCP1, cP1,
330 tunnel.tunnelId())));
331 }
332 vlanSet.get(cP1).add(vlanToCheckCP1);
333
334 if (vlanSet.get(cP2).contains(vlanToCheckCP2)) {
335 throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP2 %s already used" +
336 " by another pseudowire, in" +
337 " pseudowire %d!", vlanToCheckCP2, cP2,
338 tunnel.tunnelId())));
339 }
340 vlanSet.get(cP2).add(vlanToCheckCP2);
341
342 // check that vlans for the connect points are not used
343 intfService.getInterfacesByPort(cP1).stream()
344 .forEach(intf -> {
345
346 // check if tagged pw affects tagged interface
347 if (intf.vlanTagged().contains(vlanToCheckCP1)) {
348 throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP1 %s already" +
349 " used for this interface, in" +
350 " pseudowire %d!",
351 vlanToCheckCP1, cP1,
352 tunnel.tunnelId())));
353 }
354
355 // if vlanNative != null this interface is configured with untagged traffic also
356 // check if it collides with untagged interface
357 if ((intf.vlanNative() != null) && vlanToCheckCP1.equals(VlanId.NONE)) {
358 throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP1 " +
359 "%s already used for this " +
360 "interface, in pseudowire " +
361 "%d!", cP1,
362 tunnel.tunnelId())));
363 }
364
365 // if vlanUntagged != null this interface is configured only with untagged traffic
366 // check if it collides with untagged interface
367 if ((intf.vlanUntagged() != null) && vlanToCheckCP1.equals(VlanId.NONE)) {
368 throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for " +
369 "cP1 %s already" +
370 " used for this interface," +
371 " in pseudowire %d!",
372 cP1, tunnel.tunnelId())));
373 }
374 });
375
376 intfService.getInterfacesByPort(cP2).stream()
377 .forEach(intf -> {
378 if (intf.vlanTagged().contains(vlanToCheckCP2)) {
379 throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP2 %s already" +
380 " used for this interface, " +
381 "in pseudowire %d!",
382 vlanToCheckCP2, cP2,
383 tunnel.tunnelId())));
384 }
385
386 // if vlanNative != null this interface is configured with untagged traffic also
387 // check if it collides with untagged interface
388 if ((intf.vlanNative() != null) && vlanToCheckCP2.equals(VlanId.NONE)) {
389 throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP2 %s " +
390 "already used for this" +
391 " interface, " +
392 "in pseudowire %d!",
393 cP2, tunnel.tunnelId())));
394 }
395
396 // if vlanUntagged != null this interface is configured only with untagged traffic
397 // check if it collides with untagged interface
398 if ((intf.vlanUntagged() != null) && vlanToCheckCP2.equals(VlanId.NONE)) {
399 throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP2 %s" +
400 " already" +
401 " used for this interface, " +
402 "in pseudowire %d!",
403 cP2, tunnel.tunnelId())));
404 }
405 });
406
407 }
408
409 /**
410 * Helper method to verify the integrity of the pseudo wire.
411 *
412 * @param l2TunnelDescription the pseudo wire description
413 * @return the result of the check
414 */
415 private void verifyPseudoWire(DefaultL2TunnelDescription l2TunnelDescription,
416 Set<MplsLabel> labelSet,
417 Map<ConnectPoint, Set<VlanId>> vlanset,
418 Set<Long> tunnelSet) {
419
420 DefaultL2Tunnel l2Tunnel = l2TunnelDescription.l2Tunnel();
421 DefaultL2TunnelPolicy l2TunnelPolicy = l2TunnelDescription.l2TunnelPolicy();
422
423 verifyTunnel(l2Tunnel);
424
425 verifyPolicy(
426 l2TunnelPolicy.cP1(),
427 l2TunnelPolicy.cP2(),
428 l2TunnelPolicy.cP1InnerTag(),
429 l2TunnelPolicy.cP1OuterTag(),
430 l2TunnelPolicy.cP2InnerTag(),
431 l2TunnelPolicy.cP2OuterTag(),
432 l2Tunnel.tunnelId()
433 );
434
435 verifyGlobalValidity(l2Tunnel,
436 l2TunnelPolicy,
437 labelSet,
438 vlanset,
439 tunnelSet);
440
441 }
442
443 /**
444 * Checks if the configured pseudowires will create problems in the network.
445 * If yes, then no pseudowires is deployed from this configuration.
446 *
447 * @param pseudowires Set of pseudowries to validate
448 * @return returns true if everything goes well.
449 */
450 public boolean configurationValidity(Set<DefaultL2TunnelDescription> pseudowires) {
451
452 // structures to keep pw information
453 // in order to see if instantiating them will create
454 // problems
455 Set<Long> tunIds = new HashSet<>();
456 Set<MplsLabel> labelsUsed = new HashSet<>();
457 Map<ConnectPoint, Set<VlanId>> vlanIds = new HashMap<>();
458
459 // check that pseudowires can be instantiated in the network
460 // we try to guarantee that all the pws will work before
461 // instantiating any of them
462 for (DefaultL2TunnelDescription pw : pseudowires) {
463 verifyPseudoWire(pw, labelsUsed, vlanIds, tunIds);
464 }
465
466 return true;
Pier Ventre6b19e482016-11-07 16:21:04 -0800467 }
468
469 /**
470 * Returns all pseudo wire keys.
471 *
472 * @return all keys (tunnels id)
473 * @throws IllegalArgumentException if wrong format
474 */
475 public Set<Long> getPwIds() {
476 ImmutableSet.Builder<Long> builder = ImmutableSet.builder();
477 object.fields().forEachRemaining(entry -> {
478 Long tunnelId = Long.parseLong(entry.getKey());
479 builder.add(tunnelId);
480 });
481 return builder.build();
482 }
483
484 /**
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700485 * Parses a vlan as a string. Returns the VlanId if
486 * provided String can be parsed as an integer or is '' / '*'
487 *
488 * @param vlan string as read from configuration
489 * @return VlanId
490 * @throws IllegalArgumentException if wrong format of vlan
491 */
492 public VlanId parseVlan(String vlan) {
493
494 if (vlan.equals("*") || vlan.equals("Any")) {
495 return VlanId.vlanId("Any");
496 } else if (vlan.equals("") || vlan.equals("None")) {
497 return VlanId.vlanId("None");
498 } else {
499 try {
500 VlanId newVlan = VlanId.vlanId(vlan);
501 return newVlan;
502 } catch (IllegalArgumentException e) {
503 throw new IllegalArgumentException(INVALID_VLAN);
504 }
505 }
506 }
507
508 /**
509 *
510 * @param mode RAW or TAGGED
511 * @return the L2Mode if input is correct
512 * @throws IllegalArgumentException if not supported mode
513 */
514 public L2Mode parseMode(String mode) {
515
516 if (!mode.equals("RAW") && !mode.equals("TAGGED")) {
517 throw new IllegalArgumentException(INVALID_L2_MODE);
518 }
519
520 return L2Mode.valueOf(mode);
521 }
522
523 /**
524 *
525 * @param label the mpls label of the pseudowire
526 * @return the MplsLabel
527 * @throws IllegalArgumentException if label is invalid
528 */
529 public MplsLabel parsePWLabel(String label) {
530
531 try {
532 MplsLabel pwLabel = MplsLabel.mplsLabel(label);
533 return pwLabel;
534 } catch (Exception e) {
535 throw new IllegalArgumentException(INVALID_PW_LABEL);
536 }
537 }
538
539 /**
Pier Ventre6b19e482016-11-07 16:21:04 -0800540 * Returns pw description of given pseudo wire id.
541 *
542 * @param tunnelId pseudo wire key
543 * @return set of l2 tunnel descriptions
544 * @throws IllegalArgumentException if wrong format
545 */
546 public DefaultL2TunnelDescription getPwDescription(Long tunnelId) {
547 JsonNode pwDescription = object.get(tunnelId.toString());
548 if (!hasFields((ObjectNode) pwDescription,
549 SRC_CP, SRC_INNER_TAG, SRC_OUTER_TAG,
550 DST_CP, DST_INNER_TAG, DST_OUTER_TAG,
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700551 MODE, SD_TAG, PW_LABEL)) {
Pier Ventre6b19e482016-11-07 16:21:04 -0800552 throw new IllegalArgumentException(MISSING_PARAMS);
553 }
554 String tempString;
555
556 tempString = pwDescription.get(SRC_CP).asText();
557 ConnectPoint srcCp = ConnectPoint.deviceConnectPoint(tempString);
558
559 tempString = pwDescription.get(DST_CP).asText();
560 ConnectPoint dstCp = ConnectPoint.deviceConnectPoint(tempString);
561
562 tempString = pwDescription.get(SRC_INNER_TAG).asText();
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700563 VlanId srcInnerTag = parseVlan(tempString);
Pier Ventre6b19e482016-11-07 16:21:04 -0800564
565 tempString = pwDescription.get(SRC_OUTER_TAG).asText();
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700566 VlanId srcOuterTag = parseVlan(tempString);
Pier Ventre6b19e482016-11-07 16:21:04 -0800567
568 tempString = pwDescription.get(DST_INNER_TAG).asText();
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700569 VlanId dstInnerTag = parseVlan(tempString);
Pier Ventre6b19e482016-11-07 16:21:04 -0800570
571 tempString = pwDescription.get(DST_OUTER_TAG).asText();
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700572 VlanId dstOuterTag = parseVlan(tempString);
Pier Ventre6b19e482016-11-07 16:21:04 -0800573
574 tempString = pwDescription.get(MODE).asText();
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700575 L2Mode l2Mode = parseMode(tempString);
Pier Ventre6b19e482016-11-07 16:21:04 -0800576
577 tempString = pwDescription.get(SD_TAG).asText();
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700578 VlanId sdTag = parseVlan(tempString);
Pier Ventre6b19e482016-11-07 16:21:04 -0800579
580 tempString = pwDescription.get(PW_LABEL).asText();
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700581 MplsLabel pwLabel = parsePWLabel(tempString);
Pier Ventre6b19e482016-11-07 16:21:04 -0800582
583 DefaultL2Tunnel l2Tunnel = new DefaultL2Tunnel(
584 l2Mode,
585 sdTag,
586 tunnelId,
587 pwLabel
588 );
589
590 DefaultL2TunnelPolicy l2TunnelPolicy = new DefaultL2TunnelPolicy(
591 tunnelId,
592 srcCp,
593 srcInnerTag,
594 srcOuterTag,
595 dstCp,
596 dstInnerTag,
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700597 dstOuterTag
Pier Ventre6b19e482016-11-07 16:21:04 -0800598 );
599
600 return new DefaultL2TunnelDescription(l2Tunnel, l2TunnelPolicy);
601 }
602
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700603 /**
604 * Removes a pseudowire from the configuration tree.
605 * @param pwId Pseudowire id
606 * @return null if pwId did not exist, or the object representing the
607 * udpated configuration tree
608 */
609 public ObjectNode removePseudowire(String pwId) {
610
611 JsonNode value = object.remove(pwId);
612 if (value == null) {
613 return (ObjectNode) value;
614 } else {
615 return object;
616 }
617 }
618
619 /**
620 * Adds a pseudowire to the configuration tree of pwwas. It also checks
621 * if the configuration is valid, if not return null and does not add the node,
622 * if yes return the new configuration. Caller will propagate update events.
623 *
624 * If the pseudowire already exists in the configuration it gets updated.
625 *
626 * @param tunnelId Id of tunnel
627 * @param pwLabel PW label of tunnel
628 * @param cP1 Connection point 1
629 * @param cP1InnerVlan Inner vlan of cp1
630 * @param cP1OuterVlan Outer vlan of cp2
631 * @param cP2 Connection point 2
632 * @param cP2InnerVlan Inner vlan of cp2
633 * @param cP2OuterVlan Outer vlan of cp2
634 * @param mode Mode for the pw
635 * @param sdTag Service delimiting tag for the pw
636 * @return The ObjectNode config if configuration is valid with the new pseudowire
637 * or null.
638 */
639 public ObjectNode addPseudowire(String tunnelId, String pwLabel, String cP1,
640 String cP1InnerVlan, String cP1OuterVlan, String cP2,
641 String cP2InnerVlan, String cP2OuterVlan,
642 String mode, String sdTag) {
643
644
645 ObjectNode newPw = new ObjectNode(JsonNodeFactory.instance);
646
647 // add fields for pseudowire
648 newPw.put(SRC_CP, cP1);
649 newPw.put(DST_CP, cP2);
650 newPw.put(PW_LABEL, pwLabel);
651 newPw.put(SRC_INNER_TAG, cP1InnerVlan);
652 newPw.put(SRC_OUTER_TAG, cP1OuterVlan);
653 newPw.put(DST_INNER_TAG, cP2InnerVlan);
654 newPw.put(DST_OUTER_TAG, cP2OuterVlan);
655 newPw.put(SD_TAG, sdTag);
656 newPw.put(MODE, mode);
657
658 object.set(tunnelId, newPw);
659 try {
660 isValid();
661 } catch (IllegalArgumentException e) {
662 log.info("Pseudowire could not be created : {}", e);
663 object.remove(tunnelId);
664 return null;
665 }
666
667 return object;
668 }
Pier Ventre6b19e482016-11-07 16:21:04 -0800669}