blob: 798c0a2d8ad314b88d5586cf46ffbd60ae91205b [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
Ray Milkeyd84f89b2018-08-17 14:54:17 -070018import org.osgi.service.component.annotations.Activate;
19import org.osgi.service.component.annotations.Component;
20import org.osgi.service.component.annotations.Deactivate;
21import org.osgi.service.component.annotations.Reference;
22import org.osgi.service.component.annotations.ReferenceCardinality;
Thejaswi N K38879622015-12-08 22:14:47 +053023
24import org.onosproject.bgp.controller.BgpCfg;
Thejaswi N K5ff45df2015-12-15 17:05:29 +053025import org.onosproject.bgp.controller.BgpPeerCfg;
Thejaswi N K38879622015-12-08 22:14:47 +053026import org.onosproject.core.ApplicationId;
27import org.onosproject.core.CoreService;
28import org.onosproject.net.config.ConfigFactory;
29import org.onosproject.net.config.NetworkConfigEvent;
30import org.onosproject.net.config.NetworkConfigListener;
31import org.onosproject.net.config.NetworkConfigRegistry;
32import org.onosproject.net.config.NetworkConfigService;
33import org.onosproject.net.config.basics.SubjectFactories;
34import org.onosproject.net.provider.AbstractProvider;
35import org.onosproject.net.provider.ProviderId;
36import org.onosproject.bgp.controller.BgpController;
37import org.slf4j.Logger;
38import org.osgi.service.component.ComponentContext;
39
Thejaswi N K5ff45df2015-12-15 17:05:29 +053040import java.util.ArrayList;
41import java.util.Iterator;
Thejaswi N K38879622015-12-08 22:14:47 +053042import java.util.List;
Thejaswi N K5ff45df2015-12-15 17:05:29 +053043import java.util.Map;
44import java.util.Set;
45import java.util.TreeMap;
Thejaswi N K38879622015-12-08 22:14:47 +053046
47import static org.slf4j.LoggerFactory.getLogger;
48
49/**
50 * BGP config provider to validate and populate the configuration.
51 */
52@Component(immediate = true)
Thejaswi N K38879622015-12-08 22:14:47 +053053public class BgpCfgProvider extends AbstractProvider {
54
55 private static final Logger log = getLogger(BgpCfgProvider.class);
56
57 static final String PROVIDER_ID = "org.onosproject.provider.bgp.cfg";
58
Ray Milkeyd84f89b2018-08-17 14:54:17 -070059 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thejaswi N K38879622015-12-08 22:14:47 +053060 protected BgpController bgpController;
61
Ray Milkeyd84f89b2018-08-17 14:54:17 -070062 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thejaswi N K38879622015-12-08 22:14:47 +053063 protected CoreService coreService;
64
Ray Milkeyd84f89b2018-08-17 14:54:17 -070065 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thejaswi N K38879622015-12-08 22:14:47 +053066 protected NetworkConfigRegistry configRegistry;
67
Ray Milkeyd84f89b2018-08-17 14:54:17 -070068 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Thejaswi N K38879622015-12-08 22:14:47 +053069 protected NetworkConfigService configService;
70
71 private final ConfigFactory configFactory =
72 new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, BgpAppConfig.class, "bgpapp") {
73 @Override
74 public BgpAppConfig createConfig() {
75 return new BgpAppConfig();
76 }
77 };
78
79 private final NetworkConfigListener configListener = new InternalConfigListener();
80
81 private ApplicationId appId;
82
83 /**
84 * Creates a Bgp config provider.
85 */
86 public BgpCfgProvider() {
87 super(new ProviderId("bgp", PROVIDER_ID));
88 }
89
90 @Activate
91 public void activate(ComponentContext context) {
92 appId = coreService.registerApplication(PROVIDER_ID);
93 configService.addListener(configListener);
94 configRegistry.registerConfigFactory(configFactory);
Thejaswi N K5ff45df2015-12-15 17:05:29 +053095 readConfiguration();
Thejaswi N K38879622015-12-08 22:14:47 +053096 log.info("BGP cfg provider started");
97 }
98
99 @Deactivate
100 public void deactivate(ComponentContext context) {
101 configRegistry.unregisterConfigFactory(configFactory);
102 configService.removeListener(configListener);
103 }
104
105 void setBgpController(BgpController bgpController) {
106 this.bgpController = bgpController;
107 }
108
109 /**
110 * Reads the configuration and set it to the BGP-LS south bound protocol.
Thejaswi N K38879622015-12-08 22:14:47 +0530111 */
112 private void readConfiguration() {
113 BgpCfg bgpConfig = null;
114 List<BgpAppConfig.BgpPeerConfig> nodes;
115 bgpConfig = bgpController.getConfig();
116 BgpAppConfig config = configRegistry.getConfig(appId, BgpAppConfig.class);
117
118 if (config == null) {
119 log.warn("No configuration found");
120 return;
121 }
122
123 /*Set the configuration */
124 bgpConfig.setRouterId(config.routerId());
125 bgpConfig.setAsNumber(config.localAs());
126 bgpConfig.setLsCapability(config.lsCapability());
127 bgpConfig.setHoldTime(config.holdTime());
128 bgpConfig.setMaxSession(config.maxSession());
129 bgpConfig.setLargeASCapability(config.largeAsCapability());
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530130 bgpConfig.setEvpnCapability(config.evpnCapability());
Thejaswi N K38879622015-12-08 22:14:47 +0530131
Ray Milkey3188c9b2016-09-12 11:51:07 -0700132 if (config.flowSpecCapability() == null) {
Shashikanth VH580bdeb2016-02-19 17:26:03 +0530133 bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.NONE);
Ray Milkey3188c9b2016-09-12 11:51:07 -0700134 } else {
135 if (config.flowSpecCapability().equals("IPV4")) {
136 bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.IPV4);
137 } else if (config.flowSpecCapability().equals("VPNV4")) {
138 bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.VPNV4);
139 } else if (config.flowSpecCapability().equals("IPV4_VPNV4")) {
140 bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.IPV4_VPNV4);
141 } else {
142 bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.NONE);
143 }
Shashikanth VH580bdeb2016-02-19 17:26:03 +0530144 }
Shashikanth VHb650bfa2016-04-18 12:54:03 +0530145 bgpConfig.setFlowSpecRpdCapability(config.rpdCapability());
Shashikanth VH580bdeb2016-02-19 17:26:03 +0530146
Thejaswi N K38879622015-12-08 22:14:47 +0530147 nodes = config.bgpPeer();
148 for (int i = 0; i < nodes.size(); i++) {
Thejaswi N K0008f1d2015-12-11 12:47:41 +0530149 String connectMode = nodes.get(i).connectMode();
Thejaswi N K38879622015-12-08 22:14:47 +0530150 bgpConfig.addPeer(nodes.get(i).hostname(), nodes.get(i).asNumber(), nodes.get(i).holdTime());
Thejaswi N K0008f1d2015-12-11 12:47:41 +0530151 if (connectMode.equals(BgpAppConfig.PEER_CONNECT_ACTIVE)) {
152 bgpConfig.connectPeer(nodes.get(i).hostname());
153 }
Thejaswi N K38879622015-12-08 22:14:47 +0530154 }
Ankur Aggarwalf363d1a2019-11-11 14:56:18 +0530155
156 bgpConfig.setConnectionType(getBgpConnectionTypeFromConfig(config));
Ankur Aggarwal9deda612020-03-26 05:28:09 +0000157
158 bgpConfig.setRouteRefreshEnabled(config.routeRefreshEnabled());
159 bgpConfig.setRouteRefreshPeriodicTimer(config.rrPeriodicTimer());
160 bgpConfig.setRouteRefreshWarmupTimer(config.rrWarmupTimer());
161 bgpConfig.setRouteRefreshCooldownTimer(config.rrCooldownTimer());
Thejaswi N K38879622015-12-08 22:14:47 +0530162 }
163
164 /**
Thejaswi N K5ff45df2015-12-15 17:05:29 +0530165 * Read the configuration and update it to the BGP-LS south bound protocol.
166 */
167 private void updateConfiguration() {
168 BgpCfg bgpConfig = null;
169 List<BgpAppConfig.BgpPeerConfig> nodes;
170 TreeMap<String, BgpPeerCfg> bgpPeerTree;
171 bgpConfig = bgpController.getConfig();
172 BgpPeerCfg peer = null;
173 BgpAppConfig config = configRegistry.getConfig(appId, BgpAppConfig.class);
174
175 if (config == null) {
176 log.warn("No configuration found");
177 return;
178 }
179
180
181 /* Update the self configuration */
Shashikanth VHde663832016-04-25 18:42:04 +0530182 if (bgpController.connectedPeerCount() != 0) {
183 //TODO: If connections already exist, disconnect
184 bgpController.closeConnectedPeers();
185 }
186 bgpConfig.setRouterId(config.routerId());
187 bgpConfig.setAsNumber(config.localAs());
188 bgpConfig.setLsCapability(config.lsCapability());
189 bgpConfig.setHoldTime(config.holdTime());
190 bgpConfig.setMaxSession(config.maxSession());
191 bgpConfig.setLargeASCapability(config.largeAsCapability());
Shashikanth VH580bdeb2016-02-19 17:26:03 +0530192
Ray Milkey3188c9b2016-09-12 11:51:07 -0700193 if (config.flowSpecCapability() == null) {
Shashikanth VHde663832016-04-25 18:42:04 +0530194 bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.NONE);
Ray Milkey3188c9b2016-09-12 11:51:07 -0700195 } else {
196 if (config.flowSpecCapability().equals("IPV4")) {
197 bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.IPV4);
198 } else if (config.flowSpecCapability().equals("VPNV4")) {
199 bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.VPNV4);
200 } else if (config.flowSpecCapability().equals("IPV4_VPNV4")) {
201 bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.IPV4_VPNV4);
202 } else {
203 bgpConfig.setFlowSpecCapability(BgpCfg.FlowSpec.NONE);
204 }
Thejaswi N K5ff45df2015-12-15 17:05:29 +0530205 }
Shashikanth VHb650bfa2016-04-18 12:54:03 +0530206 bgpConfig.setFlowSpecRpdCapability(config.rpdCapability());
Thejaswi N K5ff45df2015-12-15 17:05:29 +0530207
208 /* update the peer configuration */
209 bgpPeerTree = bgpConfig.getPeerTree();
210 if (bgpPeerTree.isEmpty()) {
211 log.info("There are no BGP peers to iterate");
212 } else {
213 Set set = bgpPeerTree.entrySet();
214 Iterator i = set.iterator();
215 List<BgpPeerCfg> absPeerList = new ArrayList<BgpPeerCfg>();
216
217 boolean exists = false;
218
219 while (i.hasNext()) {
220 Map.Entry me = (Map.Entry) i.next();
221 peer = (BgpPeerCfg) me.getValue();
222
223 nodes = config.bgpPeer();
224 for (int j = 0; j < nodes.size(); j++) {
225 String peerIp = nodes.get(j).hostname();
226 if (peerIp.equals(peer.getPeerRouterId())) {
227
228 if (bgpConfig.isPeerConnectable(peer.getPeerRouterId())) {
229 peer.setAsNumber(nodes.get(j).asNumber());
230 peer.setHoldtime(nodes.get(j).holdTime());
231 log.debug("Peer neighbor IP successfully modified :" + peer.getPeerRouterId());
232 } else {
233 log.debug("Peer neighbor IP cannot be modified :" + peer.getPeerRouterId());
234 }
235
236 nodes.remove(j);
237 exists = true;
238 break;
239 }
240 }
241
242 if (!exists) {
243 absPeerList.add(peer);
244 exists = false;
245 }
Shashikanth VHde663832016-04-25 18:42:04 +0530246
247 if (peer.connectPeer() != null) {
248 peer.connectPeer().disconnectPeer();
249 peer.setConnectPeer(null);
250 }
Thejaswi N K5ff45df2015-12-15 17:05:29 +0530251 }
252
253 /* Remove the absent nodes. */
254 for (int j = 0; j < absPeerList.size(); j++) {
255 bgpConfig.removePeer(absPeerList.get(j).getPeerRouterId());
256 }
257 }
258
259
260 nodes = config.bgpPeer();
261 for (int i = 0; i < nodes.size(); i++) {
262 String connectMode = nodes.get(i).connectMode();
263 bgpConfig.addPeer(nodes.get(i).hostname(), nodes.get(i).asNumber(), nodes.get(i).holdTime());
264 if (connectMode.equals(BgpAppConfig.PEER_CONNECT_ACTIVE)) {
265 bgpConfig.connectPeer(nodes.get(i).hostname());
266 }
267 }
268
Ankur Aggarwalf363d1a2019-11-11 14:56:18 +0530269 bgpConfig.setConnectionType(getBgpConnectionTypeFromConfig(config));
Ankur Aggarwal9deda612020-03-26 05:28:09 +0000270
271 bgpConfig.setRouteRefreshEnabled(config.routeRefreshEnabled());
272 bgpConfig.setRouteRefreshPeriodicTimer(config.rrPeriodicTimer());
273 bgpConfig.setRouteRefreshWarmupTimer(config.rrWarmupTimer());
274 bgpConfig.setRouteRefreshCooldownTimer(config.rrCooldownTimer());
Ankur Aggarwalf363d1a2019-11-11 14:56:18 +0530275 }
276
277 /**
278 * Function to get Bgp Connection type from config.
279 * @param config The BgpAppConfig from which connection type is to be fetched
280 * @return Bgp connection type
281 */
282 private BgpCfg.ConnectionType getBgpConnectionTypeFromConfig(BgpAppConfig config) {
283 //config cannot be null here, because of the function call sequence
284
285 //But, let's put a sanity check for connectionType
286 if (null == config.connectionType()) {
287 //IPv4 is the default connection type
288 return BgpCfg.ConnectionType.IPV4;
289 }
290
291 if (config.connectionType().equals(BgpAppConfig.CONNECTION_TYPE_IPV4)) {
292 return BgpCfg.ConnectionType.IPV6;
293 } else if (config.connectionType().equals(BgpAppConfig.CONNECTION_TYPE_IPV4_AND_IPV6)) {
294 return BgpCfg.ConnectionType.IPV4_IPV6;
295 } else {
296 return BgpCfg.ConnectionType.IPV4;
297 }
Thejaswi N K5ff45df2015-12-15 17:05:29 +0530298 }
299
300 /**
Thejaswi N K38879622015-12-08 22:14:47 +0530301 * BGP config listener to populate the configuration.
302 */
303 private class InternalConfigListener implements NetworkConfigListener {
304
305 @Override
306 public void event(NetworkConfigEvent event) {
307 if (!event.configClass().equals(BgpAppConfig.class)) {
308 return;
309 }
310
311 switch (event.type()) {
312 case CONFIG_ADDED:
313 readConfiguration();
314 break;
315 case CONFIG_UPDATED:
Thejaswi N K5ff45df2015-12-15 17:05:29 +0530316 updateConfiguration();
Thejaswi N K38879622015-12-08 22:14:47 +0530317 break;
318 case CONFIG_REMOVED:
319 default:
320 break;
321 }
322 }
323 }
324}