blob: 57a924a8582118396c34fa50d7bd48f71aa73702 [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;
Priyanka Bc08e56d2015-11-27 15:28:33 +053031import org.onosproject.bgpio.exceptions.BgpParseException;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053032import org.onosproject.bgpio.protocol.BgpFactories;
33import org.onosproject.bgpio.protocol.BgpFactory;
Priyanka Bc08e56d2015-11-27 15:28:33 +053034import org.onosproject.bgpio.protocol.BgpLSNlri;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053035import org.onosproject.bgpio.protocol.BgpMessage;
Priyanka Bc08e56d2015-11-27 15:28:33 +053036import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
37import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
38import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
39import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
40import org.onosproject.bgpio.types.BgpValueType;
41import org.onosproject.bgpio.types.MpReachNlri;
42import org.onosproject.bgpio.types.MpUnReachNlri;
Shashikanth VH6de20d32015-10-09 12:04:13 +053043import org.slf4j.Logger;
44import org.slf4j.LoggerFactory;
45
46import com.google.common.base.MoreObjects;
47
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;
Priyanka Bc08e56d2015-11-27 15:28:33 +053064 private AdjRibIn adjRib;
65 private VpnAdjRibIn vpnAdjRib;
Shashikanth VH6de20d32015-10-09 12:04:13 +053066
Shashikanth VH9f8afb42015-11-04 18:00:30 +053067
Shashikanth VH6de20d32015-10-09 12:04:13 +053068 @Override
Shashikanth VH9f8afb42015-11-04 18:00:30 +053069 public BgpSessionInfo sessionInfo() {
70 return sessionInfo;
71 }
72
73 /**
74 * Initialize peer.
75 *
76 *@param bgpController controller instance
77 *@param sessionInfo bgp session info
78 *@param pktStats packet statistics
79 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053080 public BgpPeerImpl(BgpController bgpController, BgpSessionInfo sessionInfo, BgpPacketStatsImpl pktStats) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +053081 this.bgpController = bgpController;
82 this.sessionInfo = sessionInfo;
83 this.pktStats = pktStats;
Priyanka Bc08e56d2015-11-27 15:28:33 +053084 this.adjRib = new AdjRibIn();
85 this.vpnAdjRib = new VpnAdjRibIn();
86 }
87
88
89 @Override
90 public void buildAdjRibIn(List<BgpValueType> pathAttr) throws BgpParseException {
91 ListIterator<BgpValueType> iterator = pathAttr.listIterator();
92 while (iterator.hasNext()) {
93 BgpValueType attr = iterator.next();
94 if (attr instanceof MpReachNlri) {
95 List<BgpLSNlri> nlri = ((MpReachNlri) attr).mpReachNlri();
96 callAdd(this, nlri, pathAttr);
97 }
98 if (attr instanceof MpUnReachNlri) {
99 List<BgpLSNlri> nlri = ((MpUnReachNlri) attr).mpUnReachNlri();
100 callRemove(this, nlri);
101 }
102 }
103 }
104
105 /**
106 * Updates NLRI identifier node in a tree separately based on afi and safi.
107 *
108 * @param peerImpl BGP peer instance
109 * @param nlri MpReachNlri path attribute
110 * @param pathAttr list of BGP path attributes
111 * @throws BgpParseException throws exception
112 */
113 public void callAdd(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri, List<BgpValueType> pathAttr)
114 throws BgpParseException {
115 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
116 while (listIterator.hasNext()) {
117 BgpLSNlri nlriInfo = listIterator.next();
118 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
119 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
120 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
121 adjRib.add(nlriInfo, details);
122 } else {
123 vpnAdjRib.addVpn(nlriInfo, details, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
124 }
125 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
126 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
127 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
128 adjRib.add(nlriInfo, details);
129 } else {
130 vpnAdjRib.addVpn(nlriInfo, details, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
131 }
132 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
133 PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
134 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
135 adjRib.add(nlriInfo, details);
136 } else {
137 vpnAdjRib.addVpn(nlriInfo, details, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
138 }
139 }
140 }
141 }
142
143 /**
144 * Sets BGP path attribute and NLRI details.
145 *
146 * @param nlriInfo MpReachNlri path attribute
147 * @param pathAttr list of BGP path attributes
148 * @return details object of PathAttrNlriDetails
149 * @throws BgpParseException throw exception
150 */
151 public PathAttrNlriDetails setPathAttrDetails(BgpLSNlri nlriInfo, List<BgpValueType> pathAttr)
152 throws BgpParseException {
153 PathAttrNlriDetails details = new PathAttrNlriDetails();
154 details.setProtocolID(nlriInfo.getProtocolId());
155 details.setIdentifier(nlriInfo.getIdentifier());
156 details.setPathAttribute(pathAttr);
157 return details;
158 }
159
160 /**
161 * Removes NLRI identifier node in a tree separately based on afi and safi.
162 *
163 * @param peerImpl BGP peer instance
164 * @param nlri NLRI information
165 */
166 public void callRemove(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri) {
167 ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
168 while (listIterator.hasNext()) {
169 BgpLSNlri nlriInfo = listIterator.next();
170 if (nlriInfo instanceof BgpNodeLSNlriVer4) {
171 if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
172 adjRib.remove(nlriInfo);
173 } else {
174 vpnAdjRib.removeVpn(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
175 }
176 } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
177 if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
178 adjRib.remove(nlriInfo);
179 } else {
180 vpnAdjRib.removeVpn(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
181 }
182 } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
183 if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
184 adjRib.remove(nlriInfo);
185 } else {
186 vpnAdjRib.removeVpn(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
187 }
188 }
189 }
190 }
191
192 /**
193 * Return the adjacency RIB-IN.
194 *
195 * @return adjRib the adjacency RIB-IN
196 */
197 public AdjRibIn adjRib() {
198 return adjRib;
199 }
200
201 /**
202 * Return the adjacency RIB-IN with VPN.
203 *
204 * @return vpnAdjRib the adjacency RIB-IN with VPN
205 */
206 public VpnAdjRibIn vpnAdjRib() {
207 return vpnAdjRib;
Shashikanth VH6de20d32015-10-09 12:04:13 +0530208 }
209
210 // ************************
211 // Channel related
212 // ************************
213
214 @Override
215 public final void disconnectPeer() {
216 this.channel.close();
217 }
218
219 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530220 public final void sendMessage(BgpMessage m) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530221 log.debug("Sending message to {}", channel.getRemoteAddress());
222 try {
223 channel.write(Collections.singletonList(m));
224 this.pktStats.addOutPacket();
225 } catch (RejectedExecutionException e) {
226 log.warn(e.getMessage());
227 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
228 throw e;
229 }
230 }
231 }
232
233 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530234 public final void sendMessage(List<BgpMessage> msgs) {
Shashikanth VH6de20d32015-10-09 12:04:13 +0530235 try {
236 channel.write(msgs);
237 this.pktStats.addOutPacket(msgs.size());
238 } catch (RejectedExecutionException e) {
239 log.warn(e.getMessage());
240 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
241 throw e;
242 }
243 }
244 }
245
246 @Override
247 public final boolean isConnected() {
248 return this.connected;
249 }
250
251 @Override
252 public final void setConnected(boolean connected) {
253 this.connected = connected;
254 };
255
256 @Override
257 public final void setChannel(Channel channel) {
258 this.channel = channel;
259 final SocketAddress address = channel.getRemoteAddress();
260 if (address instanceof InetSocketAddress) {
261 final InetSocketAddress inetAddress = (InetSocketAddress) address;
262 final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
263 if (ipAddress.isIp4()) {
264 channelId = ipAddress.toString() + ':' + inetAddress.getPort();
265 } else {
266 channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort();
267 }
268 }
269 };
270
271 @Override
272 public final Channel getChannel() {
273 return this.channel;
274 };
275
276 @Override
277 public String channelId() {
278 return channelId;
279 }
280
Shashikanth VH6de20d32015-10-09 12:04:13 +0530281 @Override
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530282 public BgpFactory factory() {
283 return BgpFactories.getFactory(sessionInfo.remoteBgpVersion());
Shashikanth VH6de20d32015-10-09 12:04:13 +0530284 }
285
286 @Override
287 public boolean isHandshakeComplete() {
288 return isHandShakeComplete;
289 }
290
291 @Override
292 public String toString() {
Shashikanth VH9f8afb42015-11-04 18:00:30 +0530293 return MoreObjects.toStringHelper(getClass()).omitNullValues()
294 .add("channel", channelId())
Priyanka Bc08e56d2015-11-27 15:28:33 +0530295 .add("BgpId", sessionInfo().remoteBgpId()).toString();
Shashikanth VH6de20d32015-10-09 12:04:13 +0530296 }
297}