blob: 804fb804bd112a66e59bb481d37481f00b0ac55e [file] [log] [blame]
Satish Ke107e662015-09-21 19:00:17 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Satish Ke107e662015-09-21 19:00:17 +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.bgp.controller.impl;
18
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053019import org.onosproject.bgp.controller.BgpCfg;
20import org.onosproject.bgp.controller.BgpController;
21import org.onosproject.bgp.controller.BgpId;
Priyanka Bfc51c952016-03-26 14:30:33 +053022import org.onosproject.bgp.controller.BgpLinkListener;
Shashikanth VH3fe37982015-11-30 11:50:07 +053023import org.onosproject.bgp.controller.BgpLocalRib;
Shashikanth VHf62b5c02015-11-20 22:23:08 +053024import org.onosproject.bgp.controller.BgpNodeListener;
Jonathan Hart51539b82015-10-29 09:53:04 -070025import org.onosproject.bgp.controller.BgpPeer;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053026import org.onosproject.bgp.controller.BgpPeerManager;
Mohammad Shahid30fedc52017-08-09 11:49:40 +053027import org.onosproject.bgp.controller.BgpRouteListener;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053028import org.onosproject.bgpio.exceptions.BgpParseException;
29import org.onosproject.bgpio.protocol.BgpMessage;
Shashikanth VH3fe37982015-11-30 11:50:07 +053030import org.onosproject.bgpio.protocol.BgpUpdateMsg;
31import org.onosproject.bgpio.types.BgpValueType;
32import org.onosproject.bgpio.types.MpReachNlri;
33import org.onosproject.bgpio.types.MpUnReachNlri;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070034import org.osgi.service.component.annotations.Activate;
35import org.osgi.service.component.annotations.Component;
36import org.osgi.service.component.annotations.Deactivate;
Satish Ke107e662015-09-21 19:00:17 +053037import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
Jonathan Hart51539b82015-10-29 09:53:04 -070040import java.util.Iterator;
mohamedrahil00f6f262016-11-24 20:20:41 +053041import java.util.LinkedList;
Jonathan Hart51539b82015-10-29 09:53:04 -070042import java.util.List;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070043import java.util.Map;
Jonathan Hart51539b82015-10-29 09:53:04 -070044import java.util.Set;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070045import java.util.TreeMap;
Jonathan Hart51539b82015-10-29 09:53:04 -070046import java.util.concurrent.ConcurrentHashMap;
47import java.util.concurrent.CopyOnWriteArraySet;
48import java.util.concurrent.locks.Lock;
49import java.util.concurrent.locks.ReentrantLock;
50
Ray Milkeyd84f89b2018-08-17 14:54:17 -070051@Component(immediate = true, service = BgpController.class)
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053052public class BgpControllerImpl implements BgpController {
Satish Ke107e662015-09-21 19:00:17 +053053
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053054 private static final Logger log = LoggerFactory.getLogger(BgpControllerImpl.class);
mohamedrahil00f6f262016-11-24 20:20:41 +053055 final Controller ctrl = new Controller(this);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053056 protected ConcurrentHashMap<BgpId, BgpPeer> connectedPeers = new ConcurrentHashMap<BgpId, BgpPeer>();
Satish Ke107e662015-09-21 19:00:17 +053057
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053058 protected BgpPeerManagerImpl peerManager = new BgpPeerManagerImpl();
Shashikanth VHf62b5c02015-11-20 22:23:08 +053059
Jonathan Hart51539b82015-10-29 09:53:04 -070060 private BgpLocalRib bgplocalRib = new BgpLocalRibImpl(this);
61 private BgpLocalRib bgplocalRibVpn = new BgpLocalRibImpl(this);
Shashikanth VH3fe37982015-11-30 11:50:07 +053062
Shashikanth VHf62b5c02015-11-20 22:23:08 +053063 protected Set<BgpNodeListener> bgpNodeListener = new CopyOnWriteArraySet<>();
Priyanka Bfc51c952016-03-26 14:30:33 +053064 protected Set<BgpLinkListener> bgpLinkListener = new CopyOnWriteArraySet<>();
mohamedrahil00f6f262016-11-24 20:20:41 +053065 protected BgpController bgpController;
Shashikanth VH3fe37982015-11-30 11:50:07 +053066 private BgpConfig bgpconfig = new BgpConfig(this);
mohamedrahil00f6f262016-11-24 20:20:41 +053067 private List<String> activeExceptionList = new LinkedList();
68 private LinkedList<String> closedExceptionList = new LinkedList<String>();
69 private Map<String, List<String>> activeSessionExceptionMap = new TreeMap<>();
70 private Map<String, List<String>> closedSessionExceptionMap = new TreeMap<>();
Mohammad Shahid30fedc52017-08-09 11:49:40 +053071 protected Set<BgpRouteListener> bgpRouteListener = new CopyOnWriteArraySet<>();
mohamedrahil00f6f262016-11-24 20:20:41 +053072
73 @Override
74 public void activeSessionExceptionAdd(String peerId, String exception) {
75 if (peerId != null) {
76 activeExceptionList.add(exception);
77 activeSessionExceptionMap.put(peerId, activeExceptionList);
78 } else {
79 log.debug("Peer Id is null");
80 }
81 if (activeExceptionList.size() > 10) {
82 activeExceptionList.clear();
83 activeExceptionList.add(exception);
84 activeSessionExceptionMap.put(peerId, activeExceptionList);
85 }
86 }
87
88
89 @Override
90 public void closedSessionExceptionAdd(String peerId, String exception) {
91 if (peerId != null) {
92 closedExceptionList.add(exception);
93 closedSessionExceptionMap.put(peerId, closedExceptionList);
94 } else {
95 log.debug("Peer Id is null");
96 }
97 if (closedExceptionList.size() > 10) {
98 closedExceptionList.clear();
99 closedExceptionList.add(exception);
100 closedSessionExceptionMap.put(peerId, closedExceptionList);
101 }
102 }
103
104 @Override
105 public Map<String, List<String>> activeSessionMap() {
106 return activeSessionExceptionMap;
107 }
108
109 @Override
110 public Map<String, List<String>> closedSessionMap() {
111 return closedSessionExceptionMap;
112 }
Satish Ke107e662015-09-21 19:00:17 +0530113
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530114 @Override
115 public void addRouteListener(BgpRouteListener listener) {
116 this.bgpRouteListener.add(listener);
117 }
118
119 @Override
120 public void removeRouteListener(BgpRouteListener listener) {
121 this.bgpRouteListener.remove(listener);
122 }
123
124 @Override
125 public Set<BgpRouteListener> routeListener() {
126 return bgpRouteListener;
127 }
128
Satish Ke107e662015-09-21 19:00:17 +0530129 @Activate
130 public void activate() {
131 this.ctrl.start();
132 log.info("Started");
133 }
134
135 @Deactivate
136 public void deactivate() {
mohamedrahil00f6f262016-11-24 20:20:41 +0530137 activeSessionExceptionMap.clear();
138 closedSessionExceptionMap.clear();
Satish Ke107e662015-09-21 19:00:17 +0530139 // Close all connected peers
Shashikanth VH6de20d32015-10-09 12:04:13 +0530140 closeConnectedPeers();
Satish Ke107e662015-09-21 19:00:17 +0530141 this.ctrl.stop();
142 log.info("Stopped");
143 }
144
145 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530146 public Iterable<BgpPeer> getPeers() {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530147 return this.connectedPeers.values();
148 }
149
150 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530151 public BgpPeer getPeer(BgpId bgpId) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530152 return this.connectedPeers.get(bgpId);
153 }
154
155 @Override
Shashikanth VHf62b5c02015-11-20 22:23:08 +0530156 public void addListener(BgpNodeListener listener) {
157 this.bgpNodeListener.add(listener);
158 }
159
160 @Override
161 public void removeListener(BgpNodeListener listener) {
162 this.bgpNodeListener.remove(listener);
163 }
164
165 @Override
166 public Set<BgpNodeListener> listener() {
167 return bgpNodeListener;
168 }
169
170 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530171 public void writeMsg(BgpId bgpId, BgpMessage msg) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530172 this.getPeer(bgpId).sendMessage(msg);
Satish Ke107e662015-09-21 19:00:17 +0530173 }
174
175 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700176 public void processBgpPacket(BgpId bgpId, BgpMessage msg) throws BgpParseException {
Satish Ke107e662015-09-21 19:00:17 +0530177
Shashikanth VH3fe37982015-11-30 11:50:07 +0530178 BgpPeer peer = getPeer(bgpId);
179
Satish Ke107e662015-09-21 19:00:17 +0530180 switch (msg.getType()) {
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530181 case OPEN:
182 // TODO: Process Open message
183 break;
184 case KEEP_ALIVE:
185 // TODO: Process keepalive message
186 break;
187 case NOTIFICATION:
188 // TODO: Process notificatoin message
189 break;
190 case UPDATE:
191 BgpUpdateMsg updateMsg = (BgpUpdateMsg) msg;
192 List<BgpValueType> pathAttr = updateMsg.bgpPathAttributes().pathAttributes();
193 if (pathAttr == null) {
194 log.debug("llPathAttr is null, cannot process update message");
195 break;
196 }
197 Iterator<BgpValueType> listIterator = pathAttr.iterator();
198 boolean isLinkstate = false;
199 boolean isEvpn = false;
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530200
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530201 while (listIterator.hasNext()) {
202 BgpValueType attr = listIterator.next();
203 if (attr instanceof MpReachNlri) {
204 MpReachNlri mpReach = (MpReachNlri) attr;
205 if (mpReach.bgpFlowSpecNlri() == null
206 && mpReach.bgpEvpnNlri() == null) {
207 isLinkstate = true;
208 }
209 if (mpReach.bgpEvpnNlri() != null) {
210 isEvpn = true;
211 }
212 } else if (attr instanceof MpUnReachNlri) {
213 MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
214 if (mpUnReach.bgpFlowSpecNlri() == null
215 && mpUnReach.bgpEvpnNlri() == null) {
216 isLinkstate = true;
217 }
218 if (mpUnReach.bgpEvpnNlri() != null) {
219 isEvpn = true;
220 }
Shashikanth VHafb2e002016-02-12 14:48:29 +0530221 }
Shashikanth VH3fe37982015-11-30 11:50:07 +0530222 }
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530223 if (isLinkstate) {
224 peer.buildAdjRibIn(pathAttr);
225 }
226 if (isEvpn) {
227 for (BgpRouteListener listener : bgpRouteListener) {
228 listener.processRoute(bgpId, updateMsg);
229 }
230 }
231 break;
232 default:
233 // TODO: Process other message
234 break;
Satish Ke107e662015-09-21 19:00:17 +0530235 }
236 }
237
Shashikanth VH6de20d32015-10-09 12:04:13 +0530238 @Override
239 public void closeConnectedPeers() {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530240 BgpPeer bgpPeer;
241 for (BgpId id : this.connectedPeers.keySet()) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530242 bgpPeer = getPeer(id);
243 bgpPeer.disconnectPeer();
244 }
245 }
246
Satish Ke107e662015-09-21 19:00:17 +0530247 /**
Shashikanth VH6de20d32015-10-09 12:04:13 +0530248 * Implementation of an BGP Peer which is responsible for keeping track of connected peers and the state in which
249 * they are.
Satish Ke107e662015-09-21 19:00:17 +0530250 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530251 public class BgpPeerManagerImpl implements BgpPeerManager {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530252
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530253 private final Logger log = LoggerFactory.getLogger(BgpPeerManagerImpl.class);
Shashikanth VH6de20d32015-10-09 12:04:13 +0530254 private final Lock peerLock = new ReentrantLock();
255
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530256 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530257 public boolean addConnectedPeer(BgpId bgpId, BgpPeer bgpPeer) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530258
259 if (connectedPeers.get(bgpId) != null) {
260 this.log.error("Trying to add connectedPeer but found previous " + "value for bgp ip: {}",
261 bgpId.toString());
262 return false;
263 } else {
264 this.log.debug("Added Peer {}", bgpId.toString());
265 connectedPeers.put(bgpId, bgpPeer);
266 return true;
267 }
268 }
269
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530270 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530271 public boolean isPeerConnected(BgpId bgpId) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530272 if (connectedPeers.get(bgpId) == null) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530273 this.log.error("Is peer connected: bgpIp {}.", bgpId.toString());
Shashikanth VH6de20d32015-10-09 12:04:13 +0530274 return false;
275 }
276
277 return true;
278 }
279
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530280 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530281 public void removeConnectedPeer(BgpId bgpId) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530282 connectedPeers.remove(bgpId);
283 }
284
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530285 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530286 public BgpPeer getPeer(BgpId bgpId) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530287 return connectedPeers.get(bgpId);
288 }
289
290 /**
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530291 * Gets bgp peer instance.
292 *
293 * @param bgpController controller instance.
294 * @param sessionInfo bgp session info.
295 * @param pktStats packet statistics.
296 * @return BGPPeer peer instance.
297 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530298 public BgpPeer getBgpPeerInstance(BgpController bgpController, BgpSessionInfoImpl sessionInfo,
299 BgpPacketStatsImpl pktStats) {
300 BgpPeer bgpPeer = new BgpPeerImpl(bgpController, sessionInfo, pktStats);
Shashikanth VH6de20d32015-10-09 12:04:13 +0530301 return bgpPeer;
302 }
303
304 }
305
Vidyashree Rama7bd3d782015-11-23 08:46:33 +0530306 /**
307 * Returns controller.
308 *
309 * @return controller
310 */
311 public Controller controller() {
312 return this.ctrl;
313 }
314
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530315 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530316 public ConcurrentHashMap<BgpId, BgpPeer> connectedPeers() {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530317 return connectedPeers;
318 }
319
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530320 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530321 public BgpPeerManagerImpl peerManager() {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530322 return peerManager;
323 }
324
Satish Ke107e662015-09-21 19:00:17 +0530325 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530326 public BgpCfg getConfig() {
Satish Ke107e662015-09-21 19:00:17 +0530327 return this.bgpconfig;
328 }
Shashikanth VH6de20d32015-10-09 12:04:13 +0530329
330 @Override
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530331 public int connectedPeerCount() {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530332 return connectedPeers.size();
333 }
Shashikanth VH3fe37982015-11-30 11:50:07 +0530334
335 /**
336 * Gets the BGP local RIB.
337 *
338 * @return bgplocalRIB BGP local RIB.
339 */
340 @Override
341 public BgpLocalRib bgpLocalRib() {
Jonathan Hart51539b82015-10-29 09:53:04 -0700342 return bgplocalRib;
Shashikanth VH3fe37982015-11-30 11:50:07 +0530343 }
344
345 /**
346 * Gets the BGP local RIB with VPN.
347 *
348 * @return bgplocalRIBVpn BGP VPN local RIB .
349 */
350 @Override
351 public BgpLocalRib bgpLocalRibVpn() {
Jonathan Hart51539b82015-10-29 09:53:04 -0700352 return bgplocalRibVpn;
Shashikanth VH3fe37982015-11-30 11:50:07 +0530353 }
Priyanka Bfc51c952016-03-26 14:30:33 +0530354
355 @Override
356 public void addLinkListener(BgpLinkListener listener) {
357 this.bgpLinkListener.add(listener);
358 }
359
360 @Override
361 public void removeLinkListener(BgpLinkListener listener) {
362 this.bgpLinkListener.remove(listener);
363 }
364
365 @Override
366 public Set<BgpLinkListener> linkListener() {
367 return bgpLinkListener;
368 }
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530369}