blob: e3f09f308ba31dd680c8cb23acd7f1fff33afe4d [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
19import java.net.InetSocketAddress;
20import java.net.SocketAddress;
21import java.util.Collections;
22import java.util.List;
Priyanka Bc08e56d2015-11-27 15:28:33 +053023import java.util.ListIterator;
Shashikanth VH6de20d32015-10-09 12:04:13 +053024import java.util.concurrent.RejectedExecutionException;
25
26import org.jboss.netty.channel.Channel;
27import org.onlab.packet.IpAddress;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053028import org.onosproject.bgp.controller.BgpController;
29import org.onosproject.bgp.controller.BgpPeer;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053030import org.onosproject.bgp.controller.BgpSessionInfo;
Shashikanth VH3fe37982015-11-30 11:50:07 +053031import org.onosproject.bgp.controller.BgpLocalRib;
Priyanka Bc08e56d2015-11-27 15:28:33 +053032import org.onosproject.bgpio.exceptions.BgpParseException;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053033import org.onosproject.bgpio.protocol.BgpFactories;
34import org.onosproject.bgpio.protocol.BgpFactory;
Priyanka Bc08e56d2015-11-27 15:28:33 +053035import org.onosproject.bgpio.protocol.BgpLSNlri;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053036import org.onosproject.bgpio.protocol.BgpMessage;
Priyanka Bc08e56d2015-11-27 15:28:33 +053037import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
38import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
39import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
40import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
41import org.onosproject.bgpio.types.BgpValueType;
42import org.onosproject.bgpio.types.MpReachNlri;
43import org.onosproject.bgpio.types.MpUnReachNlri;
Shashikanth VH6de20d32015-10-09 12:04:13 +053044import org.slf4j.Logger;
45import org.slf4j.LoggerFactory;
46
47import com.google.common.base.MoreObjects;
48
49/**
50 * BGPPeerImpl implements BGPPeer, maintains peer information and store updates in RIB .
51 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053052public class BgpPeerImpl implements BgpPeer {
Shashikanth VH6de20d32015-10-09 12:04:13 +053053
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053054 protected final Logger log = LoggerFactory.getLogger(BgpPeerImpl.class);
Shashikanth VH6de20d32015-10-09 12:04:13 +053055
56 private static final String SHUTDOWN_MSG = "Worker has already been shutdown";
57
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053058 private BgpController bgpController;
Shashikanth VH6de20d32015-10-09 12:04:13 +053059 private Channel channel;
60 protected String channelId;
61 private boolean connected;
62 protected boolean isHandShakeComplete = false;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053063 private BgpSessionInfo sessionInfo;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053064 private BgpPacketStatsImpl pktStats;
Shashikanth VH3fe37982015-11-30 11:50:07 +053065 private BgpLocalRib bgplocalRIB;
66 private BgpLocalRib bgplocalRIBVpn;
Priyanka Bc08e56d2015-11-27 15:28:33 +053067 private AdjRibIn adjRib;
68 private VpnAdjRibIn vpnAdjRib;
Shashikanth VH6de20d32015-10-09 12:04:13 +053069
Shashikanth VH3fe37982015-11-30 11:50:07 +053070 /**
71 * Return the adjacency RIB-IN.
72 *
73 * @return adjRib the adjacency RIB-IN
74 */
75 public AdjRibIn adjacencyRib() {
76 return adjRib;
77 }
78
79 /**
80 * Return the adjacency RIB-IN with VPN.
81 *
82 * @return vpnAdjRib the adjacency RIB-IN with VPN
83 */
84 public VpnAdjRibIn vpnAdjacencyRib() {
85 return vpnAdjRib;
86 }
Shashikanth VH9f8afb42015-11-04 18:00:30 +053087
Shashikanth VH6de20d32015-10-09 12:04:13 +053088 @Override
Shashikanth VH9f8afb42015-11-04 18:00:30 +053089 public BgpSessionInfo sessionInfo() {
90 return sessionInfo;
91 }
92
93 /**
94 * Initialize peer.
95 *
96 *@param bgpController controller instance
97 *@param sessionInfo bgp session info
98 *@param pktStats packet statistics
99 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530100 public BgpPeerImpl(BgpController bgpController, BgpSessionInfo sessionInfo, BgpPacketStatsImpl pktStats) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530101 this.bgpController = bgpController;
102 this.sessionInfo = sessionInfo;
103 this.pktStats = pktStats;
Shashikanth VH3fe37982015-11-30 11:50:07 +0530104 this.bgplocalRIB = bgpController.bgpLocalRib();
105 this.bgplocalRIBVpn = bgpController.bgpLocalRibVpn();
Priyanka Bc08e56d2015-11-27 15:28:33 +0530106 this.adjRib = new AdjRibIn();
107 this.vpnAdjRib = new VpnAdjRibIn();
108 }
109
110
111 @Override
112 public void buildAdjRibIn(List<BgpValueType> pathAttr) throws BgpParseException {
113 ListIterator<BgpValueType> iterator = pathAttr.listIterator();
114 while (iterator.hasNext()) {
115 BgpValueType attr = iterator.next();
116 if (attr instanceof MpReachNlri) {
117 List<BgpLSNlri> nlri = ((MpReachNlri) attr).mpReachNlri();
118 callAdd(this, nlri, pathAttr);
119 }
120 if (attr instanceof MpUnReachNlri) {
121 List<BgpLSNlri> nlri = ((MpUnReachNlri) attr).mpUnReachNlri();
122 callRemove(this, nlri);
123 }
124 }
125 }
126
127 /**
128 * Updates NLRI identifier node in a tree separately based on afi and safi.
129 *
130 * @param peerImpl BGP peer instance
131 * @param nlri MpReachNlri path attribute
132 * @param pathAttr list of BGP path attributes
133 * @throws BgpParseException throws exception
134 */
135 public void callAdd(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri, List<BgpValueType> pathAttr)
136 throws BgpParseException {
137 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
138 while (listIterator.hasNext()) {
139 BgpLSNlri nlriInfo = listIterator.next();
140 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
141 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
142 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
143 adjRib.add(nlriInfo, details);
Shashikanth VH3fe37982015-11-30 11:50:07 +0530144 bgplocalRIB.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530145 } else {
146 vpnAdjRib.addVpn(nlriInfo, details, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Shashikanth VH3fe37982015-11-30 11:50:07 +0530147 bgplocalRIBVpn.add(sessionInfo(), nlriInfo, details,
148 ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530149 }
150 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
151 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
152 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
153 adjRib.add(nlriInfo, details);
Shashikanth VH3fe37982015-11-30 11:50:07 +0530154 bgplocalRIB.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530155 } else {
156 vpnAdjRib.addVpn(nlriInfo, details, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Shashikanth VH3fe37982015-11-30 11:50:07 +0530157 bgplocalRIBVpn.add(sessionInfo(), nlriInfo, details,
158 ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530159 }
160 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
161 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
162 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
163 adjRib.add(nlriInfo, details);
Shashikanth VH3fe37982015-11-30 11:50:07 +0530164 bgplocalRIB.add(sessionInfo(), nlriInfo, details);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530165 } else {
166 vpnAdjRib.addVpn(nlriInfo, details, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Shashikanth VH3fe37982015-11-30 11:50:07 +0530167 bgplocalRIBVpn.add(sessionInfo(), nlriInfo, details,
168 ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530169 }
170 }
171 }
172 }
173
174 /**
175 * Sets BGP path attribute and NLRI details.
176 *
177 * @param nlriInfo MpReachNlri path attribute
178 * @param pathAttr list of BGP path attributes
179 * @return details object of PathAttrNlriDetails
180 * @throws BgpParseException throw exception
181 */
182 public PathAttrNlriDetails setPathAttrDetails(BgpLSNlri nlriInfo, List<BgpValueType> pathAttr)
183 throws BgpParseException {
184 PathAttrNlriDetails details = new PathAttrNlriDetails();
185 details.setProtocolID(nlriInfo.getProtocolId());
186 details.setIdentifier(nlriInfo.getIdentifier());
187 details.setPathAttribute(pathAttr);
188 return details;
189 }
190
191 /**
192 * Removes NLRI identifier node in a tree separately based on afi and safi.
193 *
194 * @param peerImpl BGP peer instance
195 * @param nlri NLRI information
196 */
197 public void callRemove(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri) {
198 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
199 while (listIterator.hasNext()) {
200 BgpLSNlri nlriInfo = listIterator.next();
201 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
202 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
203 adjRib.remove(nlriInfo);
Shashikanth VH3fe37982015-11-30 11:50:07 +0530204 bgplocalRIB.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530205 } else {
206 vpnAdjRib.removeVpn(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Shashikanth VH3fe37982015-11-30 11:50:07 +0530207 bgplocalRIBVpn.delete(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530208 }
209 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
210 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
211 adjRib.remove(nlriInfo);
Shashikanth VH3fe37982015-11-30 11:50:07 +0530212 bgplocalRIB.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530213 } else {
214 vpnAdjRib.removeVpn(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Shashikanth VH3fe37982015-11-30 11:50:07 +0530215 bgplocalRIBVpn.delete(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530216 }
217 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
218 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
219 adjRib.remove(nlriInfo);
Shashikanth VH3fe37982015-11-30 11:50:07 +0530220 bgplocalRIB.delete(nlriInfo);
Priyanka Bc08e56d2015-11-27 15:28:33 +0530221 } else {
222 vpnAdjRib.removeVpn(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Shashikanth VH3fe37982015-11-30 11:50:07 +0530223 bgplocalRIBVpn.delete(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
Priyanka Bc08e56d2015-11-27 15:28:33 +0530224 }
225 }
226 }
227 }
228
229 /**
230 * Return the adjacency RIB-IN.
231 *
232 * @return adjRib the adjacency RIB-IN
233 */
234 public AdjRibIn adjRib() {
235 return adjRib;
236 }
237
238 /**
239 * Return the adjacency RIB-IN with VPN.
240 *
241 * @return vpnAdjRib the adjacency RIB-IN with VPN
242 */
243 public VpnAdjRibIn vpnAdjRib() {
244 return vpnAdjRib;
Shashikanth VH6de20d32015-10-09 12:04:13 +0530245 }
246
Shashikanth VH3fe37982015-11-30 11:50:07 +0530247 /**
248 * Update localRIB on peer disconnect.
249 *
250 */
251 public void updateLocalRIBOnPeerDisconnect() {
252 BgpLocalRibImpl localRib = (BgpLocalRibImpl) bgplocalRIB;
253 BgpLocalRibImpl localRibVpn = (BgpLocalRibImpl) bgplocalRIBVpn;
254
255 localRib.localRIBUpdate(adjacencyRib());
256 localRibVpn.localRIBUpdate(vpnAdjacencyRib());
257 }
258
Shashikanth VH6de20d32015-10-09 12:04:13 +0530259 // ************************
260 // Channel related
261 // ************************
262
263 @Override
264 public final void disconnectPeer() {
265 this.channel.close();
266 }
267
268 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530269 public final void sendMessage(BgpMessage m) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530270 log.debug("Sending message to {}", channel.getRemoteAddress());
271 try {
272 channel.write(Collections.singletonList(m));
273 this.pktStats.addOutPacket();
274 } catch (RejectedExecutionException e) {
275 log.warn(e.getMessage());
276 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
277 throw e;
278 }
279 }
280 }
281
282 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530283 public final void sendMessage(List<BgpMessage> msgs) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530284 try {
285 channel.write(msgs);
286 this.pktStats.addOutPacket(msgs.size());
287 } catch (RejectedExecutionException e) {
288 log.warn(e.getMessage());
289 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
290 throw e;
291 }
292 }
293 }
294
295 @Override
296 public final boolean isConnected() {
297 return this.connected;
298 }
299
300 @Override
301 public final void setConnected(boolean connected) {
302 this.connected = connected;
303 };
304
305 @Override
306 public final void setChannel(Channel channel) {
307 this.channel = channel;
308 final SocketAddress address = channel.getRemoteAddress();
309 if (address instanceof InetSocketAddress) {
310 final InetSocketAddress inetAddress = (InetSocketAddress) address;
311 final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
312 if (ipAddress.isIp4()) {
313 channelId = ipAddress.toString() + ':' + inetAddress.getPort();
314 } else {
315 channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort();
316 }
317 }
318 };
319
320 @Override
321 public final Channel getChannel() {
322 return this.channel;
323 };
324
325 @Override
326 public String channelId() {
327 return channelId;
328 }
329
Shashikanth VH6de20d32015-10-09 12:04:13 +0530330 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530331 public BgpFactory factory() {
332 return BgpFactories.getFactory(sessionInfo.remoteBgpVersion());
Shashikanth VH6de20d32015-10-09 12:04:13 +0530333 }
334
335 @Override
336 public boolean isHandshakeComplete() {
337 return isHandShakeComplete;
338 }
339
340 @Override
341 public String toString() {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530342 return MoreObjects.toStringHelper(getClass()).omitNullValues()
343 .add("channel", channelId())
Priyanka Bc08e56d2015-11-27 15:28:33 +0530344 .add("BgpId", sessionInfo().remoteBgpId()).toString();
Shashikanth VH6de20d32015-10-09 12:04:13 +0530345 }
346}