blob: de2c9457efd3a84c815538de1d79efb319e6516a [file] [log] [blame]
Shashikanth VH6de20d32015-10-09 12:04:13 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
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
22import java.util.ArrayList;
23import java.util.LinkedList;
24import java.util.Map;
25import java.util.Set;
26
Shashikanth VH6de20d32015-10-09 12:04:13 +053027import org.jboss.netty.channel.Channel;
28import org.onlab.packet.IpAddress;
Shashikanth VHe3a73bc2016-02-22 20:11:31 +053029import org.onlab.packet.IpPrefix;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053030import org.onosproject.bgp.controller.BgpController;
Jonathan Hart51539b82015-10-29 09:53:04 -070031import org.onosproject.bgp.controller.BgpLocalRib;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053032import org.onosproject.bgp.controller.BgpPeer;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053033import org.onosproject.bgp.controller.BgpSessionInfo;
Priyanka Bc08e56d2015-11-27 15:28:33 +053034import org.onosproject.bgpio.exceptions.BgpParseException;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053035import org.onosproject.bgpio.protocol.BgpFactories;
36import org.onosproject.bgpio.protocol.BgpFactory;
Priyanka Bc08e56d2015-11-27 15:28:33 +053037import org.onosproject.bgpio.protocol.BgpLSNlri;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053038import org.onosproject.bgpio.protocol.BgpMessage;
Shashikanth VHafb2e002016-02-12 14:48:29 +053039import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecDetails;
40import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecPrefix;
Jonathan Hart51539b82015-10-29 09:53:04 -070041import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
Priyanka Bc08e56d2015-11-27 15:28:33 +053042import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
43import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
Priyanka Bc08e56d2015-11-27 15:28:33 +053044import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
Shashikanth VHafb2e002016-02-12 14:48:29 +053045import org.onosproject.bgpio.types.AsPath;
46import org.onosproject.bgpio.types.As4Path;
Shashikanth VH58260662016-02-13 01:12:02 +053047import org.onosproject.bgpio.types.BgpExtendedCommunity;
Shashikanth VHe3a73bc2016-02-22 20:11:31 +053048import org.onosproject.bgpio.types.BgpFsDestinationPrefix;
49import org.onosproject.bgpio.types.BgpFsSourcePrefix;
Priyanka Bc08e56d2015-11-27 15:28:33 +053050import org.onosproject.bgpio.types.BgpValueType;
Shashikanth VHafb2e002016-02-12 14:48:29 +053051import org.onosproject.bgpio.types.LocalPref;
52import org.onosproject.bgpio.types.Med;
Priyanka Bc08e56d2015-11-27 15:28:33 +053053import org.onosproject.bgpio.types.MpReachNlri;
54import org.onosproject.bgpio.types.MpUnReachNlri;
Shashikanth VHafb2e002016-02-12 14:48:29 +053055import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
56import org.onosproject.bgpio.types.Origin;
57import org.onosproject.bgpio.types.RouteDistinguisher;
58import org.onosproject.bgpio.util.Constants;
Shashikanth VH6de20d32015-10-09 12:04:13 +053059import org.slf4j.Logger;
60import org.slf4j.LoggerFactory;
61
Jonathan Hart51539b82015-10-29 09:53:04 -070062import java.net.InetSocketAddress;
63import java.net.SocketAddress;
64import java.util.Collections;
65import java.util.List;
66import java.util.ListIterator;
67import java.util.concurrent.RejectedExecutionException;
Shashikanth VH6de20d32015-10-09 12:04:13 +053068
69/**
70 * BGPPeerImpl implements BGPPeer, maintains peer information and store updates in RIB .
71 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053072public class BgpPeerImpl implements BgpPeer {
Shashikanth VH6de20d32015-10-09 12:04:13 +053073
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053074 protected final Logger log = LoggerFactory.getLogger(BgpPeerImpl.class);
Shashikanth VH6de20d32015-10-09 12:04:13 +053075
76 private static final String SHUTDOWN_MSG = "Worker has already been shutdown";
77
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053078 private BgpController bgpController;
Shashikanth VH6de20d32015-10-09 12:04:13 +053079 private Channel channel;
80 protected String channelId;
81 private boolean connected;
82 protected boolean isHandShakeComplete = false;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053083 private BgpSessionInfo sessionInfo;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053084 private BgpPacketStatsImpl pktStats;
Jonathan Hart51539b82015-10-29 09:53:04 -070085 private BgpLocalRib bgplocalRib;
86 private BgpLocalRib bgplocalRibVpn;
Priyanka Bc08e56d2015-11-27 15:28:33 +053087 private AdjRibIn adjRib;
88 private VpnAdjRibIn vpnAdjRib;
Shashikanth VHe3a73bc2016-02-22 20:11:31 +053089 private BgpFlowSpecRib flowSpecRibOut;
90 private BgpFlowSpecRib flowSpecRibIn;
Shashikanth VHafb2e002016-02-12 14:48:29 +053091
92 /**
93 * Returns the flowSpec RIB out.
94 *
95 * @return flow Specification RIB out
96 */
Shashikanth VHe3a73bc2016-02-22 20:11:31 +053097 public BgpFlowSpecRib flowSpecRibOut() {
Shashikanth VHafb2e002016-02-12 14:48:29 +053098 return flowSpecRibOut;
99 }
100
101 /**
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530102 * Returns the flowSpec RIB-in.
Shashikanth VHafb2e002016-02-12 14:48:29 +0530103 *
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530104 * @return flow Specification RIB-in
Shashikanth VHafb2e002016-02-12 14:48:29 +0530105 */
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530106 public BgpFlowSpecRib flowSpecRibIn() {
107 return flowSpecRibIn;
Shashikanth VHafb2e002016-02-12 14:48:29 +0530108 }
Shashikanth VH6de20d32015-10-09 12:04:13 +0530109
Shashikanth VH3fe37982015-11-30 11:50:07 +0530110 /**
111 * Return the adjacency RIB-IN.
112 *
113 * @return adjRib the adjacency RIB-IN
114 */
115 public AdjRibIn adjacencyRib() {
116 return adjRib;
117 }
118
119 /**
120 * Return the adjacency RIB-IN with VPN.
121 *
122 * @return vpnAdjRib the adjacency RIB-IN with VPN
123 */
124 public VpnAdjRibIn vpnAdjacencyRib() {
125 return vpnAdjRib;
126 }
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530127
Shashikanth VH6de20d32015-10-09 12:04:13 +0530128 @Override
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530129 public BgpSessionInfo sessionInfo() {
130 return sessionInfo;
131 }
132
133 /**
134 * Initialize peer.
135 *
136 *@param bgpController controller instance
137 *@param sessionInfo bgp session info
138 *@param pktStats packet statistics
139 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530140 public BgpPeerImpl(BgpController bgpController, BgpSessionInfo sessionInfo, BgpPacketStatsImpl pktStats) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530141 this.bgpController = bgpController;
142 this.sessionInfo = sessionInfo;
143 this.pktStats = pktStats;
Jonathan Hart51539b82015-10-29 09:53:04 -0700144 this.bgplocalRib = bgpController.bgpLocalRib();
145 this.bgplocalRibVpn = bgpController.bgpLocalRibVpn();
Priyanka Bc08e56d2015-11-27 15:28:33 +0530146 this.adjRib = new AdjRibIn();
147 this.vpnAdjRib = new VpnAdjRibIn();
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530148 this.flowSpecRibOut = new BgpFlowSpecRib();
149 this.flowSpecRibIn = new BgpFlowSpecRib();
Priyanka Bc08e56d2015-11-27 15:28:33 +0530150 }
151
Shashikanth VHafb2e002016-02-12 14:48:29 +0530152 /**
153 * Check if peer support capability.
154 *
155 * @param type capability type
156 * @param afi address family identifier
157 * @param sAfi subsequent address family identifier
158 * @return true if capability is supported, otherwise false
159 */
160 public final boolean isCapabilitySupported(short type, short afi, byte sAfi) {
161
162 List<BgpValueType> capability = sessionInfo.remoteBgpCapability();
163 ListIterator<BgpValueType> listIterator = capability.listIterator();
164
165 while (listIterator.hasNext()) {
166 BgpValueType tlv = listIterator.next();
167
168 if (tlv.getType() == type) {
169 if (tlv.getType() == MultiProtocolExtnCapabilityTlv.TYPE) {
170 MultiProtocolExtnCapabilityTlv temp = (MultiProtocolExtnCapabilityTlv) tlv;
171 if ((temp.getAfi() == afi) && (temp.getSafi() == sAfi)) {
172 return true;
173 }
174 }
175 }
176 }
177 return false;
178 }
179
180 /**
181 * Send flow specification update message to peer.
182 *
183 * @param operType operation type
184 * @param flowSpec flow specification details
185 */
186 public final void sendFlowSpecUpdateMessageToPeer(FlowSpecOperation operType, BgpFlowSpecDetails flowSpec) {
187
188 List<BgpValueType> attributesList = new LinkedList<>();
189 byte sessionType = sessionInfo.isIbgpSession() ? (byte) 0 : (byte) 1;
190 byte sAfi = Constants.SAFI_FLOWSPEC_VALUE;
191
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);
199 if ((!isFsCapabilitySet) && (!isVpnFsCapabilitySet)) {
200 log.debug("Peer do not support BGP flow spec capability", channel.getRemoteAddress());
201 return;
202 }
203
204 if (isVpnFsCapabilitySet) {
205 sAfi = Constants.VPN_SAFI_FLOWSPEC_VALUE;
206 }
207
208 attributesList.add(new Origin(sessionType));
209
210 if (sessionType != 0) {
211 // EBGP
212 if (!bgpController.getConfig().getLargeASCapability()) {
213 List<Short> aspathSet = new ArrayList<>();
214 List<Short> aspathSeq = new ArrayList<>();
215 aspathSeq.add((short) bgpController.getConfig().getAsNumber());
216
217 AsPath asPath = new AsPath(aspathSet, aspathSeq);
218 attributesList.add(asPath);
219 } else {
220 List<Integer> aspathSet = new ArrayList<>();
221 List<Integer> aspathSeq = new ArrayList<>();
222 aspathSeq.add(bgpController.getConfig().getAsNumber());
223
224 As4Path as4Path = new As4Path(aspathSet, aspathSeq);
225 attributesList.add(as4Path);
226 }
227 attributesList.add(new Med(0));
228 } else {
229 attributesList.add(new AsPath());
230 attributesList.add(new Med(0));
231 attributesList.add(new LocalPref(100));
232 }
233
Shashikanth VH58260662016-02-13 01:12:02 +0530234 attributesList.add(new BgpExtendedCommunity(flowSpec.fsActionTlv()));
Shashikanth VHafb2e002016-02-12 14:48:29 +0530235
236 if (operType == FlowSpecOperation.ADD) {
237 attributesList.add(new MpReachNlri(flowSpec, Constants.AFI_FLOWSPEC_VALUE, sAfi));
238 } else if (operType == FlowSpecOperation.DELETE) {
239 attributesList.add(new MpUnReachNlri(flowSpec, Constants.AFI_FLOWSPEC_VALUE, sAfi));
240 }
241
242 BgpMessage msg = Controller.getBgpMessageFactory4().updateMessageBuilder()
243 .setBgpPathAttributes(attributesList).build();
244
245 log.debug("Sending Flow spec Update message to {}", channel.getRemoteAddress());
246 channel.write(Collections.singletonList(msg));
247 }
248
249 @Override
250 public void updateFlowSpec(FlowSpecOperation operType, BgpFlowSpecPrefix prefix, BgpFlowSpecDetails flowSpec) {
251 Preconditions.checkNotNull(operType, "flow specification operation type cannot be null");
252 Preconditions.checkNotNull(prefix, "flow specification prefix cannot be null");
253 Preconditions.checkNotNull(flowSpec, "flow specification details cannot be null");
254 Preconditions.checkNotNull(flowSpec.fsActionTlv(), "flow specification action cannot be null");
255
256 if (operType == FlowSpecOperation.ADD) {
257 if (flowSpec.routeDistinguisher() == null) {
Shashikanth VHe30cfc42016-02-18 23:31:02 +0530258 if (flowSpecRibOut.flowSpecTree().containsKey(prefix)) {
259 sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE,
260 flowSpecRibOut.flowSpecTree().get(prefix));
261 }
Shashikanth VHafb2e002016-02-12 14:48:29 +0530262 flowSpecRibOut.add(prefix, flowSpec);
263 } else {
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530264 if (flowSpecRibOut.vpnFlowSpecTree().containsKey(flowSpec.routeDistinguisher())) {
Shashikanth VHe30cfc42016-02-18 23:31:02 +0530265 Map<BgpFlowSpecPrefix, BgpFlowSpecDetails> fsTree;
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530266 fsTree = flowSpecRibOut.vpnFlowSpecTree().get(flowSpec.routeDistinguisher());
Shashikanth VHe30cfc42016-02-18 23:31:02 +0530267 if (fsTree.containsKey(prefix)) {
268 sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE,
269 fsTree.get(prefix));
270 }
271 }
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530272 flowSpecRibOut.add(flowSpec.routeDistinguisher(), prefix, flowSpec);
Shashikanth VHafb2e002016-02-12 14:48:29 +0530273 }
274 } else if (operType == FlowSpecOperation.DELETE) {
275 if (flowSpec.routeDistinguisher() == null) {
276 flowSpecRibOut.delete(prefix);
277 } else {
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530278 flowSpecRibOut.delete(flowSpec.routeDistinguisher(), prefix);
Shashikanth VHafb2e002016-02-12 14:48:29 +0530279 }
280 }
281 sendFlowSpecUpdateMessageToPeer(operType, flowSpec);
282 }
Priyanka Bc08e56d2015-11-27 15:28:33 +0530283
284 @Override
285 public void buildAdjRibIn(List<BgpValueType> pathAttr) throws BgpParseException {
286 ListIterator<BgpValueType> iterator = pathAttr.listIterator();
287 while (iterator.hasNext()) {
288 BgpValueType attr = iterator.next();
289 if (attr instanceof MpReachNlri) {
290 List<BgpLSNlri> nlri = ((MpReachNlri) attr).mpReachNlri();
291 callAdd(this, nlri, pathAttr);
292 }
293 if (attr instanceof MpUnReachNlri) {
294 List<BgpLSNlri> nlri = ((MpUnReachNlri) attr).mpUnReachNlri();
295 callRemove(this, nlri);
296 }
297 }
298 }
299
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530300 @Override
301 public void buildFlowSpecRib(List<BgpValueType> pathAttr) throws BgpParseException {
302 ListIterator<BgpValueType> iterator = pathAttr.listIterator();
303 BgpFlowSpecDetails bgpFlowSpecDetails = new BgpFlowSpecDetails();
304 FlowSpecOperation operType = FlowSpecOperation.UPDATE;
305
306 while (iterator.hasNext()) {
307 BgpValueType attr = iterator.next();
308 if (attr instanceof MpReachNlri) {
309 MpReachNlri mpReach = (MpReachNlri) attr;
310 bgpFlowSpecDetails.setFlowSpecComponents(mpReach.bgpFlowSpecInfo().flowSpecComponents());
311 bgpFlowSpecDetails.setRouteDistinguiher(mpReach.bgpFlowSpecInfo().routeDistinguisher());
312 operType = FlowSpecOperation.ADD;
313 }
314
315 if (attr instanceof BgpExtendedCommunity) {
316 BgpExtendedCommunity extCommunity = (BgpExtendedCommunity) attr;
317 bgpFlowSpecDetails.setFsActionTlv(extCommunity.fsActionTlv());
318 }
319
320 if (attr instanceof MpUnReachNlri) {
321 MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
322 bgpFlowSpecDetails.setFlowSpecComponents(mpUnReach.bgpFlowSpecInfo().flowSpecComponents());
323 bgpFlowSpecDetails.setRouteDistinguiher(mpUnReach.bgpFlowSpecInfo().routeDistinguisher());
324 operType = FlowSpecOperation.DELETE;
325 }
326 }
327
328 iterator = bgpFlowSpecDetails.flowSpecComponents().listIterator();
329 IpPrefix destIpPrefix = null;
330 IpPrefix srcIpPrefix = null;
331 while (iterator.hasNext()) {
332 BgpValueType fsAttr = iterator.next();
333 if (fsAttr instanceof BgpFsDestinationPrefix) {
334 BgpFsDestinationPrefix destinationPrefix = (BgpFsDestinationPrefix) fsAttr;
335 destIpPrefix = destinationPrefix.ipPrefix();
336 }
337
338 if (fsAttr instanceof BgpFsSourcePrefix) {
339 BgpFsSourcePrefix sourcePrefix = (BgpFsSourcePrefix) fsAttr;
340 srcIpPrefix = sourcePrefix.ipPrefix();
341 }
342 }
343 BgpFlowSpecPrefix prefix = new BgpFlowSpecPrefix(destIpPrefix, srcIpPrefix);
344 if (operType == FlowSpecOperation.ADD) {
345 if (bgpFlowSpecDetails.routeDistinguisher() == null) {
346 flowSpecRibIn.add(prefix, bgpFlowSpecDetails);
347 } else {
348 flowSpecRibIn.add(bgpFlowSpecDetails.routeDistinguisher(), prefix, bgpFlowSpecDetails);
349 }
350 } else if (operType == FlowSpecOperation.DELETE) {
351 if (bgpFlowSpecDetails.routeDistinguisher() == null) {
352 flowSpecRibIn.delete(prefix);
353 } else {
354 flowSpecRibIn.delete(bgpFlowSpecDetails.routeDistinguisher(), prefix);
355 }
356 }
357 }
358
Priyanka Bc08e56d2015-11-27 15:28:33 +0530359 /**
360 * Updates NLRI identifier node in a tree separately based on afi and safi.
361 *
362 * @param peerImpl BGP peer instance
363 * @param nlri MpReachNlri path attribute
364 * @param pathAttr list of BGP path attributes
365 * @throws BgpParseException throws exception
366 */
367 public void callAdd(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri, List<BgpValueType> pathAttr)
368 throws BgpParseException {
369 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
370 while (listIterator.hasNext()) {
371 BgpLSNlri nlriInfo = listIterator.next();
372 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
373 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
374 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
375 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700376 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530377 } else {
378 vpnAdjRib.addVpn(nlriInfo, details, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700379 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530380 ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530381 }
382 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
383 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
384 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
385 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700386 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530387 } else {
388 vpnAdjRib.addVpn(nlriInfo, details, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700389 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530390 ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530391 }
392 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
393 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
394 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
395 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700396 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530397 } else {
398 vpnAdjRib.addVpn(nlriInfo, details, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700399 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530400 ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530401 }
402 }
403 }
404 }
405
406 /**
407 * Sets BGP path attribute and NLRI details.
408 *
409 * @param nlriInfo MpReachNlri path attribute
410 * @param pathAttr list of BGP path attributes
411 * @return details object of PathAttrNlriDetails
412 * @throws BgpParseException throw exception
413 */
414 public PathAttrNlriDetails setPathAttrDetails(BgpLSNlri nlriInfo, List<BgpValueType> pathAttr)
415 throws BgpParseException {
416 PathAttrNlriDetails details = new PathAttrNlriDetails();
417 details.setProtocolID(nlriInfo.getProtocolId());
418 details.setIdentifier(nlriInfo.getIdentifier());
419 details.setPathAttribute(pathAttr);
420 return details;
421 }
422
423 /**
424 * Removes NLRI identifier node in a tree separately based on afi and safi.
425 *
426 * @param peerImpl BGP peer instance
427 * @param nlri NLRI information
Priyanka Bfc51c952016-03-26 14:30:33 +0530428 * @throws BgpParseException BGP parse exception
Priyanka Bc08e56d2015-11-27 15:28:33 +0530429 */
Priyanka Bfc51c952016-03-26 14:30:33 +0530430 public void callRemove(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri) throws BgpParseException {
Priyanka Bc08e56d2015-11-27 15:28:33 +0530431 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
432 while (listIterator.hasNext()) {
433 BgpLSNlri nlriInfo = listIterator.next();
434 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
435 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
436 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700437 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530438 } else {
439 vpnAdjRib.removeVpn(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700440 bgplocalRibVpn.delete(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530441 }
442 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
443 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
444 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700445 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530446 } else {
447 vpnAdjRib.removeVpn(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700448 bgplocalRibVpn.delete(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530449 }
450 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
451 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
452 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700453 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530454 } else {
455 vpnAdjRib.removeVpn(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700456 bgplocalRibVpn.delete(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530457 }
458 }
459 }
460 }
461
462 /**
463 * Return the adjacency RIB-IN.
464 *
465 * @return adjRib the adjacency RIB-IN
466 */
467 public AdjRibIn adjRib() {
468 return adjRib;
469 }
470
471 /**
472 * Return the adjacency RIB-IN with VPN.
473 *
474 * @return vpnAdjRib the adjacency RIB-IN with VPN
475 */
476 public VpnAdjRibIn vpnAdjRib() {
477 return vpnAdjRib;
Shashikanth VH6de20d32015-10-09 12:04:13 +0530478 }
479
Shashikanth VH3fe37982015-11-30 11:50:07 +0530480 /**
481 * Update localRIB on peer disconnect.
482 *
Priyanka Bfc51c952016-03-26 14:30:33 +0530483 * @throws BgpParseException while updating local RIB
Shashikanth VH3fe37982015-11-30 11:50:07 +0530484 */
Priyanka Bfc51c952016-03-26 14:30:33 +0530485 public void updateLocalRibOnPeerDisconnect() throws BgpParseException {
Jonathan Hart51539b82015-10-29 09:53:04 -0700486 BgpLocalRibImpl localRib = (BgpLocalRibImpl) bgplocalRib;
487 BgpLocalRibImpl localRibVpn = (BgpLocalRibImpl) bgplocalRibVpn;
Shashikanth VH3fe37982015-11-30 11:50:07 +0530488
Jonathan Hart51539b82015-10-29 09:53:04 -0700489 localRib.localRibUpdate(adjacencyRib());
490 localRibVpn.localRibUpdate(vpnAdjacencyRib());
Shashikanth VH3fe37982015-11-30 11:50:07 +0530491 }
492
Shashikanth VHafb2e002016-02-12 14:48:29 +0530493 /**
494 * Update peer flow specification RIB on peer disconnect.
Shashikanth VHafb2e002016-02-12 14:48:29 +0530495 */
496 public void updateFlowSpecOnPeerDisconnect() {
497
498 boolean isCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
499 Constants.AFI_FLOWSPEC_VALUE,
500 Constants.SAFI_FLOWSPEC_VALUE);
501 if (isCapabilitySet) {
502 Set<BgpFlowSpecPrefix> flowSpecKeys = flowSpecRibOut.flowSpecTree().keySet();
503 for (BgpFlowSpecPrefix key : flowSpecKeys) {
504 BgpFlowSpecDetails flowSpecDetails = flowSpecRibOut.flowSpecTree().get(key);
505 sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE, flowSpecDetails);
506 }
507 }
508
509 boolean isVpnCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
510 Constants.AFI_FLOWSPEC_VALUE,
511 Constants.VPN_SAFI_FLOWSPEC_VALUE);
512 if (isVpnCapabilitySet) {
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530513 Set<RouteDistinguisher> flowSpecKeys = flowSpecRibOut.vpnFlowSpecTree().keySet();
Shashikanth VHafb2e002016-02-12 14:48:29 +0530514 for (RouteDistinguisher key : flowSpecKeys) {
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530515 Map<BgpFlowSpecPrefix, BgpFlowSpecDetails> fsTree = flowSpecRibOut.vpnFlowSpecTree().get(key);
Shashikanth VHafb2e002016-02-12 14:48:29 +0530516
517 Set<BgpFlowSpecPrefix> fsKeys = fsTree.keySet();
518 for (BgpFlowSpecPrefix fsKey : fsKeys) {
Shashikanth VHe3a73bc2016-02-22 20:11:31 +0530519 BgpFlowSpecDetails flowSpecDetails = flowSpecRibOut.flowSpecTree().get(fsKey);
Shashikanth VHafb2e002016-02-12 14:48:29 +0530520 sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE, flowSpecDetails);
521 }
522 }
523 }
524 }
525
Shashikanth VH6de20d32015-10-09 12:04:13 +0530526 // ************************
527 // Channel related
528 // ************************
529
530 @Override
531 public final void disconnectPeer() {
Shashikanth VHafb2e002016-02-12 14:48:29 +0530532 this.updateFlowSpecOnPeerDisconnect();
Shashikanth VH6de20d32015-10-09 12:04:13 +0530533 this.channel.close();
534 }
535
536 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530537 public final void sendMessage(BgpMessage m) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530538 log.debug("Sending message to {}", channel.getRemoteAddress());
539 try {
540 channel.write(Collections.singletonList(m));
541 this.pktStats.addOutPacket();
542 } catch (RejectedExecutionException e) {
543 log.warn(e.getMessage());
544 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
545 throw e;
546 }
547 }
548 }
549
550 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530551 public final void sendMessage(List<BgpMessage> msgs) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530552 try {
553 channel.write(msgs);
554 this.pktStats.addOutPacket(msgs.size());
555 } catch (RejectedExecutionException e) {
556 log.warn(e.getMessage());
557 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
558 throw e;
559 }
560 }
561 }
562
563 @Override
564 public final boolean isConnected() {
565 return this.connected;
566 }
567
568 @Override
569 public final void setConnected(boolean connected) {
570 this.connected = connected;
571 };
572
573 @Override
574 public final void setChannel(Channel channel) {
575 this.channel = channel;
576 final SocketAddress address = channel.getRemoteAddress();
577 if (address instanceof InetSocketAddress) {
578 final InetSocketAddress inetAddress = (InetSocketAddress) address;
579 final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
580 if (ipAddress.isIp4()) {
581 channelId = ipAddress.toString() + ':' + inetAddress.getPort();
582 } else {
583 channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort();
584 }
585 }
586 };
587
588 @Override
589 public final Channel getChannel() {
590 return this.channel;
591 };
592
593 @Override
594 public String channelId() {
595 return channelId;
596 }
597
Shashikanth VH6de20d32015-10-09 12:04:13 +0530598 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530599 public BgpFactory factory() {
600 return BgpFactories.getFactory(sessionInfo.remoteBgpVersion());
Shashikanth VH6de20d32015-10-09 12:04:13 +0530601 }
602
603 @Override
604 public boolean isHandshakeComplete() {
605 return isHandShakeComplete;
606 }
607
608 @Override
609 public String toString() {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530610 return MoreObjects.toStringHelper(getClass()).omitNullValues()
611 .add("channel", channelId())
Priyanka Bc08e56d2015-11-27 15:28:33 +0530612 .add("BgpId", sessionInfo().remoteBgpId()).toString();
Shashikanth VH6de20d32015-10-09 12:04:13 +0530613 }
614}