diff options
Diffstat (limited to 'framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java')
-rw-r--r-- | framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java | 473 |
1 files changed, 0 insertions, 473 deletions
diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java deleted file mode 100644 index dedf6ac3..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright 2014-2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.routing.bgp; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelStateEvent; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.SimpleChannelHandler; -import org.jboss.netty.util.HashedWheelTimer; -import org.jboss.netty.util.Timeout; -import org.jboss.netty.util.Timer; -import org.jboss.netty.util.TimerTask; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.Ip6Prefix; -import org.onlab.packet.IpPrefix; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.Collection; -import java.util.Collections; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; - -/** - * Class for handling the BGP peer sessions. - * There is one instance per each BGP peer session. - */ -public class BgpSession extends SimpleChannelHandler { - private static final Logger log = - LoggerFactory.getLogger(BgpSession.class); - - private final BgpSessionManager bgpSessionManager; - - // Local flag to indicate the session is closed. - // It is used to avoid the Netty's asynchronous closing of a channel. - private boolean isClosed = false; - - // BGP session info: local and remote - private final BgpSessionInfo localInfo; // BGP session local info - private final BgpSessionInfo remoteInfo; // BGP session remote info - - // Timers state - private Timer timer = new HashedWheelTimer(); - private volatile Timeout keepaliveTimeout; // Periodic KEEPALIVE - private volatile Timeout sessionTimeout; // Session timeout - - // BGP RIB-IN routing entries from this peer - private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRibIn4 = - new ConcurrentHashMap<>(); - private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRibIn6 = - new ConcurrentHashMap<>(); - - /** - * Constructor for a given BGP Session Manager. - * - * @param bgpSessionManager the BGP Session Manager to use - */ - BgpSession(BgpSessionManager bgpSessionManager) { - this.bgpSessionManager = bgpSessionManager; - this.localInfo = new BgpSessionInfo(); - this.remoteInfo = new BgpSessionInfo(); - - // NOTE: We support only BGP4 - this.localInfo.setBgpVersion(BgpConstants.BGP_VERSION); - } - - /** - * Gets the BGP Session Manager. - * - * @return the BGP Session Manager - */ - BgpSessionManager getBgpSessionManager() { - return bgpSessionManager; - } - - /** - * Gets the BGP Session local information. - * - * @return the BGP Session local information. - */ - public BgpSessionInfo localInfo() { - return localInfo; - } - - /** - * Gets the BGP Session remote information. - * - * @return the BGP Session remote information. - */ - public BgpSessionInfo remoteInfo() { - return remoteInfo; - } - - /** - * Gets the BGP Multiprotocol Extensions for the session. - * - * @return true if the BGP Multiprotocol Extensions are enabled for the - * session, otherwise false - */ - public boolean mpExtensions() { - return remoteInfo.mpExtensions() && localInfo.mpExtensions(); - } - - /** - * Gets the BGP session 4 octet AS path capability. - * - * @return true when the BGP session is 4 octet AS path capable - */ - public boolean isAs4OctetCapable() { - return remoteInfo.as4OctetCapability() && - localInfo.as4OctetCapability(); - } - - /** - * Gets the IPv4 BGP RIB-IN routing entries. - * - * @return the IPv4 BGP RIB-IN routing entries - */ - public Collection<BgpRouteEntry> getBgpRibIn4() { - return bgpRibIn4.values(); - } - - /** - * Gets the IPv6 BGP RIB-IN routing entries. - * - * @return the IPv6 BGP RIB-IN routing entries - */ - public Collection<BgpRouteEntry> getBgpRibIn6() { - return bgpRibIn6.values(); - } - - /** - * Finds an IPv4 BGP routing entry for a prefix in the IPv4 BGP RIB-IN. - * - * @param prefix the IPv4 prefix of the route to search for - * @return the IPv4 BGP routing entry if found, otherwise null - */ - public BgpRouteEntry findBgpRoute(Ip4Prefix prefix) { - return bgpRibIn4.get(prefix); - } - - /** - * Finds an IPv6 BGP routing entry for a prefix in the IPv6 BGP RIB-IN. - * - * @param prefix the IPv6 prefix of the route to search for - * @return the IPv6 BGP routing entry if found, otherwise null - */ - public BgpRouteEntry findBgpRoute(Ip6Prefix prefix) { - return bgpRibIn6.get(prefix); - } - - /** - * Finds a BGP routing entry for a prefix in the BGP RIB-IN. The prefix - * can be either IPv4 or IPv6. - * - * @param prefix the IP prefix of the route to search for - * @return the BGP routing entry if found, otherwise null - */ - public BgpRouteEntry findBgpRoute(IpPrefix prefix) { - if (prefix.isIp4()) { - // IPv4 prefix - Ip4Prefix ip4Prefix = prefix.getIp4Prefix(); - return bgpRibIn4.get(ip4Prefix); - } - - // IPv6 prefix - Ip6Prefix ip6Prefix = prefix.getIp6Prefix(); - return bgpRibIn6.get(ip6Prefix); - } - - /** - * Adds a BGP route. The route can be either IPv4 or IPv6. - * - * @param bgpRouteEntry the BGP route entry to use - */ - void addBgpRoute(BgpRouteEntry bgpRouteEntry) { - if (bgpRouteEntry.isIp4()) { - // IPv4 route - Ip4Prefix ip4Prefix = bgpRouteEntry.prefix().getIp4Prefix(); - bgpRibIn4.put(ip4Prefix, bgpRouteEntry); - } else { - // IPv6 route - Ip6Prefix ip6Prefix = bgpRouteEntry.prefix().getIp6Prefix(); - bgpRibIn6.put(ip6Prefix, bgpRouteEntry); - } - } - - /** - * Removes an IPv4 BGP route for a prefix. - * - * @param prefix the prefix to use - * @return true if the route was found and removed, otherwise false - */ - boolean removeBgpRoute(Ip4Prefix prefix) { - return (bgpRibIn4.remove(prefix) != null); - } - - /** - * Removes an IPv6 BGP route for a prefix. - * - * @param prefix the prefix to use - * @return true if the route was found and removed, otherwise false - */ - boolean removeBgpRoute(Ip6Prefix prefix) { - return (bgpRibIn6.remove(prefix) != null); - } - - /** - * Removes a BGP route for a prefix. The prefix can be either IPv4 or IPv6. - * - * @param prefix the prefix to use - * @return true if the route was found and removed, otherwise false - */ - boolean removeBgpRoute(IpPrefix prefix) { - if (prefix.isIp4()) { - return (bgpRibIn4.remove(prefix.getIp4Prefix()) != null); // IPv4 - } - return (bgpRibIn6.remove(prefix.getIp6Prefix()) != null); // IPv6 - } - - /** - * Tests whether the session is closed. - * <p> - * NOTE: We use this method to avoid the Netty's asynchronous closing - * of a channel. - * </p> - * @return true if the session is closed - */ - boolean isClosed() { - return isClosed; - } - - /** - * Closes the session. - * - * @param ctx the Channel Handler Context - */ - void closeSession(ChannelHandlerContext ctx) { - timer.stop(); - closeChannel(ctx); - } - - /** - * Closes the Netty channel. - * - * @param ctx the Channel Handler Context - */ - void closeChannel(ChannelHandlerContext ctx) { - isClosed = true; - ctx.getChannel().close(); - } - - @Override - public void channelOpen(ChannelHandlerContext ctx, - ChannelStateEvent channelEvent) { - bgpSessionManager.addSessionChannel(channelEvent.getChannel()); - } - - @Override - public void channelClosed(ChannelHandlerContext ctx, - ChannelStateEvent channelEvent) { - bgpSessionManager.removeSessionChannel(channelEvent.getChannel()); - } - - @Override - public void channelConnected(ChannelHandlerContext ctx, - ChannelStateEvent channelEvent) { - localInfo.setAddress(ctx.getChannel().getLocalAddress()); - remoteInfo.setAddress(ctx.getChannel().getRemoteAddress()); - - // Assign the local and remote IPv4 addresses - InetAddress inetAddr; - if (localInfo.address() instanceof InetSocketAddress) { - inetAddr = ((InetSocketAddress) localInfo.address()).getAddress(); - localInfo.setIp4Address(Ip4Address.valueOf(inetAddr.getAddress())); - } - if (remoteInfo.address() instanceof InetSocketAddress) { - inetAddr = ((InetSocketAddress) remoteInfo.address()).getAddress(); - remoteInfo.setIp4Address(Ip4Address.valueOf(inetAddr.getAddress())); - } - - log.debug("BGP Session Connected from {} on {}", - remoteInfo.address(), localInfo.address()); - if (!bgpSessionManager.peerConnected(this)) { - log.debug("Cannot setup BGP Session Connection from {}. Closing...", - remoteInfo.address()); - ctx.getChannel().close(); - } - - // - // Assign the local BGP ID - // NOTE: This should be configuration-based - // - localInfo.setBgpId(bgpSessionManager.getMyBgpId()); - } - - @Override - public void channelDisconnected(ChannelHandlerContext ctx, - ChannelStateEvent channelEvent) { - log.debug("BGP Session Disconnected from {} on {}", - ctx.getChannel().getRemoteAddress(), - ctx.getChannel().getLocalAddress()); - processChannelDisconnected(); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { - log.debug("BGP Session Exception Caught from {} on {}: {}", - ctx.getChannel().getRemoteAddress(), - ctx.getChannel().getLocalAddress(), - e); - processChannelDisconnected(); - } - - /** - * Processes the channel being disconnected. - */ - private void processChannelDisconnected() { - // - // Withdraw the routes advertised by this BGP peer - // - // NOTE: We must initialize the RIB-IN before propagating the withdraws - // for further processing. Otherwise, the BGP Decision Process - // will use those routes again. - // - Collection<BgpRouteEntry> deletedRoutes4 = bgpRibIn4.values(); - Collection<BgpRouteEntry> deletedRoutes6 = bgpRibIn6.values(); - bgpRibIn4 = new ConcurrentHashMap<>(); - bgpRibIn6 = new ConcurrentHashMap<>(); - - // Push the updates to the BGP Merged RIB - BgpRouteSelector bgpRouteSelector = - bgpSessionManager.getBgpRouteSelector(); - Collection<BgpRouteEntry> addedRoutes = Collections.emptyList(); - bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes4); - bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes6); - - bgpSessionManager.peerDisconnected(this); - } - - /** - * Restarts the BGP KeepaliveTimer. - * - * @param ctx the Channel Handler Context to use - */ - void restartKeepaliveTimer(ChannelHandlerContext ctx) { - long localKeepaliveInterval = 0; - - // - // Compute the local Keepalive interval - // - if (localInfo.holdtime() != 0) { - localKeepaliveInterval = Math.max(localInfo.holdtime() / - BgpConstants.BGP_KEEPALIVE_PER_HOLD_INTERVAL, - BgpConstants.BGP_KEEPALIVE_MIN_INTERVAL); - } - - // Restart the Keepalive timer - if (localKeepaliveInterval == 0) { - return; // Nothing to do - } - keepaliveTimeout = timer.newTimeout(new TransmitKeepaliveTask(ctx), - localKeepaliveInterval, - TimeUnit.SECONDS); - } - - /** - * Task class for transmitting KEEPALIVE messages. - */ - private final class TransmitKeepaliveTask implements TimerTask { - private final ChannelHandlerContext ctx; - - /** - * Constructor for given Channel Handler Context. - * - * @param ctx the Channel Handler Context to use - */ - TransmitKeepaliveTask(ChannelHandlerContext ctx) { - this.ctx = ctx; - } - - @Override - public void run(Timeout timeout) throws Exception { - if (timeout.isCancelled()) { - return; - } - if (!ctx.getChannel().isOpen()) { - return; - } - - // Transmit the KEEPALIVE - ChannelBuffer txMessage = BgpKeepalive.prepareBgpKeepalive(); - ctx.getChannel().write(txMessage); - - // Restart the KEEPALIVE timer - restartKeepaliveTimer(ctx); - } - } - - /** - * Restarts the BGP Session Timeout Timer. - * - * @param ctx the Channel Handler Context to use - */ - void restartSessionTimeoutTimer(ChannelHandlerContext ctx) { - if (remoteInfo.holdtime() == 0) { - return; // Nothing to do - } - if (sessionTimeout != null) { - sessionTimeout.cancel(); - } - sessionTimeout = timer.newTimeout(new SessionTimeoutTask(ctx), - remoteInfo.holdtime(), - TimeUnit.SECONDS); - } - - /** - * Task class for BGP Session timeout. - */ - private final class SessionTimeoutTask implements TimerTask { - private final ChannelHandlerContext ctx; - - /** - * Constructor for given Channel Handler Context. - * - * @param ctx the Channel Handler Context to use - */ - SessionTimeoutTask(ChannelHandlerContext ctx) { - this.ctx = ctx; - } - - @Override - public void run(Timeout timeout) throws Exception { - if (timeout.isCancelled()) { - return; - } - if (!ctx.getChannel().isOpen()) { - return; - } - - log.debug("BGP Session Timeout: peer {}", remoteInfo.address()); - // - // ERROR: Invalid Optional Parameter Length field: Unspecific - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.HoldTimerExpired.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - null); - ctx.getChannel().write(txMessage); - closeChannel(ctx); - } - } -} |