blob: 1fd03bd6413d8f6b45566420e9e9d4a9f4cb5671 [file] [log] [blame]
janani b35f6cbc2017-03-24 21:56:58 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
janani b35f6cbc2017-03-24 21:56:58 +05303 *
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.l3vpn.netl3vpn.impl;
18
19import org.onosproject.l3vpn.netl3vpn.AccessInfo;
20import org.onosproject.l3vpn.netl3vpn.BgpDriverInfo;
21import org.onosproject.l3vpn.netl3vpn.BgpInfo;
22import org.onosproject.l3vpn.netl3vpn.InterfaceInfo;
23import org.onosproject.l3vpn.netl3vpn.NetL3VpnException;
24import org.onosproject.l3vpn.netl3vpn.VpnType;
25import org.onosproject.net.DeviceId;
Vidyashree Rama04147ca2017-05-26 11:32:47 +053026import org.onosproject.yang.gen.v1.ietfinterfaces.rev20140508.ietfinterfaces.devices.device.Interfaces;
27import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.DefaultL3VpnSvc;
28import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.SiteRole;
29import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.l3vpnsvc.DefaultSites;
30import org.onosproject.yang.gen.v1.ietfnetworkinstance.rev20160623.ietfnetworkinstance.DefaultDevices;
31import org.onosproject.yang.gen.v1.ietfnetworkinstance.rev20160623.ietfnetworkinstance.Devices;
32import org.onosproject.yang.gen.v1.ietfnetworkinstance.rev20160623.ietfnetworkinstance.devices.DefaultDevice;
33import org.onosproject.yang.gen.v1.ietfnetworkinstance.rev20160623.ietfnetworkinstance.devices.Device;
34import org.onosproject.yang.gen.v1.ietfnetworkinstance.rev20160623.ietfnetworkinstance.devices.DeviceKeys;
35import org.onosproject.yang.gen.v1.ietfnetworkinstance.rev20160623.ietfnetworkinstance.devices.device.NetworkInstances;
janani b35f6cbc2017-03-24 21:56:58 +053036import org.onosproject.yang.model.DataNode;
37import org.onosproject.yang.model.DefaultModelObjectData;
Vidyashree Rama04147ca2017-05-26 11:32:47 +053038import org.onosproject.yang.model.DefaultResourceData;
janani b35f6cbc2017-03-24 21:56:58 +053039import org.onosproject.yang.model.InnerModelObject;
40import org.onosproject.yang.model.ModelObjectData;
41import org.onosproject.yang.model.ModelObjectId;
42import org.onosproject.yang.model.ResourceData;
43import org.onosproject.yang.model.ResourceId;
janani b35f6cbc2017-03-24 21:56:58 +053044
45import java.util.LinkedList;
46import java.util.List;
47import java.util.Map;
48
janani b9ed76be2017-08-29 19:11:33 +053049import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.DEVICE;
50import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.DEVICES;
51import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.ROOT;
52import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.VPN;
janani b35f6cbc2017-03-24 21:56:58 +053053import static org.onosproject.l3vpn.netl3vpn.VpnType.ANY_TO_ANY;
54import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
55import static org.onosproject.l3vpn.netl3vpn.VpnType.SPOKE;
56
57/**
58 * Representation of utility for YANG tree builder.
59 */
60public final class NetL3VpnUtil {
61
62 /**
janani b35f6cbc2017-03-24 21:56:58 +053063 * Error message for site VPN name being not present in global VPN.
64 */
65 static final String SITE_VPN_MISMATCH = "Site VPN instance name did not " +
66 "match any of the global VPN names";
67
68 /**
69 * Error message for VPN attachment object being null.
70 */
71 static final String VPN_ATTACHMENT_NULL = "The VPN attachment information" +
72 " cannot be null";
73
74 /**
75 * Error message for VPN policy being not supported.
76 */
77 static final String VPN_POLICY_NOT_SUPPORTED = "VPN policy implementation" +
78 " is not supported.";
79
80 /**
81 * Static constant value for hundred.
82 */
83 static final String CONS_HUNDRED = "100:";
84
85 /**
86 * Error message for site role being not present in site network access.
87 */
88 static final String SITE_ROLE_NULL = "There must be a site role available" +
89 " for the VPN in site network access.";
90
91 /**
92 * Error message for bearer object information being null.
93 */
94 static final String BEARER_NULL = "The bearer information of the access " +
95 "is not available";
96
97 /**
98 * Error message for requested type or ip connect being null.
99 */
100 static final String IP_INT_INFO_NULL = "The required information of " +
101 "request type or ip connection is not available";
102
103 /**
104 * Error message for device info being not available from augment.
105 */
106 static final String DEVICE_INFO_NULL = "Bearer of site does not have any " +
107 "device information in the augment info.";
108
109 /**
janani b176905a2017-03-28 17:36:18 +0530110 * Static constant value for ip address.
janani b35f6cbc2017-03-24 21:56:58 +0530111 */
janani b176905a2017-03-28 17:36:18 +0530112 static final String IP = "ipaddress";
janani b35f6cbc2017-03-24 21:56:58 +0530113
114 /**
janani b9ed76be2017-08-29 19:11:33 +0530115 * Static constant value for lsr id.
116 */
117 static final String LSR_ID = "lsrId";
118
119 /**
janani b35f6cbc2017-03-24 21:56:58 +0530120 * Error message for VPN type being not supported.
121 */
122 static final String VPN_TYPE_UNSUPPORTED = "The VPN type is not supported";
123
124 /**
125 * Error message when the generated ID has crossed the limit.
126 */
127 static final String ID_LIMIT_EXCEEDED = "The ID generation has got " +
128 "exceeded";
129
130 /**
131 * Static constant value ID management limit.
132 */
133 static final Long ID_LIMIT = 4294967295L;
134
135 /**
136 * Error message for interface information being not available.
137 */
138 static final String INT_INFO_NULL = "Requested type does not have any " +
139 "interface information in the augment info.";
140
141 /**
142 * Static constant value of port name.
143 */
144 static final String PORT_NAME = "portName";
145
janani b176905a2017-03-28 17:36:18 +0530146 /**
147 * Static constants to use with accumulator for maximum number of events.
148 */
149 static final int MAX_EVENTS = 1000;
150
151 /**
152 * Static constants to use with accumulator for maximum number of millis.
153 */
154 static final int MAX_BATCH_MS = 5000;
155
156 /**
157 * Static constants to use with accumulator for maximum number of idle
158 * millis.
159 */
160 static final int MAX_IDLE_MS = 1000;
161
162 /**
163 * Static constants for timer name.
164 */
165 static final String TIMER = "dynamic-config-l3vpn-timer";
166
167 /**
168 * Error message for unknown event being occurred.
169 */
170 static final String UNKNOWN_EVENT = "NetL3VPN listener: unknown event: {}";
171
172 /**
173 * Error message for event being null.
174 */
175 static final String EVENT_NULL = "Event cannot be null";
176
janani b9ed76be2017-08-29 19:11:33 +0530177 /**
178 * Unique tunnel name for net-l3VPN.
179 */
180 static final String NEW_NAME = "onos-netl3vpn";
181
janani b35f6cbc2017-03-24 21:56:58 +0530182 private static final String SITE_ROLE_INVALID = "The given site role is " +
183 "invalid";
184 private static final String ANY_TO_ANY_ROLE = "AnyToAnyRole";
185 private static final String HUB_ROLE = "HubRole";
186 private static final String SPOKE_ROLE = "SpokeRole";
janani b9ed76be2017-08-29 19:11:33 +0530187 private static final String COLON = ":";
janani b35f6cbc2017-03-24 21:56:58 +0530188
189 // No instantiation.
190 private NetL3VpnUtil() {
191 }
192
193 /**
194 * Returns the model object id for service L3VPN container.
195 *
196 * @return model object id
197 */
198 static ModelObjectId getModIdForL3VpnSvc() {
199 return ModelObjectId.builder().addChild(DefaultL3VpnSvc.class).build();
200 }
201
202 /**
203 * Returns the model object id for service sites container.
204 *
205 * @return model object id
206 */
207 static ModelObjectId getModIdForSites() {
208 return ModelObjectId.builder().addChild(DefaultL3VpnSvc.class)
209 .addChild(DefaultSites.class).build();
210 }
211
212 /**
213 * Returns the resource data from the data node and the resource id.
214 *
215 * @param dataNode data node
216 * @param resId resource id
217 * @return resource data
218 */
219 static ResourceData getResourceData(DataNode dataNode, ResourceId resId) {
220 return DefaultResourceData.builder().addDataNode(dataNode)
221 .resourceId(resId).build();
222 }
223
224 /**
225 * Returns the VPN role from the service site role.
226 *
227 * @param siteRole service site role
228 * @return VPN type
229 */
230 static VpnType getRole(Class<? extends SiteRole> siteRole) {
231 switch (siteRole.getSimpleName()) {
232 case ANY_TO_ANY_ROLE:
233 return ANY_TO_ANY;
234
235 case HUB_ROLE:
236 return HUB;
237
238 case SPOKE_ROLE:
239 return SPOKE;
240
241 default:
242 throw new NetL3VpnException(SITE_ROLE_INVALID);
243 }
244 }
245
246 /**
247 * Returns error message for management ip being unavailable in device.
248 *
249 * @param ip management ip
250 * @return error message
251 */
252 static String getMgmtIpUnAvailErr(String ip) {
253 return "The device with management ip " + ip + " is not available.";
254 }
255
256 /**
257 * Returns true if device id present in the interface map; false otherwise.
258 *
259 * @param info interface map
260 * @param id device id
261 * @return true if device id available; false otherwise
262 */
263 private static boolean isDevIdPresent(Map<AccessInfo, InterfaceInfo> info,
264 String id) {
265 for (Map.Entry<AccessInfo, InterfaceInfo> inter : info.entrySet()) {
266 InterfaceInfo interfaceInfo = inter.getValue();
267 DeviceId devId = interfaceInfo.devInfo().deviceId();
268 if (devId.toString().equals(id)) {
269 return true;
270 }
271 }
272 return false;
273 }
274
275 /**
276 * Builds the device model VPN instance model object data, with respect to
277 * the device level.
278 *
279 * @param id device id
280 * @param ins VPN instance
281 * @return model object data, with device level
282 */
283 private static ModelObjectData buildInsModDataDevice(String id,
284 NetworkInstances ins) {
285 DeviceKeys devKeys = new DeviceKeys();
286 devKeys.deviceid(id);
287 ModelObjectId modelId = ModelObjectId.builder()
288 .addChild(DefaultDevices.class)
289 .addChild(DefaultDevice.class, devKeys)
290 .build();
Thomas Vachuskad17bc732017-03-24 11:46:55 -0700291 return DefaultModelObjectData.builder().identifier(modelId)
janani b35f6cbc2017-03-24 21:56:58 +0530292 .addModelObject((InnerModelObject) ins).build();
293 }
294
295 /**
296 * Builds the device model VPN instance model object data, with respect to
297 * the devices level.
298 *
299 * @param id device id
300 * @param ins VPN instance
301 * @return model object data, with devices level
302 */
303 private static ModelObjectData buildInsModDataDevices(String id,
304 NetworkInstances ins) {
305 ModelObjectId modelId = ModelObjectId.builder()
306 .addChild(DefaultDevices.class).build();
307 Device device = new DefaultDevice();
308 device.deviceid(id);
309 device.networkInstances(ins);
Thomas Vachuskad17bc732017-03-24 11:46:55 -0700310 return DefaultModelObjectData.builder().identifier(modelId)
janani b35f6cbc2017-03-24 21:56:58 +0530311 .addModelObject((InnerModelObject) device).build();
312 }
313
314 /**
315 * Builds the device model VPN instance model object data, with respect to
316 * root level.
317 *
318 * @param id device id
319 * @param ins VPN instance
320 * @return model object data, with root level
321 */
322 private static ModelObjectData buildInsModDataRoot(String id,
323 NetworkInstances ins) {
324 Devices devices = new DefaultDevices();
325 Device device = new DefaultDevice();
326 List<Device> deviceList = new LinkedList<>();
327 device.deviceid(id);
328 device.networkInstances(ins);
329 deviceList.add(device);
330 devices.device(deviceList);
331 return DefaultModelObjectData.builder()
332 .addModelObject((InnerModelObject) devices).build();
333 }
334
335 /**
336 * Builds the device model interface model object data, with respect to
337 * device level.
338 *
339 * @param id device id
340 * @param ifs interface object
341 * @return model object data, with device level
342 */
343 private static ModelObjectData buildIntModDataDevice(String id,
344 Interfaces ifs) {
Vidyashree Rama04147ca2017-05-26 11:32:47 +0530345 org.onosproject.yang.gen.v1.ietfinterfaces
346 .rev20140508.ietfinterfaces.devices.DeviceKeys keys = new org.
347 onosproject.yang.gen.v1.ietfinterfaces.rev20140508
348 .ietfinterfaces.devices.DeviceKeys();
janani b35f6cbc2017-03-24 21:56:58 +0530349 keys.deviceid(id);
350 ModelObjectId modelId = ModelObjectId.builder()
Vidyashree Rama04147ca2017-05-26 11:32:47 +0530351 .addChild(org.onosproject.yang.gen.v1.ietfinterfaces.rev20140508
janani b35f6cbc2017-03-24 21:56:58 +0530352 .ietfinterfaces.DefaultDevices.class)
Vidyashree Rama04147ca2017-05-26 11:32:47 +0530353 .addChild(org.onosproject.yang.gen.v1.ietfinterfaces.rev20140508
janani b35f6cbc2017-03-24 21:56:58 +0530354 .ietfinterfaces.devices.DefaultDevice.class,
355 keys)
356 .build();
Thomas Vachuskad17bc732017-03-24 11:46:55 -0700357 return DefaultModelObjectData.builder().identifier(modelId)
janani b35f6cbc2017-03-24 21:56:58 +0530358 .addModelObject((InnerModelObject) ifs).build();
359 }
360
361 /**
362 * Returns the VPN instance create model object data.
363 *
364 * @param intMap interface map
365 * @param instances VPN instances
366 * @param id device id
367 * @return VPN instance model object data
368 */
369 static ModelObjectData getVpnCreateModObj(Map<AccessInfo, InterfaceInfo> intMap,
370 NetworkInstances instances,
371 String id) {
372 ModelObjectData modData;
373 boolean devAdded = isDevIdPresent(intMap, id);
374 if (devAdded) {
375 modData = buildInsModDataDevice(id, instances);
376 } else if (intMap.size() != 0) {
377 modData = buildInsModDataDevices(id, instances);
378 } else {
379 modData = buildInsModDataRoot(id, instances);
380 }
381 return modData;
382 }
383
384 /**
385 * Returns error message for interface being unavailable in device.
386 *
387 * @param intName interface name
388 * @return error message
389 */
390 static String getIntNotAvailable(String intName) {
391 return "The interface " + intName + " is not available.";
392 }
393
394 /**
395 * Returns the interface create model object data.
396 *
janani bd821b182017-03-30 16:34:49 +0530397 * @param ifNames interfaces
398 * @param ifs interface instance
399 * @param id device id
janani b35f6cbc2017-03-24 21:56:58 +0530400 * @return interface model object data
401 */
janani bd821b182017-03-30 16:34:49 +0530402 static ModelObjectData getIntCreateModObj(List<String> ifNames,
janani b35f6cbc2017-03-24 21:56:58 +0530403 Interfaces ifs, String id) {
404 ModelObjectData modData;
janani bd821b182017-03-30 16:34:49 +0530405 if (ifNames.size() > 1) {
janani b35f6cbc2017-03-24 21:56:58 +0530406 modData = buildIntModDataDevice(id, ifs);
407 } else {
408 modData = buildIntModDataRoot(id, ifs);
409 }
410 return modData;
411 }
412
413 /**
414 * Builds the device model interface model object data, with respect to
415 * root level.
416 *
417 * @param id device id
418 * @param ifs interface object
419 * @return model object data, with root level
420 */
421 private static ModelObjectData buildIntModDataRoot(String id,
422 Interfaces ifs) {
Vidyashree Rama04147ca2017-05-26 11:32:47 +0530423 org.onosproject.yang.gen.v1.ietfinterfaces
424 .rev20140508.ietfinterfaces.Devices devices = new org
425 .onosproject.yang.gen.v1.ietfinterfaces.rev20140508
426 .ietfinterfaces.DefaultDevices();
427 org.onosproject.yang.gen.v1.ietfinterfaces.rev20140508.ietfinterfaces.
428 devices.Device device = new org.onosproject.yang.gen.v1.
429 ietfinterfaces.rev20140508.ietfinterfaces.devices.DefaultDevice();
430 List<org.onosproject.yang.gen.v1.ietfinterfaces.rev20140508
431 .ietfinterfaces.devices.Device> deviceList = new LinkedList<>();
janani b35f6cbc2017-03-24 21:56:58 +0530432
433 device.deviceid(id);
434 device.interfaces(ifs);
435 deviceList.add(device);
436 devices.device(deviceList);
437 return DefaultModelObjectData.builder()
438 .addModelObject((InnerModelObject) devices).build();
439 }
440
441 /**
442 * Returns the BGP create driver info.
443 *
444 * @param bgpMap BGP map
445 * @param id device id
janani bd821b182017-03-30 16:34:49 +0530446 * @param devBgp device BGP info
447 * @param intBgp interface BGP info
448 * @return BGP driver config
janani b35f6cbc2017-03-24 21:56:58 +0530449 */
450 static BgpDriverInfo getBgpCreateConfigObj(Map<BgpInfo, DeviceId> bgpMap,
janani bd821b182017-03-30 16:34:49 +0530451 String id, BgpInfo devBgp,
452 BgpInfo intBgp) {
janani b35f6cbc2017-03-24 21:56:58 +0530453 boolean isDevIdPresent = isDevIdBgpPresent(bgpMap, id);
454 BgpDriverInfo info;
janani bd821b182017-03-30 16:34:49 +0530455 if (devBgp != intBgp) {
456 //TODO: With ipv6 BGP it has to be changed
457 info = new BgpDriverInfo(VPN, id);
458 } else if (isDevIdPresent) {
janani b35f6cbc2017-03-24 21:56:58 +0530459 info = new BgpDriverInfo(DEVICE, id);
janani b35f6cbc2017-03-24 21:56:58 +0530460 } else if (bgpMap.size() != 0) {
461 info = new BgpDriverInfo(DEVICES, id);
462 } else {
463 info = new BgpDriverInfo(ROOT, id);
464 }
465 return info;
466 }
467
468 /**
469 * Returns true if the device is present in the BGP map; false otherwise.
470 *
471 * @param bgpMap BGP map
472 * @param id device id
473 * @return true if device is present; false otherwise
474 */
475 private static boolean isDevIdBgpPresent(Map<BgpInfo, DeviceId> bgpMap,
476 String id) {
477 for (Map.Entry<BgpInfo, DeviceId> info : bgpMap.entrySet()) {
478 DeviceId devId = info.getValue();
479 if (devId.toString().equals(id)) {
480 return true;
481 }
482 }
483 return false;
484 }
janani bd821b182017-03-30 16:34:49 +0530485
486 /**
487 * Returns the model object data for VPN instance deletion.
488 *
489 * @param intMap interface map
490 * @param ins VPN instance
491 * @param id device id
492 * @return model object data
493 */
494 static ModelObjectData getVpnDelModObj(Map<AccessInfo, InterfaceInfo> intMap,
495 NetworkInstances ins,
496 String id) {
497 boolean isDevIdPresent = isDevIdPresent(intMap, id);
498 ModelObjectData modData;
499 if (intMap.size() == 0) {
500 modData = buildInsModDataRoot(id, ins);
501 } else if (isDevIdPresent) {
502 modData = buildInsModDataDevice(id, ins);
503 } else {
504 modData = buildInsModDataDevices(id, ins);
505 }
506 return modData;
507 }
508
509 /**
510 * Returns the BGP driver info for VPN BGP instance deletion.
511 *
512 * @param bgpMap BGP map
513 * @param id device id
514 * @return BGP driver info
515 */
516 static BgpDriverInfo getVpnBgpDelModObj(Map<BgpInfo, DeviceId> bgpMap,
517 String id) {
518 boolean isDevIdPresent = isDevIdBgpPresent(bgpMap, id);
519 BgpDriverInfo driInfo;
520 if (bgpMap.size() == 0) {
521 driInfo = new BgpDriverInfo(ROOT, id);
522 } else if (isDevIdPresent) {
523 driInfo = new BgpDriverInfo(DEVICE, id);
524 } else {
525 driInfo = new BgpDriverInfo(DEVICES, id);
526 }
527 return driInfo;
528 }
janani b9ed76be2017-08-29 19:11:33 +0530529
530 /**
531 * Returns the device id whose management ip address or lsr ID matches with
532 * the ip or lsr ID received respectively.
533 *
534 * @param ip value of ip or lsr id
535 * @param isIp if ip or lsr id
536 * @param devices available devices
537 * @return device id
538 */
539 static DeviceId getId(String ip, boolean isIp,
540 Iterable<org.onosproject.net.Device> devices) {
541 for (org.onosproject.net.Device device : devices) {
542 String val;
543 if (isIp) {
544 val = device.annotations().value(IP);
545 } else {
546 val = device.annotations().value(LSR_ID);
547 }
548 if (ip.equals(val)) {
549 return device.id();
550 }
551 }
552 throw new NetL3VpnException(getMgmtIpUnAvailErr(ip));
553 }
554
555 /**
556 * Returns ip address from the device id by parsing.
557 *
558 * @param devId device id
559 * @return ip address
560 */
561 static String getIpFromDevId(DeviceId devId) {
562 String devKey = devId.toString();
563 int firstInd = devKey.indexOf(COLON);
564 int secInd = devKey.indexOf(COLON, firstInd + 1);
565 return devKey.substring(firstInd + 1, secInd);
566 }
janani b35f6cbc2017-03-24 21:56:58 +0530567}