blob: b7480b088e838df623e7835dae90b915c91b33cc [file] [log] [blame]
Shashikanth VH6de20d32015-10-09 12:04:13 +05301/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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 VH5dd8dbe2015-11-26 13:22:18 +053029import org.onosproject.bgp.controller.BgpController;
Jonathan Hart51539b82015-10-29 09:53:04 -070030import org.onosproject.bgp.controller.BgpLocalRib;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053031import org.onosproject.bgp.controller.BgpPeer;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053032import org.onosproject.bgp.controller.BgpSessionInfo;
Priyanka Bc08e56d2015-11-27 15:28:33 +053033import org.onosproject.bgpio.exceptions.BgpParseException;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053034import org.onosproject.bgpio.protocol.BgpFactories;
35import org.onosproject.bgpio.protocol.BgpFactory;
Priyanka Bc08e56d2015-11-27 15:28:33 +053036import org.onosproject.bgpio.protocol.BgpLSNlri;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053037import org.onosproject.bgpio.protocol.BgpMessage;
Shashikanth VHafb2e002016-02-12 14:48:29 +053038import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecDetails;
39import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecPrefix;
Jonathan Hart51539b82015-10-29 09:53:04 -070040import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
Priyanka Bc08e56d2015-11-27 15:28:33 +053041import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
42import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
Priyanka Bc08e56d2015-11-27 15:28:33 +053043import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
Shashikanth VHafb2e002016-02-12 14:48:29 +053044import org.onosproject.bgpio.types.AsPath;
45import org.onosproject.bgpio.types.As4Path;
Shashikanth VH58260662016-02-13 01:12:02 +053046import org.onosproject.bgpio.types.BgpExtendedCommunity;
Priyanka Bc08e56d2015-11-27 15:28:33 +053047import org.onosproject.bgpio.types.BgpValueType;
Shashikanth VHafb2e002016-02-12 14:48:29 +053048import org.onosproject.bgpio.types.LocalPref;
49import org.onosproject.bgpio.types.Med;
Priyanka Bc08e56d2015-11-27 15:28:33 +053050import org.onosproject.bgpio.types.MpReachNlri;
51import org.onosproject.bgpio.types.MpUnReachNlri;
Shashikanth VHafb2e002016-02-12 14:48:29 +053052import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
53import org.onosproject.bgpio.types.Origin;
54import org.onosproject.bgpio.types.RouteDistinguisher;
55import org.onosproject.bgpio.util.Constants;
Shashikanth VH6de20d32015-10-09 12:04:13 +053056import org.slf4j.Logger;
57import org.slf4j.LoggerFactory;
58
Jonathan Hart51539b82015-10-29 09:53:04 -070059import java.net.InetSocketAddress;
60import java.net.SocketAddress;
61import java.util.Collections;
62import 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 VHafb2e002016-02-12 14:48:29 +053086 private BgpFlowSpecRibOut flowSpecRibOut;
87 private BgpFlowSpecRibOut vpnFlowSpecRibOut;
88
89 /**
90 * Returns the flowSpec RIB out.
91 *
92 * @return flow Specification RIB out
93 */
94 public BgpFlowSpecRibOut flowSpecRibOut() {
95 return flowSpecRibOut;
96 }
97
98 /**
99 * Returns the VPN flowSpec RIB out.
100 *
101 * @return VPN flow Specification RIB out
102 */
103 public BgpFlowSpecRibOut vpnFlowSpecRibOut() {
104 return vpnFlowSpecRibOut;
105 }
Shashikanth VH6de20d32015-10-09 12:04:13 +0530106
Shashikanth VH3fe37982015-11-30 11:50:07 +0530107 /**
108 * Return the adjacency RIB-IN.
109 *
110 * @return adjRib the adjacency RIB-IN
111 */
112 public AdjRibIn adjacencyRib() {
113 return adjRib;
114 }
115
116 /**
117 * Return the adjacency RIB-IN with VPN.
118 *
119 * @return vpnAdjRib the adjacency RIB-IN with VPN
120 */
121 public VpnAdjRibIn vpnAdjacencyRib() {
122 return vpnAdjRib;
123 }
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530124
Shashikanth VH6de20d32015-10-09 12:04:13 +0530125 @Override
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530126 public BgpSessionInfo sessionInfo() {
127 return sessionInfo;
128 }
129
130 /**
131 * Initialize peer.
132 *
133 *@param bgpController controller instance
134 *@param sessionInfo bgp session info
135 *@param pktStats packet statistics
136 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530137 public BgpPeerImpl(BgpController bgpController, BgpSessionInfo sessionInfo, BgpPacketStatsImpl pktStats) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530138 this.bgpController = bgpController;
139 this.sessionInfo = sessionInfo;
140 this.pktStats = pktStats;
Jonathan Hart51539b82015-10-29 09:53:04 -0700141 this.bgplocalRib = bgpController.bgpLocalRib();
142 this.bgplocalRibVpn = bgpController.bgpLocalRibVpn();
Priyanka Bc08e56d2015-11-27 15:28:33 +0530143 this.adjRib = new AdjRibIn();
144 this.vpnAdjRib = new VpnAdjRibIn();
Shashikanth VHafb2e002016-02-12 14:48:29 +0530145 this.flowSpecRibOut = new BgpFlowSpecRibOut();
146 this.vpnFlowSpecRibOut = new BgpFlowSpecRibOut();
Priyanka Bc08e56d2015-11-27 15:28:33 +0530147 }
148
Shashikanth VHafb2e002016-02-12 14:48:29 +0530149 /**
150 * Check if peer support capability.
151 *
152 * @param type capability type
153 * @param afi address family identifier
154 * @param sAfi subsequent address family identifier
155 * @return true if capability is supported, otherwise false
156 */
157 public final boolean isCapabilitySupported(short type, short afi, byte sAfi) {
158
159 List<BgpValueType> capability = sessionInfo.remoteBgpCapability();
160 ListIterator<BgpValueType> listIterator = capability.listIterator();
161
162 while (listIterator.hasNext()) {
163 BgpValueType tlv = listIterator.next();
164
165 if (tlv.getType() == type) {
166 if (tlv.getType() == MultiProtocolExtnCapabilityTlv.TYPE) {
167 MultiProtocolExtnCapabilityTlv temp = (MultiProtocolExtnCapabilityTlv) tlv;
168 if ((temp.getAfi() == afi) && (temp.getSafi() == sAfi)) {
169 return true;
170 }
171 }
172 }
173 }
174 return false;
175 }
176
177 /**
178 * Send flow specification update message to peer.
179 *
180 * @param operType operation type
181 * @param flowSpec flow specification details
182 */
183 public final void sendFlowSpecUpdateMessageToPeer(FlowSpecOperation operType, BgpFlowSpecDetails flowSpec) {
184
185 List<BgpValueType> attributesList = new LinkedList<>();
186 byte sessionType = sessionInfo.isIbgpSession() ? (byte) 0 : (byte) 1;
187 byte sAfi = Constants.SAFI_FLOWSPEC_VALUE;
188
189 boolean isFsCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
190 Constants.AFI_FLOWSPEC_VALUE,
191 Constants.SAFI_FLOWSPEC_VALUE);
192
193 boolean isVpnFsCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
194 Constants.AFI_FLOWSPEC_VALUE,
195 Constants.VPN_SAFI_FLOWSPEC_VALUE);
196 if ((!isFsCapabilitySet) && (!isVpnFsCapabilitySet)) {
197 log.debug("Peer do not support BGP flow spec capability", channel.getRemoteAddress());
198 return;
199 }
200
201 if (isVpnFsCapabilitySet) {
202 sAfi = Constants.VPN_SAFI_FLOWSPEC_VALUE;
203 }
204
205 attributesList.add(new Origin(sessionType));
206
207 if (sessionType != 0) {
208 // EBGP
209 if (!bgpController.getConfig().getLargeASCapability()) {
210 List<Short> aspathSet = new ArrayList<>();
211 List<Short> aspathSeq = new ArrayList<>();
212 aspathSeq.add((short) bgpController.getConfig().getAsNumber());
213
214 AsPath asPath = new AsPath(aspathSet, aspathSeq);
215 attributesList.add(asPath);
216 } else {
217 List<Integer> aspathSet = new ArrayList<>();
218 List<Integer> aspathSeq = new ArrayList<>();
219 aspathSeq.add(bgpController.getConfig().getAsNumber());
220
221 As4Path as4Path = new As4Path(aspathSet, aspathSeq);
222 attributesList.add(as4Path);
223 }
224 attributesList.add(new Med(0));
225 } else {
226 attributesList.add(new AsPath());
227 attributesList.add(new Med(0));
228 attributesList.add(new LocalPref(100));
229 }
230
Shashikanth VH58260662016-02-13 01:12:02 +0530231 attributesList.add(new BgpExtendedCommunity(flowSpec.fsActionTlv()));
Shashikanth VHafb2e002016-02-12 14:48:29 +0530232
233 if (operType == FlowSpecOperation.ADD) {
234 attributesList.add(new MpReachNlri(flowSpec, Constants.AFI_FLOWSPEC_VALUE, sAfi));
235 } else if (operType == FlowSpecOperation.DELETE) {
236 attributesList.add(new MpUnReachNlri(flowSpec, Constants.AFI_FLOWSPEC_VALUE, sAfi));
237 }
238
239 BgpMessage msg = Controller.getBgpMessageFactory4().updateMessageBuilder()
240 .setBgpPathAttributes(attributesList).build();
241
242 log.debug("Sending Flow spec Update message to {}", channel.getRemoteAddress());
243 channel.write(Collections.singletonList(msg));
244 }
245
246 @Override
247 public void updateFlowSpec(FlowSpecOperation operType, BgpFlowSpecPrefix prefix, BgpFlowSpecDetails flowSpec) {
248 Preconditions.checkNotNull(operType, "flow specification operation type cannot be null");
249 Preconditions.checkNotNull(prefix, "flow specification prefix cannot be null");
250 Preconditions.checkNotNull(flowSpec, "flow specification details cannot be null");
251 Preconditions.checkNotNull(flowSpec.fsActionTlv(), "flow specification action cannot be null");
252
253 if (operType == FlowSpecOperation.ADD) {
254 if (flowSpec.routeDistinguisher() == null) {
Shashikanth VHe30cfc42016-02-18 23:31:02 +0530255 if (flowSpecRibOut.flowSpecTree().containsKey(prefix)) {
256 sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE,
257 flowSpecRibOut.flowSpecTree().get(prefix));
258 }
Shashikanth VHafb2e002016-02-12 14:48:29 +0530259 flowSpecRibOut.add(prefix, flowSpec);
260 } else {
Shashikanth VHe30cfc42016-02-18 23:31:02 +0530261 if (vpnFlowSpecRibOut.vpnFlowSpecTree().containsKey(flowSpec.routeDistinguisher())) {
262 Map<BgpFlowSpecPrefix, BgpFlowSpecDetails> fsTree;
263 fsTree = vpnFlowSpecRibOut.vpnFlowSpecTree().get(flowSpec.routeDistinguisher());
264 if (fsTree.containsKey(prefix)) {
265 sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE,
266 fsTree.get(prefix));
267 }
268 }
Shashikanth VHafb2e002016-02-12 14:48:29 +0530269 vpnFlowSpecRibOut.add(flowSpec.routeDistinguisher(), prefix, flowSpec);
270 }
271 } else if (operType == FlowSpecOperation.DELETE) {
272 if (flowSpec.routeDistinguisher() == null) {
273 flowSpecRibOut.delete(prefix);
274 } else {
275 vpnFlowSpecRibOut.delete(flowSpec.routeDistinguisher(), prefix);
276 }
277 }
278 sendFlowSpecUpdateMessageToPeer(operType, flowSpec);
279 }
Priyanka Bc08e56d2015-11-27 15:28:33 +0530280
281 @Override
282 public void buildAdjRibIn(List<BgpValueType> pathAttr) throws BgpParseException {
283 ListIterator<BgpValueType> iterator = pathAttr.listIterator();
284 while (iterator.hasNext()) {
285 BgpValueType attr = iterator.next();
286 if (attr instanceof MpReachNlri) {
287 List<BgpLSNlri> nlri = ((MpReachNlri) attr).mpReachNlri();
288 callAdd(this, nlri, pathAttr);
289 }
290 if (attr instanceof MpUnReachNlri) {
291 List<BgpLSNlri> nlri = ((MpUnReachNlri) attr).mpUnReachNlri();
292 callRemove(this, nlri);
293 }
294 }
295 }
296
297 /**
298 * Updates NLRI identifier node in a tree separately based on afi and safi.
299 *
300 * @param peerImpl BGP peer instance
301 * @param nlri MpReachNlri path attribute
302 * @param pathAttr list of BGP path attributes
303 * @throws BgpParseException throws exception
304 */
305 public void callAdd(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri, List<BgpValueType> pathAttr)
306 throws BgpParseException {
307 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
308 while (listIterator.hasNext()) {
309 BgpLSNlri nlriInfo = listIterator.next();
310 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
311 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
312 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
313 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700314 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530315 } else {
316 vpnAdjRib.addVpn(nlriInfo, details, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700317 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530318 ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530319 }
320 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
321 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
322 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
323 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700324 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530325 } else {
326 vpnAdjRib.addVpn(nlriInfo, details, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700327 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530328 ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530329 }
330 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
331 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
332 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
333 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700334 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530335 } else {
336 vpnAdjRib.addVpn(nlriInfo, details, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700337 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530338 ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530339 }
340 }
341 }
342 }
343
344 /**
345 * Sets BGP path attribute and NLRI details.
346 *
347 * @param nlriInfo MpReachNlri path attribute
348 * @param pathAttr list of BGP path attributes
349 * @return details object of PathAttrNlriDetails
350 * @throws BgpParseException throw exception
351 */
352 public PathAttrNlriDetails setPathAttrDetails(BgpLSNlri nlriInfo, List<BgpValueType> pathAttr)
353 throws BgpParseException {
354 PathAttrNlriDetails details = new PathAttrNlriDetails();
355 details.setProtocolID(nlriInfo.getProtocolId());
356 details.setIdentifier(nlriInfo.getIdentifier());
357 details.setPathAttribute(pathAttr);
358 return details;
359 }
360
361 /**
362 * Removes NLRI identifier node in a tree separately based on afi and safi.
363 *
364 * @param peerImpl BGP peer instance
365 * @param nlri NLRI information
366 */
367 public void callRemove(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri) {
368 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
369 while (listIterator.hasNext()) {
370 BgpLSNlri nlriInfo = listIterator.next();
371 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
372 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
373 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700374 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530375 } else {
376 vpnAdjRib.removeVpn(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700377 bgplocalRibVpn.delete(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530378 }
379 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
380 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
381 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700382 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530383 } else {
384 vpnAdjRib.removeVpn(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700385 bgplocalRibVpn.delete(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530386 }
387 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
388 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
389 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700390 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530391 } else {
392 vpnAdjRib.removeVpn(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700393 bgplocalRibVpn.delete(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530394 }
395 }
396 }
397 }
398
399 /**
400 * Return the adjacency RIB-IN.
401 *
402 * @return adjRib the adjacency RIB-IN
403 */
404 public AdjRibIn adjRib() {
405 return adjRib;
406 }
407
408 /**
409 * Return the adjacency RIB-IN with VPN.
410 *
411 * @return vpnAdjRib the adjacency RIB-IN with VPN
412 */
413 public VpnAdjRibIn vpnAdjRib() {
414 return vpnAdjRib;
Shashikanth VH6de20d32015-10-09 12:04:13 +0530415 }
416
Shashikanth VH3fe37982015-11-30 11:50:07 +0530417 /**
418 * Update localRIB on peer disconnect.
419 *
420 */
Jonathan Hart51539b82015-10-29 09:53:04 -0700421 public void updateLocalRibOnPeerDisconnect() {
422 BgpLocalRibImpl localRib = (BgpLocalRibImpl) bgplocalRib;
423 BgpLocalRibImpl localRibVpn = (BgpLocalRibImpl) bgplocalRibVpn;
Shashikanth VH3fe37982015-11-30 11:50:07 +0530424
Jonathan Hart51539b82015-10-29 09:53:04 -0700425 localRib.localRibUpdate(adjacencyRib());
426 localRibVpn.localRibUpdate(vpnAdjacencyRib());
Shashikanth VH3fe37982015-11-30 11:50:07 +0530427 }
428
Shashikanth VHafb2e002016-02-12 14:48:29 +0530429 /**
430 * Update peer flow specification RIB on peer disconnect.
431 *
432 */
433 public void updateFlowSpecOnPeerDisconnect() {
434
435 boolean isCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
436 Constants.AFI_FLOWSPEC_VALUE,
437 Constants.SAFI_FLOWSPEC_VALUE);
438 if (isCapabilitySet) {
439 Set<BgpFlowSpecPrefix> flowSpecKeys = flowSpecRibOut.flowSpecTree().keySet();
440 for (BgpFlowSpecPrefix key : flowSpecKeys) {
441 BgpFlowSpecDetails flowSpecDetails = flowSpecRibOut.flowSpecTree().get(key);
442 sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE, flowSpecDetails);
443 }
444 }
445
446 boolean isVpnCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
447 Constants.AFI_FLOWSPEC_VALUE,
448 Constants.VPN_SAFI_FLOWSPEC_VALUE);
449 if (isVpnCapabilitySet) {
450 Set<RouteDistinguisher> flowSpecKeys = vpnFlowSpecRibOut.vpnFlowSpecTree().keySet();
451 for (RouteDistinguisher key : flowSpecKeys) {
452 Map<BgpFlowSpecPrefix, BgpFlowSpecDetails> fsTree = vpnFlowSpecRibOut.vpnFlowSpecTree().get(key);
453
454 Set<BgpFlowSpecPrefix> fsKeys = fsTree.keySet();
455 for (BgpFlowSpecPrefix fsKey : fsKeys) {
456 BgpFlowSpecDetails flowSpecDetails = vpnFlowSpecRibOut.flowSpecTree().get(fsKey);
457 sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE, flowSpecDetails);
458 }
459 }
460 }
461 }
462
Shashikanth VH6de20d32015-10-09 12:04:13 +0530463 // ************************
464 // Channel related
465 // ************************
466
467 @Override
468 public final void disconnectPeer() {
Shashikanth VHafb2e002016-02-12 14:48:29 +0530469 this.updateFlowSpecOnPeerDisconnect();
Shashikanth VH6de20d32015-10-09 12:04:13 +0530470 this.channel.close();
471 }
472
473 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530474 public final void sendMessage(BgpMessage m) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530475 log.debug("Sending message to {}", channel.getRemoteAddress());
476 try {
477 channel.write(Collections.singletonList(m));
478 this.pktStats.addOutPacket();
479 } catch (RejectedExecutionException e) {
480 log.warn(e.getMessage());
481 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
482 throw e;
483 }
484 }
485 }
486
487 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530488 public final void sendMessage(List<BgpMessage> msgs) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530489 try {
490 channel.write(msgs);
491 this.pktStats.addOutPacket(msgs.size());
492 } catch (RejectedExecutionException e) {
493 log.warn(e.getMessage());
494 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
495 throw e;
496 }
497 }
498 }
499
500 @Override
501 public final boolean isConnected() {
502 return this.connected;
503 }
504
505 @Override
506 public final void setConnected(boolean connected) {
507 this.connected = connected;
508 };
509
510 @Override
511 public final void setChannel(Channel channel) {
512 this.channel = channel;
513 final SocketAddress address = channel.getRemoteAddress();
514 if (address instanceof InetSocketAddress) {
515 final InetSocketAddress inetAddress = (InetSocketAddress) address;
516 final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
517 if (ipAddress.isIp4()) {
518 channelId = ipAddress.toString() + ':' + inetAddress.getPort();
519 } else {
520 channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort();
521 }
522 }
523 };
524
525 @Override
526 public final Channel getChannel() {
527 return this.channel;
528 };
529
530 @Override
531 public String channelId() {
532 return channelId;
533 }
534
Shashikanth VH6de20d32015-10-09 12:04:13 +0530535 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530536 public BgpFactory factory() {
537 return BgpFactories.getFactory(sessionInfo.remoteBgpVersion());
Shashikanth VH6de20d32015-10-09 12:04:13 +0530538 }
539
540 @Override
541 public boolean isHandshakeComplete() {
542 return isHandShakeComplete;
543 }
544
545 @Override
546 public String toString() {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530547 return MoreObjects.toStringHelper(getClass()).omitNullValues()
548 .add("channel", channelId())
Priyanka Bc08e56d2015-11-27 15:28:33 +0530549 .add("BgpId", sessionInfo().remoteBgpId()).toString();
Shashikanth VH6de20d32015-10-09 12:04:13 +0530550 }
551}