blob: 8e42208d5257e53ccca05a4cdf4cb5a6f457a222 [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 VH6de20d32015-10-09 12:04:13 +053020import org.jboss.netty.channel.Channel;
21import org.onlab.packet.IpAddress;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053022import org.onosproject.bgp.controller.BgpController;
Jonathan Hart51539b82015-10-29 09:53:04 -070023import org.onosproject.bgp.controller.BgpLocalRib;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053024import org.onosproject.bgp.controller.BgpPeer;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053025import org.onosproject.bgp.controller.BgpSessionInfo;
Priyanka Bc08e56d2015-11-27 15:28:33 +053026import org.onosproject.bgpio.exceptions.BgpParseException;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053027import org.onosproject.bgpio.protocol.BgpFactories;
28import org.onosproject.bgpio.protocol.BgpFactory;
Priyanka Bc08e56d2015-11-27 15:28:33 +053029import org.onosproject.bgpio.protocol.BgpLSNlri;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053030import org.onosproject.bgpio.protocol.BgpMessage;
Jonathan Hart51539b82015-10-29 09:53:04 -070031import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
Priyanka Bc08e56d2015-11-27 15:28:33 +053032import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
33import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
Priyanka Bc08e56d2015-11-27 15:28:33 +053034import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
35import org.onosproject.bgpio.types.BgpValueType;
36import org.onosproject.bgpio.types.MpReachNlri;
37import org.onosproject.bgpio.types.MpUnReachNlri;
Shashikanth VH6de20d32015-10-09 12:04:13 +053038import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
Jonathan Hart51539b82015-10-29 09:53:04 -070041import java.net.InetSocketAddress;
42import java.net.SocketAddress;
43import java.util.Collections;
44import java.util.List;
45import java.util.ListIterator;
46import java.util.concurrent.RejectedExecutionException;
Shashikanth VH6de20d32015-10-09 12:04:13 +053047
48/**
49 * BGPPeerImpl implements BGPPeer, maintains peer information and store updates in RIB .
50 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053051public class BgpPeerImpl implements BgpPeer {
Shashikanth VH6de20d32015-10-09 12:04:13 +053052
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053053 protected final Logger log = LoggerFactory.getLogger(BgpPeerImpl.class);
Shashikanth VH6de20d32015-10-09 12:04:13 +053054
55 private static final String SHUTDOWN_MSG = "Worker has already been shutdown";
56
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053057 private BgpController bgpController;
Shashikanth VH6de20d32015-10-09 12:04:13 +053058 private Channel channel;
59 protected String channelId;
60 private boolean connected;
61 protected boolean isHandShakeComplete = false;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053062 private BgpSessionInfo sessionInfo;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053063 private BgpPacketStatsImpl pktStats;
Jonathan Hart51539b82015-10-29 09:53:04 -070064 private BgpLocalRib bgplocalRib;
65 private BgpLocalRib bgplocalRibVpn;
Priyanka Bc08e56d2015-11-27 15:28:33 +053066 private AdjRibIn adjRib;
67 private VpnAdjRibIn vpnAdjRib;
Shashikanth VH6de20d32015-10-09 12:04:13 +053068
Shashikanth VH3fe37982015-11-30 11:50:07 +053069 /**
70 * Return the adjacency RIB-IN.
71 *
72 * @return adjRib the adjacency RIB-IN
73 */
74 public AdjRibIn adjacencyRib() {
75 return adjRib;
76 }
77
78 /**
79 * Return the adjacency RIB-IN with VPN.
80 *
81 * @return vpnAdjRib the adjacency RIB-IN with VPN
82 */
83 public VpnAdjRibIn vpnAdjacencyRib() {
84 return vpnAdjRib;
85 }
Shashikanth VH9f8afb42015-11-04 18:00:30 +053086
Shashikanth VH6de20d32015-10-09 12:04:13 +053087 @Override
Shashikanth VH9f8afb42015-11-04 18:00:30 +053088 public BgpSessionInfo sessionInfo() {
89 return sessionInfo;
90 }
91
92 /**
93 * Initialize peer.
94 *
95 *@param bgpController controller instance
96 *@param sessionInfo bgp session info
97 *@param pktStats packet statistics
98 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053099 public BgpPeerImpl(BgpController bgpController, BgpSessionInfo sessionInfo, BgpPacketStatsImpl pktStats) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530100 this.bgpController = bgpController;
101 this.sessionInfo = sessionInfo;
102 this.pktStats = pktStats;
Jonathan Hart51539b82015-10-29 09:53:04 -0700103 this.bgplocalRib = bgpController.bgpLocalRib();
104 this.bgplocalRibVpn = bgpController.bgpLocalRibVpn();
Priyanka Bc08e56d2015-11-27 15:28:33 +0530105 this.adjRib = new AdjRibIn();
106 this.vpnAdjRib = new VpnAdjRibIn();
107 }
108
109
110 @Override
111 public void buildAdjRibIn(List<BgpValueType> pathAttr) throws BgpParseException {
112 ListIterator<BgpValueType> iterator = pathAttr.listIterator();
113 while (iterator.hasNext()) {
114 BgpValueType attr = iterator.next();
115 if (attr instanceof MpReachNlri) {
116 List<BgpLSNlri> nlri = ((MpReachNlri) attr).mpReachNlri();
117 callAdd(this, nlri, pathAttr);
118 }
119 if (attr instanceof MpUnReachNlri) {
120 List<BgpLSNlri> nlri = ((MpUnReachNlri) attr).mpUnReachNlri();
121 callRemove(this, nlri);
122 }
123 }
124 }
125
126 /**
127 * Updates NLRI identifier node in a tree separately based on afi and safi.
128 *
129 * @param peerImpl BGP peer instance
130 * @param nlri MpReachNlri path attribute
131 * @param pathAttr list of BGP path attributes
132 * @throws BgpParseException throws exception
133 */
134 public void callAdd(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri, List<BgpValueType> pathAttr)
135 throws BgpParseException {
136 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
137 while (listIterator.hasNext()) {
138 BgpLSNlri nlriInfo = listIterator.next();
139 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
140 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
141 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
142 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700143 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530144 } else {
145 vpnAdjRib.addVpn(nlriInfo, details, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700146 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530147 ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530148 }
149 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
150 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
151 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
152 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700153 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530154 } else {
155 vpnAdjRib.addVpn(nlriInfo, details, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700156 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530157 ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530158 }
159 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
160 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
161 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
162 adjRib.add(nlriInfo, details);
Jonathan Hart51539b82015-10-29 09:53:04 -0700163 bgplocalRib.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530164 } else {
165 vpnAdjRib.addVpn(nlriInfo, details, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700166 bgplocalRibVpn.add(sessionInfo(), nlriInfo, details,
Shashikanth VH3fe37982015-11-30 11:50:07 +0530167 ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530168 }
169 }
170 }
171 }
172
173 /**
174 * Sets BGP path attribute and NLRI details.
175 *
176 * @param nlriInfo MpReachNlri path attribute
177 * @param pathAttr list of BGP path attributes
178 * @return details object of PathAttrNlriDetails
179 * @throws BgpParseException throw exception
180 */
181 public PathAttrNlriDetails setPathAttrDetails(BgpLSNlri nlriInfo, List<BgpValueType> pathAttr)
182 throws BgpParseException {
183 PathAttrNlriDetails details = new PathAttrNlriDetails();
184 details.setProtocolID(nlriInfo.getProtocolId());
185 details.setIdentifier(nlriInfo.getIdentifier());
186 details.setPathAttribute(pathAttr);
187 return details;
188 }
189
190 /**
191 * Removes NLRI identifier node in a tree separately based on afi and safi.
192 *
193 * @param peerImpl BGP peer instance
194 * @param nlri NLRI information
195 */
196 public void callRemove(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri) {
197 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
198 while (listIterator.hasNext()) {
199 BgpLSNlri nlriInfo = listIterator.next();
200 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
201 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
202 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700203 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530204 } else {
205 vpnAdjRib.removeVpn(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700206 bgplocalRibVpn.delete(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530207 }
208 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
209 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
210 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700211 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530212 } else {
213 vpnAdjRib.removeVpn(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700214 bgplocalRibVpn.delete(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530215 }
216 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
217 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
218 adjRib.remove(nlriInfo);
Jonathan Hart51539b82015-10-29 09:53:04 -0700219 bgplocalRib.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530220 } else {
221 vpnAdjRib.removeVpn(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Jonathan Hart51539b82015-10-29 09:53:04 -0700222 bgplocalRibVpn.delete(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530223 }
224 }
225 }
226 }
227
228 /**
229 * Return the adjacency RIB-IN.
230 *
231 * @return adjRib the adjacency RIB-IN
232 */
233 public AdjRibIn adjRib() {
234 return adjRib;
235 }
236
237 /**
238 * Return the adjacency RIB-IN with VPN.
239 *
240 * @return vpnAdjRib the adjacency RIB-IN with VPN
241 */
242 public VpnAdjRibIn vpnAdjRib() {
243 return vpnAdjRib;
Shashikanth VH6de20d32015-10-09 12:04:13 +0530244 }
245
Shashikanth VH3fe37982015-11-30 11:50:07 +0530246 /**
247 * Update localRIB on peer disconnect.
248 *
249 */
Jonathan Hart51539b82015-10-29 09:53:04 -0700250 public void updateLocalRibOnPeerDisconnect() {
251 BgpLocalRibImpl localRib = (BgpLocalRibImpl) bgplocalRib;
252 BgpLocalRibImpl localRibVpn = (BgpLocalRibImpl) bgplocalRibVpn;
Shashikanth VH3fe37982015-11-30 11:50:07 +0530253
Jonathan Hart51539b82015-10-29 09:53:04 -0700254 localRib.localRibUpdate(adjacencyRib());
255 localRibVpn.localRibUpdate(vpnAdjacencyRib());
Shashikanth VH3fe37982015-11-30 11:50:07 +0530256 }
257
Shashikanth VH6de20d32015-10-09 12:04:13 +0530258 // ************************
259 // Channel related
260 // ************************
261
262 @Override
263 public final void disconnectPeer() {
264 this.channel.close();
265 }
266
267 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530268 public final void sendMessage(BgpMessage m) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530269 log.debug("Sending message to {}", channel.getRemoteAddress());
270 try {
271 channel.write(Collections.singletonList(m));
272 this.pktStats.addOutPacket();
273 } catch (RejectedExecutionException e) {
274 log.warn(e.getMessage());
275 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
276 throw e;
277 }
278 }
279 }
280
281 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530282 public final void sendMessage(List<BgpMessage> msgs) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530283 try {
284 channel.write(msgs);
285 this.pktStats.addOutPacket(msgs.size());
286 } catch (RejectedExecutionException e) {
287 log.warn(e.getMessage());
288 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
289 throw e;
290 }
291 }
292 }
293
294 @Override
295 public final boolean isConnected() {
296 return this.connected;
297 }
298
299 @Override
300 public final void setConnected(boolean connected) {
301 this.connected = connected;
302 };
303
304 @Override
305 public final void setChannel(Channel channel) {
306 this.channel = channel;
307 final SocketAddress address = channel.getRemoteAddress();
308 if (address instanceof InetSocketAddress) {
309 final InetSocketAddress inetAddress = (InetSocketAddress) address;
310 final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
311 if (ipAddress.isIp4()) {
312 channelId = ipAddress.toString() + ':' + inetAddress.getPort();
313 } else {
314 channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort();
315 }
316 }
317 };
318
319 @Override
320 public final Channel getChannel() {
321 return this.channel;
322 };
323
324 @Override
325 public String channelId() {
326 return channelId;
327 }
328
Shashikanth VH6de20d32015-10-09 12:04:13 +0530329 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530330 public BgpFactory factory() {
331 return BgpFactories.getFactory(sessionInfo.remoteBgpVersion());
Shashikanth VH6de20d32015-10-09 12:04:13 +0530332 }
333
334 @Override
335 public boolean isHandshakeComplete() {
336 return isHandShakeComplete;
337 }
338
339 @Override
340 public String toString() {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530341 return MoreObjects.toStringHelper(getClass()).omitNullValues()
342 .add("channel", channelId())
Priyanka Bc08e56d2015-11-27 15:28:33 +0530343 .add("BgpId", sessionInfo().remoteBgpId()).toString();
Shashikanth VH6de20d32015-10-09 12:04:13 +0530344 }
345}