blob: d090420540ba16f9ac0d15b1df0cc79eab9e05dc [file] [log] [blame]
Thejaswi N K38879622015-12-08 22:14:47 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thejaswi N K38879622015-12-08 22:14:47 +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 */
16package org.onosproject.provider.bgp.cfg.impl;
17
18import com.fasterxml.jackson.databind.JsonNode;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070019import org.osgi.service.component.annotations.Reference;
20import org.osgi.service.component.annotations.ReferenceCardinality;
Thejaswi N K38879622015-12-08 22:14:47 +053021import org.onlab.osgi.DefaultServiceDirectory;
22import org.onlab.packet.IpAddress;
23import org.onosproject.bgp.controller.BgpCfg;
24import org.onosproject.bgp.controller.BgpController;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.net.config.Config;
mohamedrahil00f6f262016-11-24 20:20:41 +053027import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
Thejaswi N K38879622015-12-08 22:14:47 +053029
30import java.util.ArrayList;
31import java.util.List;
32
Mohammad Shahid30fedc52017-08-09 11:49:40 +053033import static com.google.common.base.Preconditions.checkNotNull;
Thejaswi N K38879622015-12-08 22:14:47 +053034import static org.onosproject.net.config.Config.FieldPresence.MANDATORY;
35import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL;
Thejaswi N K38879622015-12-08 22:14:47 +053036
37/**
38 * Configuration object for BGP.
39 */
40public class BgpAppConfig extends Config<ApplicationId> {
Ray Milkeyd84f89b2018-08-17 14:54:17 -070041 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thejaswi N K38879622015-12-08 22:14:47 +053042 BgpController bgpController;
43
44 BgpCfg bgpConfig = null;
45
mohamedrahil00f6f262016-11-24 20:20:41 +053046 protected final Logger log = LoggerFactory.getLogger(BgpAppConfig.class);
Thejaswi N K38879622015-12-08 22:14:47 +053047 public static final String ROUTER_ID = "routerId";
48 public static final String LOCAL_AS = "localAs";
49 public static final String MAX_SESSION = "maxSession";
50 public static final String LS_CAPABILITY = "lsCapability";
51 public static final String HOLD_TIME = "holdTime";
52 public static final String LARGE_AS_CAPABILITY = "largeAsCapability";
Shashikanth VH580bdeb2016-02-19 17:26:03 +053053 public static final String FLOW_SPEC_CAPABILITY = "flowSpecCapability";
Shashikanth VHb650bfa2016-04-18 12:54:03 +053054 public static final String FLOW_SPEC_RPD_CAPABILITY = "flowSpecRpdCapability";
Mohammad Shahid30fedc52017-08-09 11:49:40 +053055 public static final String EVPN_CAPABILITY = "evpnCapability";
Thejaswi N K38879622015-12-08 22:14:47 +053056
57 public static final String BGP_PEER = "bgpPeer";
58 public static final String PEER_IP = "peerIp";
59 public static final String REMOTE_AS = "remoteAs";
60 public static final String PEER_HOLD_TIME = "peerHoldTime";
Thejaswi N K0008f1d2015-12-11 12:47:41 +053061 public static final String PEER_CONNECT_MODE = "connectMode";
62 public static final String PEER_CONNECT_PASSIVE = "passive";
63 public static final String PEER_CONNECT_ACTIVE = "active";
Thejaswi N K38879622015-12-08 22:14:47 +053064
Ankur Aggarwalf363d1a2019-11-11 14:56:18 +053065 public static final String CONNECTION_TYPE = "connectionType";
66 public static final String CONNECTION_TYPE_IPV4 = "IPV4";
67 public static final String CONNECTION_TYPE_IPV6 = "IPV6";
68 public static final String CONNECTION_TYPE_IPV4_AND_IPV6 = "IPV4_IPV6";
69
Ankur Aggarwal9deda612020-03-26 05:28:09 +000070 public static final String ROUTE_REFRESH_ENABLED = "routeRefreshEnabled";
71 public static final String RR_PERIODIC_TIMER = "rrPeriodicTimer";
72 public static final String RR_COOLDOWN_TIMER = "rrCooldownTimer";
73 public static final String RR_WARMUP_TIMER = "rrWarmupTimer";
74
Thejaswi N K38879622015-12-08 22:14:47 +053075 static final int MAX_SHORT_AS_NUMBER = 65535;
76 static final long MAX_LONG_AS_NUMBER = 4294967295L;
77
Shashikanth VHde663832016-04-25 18:42:04 +053078 static final int MIN_SESSION_NUMBER = 1;
79 static final long MAX_SESSION_NUMBER = 21;
80
81 static final int MIN_HOLDTIME = 0;
82 static final long MAX_HOLDTIME = 65535;
83
Ankur Aggarwal9deda612020-03-26 05:28:09 +000084 static final String RR_ENABLED_DEFAULT_VALUE = "false";
85 static final String PERIODIC_TIMER_DEFAULT_VALUE = "1800"; //30 minutes
86 static final String COOLDOWN_TIMER_DEFAULT_VALUE = "300"; //5 minutes
87 static final String WARMUP_TIMER_DEFAULT_VALUE = "30"; //30 seconds
88
89 static final long MIN_PERIODIC_TIMER = 1;
90 static final long MAX_PERIODIC_TIMER = Integer.MAX_VALUE;
91 static final long MIN_COOLDOWN_TIMER = 1;
92 static final long MAX_COOLDOWN_TIMER = Integer.MAX_VALUE;
93 static final long MIN_WARMUP_TIMER = 1;
94 static final long MAX_WARMUP_TIMER = Integer.MAX_VALUE;
95
Thejaswi N K38879622015-12-08 22:14:47 +053096 @Override
97 public boolean isValid() {
98 boolean fields = false;
99
100 this.bgpController = DefaultServiceDirectory.getService(BgpController.class);
101 bgpConfig = bgpController.getConfig();
102
103 fields = hasOnlyFields(ROUTER_ID, LOCAL_AS, MAX_SESSION, LS_CAPABILITY,
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530104 HOLD_TIME, LARGE_AS_CAPABILITY, FLOW_SPEC_CAPABILITY,
Ankur Aggarwal9deda612020-03-26 05:28:09 +0000105 FLOW_SPEC_RPD_CAPABILITY, BGP_PEER, EVPN_CAPABILITY, CONNECTION_TYPE,
106 ROUTE_REFRESH_ENABLED, RR_PERIODIC_TIMER, RR_COOLDOWN_TIMER, RR_WARMUP_TIMER) &&
Thejaswi N K38879622015-12-08 22:14:47 +0530107 isIpAddress(ROUTER_ID, MANDATORY) && isNumber(LOCAL_AS, MANDATORY) &&
Shashikanth VHde663832016-04-25 18:42:04 +0530108 isNumber(MAX_SESSION, OPTIONAL, MIN_SESSION_NUMBER, MAX_SESSION_NUMBER)
109 && isNumber(HOLD_TIME, OPTIONAL, MIN_HOLDTIME, MAX_HOLDTIME) &&
Shashikanth VH580bdeb2016-02-19 17:26:03 +0530110 isBoolean(LS_CAPABILITY, OPTIONAL) && isBoolean(LARGE_AS_CAPABILITY, OPTIONAL) &&
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530111 isString(FLOW_SPEC_CAPABILITY, OPTIONAL) && isBoolean(FLOW_SPEC_RPD_CAPABILITY, OPTIONAL)
Ankur Aggarwal9deda612020-03-26 05:28:09 +0000112 && isBoolean(EVPN_CAPABILITY, OPTIONAL) && isString(CONNECTION_TYPE, OPTIONAL)
113 && isBoolean(ROUTE_REFRESH_ENABLED, OPTIONAL)
114 && isNumber(RR_PERIODIC_TIMER, OPTIONAL, MIN_PERIODIC_TIMER, MAX_PERIODIC_TIMER)
115 && isNumber(RR_COOLDOWN_TIMER, OPTIONAL, MIN_COOLDOWN_TIMER, MAX_COOLDOWN_TIMER)
116 && isNumber(RR_WARMUP_TIMER, OPTIONAL, MIN_WARMUP_TIMER, MAX_WARMUP_TIMER);
Thejaswi N K38879622015-12-08 22:14:47 +0530117
118 if (!fields) {
119 return fields;
120 }
121
122 return validateBgpConfiguration();
123 }
124
125 /**
126 * Returns routerId from the configuration.
127 *
128 * @return routerId
129 */
130 public String routerId() {
131 return get(ROUTER_ID, null);
132 }
133
134 /**
135 * Returns localAs number from the configuration.
136 *
137 * @return local As number
138 */
139 public int localAs() {
140 return Integer.parseInt(get(LOCAL_AS, null));
141 }
142
143 /**
144 * Returns max session from the configuration.
145 *
146 * @return max session
147 */
148 public int maxSession() {
149 return Integer.parseInt(get(MAX_SESSION, null));
150 }
151
152 /**
153 * Returns BGP-LS capability support from the configuration.
154 *
155 * @return true if BGP-LS capability is set else false
156 */
157 public boolean lsCapability() {
158 return Boolean.parseBoolean(get(LS_CAPABILITY, null));
159 }
160
161 /**
Shashikanth VHb650bfa2016-04-18 12:54:03 +0530162 * Returns flow spec route policy distribution capability support from the configuration.
163 *
164 * @return true if flow spec route policy distribution capability is set otherwise false
165 */
166 public boolean rpdCapability() {
167 return Boolean.parseBoolean(get(FLOW_SPEC_RPD_CAPABILITY, null));
168 }
169
170 /**
Thejaswi N K38879622015-12-08 22:14:47 +0530171 * Returns largeAs capability support from the configuration.
172 *
173 * @return largeAs capability
174 */
175 public boolean largeAsCapability() {
176 return Boolean.parseBoolean(get(LARGE_AS_CAPABILITY, null));
177 }
178
179 /**
Shashikanth VH580bdeb2016-02-19 17:26:03 +0530180 * Returns flow specification capability support from the configuration.
181 *
182 * @return flow specification capability
183 */
184 public String flowSpecCapability() {
185 return get(FLOW_SPEC_CAPABILITY, null);
186 }
187
188 /**
Thejaswi N K38879622015-12-08 22:14:47 +0530189 * Returns holdTime of the local node from the configuration.
190 *
191 * @return holdTime
192 */
193 public short holdTime() {
194 return Short.parseShort(get(HOLD_TIME, null));
195 }
196
197 /**
Ankur Aggarwalf363d1a2019-11-11 14:56:18 +0530198 * Returns BGP connection type from the configuration.
199 *
200 * @return BGP connection type
201 */
202 public String connectionType() {
203 return get(CONNECTION_TYPE, null);
204 }
205
206 /**
Ankur Aggarwal9deda612020-03-26 05:28:09 +0000207 * Returns if route refresh is enabled in the configuration.
208 *
209 * @return route refresh enabled
210 */
211 public boolean routeRefreshEnabled() {
212 return Boolean.parseBoolean(get(ROUTE_REFRESH_ENABLED, RR_ENABLED_DEFAULT_VALUE));
213 }
214
215 /**
216 * Returns value of route refresh periodic timer from the configuration.
217 *
218 * @return route refresh periodic timer
219 */
220 public long rrPeriodicTimer() {
221 return Long.parseLong(get(RR_PERIODIC_TIMER, PERIODIC_TIMER_DEFAULT_VALUE));
222 }
223
224 /**
225 * Returns value of route refresh warmup timer from the configuration.
226 *
227 * @return route refresh warmup timer
228 */
229 public long rrWarmupTimer() {
230 return Long.parseLong(get(RR_WARMUP_TIMER, WARMUP_TIMER_DEFAULT_VALUE));
231 }
232
233 /**
234 * Returns value of route refresh cooldown timer from the configuration.
235 *
236 * @return route refresh cooldown timer
237 */
238 public long rrCooldownTimer() {
239 return Long.parseLong(get(RR_COOLDOWN_TIMER, COOLDOWN_TIMER_DEFAULT_VALUE));
240 }
241
242 /**
Ankur Aggarwalf363d1a2019-11-11 14:56:18 +0530243 * Validates the BGP connection type.
244 *
245 * @return true if valid else false
246 */
247 public boolean validateConnectionType() {
248 if (connectionType() != null) {
249 String connectionType = connectionType();
250 if (!connectionType.equals(CONNECTION_TYPE_IPV4) && !connectionType.equals(CONNECTION_TYPE_IPV6)
251 && !connectionType.equals(CONNECTION_TYPE_IPV4_AND_IPV6)) {
252 log.error("Connection Type is invalid");
253 return false;
254 }
255 }
256 log.debug("Connection Type is valid");
257 return true;
258 }
259
260 /**
Shashikanth VH580bdeb2016-02-19 17:26:03 +0530261 * Validates the flow specification capability.
262 *
263 * @return true if valid else false
264 */
265 public boolean validateFlowSpec() {
266 if (flowSpecCapability() != null) {
267 String flowSpec = flowSpecCapability();
Shashikanth VH09792f02016-05-10 16:59:57 +0530268 if ((!flowSpec.equals("IPV4")) && (!flowSpec.equals("VPNV4")) && (!flowSpec.equals("IPV4_VPNV4"))) {
mohamedrahil00f6f262016-11-24 20:20:41 +0530269 log.debug("Flow specification capabality is false");
Shashikanth VH09792f02016-05-10 16:59:57 +0530270 return false;
Shashikanth VH580bdeb2016-02-19 17:26:03 +0530271 }
272 }
mohamedrahil00f6f262016-11-24 20:20:41 +0530273 log.debug("Flow specification capabality is true");
Shashikanth VH09792f02016-05-10 16:59:57 +0530274 return true;
Shashikanth VH580bdeb2016-02-19 17:26:03 +0530275 }
276
277 /**
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530278 * Returns evpn capability support from the configuration.
279 *
280 * @return evpn capability
281 */
282 public boolean evpnCapability() {
283 return Boolean.parseBoolean(get(EVPN_CAPABILITY, null));
284 }
285
286 /**
Shashikanth VHde663832016-04-25 18:42:04 +0530287 * Validates the hold time value.
288 *
289 * @return true if valid else false
290 */
291 public boolean validateHoldTime() {
292 if (holdTime() != 0) {
293 short holdTime = holdTime();
294 if ((holdTime == 1) || (holdTime == 2)) {
295 return false;
296 }
297 }
298 return true;
299 }
300
301 /**
Thejaswi N K38879622015-12-08 22:14:47 +0530302 * Validates the Bgp local and peer configuration.
303 *
304 * @return true if valid else false
305 */
306 public boolean validateBgpConfiguration() {
307
308 if (!validateLocalAs()) {
309 return false;
310 }
311
312 if (!validateRouterId()) {
313 return false;
314 }
315
316 if (!validateBgpPeers()) {
317 return false;
318 }
319
Shashikanth VH580bdeb2016-02-19 17:26:03 +0530320 if (!validateFlowSpec()) {
321 return false;
322 }
Shashikanth VHde663832016-04-25 18:42:04 +0530323
324 if (!validateHoldTime()) {
325 return false;
326 }
Ankur Aggarwalf363d1a2019-11-11 14:56:18 +0530327
328 if (!validateConnectionType()) {
329 return false;
330 }
Thejaswi N K38879622015-12-08 22:14:47 +0530331 return true;
332 }
333
334 /**
335 * Validates the Bgp As number.
336 *
337 * @return true if valid else false
338 */
339 public boolean validateLocalAs() {
340
341 long localAs = 0;
342 localAs = localAs();
343
Thejaswi N K38879622015-12-08 22:14:47 +0530344 if (largeAsCapability()) {
345
346 if (localAs == 0 || localAs >= MAX_LONG_AS_NUMBER) {
347 return false;
348 }
349 } else {
350 if (localAs == 0 || localAs >= MAX_SHORT_AS_NUMBER) {
351 return false;
352 }
353 }
354
355 return true;
356 }
357
358 /**
359 * Validates the Bgp peer As number.
360 *
Jian Lidfba7392016-01-22 16:46:58 -0800361 * @param remoteAs remote As number
Thejaswi N K38879622015-12-08 22:14:47 +0530362 * @return true if valid else false
363 */
364 public boolean validateRemoteAs(long remoteAs) {
365 if (largeAsCapability()) {
366
367 if (remoteAs == 0 || remoteAs >= MAX_LONG_AS_NUMBER) {
368 return false;
369 }
370 } else {
371 if (remoteAs == 0 || remoteAs >= MAX_SHORT_AS_NUMBER) {
372 return false;
373 }
374 }
375 return true;
376 }
377
378 /**
379 * Validates the Bgp Router ID configuration.
380 *
381 * @return true if valid else false
382 */
383 public boolean validateRouterId() {
384 String routerId = routerId();
Shashikanth VHde663832016-04-25 18:42:04 +0530385 // TODO: router ID validation
Thejaswi N K38879622015-12-08 22:14:47 +0530386 return true;
387 }
388
389 /**
390 * Validates the Bgp peer holdTime.
391 *
Jian Lidfba7392016-01-22 16:46:58 -0800392 * @param remoteAs remote As number
Thejaswi N K38879622015-12-08 22:14:47 +0530393 * @return true if valid else false
394 */
395 public boolean validatePeerHoldTime(long remoteAs) {
396 //TODO:Validate it later..
397 return true;
398 }
399
400 /**
401 * Validates the Bgp peer configuration.
402 *
403 * @return true if valid else false
404 */
405 public boolean validateBgpPeers() {
406 List<BgpPeerConfig> nodes;
Thejaswi N K0008f1d2015-12-11 12:47:41 +0530407 String connectMode;
Thejaswi N K38879622015-12-08 22:14:47 +0530408
409 nodes = bgpPeer();
410 for (int i = 0; i < nodes.size(); i++) {
Thejaswi N K0008f1d2015-12-11 12:47:41 +0530411 connectMode = nodes.get(i).connectMode();
Thejaswi N K38879622015-12-08 22:14:47 +0530412 if ((IpAddress.valueOf(nodes.get(i).hostname()) == null) ||
413 !validateRemoteAs(nodes.get(i).asNumber()) ||
Thejaswi N K0008f1d2015-12-11 12:47:41 +0530414 !validatePeerHoldTime(nodes.get(i).holdTime()) ||
415 !(connectMode.equals(PEER_CONNECT_ACTIVE) || connectMode.equals(PEER_CONNECT_PASSIVE))) {
mohamedrahil00f6f262016-11-24 20:20:41 +0530416 log.debug("BGP peer configration false");
Thejaswi N K38879622015-12-08 22:14:47 +0530417 return false;
418 }
419 }
mohamedrahil00f6f262016-11-24 20:20:41 +0530420 log.debug("BGP peer configration true");
Thejaswi N K38879622015-12-08 22:14:47 +0530421 return true;
422 }
423
424 /**
425 * Returns the set of nodes read from network config.
426 *
427 * @return list of BgpPeerConfig or null
428 */
429 public List<BgpPeerConfig> bgpPeer() {
430 List<BgpPeerConfig> nodes = new ArrayList<BgpPeerConfig>();
Thejaswi N K38879622015-12-08 22:14:47 +0530431 JsonNode jsonNodes = object.get(BGP_PEER);
432 if (jsonNodes == null) {
433 return null;
434 }
435
436 jsonNodes.forEach(jsonNode -> nodes.add(new BgpPeerConfig(
437 jsonNode.path(PEER_IP).asText(),
438 jsonNode.path(REMOTE_AS).asInt(),
Thejaswi N K0008f1d2015-12-11 12:47:41 +0530439 jsonNode.path(PEER_HOLD_TIME).asInt(),
440 jsonNode.path(PEER_CONNECT_MODE).asText())));
Thejaswi N K38879622015-12-08 22:14:47 +0530441
442 return nodes;
443 }
444
445 /**
446 * Configuration for Bgp peer nodes.
447 */
448 public static class BgpPeerConfig {
449
450 private final String hostname;
451 private final int asNumber;
452 private final short holdTime;
Thejaswi N K0008f1d2015-12-11 12:47:41 +0530453 private final String connectMode;
Thejaswi N K38879622015-12-08 22:14:47 +0530454
Thejaswi N K0008f1d2015-12-11 12:47:41 +0530455 public BgpPeerConfig(String hostname, int asNumber, int holdTime, String connectMode) {
Thejaswi N K38879622015-12-08 22:14:47 +0530456 this.hostname = checkNotNull(hostname);
457 this.asNumber = asNumber;
458 this.holdTime = (short) holdTime;
Thejaswi N K0008f1d2015-12-11 12:47:41 +0530459 this.connectMode = connectMode;
Thejaswi N K38879622015-12-08 22:14:47 +0530460 }
461
462 /**
463 * Returns hostname of the peer node.
464 *
465 * @return hostname
466 */
467 public String hostname() {
468 return this.hostname;
469 }
470
471 /**
472 * Returns asNumber if peer.
473 *
474 * @return asNumber
475 */
476 public int asNumber() {
477 return this.asNumber;
478 }
479
480 /**
481 * Returns holdTime of the peer node.
482 *
483 * @return holdTime
484 */
485 public short holdTime() {
486 return this.holdTime;
487 }
Thejaswi N K0008f1d2015-12-11 12:47:41 +0530488
489 /**
490 * Returns connection mode for the peer node.
491 *
492 * @return active or passive connection
493 */
494 public String connectMode() {
495 return this.connectMode;
496 }
Thejaswi N K38879622015-12-08 22:14:47 +0530497 }
498}