blob: d53bbc23150069cc763ccace44cce63ca8a4f92a [file] [log] [blame]
Shashikanth VH6de20d32015-10-09 12:04:13 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Shashikanth VH6de20d32015-10-09 12:04:13 +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
Jonathan Hart51539b82015-10-29 09:53:04 -070019import com.google.common.base.MoreObjects;
Shashikanth VHafb2e002016-02-12 14:48:29 +053020import com.google.common.base.Preconditions;
21
Shashikanth VH6de20d32015-10-09 12:04:13 +053022import org.jboss.netty.channel.Channel;
23import org.onlab.packet.IpAddress;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053024import org.onosproject.bgp.controller.BgpController;
Jonathan Hart51539b82015-10-29 09:53:04 -070025import org.onosproject.bgp.controller.BgpLocalRib;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053026import org.onosproject.bgp.controller.BgpPeer;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053027import org.onosproject.bgp.controller.BgpSessionInfo;
Priyanka Bc08e56d2015-11-27 15:28:33 +053028import org.onosproject.bgpio.exceptions.BgpParseException;
Mohammad Shahid30fedc52017-08-09 11:49:40 +053029import org.onosproject.bgpio.protocol.BgpEvpnNlri;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053030import org.onosproject.bgpio.protocol.BgpFactories;
31import org.onosproject.bgpio.protocol.BgpFactory;
Priyanka Bc08e56d2015-11-27 15:28:33 +053032import org.onosproject.bgpio.protocol.BgpLSNlri;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053033import org.onosproject.bgpio.protocol.BgpMessage;
Shashikanth VH26fd38a2016-04-26 18:11:37 +053034import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecNlri;
35import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecRouteKey;
Jonathan Hart51539b82015-10-29 09:53:04 -070036import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
Priyanka Bc08e56d2015-11-27 15:28:33 +053037import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
38import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
Priyanka Bc08e56d2015-11-27 15:28:33 +053039import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
Shashikanth VHafb2e002016-02-12 14:48:29 +053040import org.onosproject.bgpio.types.As4Path;
Mohammad Shahid30fedc52017-08-09 11:49:40 +053041import org.onosproject.bgpio.types.AsPath;
Shashikanth VH58260662016-02-13 01:12:02 +053042import org.onosproject.bgpio.types.BgpExtendedCommunity;
Priyanka Bc08e56d2015-11-27 15:28:33 +053043import org.onosproject.bgpio.types.BgpValueType;
Shashikanth VHafb2e002016-02-12 14:48:29 +053044import org.onosproject.bgpio.types.LocalPref;
45import org.onosproject.bgpio.types.Med;
Priyanka Bc08e56d2015-11-27 15:28:33 +053046import org.onosproject.bgpio.types.MpReachNlri;
47import org.onosproject.bgpio.types.MpUnReachNlri;
Shashikanth VHafb2e002016-02-12 14:48:29 +053048import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
Ankur Aggarwal2d7ff642020-07-29 08:46:04 +000049import org.onosproject.bgpio.types.RouteRefreshCapabilityTlv;
Shashikanth VHafb2e002016-02-12 14:48:29 +053050import org.onosproject.bgpio.types.Origin;
Shashikanth VH26fd38a2016-04-26 18:11:37 +053051import org.onosproject.bgpio.types.RpdCapabilityTlv;
Mohammad Shahid30fedc52017-08-09 11:49:40 +053052import org.onosproject.bgpio.types.attr.WideCommunity;
Shashikanth VHafb2e002016-02-12 14:48:29 +053053import org.onosproject.bgpio.util.Constants;
Shashikanth VH6de20d32015-10-09 12:04:13 +053054import org.slf4j.Logger;
55import org.slf4j.LoggerFactory;
56
Jonathan Hart51539b82015-10-29 09:53:04 -070057import java.net.InetSocketAddress;
58import java.net.SocketAddress;
Shashikanth VH26fd38a2016-04-26 18:11:37 +053059import java.util.ArrayList;
Jonathan Hart51539b82015-10-29 09:53:04 -070060import java.util.Collections;
Shashikanth VH26fd38a2016-04-26 18:11:37 +053061import java.util.LinkedList;
Jonathan Hart51539b82015-10-29 09:53:04 -070062import java.util.List;
63import java.util.ListIterator;
64import java.util.concurrent.RejectedExecutionException;
Shashikanth VH6de20d32015-10-09 12:04:13 +053065
66/**
67 * BGPPeerImpl implements BGPPeer, maintains peer information and store updates in RIB .
68 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053069public class BgpPeerImpl implements BgpPeer {
Shashikanth VH6de20d32015-10-09 12:04:13 +053070
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053071 protected final Logger log = LoggerFactory.getLogger(BgpPeerImpl.class);
Shashikanth VH6de20d32015-10-09 12:04:13 +053072
73 private static final String SHUTDOWN_MSG = "Worker has already been shutdown";
74
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053075 private BgpController bgpController;
Shashikanth VH6de20d32015-10-09 12:04:13 +053076 private Channel channel;
77 protected String channelId;
78 private boolean connected;
79 protected boolean isHandShakeComplete = false;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053080 private BgpSessionInfo sessionInfo;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053081 private BgpPacketStatsImpl pktStats;
Jonathan Hart51539b82015-10-29 09:53:04 -070082 private BgpLocalRib bgplocalRib;
83 private BgpLocalRib bgplocalRibVpn;
Priyanka Bc08e56d2015-11-27 15:28:33 +053084 private AdjRibIn adjRib;
85 private VpnAdjRibIn vpnAdjRib;
Shashikanth VH6de20d32015-10-09 12:04:13 +053086
Shashikanth VH3fe37982015-11-30 11:50:07 +053087 /**
88 * Return the adjacency RIB-IN.
89 *
90 * @return adjRib the adjacency RIB-IN
91 */
92 public AdjRibIn adjacencyRib() {
93 return adjRib;
94 }
95
96 /**
97 * Return the adjacency RIB-IN with VPN.
98 *
99 * @return vpnAdjRib the adjacency RIB-IN with VPN
100 */
101 public VpnAdjRibIn vpnAdjacencyRib() {
102 return vpnAdjRib;
103 }
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530104
Shashikanth VH6de20d32015-10-09 12:04:13 +0530105 @Override
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530106 public BgpSessionInfo sessionInfo() {
107 return sessionInfo;
108 }
109
110 /**
111 * Initialize peer.
112 *
113 *@param bgpController controller instance
114 *@param sessionInfo bgp session info
115 *@param pktStats packet statistics
116 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530117 public BgpPeerImpl(BgpController bgpController, BgpSessionInfo sessionInfo, BgpPacketStatsImpl pktStats) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530118 this.bgpController = bgpController;
119 this.sessionInfo = sessionInfo;
120 this.pktStats = pktStats;
Jonathan Hart51539b82015-10-29 09:53:04 -0700121 this.bgplocalRib = bgpController.bgpLocalRib();
122 this.bgplocalRibVpn = bgpController.bgpLocalRibVpn();
Priyanka Bc08e56d2015-11-27 15:28:33 +0530123 this.adjRib = new AdjRibIn();
124 this.vpnAdjRib = new VpnAdjRibIn();
125 }
126
Shashikanth VHafb2e002016-02-12 14:48:29 +0530127 /**
128 * Check if peer support capability.
129 *
130 * @param type capability type
131 * @param afi address family identifier
132 * @param sAfi subsequent address family identifier
133 * @return true if capability is supported, otherwise false
134 */
135 public final boolean isCapabilitySupported(short type, short afi, byte sAfi) {
136
137 List<BgpValueType> capability = sessionInfo.remoteBgpCapability();
138 ListIterator<BgpValueType> listIterator = capability.listIterator();
139
140 while (listIterator.hasNext()) {
141 BgpValueType tlv = listIterator.next();
142
143 if (tlv.getType() == type) {
144 if (tlv.getType() == MultiProtocolExtnCapabilityTlv.TYPE) {
145 MultiProtocolExtnCapabilityTlv temp = (MultiProtocolExtnCapabilityTlv) tlv;
146 if ((temp.getAfi() == afi) && (temp.getSafi() == sAfi)) {
mohamedrahil00f6f262016-11-24 20:20:41 +0530147 log.debug("Multi prorotcol extension capabality TLV is true");
Shashikanth VHafb2e002016-02-12 14:48:29 +0530148 return true;
mohamedrahil00f6f262016-11-24 20:20:41 +0530149
Shashikanth VHafb2e002016-02-12 14:48:29 +0530150 }
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530151 } else if (tlv.getType() == RpdCapabilityTlv.TYPE) {
152 RpdCapabilityTlv temp = (RpdCapabilityTlv) tlv;
153 if ((temp.getAfi() == afi) && (temp.getSafi() == sAfi)) {
mohamedrahil00f6f262016-11-24 20:20:41 +0530154 log.debug("RPD capabality TLV is true");
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530155 return true;
156 }
Shashikanth VHafb2e002016-02-12 14:48:29 +0530157 }
158 }
159 }
mohamedrahil00f6f262016-11-24 20:20:41 +0530160 log.debug("IS capabality is not supported ");
Shashikanth VHafb2e002016-02-12 14:48:29 +0530161 return false;
162 }
163
Ankur Aggarwal2d7ff642020-07-29 08:46:04 +0000164 private final boolean isRouteRefreshSupported() {
165 List<BgpValueType> capabilities = sessionInfo.remoteBgpCapability();
166
167 for (BgpValueType currentCapability : capabilities) {
168 if (currentCapability instanceof RouteRefreshCapabilityTlv) {
169 //Presence of Reoute Refresh capability TLV means route refresh is supported
170 log.debug("Route Refresh is supported by peer");
171 return true;
172 }
173 }
174 return false;
175 }
176
Shashikanth VHafb2e002016-02-12 14:48:29 +0530177 /**
178 * Send flow specification update message to peer.
179 *
180 * @param operType operation type
Shashikanth VH83f77e42016-05-26 20:34:56 +0530181 * @param routeKey flow rule key
Shashikanth VHafb2e002016-02-12 14:48:29 +0530182 * @param flowSpec flow specification details
Shashikanth VH83f77e42016-05-26 20:34:56 +0530183 * @param wideCommunity for route policy
Shashikanth VHafb2e002016-02-12 14:48:29 +0530184 */
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530185 public final void sendFlowSpecUpdateMessageToPeer(FlowSpecOperation operType, BgpFlowSpecRouteKey routeKey,
186 BgpFlowSpecNlri flowSpec, WideCommunity wideCommunity) {
Shashikanth VHafb2e002016-02-12 14:48:29 +0530187
188 List<BgpValueType> attributesList = new LinkedList<>();
189 byte sessionType = sessionInfo.isIbgpSession() ? (byte) 0 : (byte) 1;
Shashikanth VHe38c21e2016-05-26 21:37:25 +0530190 byte sAfi = Constants.SAFI_FLOWSPEC_VALUE;
Shashikanth VHafb2e002016-02-12 14:48:29 +0530191
192 boolean isFsCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
193 Constants.AFI_FLOWSPEC_VALUE,
194 Constants.SAFI_FLOWSPEC_VALUE);
195
196 boolean isVpnFsCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
197 Constants.AFI_FLOWSPEC_VALUE,
198 Constants.VPN_SAFI_FLOWSPEC_VALUE);
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530199
200 boolean isRpdCapabilitySet = isCapabilitySupported(RpdCapabilityTlv.TYPE,
201 Constants.AFI_FLOWSPEC_RPD_VALUE,
202 Constants.SAFI_FLOWSPEC_RPD_VALUE);
203
204 boolean isVpnRpdCapabilitySet = isCapabilitySupported(RpdCapabilityTlv.TYPE,
205 Constants.AFI_FLOWSPEC_RPD_VALUE,
206 Constants.VPN_SAFI_FLOWSPEC_RDP_VALUE);
207
208 if ((!isFsCapabilitySet) && (!isVpnFsCapabilitySet) && (!isRpdCapabilitySet) && (!isVpnRpdCapabilitySet)) {
Shashikanth VHafb2e002016-02-12 14:48:29 +0530209 log.debug("Peer do not support BGP flow spec capability", channel.getRemoteAddress());
210 return;
211 }
212
Shashikanth VHe38c21e2016-05-26 21:37:25 +0530213 if (isVpnFsCapabilitySet) {
Shashikanth VHafb2e002016-02-12 14:48:29 +0530214 sAfi = Constants.VPN_SAFI_FLOWSPEC_VALUE;
Shashikanth VHe38c21e2016-05-26 21:37:25 +0530215 } else if (isVpnRpdCapabilitySet) {
216 sAfi = Constants.VPN_SAFI_FLOWSPEC_RDP_VALUE;
Shashikanth VHafb2e002016-02-12 14:48:29 +0530217 }
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530218 attributesList.add(new Origin((byte) 0));
Shashikanth VHafb2e002016-02-12 14:48:29 +0530219
220 if (sessionType != 0) {
221 // EBGP
222 if (!bgpController.getConfig().getLargeASCapability()) {
223 List<Short> aspathSet = new ArrayList<>();
224 List<Short> aspathSeq = new ArrayList<>();
225 aspathSeq.add((short) bgpController.getConfig().getAsNumber());
226
227 AsPath asPath = new AsPath(aspathSet, aspathSeq);
228 attributesList.add(asPath);
229 } else {
230 List<Integer> aspathSet = new ArrayList<>();
231 List<Integer> aspathSeq = new ArrayList<>();
232 aspathSeq.add(bgpController.getConfig().getAsNumber());
233
234 As4Path as4Path = new As4Path(aspathSet, aspathSeq);
235 attributesList.add(as4Path);
236 }
237 attributesList.add(new Med(0));
238 } else {
239 attributesList.add(new AsPath());
240 attributesList.add(new Med(0));
241 attributesList.add(new LocalPref(100));
242 }
243
Shashikanth VH58260662016-02-13 01:12:02 +0530244 attributesList.add(new BgpExtendedCommunity(flowSpec.fsActionTlv()));
Shashikanth VHe38c21e2016-05-26 21:37:25 +0530245 if (wideCommunity != null) {
246 attributesList.add(wideCommunity);
247 }
Shashikanth VHafb2e002016-02-12 14:48:29 +0530248
249 if (operType == FlowSpecOperation.ADD) {
250 attributesList.add(new MpReachNlri(flowSpec, Constants.AFI_FLOWSPEC_VALUE, sAfi));
251 } else if (operType == FlowSpecOperation.DELETE) {
252 attributesList.add(new MpUnReachNlri(flowSpec, Constants.AFI_FLOWSPEC_VALUE, sAfi));
253 }
254
255 BgpMessage msg = Controller.getBgpMessageFactory4().updateMessageBuilder()
256 .setBgpPathAttributes(attributesList).build();
257
mohamedrahil00f6f262016-11-24 20:20:41 +0530258 log.debug("Sending flow spec update message to {}", channel.getRemoteAddress());
Shashikanth VHafb2e002016-02-12 14:48:29 +0530259 channel.write(Collections.singletonList(msg));
260 }
261
262 @Override
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530263 public void updateFlowSpec(FlowSpecOperation operType, BgpFlowSpecRouteKey routeKey,
264 BgpFlowSpecNlri flowSpec, WideCommunity wideCommunity) {
Shashikanth VHafb2e002016-02-12 14:48:29 +0530265 Preconditions.checkNotNull(operType, "flow specification operation type cannot be null");
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530266 Preconditions.checkNotNull(routeKey, "flow specification prefix cannot be null");
Shashikanth VHafb2e002016-02-12 14:48:29 +0530267 Preconditions.checkNotNull(flowSpec, "flow specification details cannot be null");
268 Preconditions.checkNotNull(flowSpec.fsActionTlv(), "flow specification action cannot be null");
269
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530270 sendFlowSpecUpdateMessageToPeer(operType, routeKey, flowSpec, wideCommunity);
Shashikanth VHafb2e002016-02-12 14:48:29 +0530271 }
Priyanka Bc08e56d2015-11-27 15:28:33 +0530272
273 @Override
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530274 public void updateEvpnNlri(FlowSpecOperation operType, IpAddress nextHop,
275 List<BgpValueType> extcommunity,
276 List<BgpEvpnNlri> evpnNlris) {
277 Preconditions.checkNotNull(operType, "Operation type cannot be null");
278 Preconditions.checkNotNull(evpnNlris, "Evpn nlri cannot be null");
279 sendEvpnUpdateMessageToPeer(operType, nextHop, extcommunity, evpnNlris);
280 }
281
282 private void sendEvpnUpdateMessageToPeer(FlowSpecOperation operType,
283 IpAddress nextHop,
284 List<BgpValueType> extcommunity,
285 List<BgpEvpnNlri> evpnNlris) {
286 List<BgpValueType> attributesList = new LinkedList<>();
287 byte sessionType = sessionInfo.isIbgpSession() ? (byte) 0 : (byte) 1;
288 short afi = Constants.AFI_EVPN_VALUE;
289 byte safi = Constants.SAFI_EVPN_VALUE;
290 boolean isEvpnCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
291 afi, safi);
292 if (!isEvpnCapabilitySet) {
293 log.debug("Peer do not support BGP Evpn capability",
294 channel.getRemoteAddress());
295 return;
296 }
297 attributesList.add(new Origin((byte) 0));
298
299 if (sessionType != 0) {
300 // EBGP
301 if (!bgpController.getConfig().getLargeASCapability()) {
302 List<Short> aspathSet = new ArrayList<>();
303 List<Short> aspathSeq = new ArrayList<>();
304 aspathSeq.add((short) bgpController.getConfig().getAsNumber());
305
306 AsPath asPath = new AsPath(aspathSet, aspathSeq);
307 attributesList.add(asPath);
308 } else {
309 List<Integer> aspathSet = new ArrayList<>();
310 List<Integer> aspathSeq = new ArrayList<>();
311 aspathSeq.add(bgpController.getConfig().getAsNumber());
312
313 As4Path as4Path = new As4Path(aspathSet, aspathSeq);
314 attributesList.add(as4Path);
315 }
316 } else {
317 attributesList.add(new AsPath());
318 }
319
320 if (!extcommunity.isEmpty()) {
321 attributesList.add(new BgpExtendedCommunity(extcommunity));
322 }
323 if (operType == FlowSpecOperation.ADD || operType == FlowSpecOperation.UPDATE) {
324 attributesList
325 .add(new MpReachNlri(evpnNlris, afi, safi, nextHop.getIp4Address()));
326 } else if (operType == FlowSpecOperation.DELETE) {
327 attributesList.add(new MpUnReachNlri(evpnNlris, afi, safi));
328 }
329
330 BgpMessage msg = Controller.getBgpMessageFactory4()
331 .updateMessageBuilder().setBgpPathAttributes(attributesList)
332 .build();
333 channel.write(Collections.singletonList(msg));
334 }
335
336 @Override
Ankur Aggarwal2d7ff642020-07-29 08:46:04 +0000337 public void sendRouteRefreshMessage() {
338 if (!isRouteRefreshSupported()) {
339 log.debug("Route Refresh not supported by peer, so cannot send message");
340 return;
341 }
342
343 BgpMessage msg = Controller.getBgpMessageFactory4()
344 .routeRefreshMsgBuilder()
345 .addAfiSafiValue(Constants.AFI_IPV6_UNICAST, Constants.EMPTY, Constants.SAFI_UNICAST)
346 .addAfiSafiValue(Constants.AFI_VALUE, Constants.EMPTY, Constants.SAFI_VALUE)
347 .build();
348
349 channel.write(Collections.singletonList(msg));
350
351 log.info("Route Refresh sent to {}", channelId);
352 }
353
354 @Override
Priyanka Bc08e56d2015-11-27 15:28:33 +0530355 public void buildAdjRibIn(List<BgpValueType> pathAttr) throws BgpParseException {
356 ListIterator<BgpValueType> iterator = pathAttr.listIterator();
357 while (iterator.hasNext()) {
358 BgpValueType attr = iterator.next();
359 if (attr instanceof MpReachNlri) {
360 List<BgpLSNlri> nlri = ((MpReachNlri) attr).mpReachNlri();
361 callAdd(this, nlri, pathAttr);
362 }
363 if (attr instanceof MpUnReachNlri) {
364 List<BgpLSNlri> nlri = ((MpUnReachNlri) attr).mpUnReachNlri();
365 callRemove(this, nlri);
366 }
367 }
368 }
369
370 /**
371 * Updates NLRI identifier node in a tree separately based on afi and safi.
372 *
373 * @param peerImpl BGP peer instance
374 * @param nlri MpReachNlri path attribute
375 * @param pathAttr list of BGP path attributes
376 * @throws BgpParseException throws exception
377 */
378 public void callAdd(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri, List<BgpValueType> pathAttr)
379 throws BgpParseException {
380 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
381 while (listIterator.hasNext()) {
382 BgpLSNlri nlriInfo = listIterator.next();
383 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
384 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
385 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
386 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700387 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530388 } else {
389 vpnAdjRib.addVpn(nlriInfo, details, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700390 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530391 ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530392 }
393 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
394 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
395 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
396 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700397 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530398 } else {
399 vpnAdjRib.addVpn(nlriInfo, details, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700400 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530401 ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530402 }
403 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
404 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
405 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
406 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700407 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530408 } else {
409 vpnAdjRib.addVpn(nlriInfo, details, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700410 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530411 ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530412 }
413 }
414 }
415 }
416
417 /**
418 * Sets BGP path attribute and NLRI details.
419 *
420 * @param nlriInfo MpReachNlri path attribute
421 * @param pathAttr list of BGP path attributes
422 * @return details object of PathAttrNlriDetails
423 * @throws BgpParseException throw exception
424 */
425 public PathAttrNlriDetails setPathAttrDetails(BgpLSNlri nlriInfo, List<BgpValueType> pathAttr)
426 throws BgpParseException {
427 PathAttrNlriDetails details = new PathAttrNlriDetails();
428 details.setProtocolID(nlriInfo.getProtocolId());
429 details.setIdentifier(nlriInfo.getIdentifier());
430 details.setPathAttribute(pathAttr);
431 return details;
432 }
433
434 /**
435 * Removes NLRI identifier node in a tree separately based on afi and safi.
436 *
437 * @param peerImpl BGP peer instance
438 * @param nlri NLRI information
Priyanka Bfc51c952016-03-26 14:30:33 +0530439 * @throws BgpParseException BGP parse exception
Priyanka Bc08e56d2015-11-27 15:28:33 +0530440 */
Priyanka Bfc51c952016-03-26 14:30:33 +0530441 public void callRemove(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri) throws BgpParseException {
Priyanka Bc08e56d2015-11-27 15:28:33 +0530442 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
443 while (listIterator.hasNext()) {
444 BgpLSNlri nlriInfo = listIterator.next();
445 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
446 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
447 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700448 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530449 } else {
450 vpnAdjRib.removeVpn(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700451 bgplocalRibVpn.delete(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530452 }
453 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
454 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
455 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700456 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530457 } else {
458 vpnAdjRib.removeVpn(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700459 bgplocalRibVpn.delete(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530460 }
461 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
462 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
463 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700464 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530465 } else {
466 vpnAdjRib.removeVpn(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700467 bgplocalRibVpn.delete(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530468 }
469 }
470 }
471 }
472
473 /**
474 * Return the adjacency RIB-IN.
475 *
476 * @return adjRib the adjacency RIB-IN
477 */
478 public AdjRibIn adjRib() {
479 return adjRib;
480 }
481
482 /**
483 * Return the adjacency RIB-IN with VPN.
484 *
485 * @return vpnAdjRib the adjacency RIB-IN with VPN
486 */
487 public VpnAdjRibIn vpnAdjRib() {
488 return vpnAdjRib;
Shashikanth VH6de20d32015-10-09 12:04:13 +0530489 }
490
Shashikanth VH3fe37982015-11-30 11:50:07 +0530491 /**
492 * Update localRIB on peer disconnect.
493 *
Priyanka Bfc51c952016-03-26 14:30:33 +0530494 * @throws BgpParseException while updating local RIB
Shashikanth VH3fe37982015-11-30 11:50:07 +0530495 */
Priyanka Bfc51c952016-03-26 14:30:33 +0530496 public void updateLocalRibOnPeerDisconnect() throws BgpParseException {
Jonathan Hart51539b82015-10-29 09:53:04 -0700497 BgpLocalRibImpl localRib = (BgpLocalRibImpl) bgplocalRib;
498 BgpLocalRibImpl localRibVpn = (BgpLocalRibImpl) bgplocalRibVpn;
Shashikanth VH3fe37982015-11-30 11:50:07 +0530499
Jonathan Hart51539b82015-10-29 09:53:04 -0700500 localRib.localRibUpdate(adjacencyRib());
501 localRibVpn.localRibUpdate(vpnAdjacencyRib());
Shashikanth VH3fe37982015-11-30 11:50:07 +0530502 }
503
Shashikanth VH6de20d32015-10-09 12:04:13 +0530504 // ************************
505 // Channel related
506 // ************************
507
508 @Override
509 public final void disconnectPeer() {
510 this.channel.close();
511 }
512
513 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530514 public final void sendMessage(BgpMessage m) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530515 log.debug("Sending message to {}", channel.getRemoteAddress());
516 try {
517 channel.write(Collections.singletonList(m));
518 this.pktStats.addOutPacket();
519 } catch (RejectedExecutionException e) {
520 log.warn(e.getMessage());
521 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
522 throw e;
523 }
524 }
525 }
526
527 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530528 public final void sendMessage(List<BgpMessage> msgs) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530529 try {
530 channel.write(msgs);
531 this.pktStats.addOutPacket(msgs.size());
532 } catch (RejectedExecutionException e) {
533 log.warn(e.getMessage());
534 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
535 throw e;
536 }
537 }
538 }
539
540 @Override
541 public final boolean isConnected() {
542 return this.connected;
543 }
544
545 @Override
546 public final void setConnected(boolean connected) {
547 this.connected = connected;
Jon Hall8c7b06a2017-02-22 13:37:33 -0800548 }
Shashikanth VH6de20d32015-10-09 12:04:13 +0530549
550 @Override
551 public final void setChannel(Channel channel) {
552 this.channel = channel;
553 final SocketAddress address = channel.getRemoteAddress();
554 if (address instanceof InetSocketAddress) {
555 final InetSocketAddress inetAddress = (InetSocketAddress) address;
556 final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
557 if (ipAddress.isIp4()) {
558 channelId = ipAddress.toString() + ':' + inetAddress.getPort();
559 } else {
560 channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort();
561 }
562 }
Jon Hall8c7b06a2017-02-22 13:37:33 -0800563 }
Shashikanth VH6de20d32015-10-09 12:04:13 +0530564
565 @Override
566 public final Channel getChannel() {
567 return this.channel;
Jon Hall8c7b06a2017-02-22 13:37:33 -0800568 }
Shashikanth VH6de20d32015-10-09 12:04:13 +0530569
570 @Override
571 public String channelId() {
572 return channelId;
573 }
574
Shashikanth VH6de20d32015-10-09 12:04:13 +0530575 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530576 public BgpFactory factory() {
577 return BgpFactories.getFactory(sessionInfo.remoteBgpVersion());
Shashikanth VH6de20d32015-10-09 12:04:13 +0530578 }
579
580 @Override
581 public boolean isHandshakeComplete() {
582 return isHandShakeComplete;
583 }
584
585 @Override
586 public String toString() {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530587 return MoreObjects.toStringHelper(getClass()).omitNullValues()
588 .add("channel", channelId())
Priyanka Bc08e56d2015-11-27 15:28:33 +0530589 .add("BgpId", sessionInfo().remoteBgpId()).toString();
Shashikanth VH6de20d32015-10-09 12:04:13 +0530590 }
591}