blob: 92ca7a46bedc3d31a3b7bebd77dbea1cf0ad1aa6 [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
Satish Ke107e662015-09-21 19:00:17 +053019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Service;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053023import org.onosproject.bgp.controller.BgpCfg;
24import org.onosproject.bgp.controller.BgpController;
25import org.onosproject.bgp.controller.BgpId;
Priyanka Bfc51c952016-03-26 14:30:33 +053026import org.onosproject.bgp.controller.BgpLinkListener;
Shashikanth VH3fe37982015-11-30 11:50:07 +053027import org.onosproject.bgp.controller.BgpLocalRib;
Shashikanth VHf62b5c02015-11-20 22:23:08 +053028import org.onosproject.bgp.controller.BgpNodeListener;
Jonathan Hart51539b82015-10-29 09:53:04 -070029import org.onosproject.bgp.controller.BgpPeer;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053030import org.onosproject.bgp.controller.BgpPeerManager;
Mohammad Shahid30fedc52017-08-09 11:49:40 +053031import org.onosproject.bgp.controller.BgpRouteListener;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053032import org.onosproject.bgpio.exceptions.BgpParseException;
33import org.onosproject.bgpio.protocol.BgpMessage;
Shashikanth VH3fe37982015-11-30 11:50:07 +053034import org.onosproject.bgpio.protocol.BgpUpdateMsg;
35import org.onosproject.bgpio.types.BgpValueType;
36import org.onosproject.bgpio.types.MpReachNlri;
37import org.onosproject.bgpio.types.MpUnReachNlri;
Satish Ke107e662015-09-21 19:00:17 +053038import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
Jonathan Hart51539b82015-10-29 09:53:04 -070041import java.util.Iterator;
mohamedrahil00f6f262016-11-24 20:20:41 +053042import java.util.LinkedList;
43import java.util.Map;
44import java.util.TreeMap;
Jonathan Hart51539b82015-10-29 09:53:04 -070045import java.util.List;
46import java.util.Set;
47import java.util.concurrent.ConcurrentHashMap;
48import java.util.concurrent.CopyOnWriteArraySet;
49import java.util.concurrent.locks.Lock;
50import java.util.concurrent.locks.ReentrantLock;
51
Satish Ke107e662015-09-21 19:00:17 +053052@Component(immediate = true)
53@Service
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053054public class BgpControllerImpl implements BgpController {
Satish Ke107e662015-09-21 19:00:17 +053055
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053056 private static final Logger log = LoggerFactory.getLogger(BgpControllerImpl.class);
mohamedrahil00f6f262016-11-24 20:20:41 +053057 final Controller ctrl = new Controller(this);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053058 protected ConcurrentHashMap<BgpId, BgpPeer> connectedPeers = new ConcurrentHashMap<BgpId, BgpPeer>();
Satish Ke107e662015-09-21 19:00:17 +053059
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053060 protected BgpPeerManagerImpl peerManager = new BgpPeerManagerImpl();
Shashikanth VHf62b5c02015-11-20 22:23:08 +053061
Jonathan Hart51539b82015-10-29 09:53:04 -070062 private BgpLocalRib bgplocalRib = new BgpLocalRibImpl(this);
63 private BgpLocalRib bgplocalRibVpn = new BgpLocalRibImpl(this);
Shashikanth VH3fe37982015-11-30 11:50:07 +053064
Shashikanth VHf62b5c02015-11-20 22:23:08 +053065 protected Set<BgpNodeListener> bgpNodeListener = new CopyOnWriteArraySet<>();
Priyanka Bfc51c952016-03-26 14:30:33 +053066 protected Set<BgpLinkListener> bgpLinkListener = new CopyOnWriteArraySet<>();
mohamedrahil00f6f262016-11-24 20:20:41 +053067 protected BgpController bgpController;
Shashikanth VH3fe37982015-11-30 11:50:07 +053068 private BgpConfig bgpconfig = new BgpConfig(this);
mohamedrahil00f6f262016-11-24 20:20:41 +053069 private List<String> activeExceptionList = new LinkedList();
70 private LinkedList<String> closedExceptionList = new LinkedList<String>();
71 private Map<String, List<String>> activeSessionExceptionMap = new TreeMap<>();
72 private Map<String, List<String>> closedSessionExceptionMap = new TreeMap<>();
Mohammad Shahid30fedc52017-08-09 11:49:40 +053073 protected Set<BgpRouteListener> bgpRouteListener = new CopyOnWriteArraySet<>();
mohamedrahil00f6f262016-11-24 20:20:41 +053074
75 @Override
76 public void activeSessionExceptionAdd(String peerId, String exception) {
77 if (peerId != null) {
78 activeExceptionList.add(exception);
79 activeSessionExceptionMap.put(peerId, activeExceptionList);
80 } else {
81 log.debug("Peer Id is null");
82 }
83 if (activeExceptionList.size() > 10) {
84 activeExceptionList.clear();
85 activeExceptionList.add(exception);
86 activeSessionExceptionMap.put(peerId, activeExceptionList);
87 }
88 }
89
90
91 @Override
92 public void closedSessionExceptionAdd(String peerId, String exception) {
93 if (peerId != null) {
94 closedExceptionList.add(exception);
95 closedSessionExceptionMap.put(peerId, closedExceptionList);
96 } else {
97 log.debug("Peer Id is null");
98 }
99 if (closedExceptionList.size() > 10) {
100 closedExceptionList.clear();
101 closedExceptionList.add(exception);
102 closedSessionExceptionMap.put(peerId, closedExceptionList);
103 }
104 }
105
106 @Override
107 public Map<String, List<String>> activeSessionMap() {
108 return activeSessionExceptionMap;
109 }
110
111 @Override
112 public Map<String, List<String>> closedSessionMap() {
113 return closedSessionExceptionMap;
114 }
Satish Ke107e662015-09-21 19:00:17 +0530115
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530116 @Override
117 public void addRouteListener(BgpRouteListener listener) {
118 this.bgpRouteListener.add(listener);
119 }
120
121 @Override
122 public void removeRouteListener(BgpRouteListener listener) {
123 this.bgpRouteListener.remove(listener);
124 }
125
126 @Override
127 public Set<BgpRouteListener> routeListener() {
128 return bgpRouteListener;
129 }
130
Satish Ke107e662015-09-21 19:00:17 +0530131 @Activate
132 public void activate() {
133 this.ctrl.start();
134 log.info("Started");
135 }
136
137 @Deactivate
138 public void deactivate() {
mohamedrahil00f6f262016-11-24 20:20:41 +0530139 activeSessionExceptionMap.clear();
140 closedSessionExceptionMap.clear();
Satish Ke107e662015-09-21 19:00:17 +0530141 // Close all connected peers
Shashikanth VH6de20d32015-10-09 12:04:13 +0530142 closeConnectedPeers();
Satish Ke107e662015-09-21 19:00:17 +0530143 this.ctrl.stop();
144 log.info("Stopped");
145 }
146
147 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530148 public Iterable<BgpPeer> getPeers() {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530149 return this.connectedPeers.values();
150 }
151
152 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530153 public BgpPeer getPeer(BgpId bgpId) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530154 return this.connectedPeers.get(bgpId);
155 }
156
157 @Override
Shashikanth VHf62b5c02015-11-20 22:23:08 +0530158 public void addListener(BgpNodeListener listener) {
159 this.bgpNodeListener.add(listener);
160 }
161
162 @Override
163 public void removeListener(BgpNodeListener listener) {
164 this.bgpNodeListener.remove(listener);
165 }
166
167 @Override
168 public Set<BgpNodeListener> listener() {
169 return bgpNodeListener;
170 }
171
172 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530173 public void writeMsg(BgpId bgpId, BgpMessage msg) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530174 this.getPeer(bgpId).sendMessage(msg);
Satish Ke107e662015-09-21 19:00:17 +0530175 }
176
177 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700178 public void processBgpPacket(BgpId bgpId, BgpMessage msg) throws BgpParseException {
Satish Ke107e662015-09-21 19:00:17 +0530179
Shashikanth VH3fe37982015-11-30 11:50:07 +0530180 BgpPeer peer = getPeer(bgpId);
181
Satish Ke107e662015-09-21 19:00:17 +0530182 switch (msg.getType()) {
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530183 case OPEN:
184 // TODO: Process Open message
185 break;
186 case KEEP_ALIVE:
187 // TODO: Process keepalive message
188 break;
189 case NOTIFICATION:
190 // TODO: Process notificatoin message
191 break;
192 case UPDATE:
193 BgpUpdateMsg updateMsg = (BgpUpdateMsg) msg;
194 List<BgpValueType> pathAttr = updateMsg.bgpPathAttributes().pathAttributes();
195 if (pathAttr == null) {
196 log.debug("llPathAttr is null, cannot process update message");
197 break;
198 }
199 Iterator<BgpValueType> listIterator = pathAttr.iterator();
200 boolean isLinkstate = false;
201 boolean isEvpn = false;
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530202
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530203 while (listIterator.hasNext()) {
204 BgpValueType attr = listIterator.next();
205 if (attr instanceof MpReachNlri) {
206 MpReachNlri mpReach = (MpReachNlri) attr;
207 if (mpReach.bgpFlowSpecNlri() == null
208 && mpReach.bgpEvpnNlri() == null) {
209 isLinkstate = true;
210 }
211 if (mpReach.bgpEvpnNlri() != null) {
212 isEvpn = true;
213 }
214 } else if (attr instanceof MpUnReachNlri) {
215 MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
216 if (mpUnReach.bgpFlowSpecNlri() == null
217 && mpUnReach.bgpEvpnNlri() == null) {
218 isLinkstate = true;
219 }
220 if (mpUnReach.bgpEvpnNlri() != null) {
221 isEvpn = true;
222 }
Shashikanth VHafb2e002016-02-12 14:48:29 +0530223 }
Shashikanth VH3fe37982015-11-30 11:50:07 +0530224 }
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530225 if (isLinkstate) {
226 peer.buildAdjRibIn(pathAttr);
227 }
228 if (isEvpn) {
229 for (BgpRouteListener listener : bgpRouteListener) {
230 listener.processRoute(bgpId, updateMsg);
231 }
232 }
233 break;
234 default:
235 // TODO: Process other message
236 break;
Satish Ke107e662015-09-21 19:00:17 +0530237 }
238 }
239
Shashikanth VH6de20d32015-10-09 12:04:13 +0530240 @Override
241 public void closeConnectedPeers() {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530242 BgpPeer bgpPeer;
243 for (BgpId id : this.connectedPeers.keySet()) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530244 bgpPeer = getPeer(id);
245 bgpPeer.disconnectPeer();
246 }
247 }
248
Satish Ke107e662015-09-21 19:00:17 +0530249 /**
Shashikanth VH6de20d32015-10-09 12:04:13 +0530250 * Implementation of an BGP Peer which is responsible for keeping track of connected peers and the state in which
251 * they are.
Satish Ke107e662015-09-21 19:00:17 +0530252 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530253 public class BgpPeerManagerImpl implements BgpPeerManager {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530254
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530255 private final Logger log = LoggerFactory.getLogger(BgpPeerManagerImpl.class);
Shashikanth VH6de20d32015-10-09 12:04:13 +0530256 private final Lock peerLock = new ReentrantLock();
257
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530258 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530259 public boolean addConnectedPeer(BgpId bgpId, BgpPeer bgpPeer) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530260
261 if (connectedPeers.get(bgpId) != null) {
262 this.log.error("Trying to add connectedPeer but found previous " + "value for bgp ip: {}",
263 bgpId.toString());
264 return false;
265 } else {
266 this.log.debug("Added Peer {}", bgpId.toString());
267 connectedPeers.put(bgpId, bgpPeer);
268 return true;
269 }
270 }
271
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530272 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530273 public boolean isPeerConnected(BgpId bgpId) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530274 if (connectedPeers.get(bgpId) == null) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530275 this.log.error("Is peer connected: bgpIp {}.", bgpId.toString());
Shashikanth VH6de20d32015-10-09 12:04:13 +0530276 return false;
277 }
278
279 return true;
280 }
281
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530282 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530283 public void removeConnectedPeer(BgpId bgpId) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530284 connectedPeers.remove(bgpId);
285 }
286
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530287 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530288 public BgpPeer getPeer(BgpId bgpId) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530289 return connectedPeers.get(bgpId);
290 }
291
292 /**
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530293 * Gets bgp peer instance.
294 *
295 * @param bgpController controller instance.
296 * @param sessionInfo bgp session info.
297 * @param pktStats packet statistics.
298 * @return BGPPeer peer instance.
299 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530300 public BgpPeer getBgpPeerInstance(BgpController bgpController, BgpSessionInfoImpl sessionInfo,
301 BgpPacketStatsImpl pktStats) {
302 BgpPeer bgpPeer = new BgpPeerImpl(bgpController, sessionInfo, pktStats);
Shashikanth VH6de20d32015-10-09 12:04:13 +0530303 return bgpPeer;
304 }
305
306 }
307
Vidyashree Rama7bd3d782015-11-23 08:46:33 +0530308 /**
309 * Returns controller.
310 *
311 * @return controller
312 */
313 public Controller controller() {
314 return this.ctrl;
315 }
316
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530317 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530318 public ConcurrentHashMap<BgpId, BgpPeer> connectedPeers() {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530319 return connectedPeers;
320 }
321
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530322 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530323 public BgpPeerManagerImpl peerManager() {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530324 return peerManager;
325 }
326
Satish Ke107e662015-09-21 19:00:17 +0530327 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530328 public BgpCfg getConfig() {
Satish Ke107e662015-09-21 19:00:17 +0530329 return this.bgpconfig;
330 }
Shashikanth VH6de20d32015-10-09 12:04:13 +0530331
332 @Override
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530333 public int connectedPeerCount() {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530334 return connectedPeers.size();
335 }
Shashikanth VH3fe37982015-11-30 11:50:07 +0530336
337 /**
338 * Gets the BGP local RIB.
339 *
340 * @return bgplocalRIB BGP local RIB.
341 */
342 @Override
343 public BgpLocalRib bgpLocalRib() {
Jonathan Hart51539b82015-10-29 09:53:04 -0700344 return bgplocalRib;
Shashikanth VH3fe37982015-11-30 11:50:07 +0530345 }
346
347 /**
348 * Gets the BGP local RIB with VPN.
349 *
350 * @return bgplocalRIBVpn BGP VPN local RIB .
351 */
352 @Override
353 public BgpLocalRib bgpLocalRibVpn() {
Jonathan Hart51539b82015-10-29 09:53:04 -0700354 return bgplocalRibVpn;
Shashikanth VH3fe37982015-11-30 11:50:07 +0530355 }
Priyanka Bfc51c952016-03-26 14:30:33 +0530356
357 @Override
358 public void addLinkListener(BgpLinkListener listener) {
359 this.bgpLinkListener.add(listener);
360 }
361
362 @Override
363 public void removeLinkListener(BgpLinkListener listener) {
364 this.bgpLinkListener.remove(listener);
365 }
366
367 @Override
368 public Set<BgpLinkListener> linkListener() {
369 return bgpLinkListener;
370 }
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530371}