Pavlin Radoslavov

Refactor the SDN-IP BGP code so the BGP routes are withdrawn if

the onos-app-sdnip feature is uninstalled.

Change-Id: I49c40ee172a06d5809da69f736648fa639745975
......@@ -167,8 +167,33 @@ public class Router implements RouteListener {
* Shuts the router down.
*/
public void shutdown() {
// Stop all threads
bgpUpdatesExecutor.shutdownNow();
bgpIntentsSynchronizerExecutor.shutdownNow();
synchronized (this) {
// Cleanup all local state
bgpRoutes = new ConcurrentInvertedRadixTree<>(
new DefaultByteArrayNodeFactory());
routeUpdates.clear();
routesWaitingOnArp.clear();
pushedRouteIntents.clear();
//
// Withdraw all SDN-IP intents
//
if (!isElectedLeader) {
return; // Nothing to do: not the leader anymore
}
log.debug("Withdrawing all SDN-IP Route Intents...");
for (Intent intent : intentService.getIntents()) {
if (!(intent instanceof MultiPointToSinglePointIntent)
|| !intent.appId().equals(appId)) {
continue;
}
intentService.withdraw(intent);
}
}
}
//@Override TODO hook this up to something
......
......@@ -237,6 +237,18 @@ public class BgpSession extends SimpleChannelHandler {
}
@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) {
localAddress = ctx.getChannel().getLocalAddress();
......
......@@ -32,6 +32,8 @@ import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.onlab.onos.sdnip.RouteListener;
import org.onlab.onos.sdnip.RouteUpdate;
......@@ -46,7 +48,10 @@ import org.slf4j.LoggerFactory;
public class BgpSessionManager {
private static final Logger log =
LoggerFactory.getLogger(BgpSessionManager.class);
boolean isShutdown = true;
private Channel serverChannel; // Listener for incoming BGP connections
private ServerBootstrap serverBootstrap;
private ChannelGroup allChannels = new DefaultChannelGroup();
private ConcurrentMap<SocketAddress, BgpSession> bgpSessions =
new ConcurrentHashMap<>();
private Ip4Address myBgpId; // Same BGP ID for all peers
......@@ -85,6 +90,24 @@ public class BgpSessionManager {
}
/**
* Adds the channel for a BGP session.
*
* @param channel the channel to add
*/
void addSessionChannel(Channel channel) {
allChannels.add(channel);
}
/**
* Removes the channel for a BGP session.
*
* @param channel the channel to remove
*/
void removeSessionChannel(Channel channel) {
allChannels.remove(channel);
}
/**
* Processes the connection from a BGP peer.
*
* @param bgpSession the BGP session for the peer
......@@ -160,6 +183,7 @@ public class BgpSessionManager {
*/
public void startUp(int listenPortNumber) {
log.debug("BGP Session Manager startUp()");
isShutdown = false;
ChannelFactory channelFactory =
new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),
......@@ -183,13 +207,14 @@ public class BgpSessionManager {
InetSocketAddress listenAddress =
new InetSocketAddress(listenPortNumber);
ServerBootstrap serverBootstrap = new ServerBootstrap(channelFactory);
serverBootstrap = new ServerBootstrap(channelFactory);
// serverBootstrap.setOptions("reuseAddr", true);
serverBootstrap.setOption("child.keepAlive", true);
serverBootstrap.setOption("child.tcpNoDelay", true);
serverBootstrap.setPipelineFactory(pipelineFactory);
try {
serverChannel = serverBootstrap.bind(listenAddress);
allChannels.add(serverChannel);
} catch (ChannelException e) {
log.debug("Exception binding to BGP port {}: ",
listenAddress.getPort(), e);
......@@ -200,10 +225,9 @@ public class BgpSessionManager {
* Shuts down the BGP Session Manager operation.
*/
public void shutDown() {
// TODO: Complete the implementation: remove routes, etc.
if (serverChannel != null) {
serverChannel.close();
}
isShutdown = true;
allChannels.close().awaitUninterruptibly();
serverBootstrap.releaseExternalResources();
}
/**
......@@ -223,6 +247,9 @@ public class BgpSessionManager {
synchronized void routeUpdates(BgpSession bgpSession,
Collection<BgpRouteEntry> addedBgpRouteEntries,
Collection<BgpRouteEntry> deletedBgpRouteEntries) {
if (isShutdown) {
return; // Ignore any leftover updates if shutdown
}
// Process the deleted route entries
for (BgpRouteEntry bgpRouteEntry : deletedBgpRouteEntries) {
processDeletedRoute(bgpSession, bgpRouteEntry);
......