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 { ...@@ -167,8 +167,33 @@ public class Router implements RouteListener {
167 * Shuts the router down. 167 * Shuts the router down.
168 */ 168 */
169 public void shutdown() { 169 public void shutdown() {
170 + // Stop all threads
170 bgpUpdatesExecutor.shutdownNow(); 171 bgpUpdatesExecutor.shutdownNow();
171 bgpIntentsSynchronizerExecutor.shutdownNow(); 172 bgpIntentsSynchronizerExecutor.shutdownNow();
173 +
174 + synchronized (this) {
175 + // Cleanup all local state
176 + bgpRoutes = new ConcurrentInvertedRadixTree<>(
177 + new DefaultByteArrayNodeFactory());
178 + routeUpdates.clear();
179 + routesWaitingOnArp.clear();
180 + pushedRouteIntents.clear();
181 +
182 + //
183 + // Withdraw all SDN-IP intents
184 + //
185 + if (!isElectedLeader) {
186 + return; // Nothing to do: not the leader anymore
187 + }
188 + log.debug("Withdrawing all SDN-IP Route Intents...");
189 + for (Intent intent : intentService.getIntents()) {
190 + if (!(intent instanceof MultiPointToSinglePointIntent)
191 + || !intent.appId().equals(appId)) {
192 + continue;
193 + }
194 + intentService.withdraw(intent);
195 + }
196 + }
172 } 197 }
173 198
174 //@Override TODO hook this up to something 199 //@Override TODO hook this up to something
......
...@@ -237,6 +237,18 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -237,6 +237,18 @@ public class BgpSession extends SimpleChannelHandler {
237 } 237 }
238 238
239 @Override 239 @Override
240 + public void channelOpen(ChannelHandlerContext ctx,
241 + ChannelStateEvent channelEvent) {
242 + bgpSessionManager.addSessionChannel(channelEvent.getChannel());
243 + }
244 +
245 + @Override
246 + public void channelClosed(ChannelHandlerContext ctx,
247 + ChannelStateEvent channelEvent) {
248 + bgpSessionManager.removeSessionChannel(channelEvent.getChannel());
249 + }
250 +
251 + @Override
240 public void channelConnected(ChannelHandlerContext ctx, 252 public void channelConnected(ChannelHandlerContext ctx,
241 ChannelStateEvent channelEvent) { 253 ChannelStateEvent channelEvent) {
242 localAddress = ctx.getChannel().getLocalAddress(); 254 localAddress = ctx.getChannel().getLocalAddress();
......
...@@ -32,6 +32,8 @@ import org.jboss.netty.channel.ChannelFactory; ...@@ -32,6 +32,8 @@ import org.jboss.netty.channel.ChannelFactory;
32 import org.jboss.netty.channel.ChannelPipeline; 32 import org.jboss.netty.channel.ChannelPipeline;
33 import org.jboss.netty.channel.ChannelPipelineFactory; 33 import org.jboss.netty.channel.ChannelPipelineFactory;
34 import org.jboss.netty.channel.Channels; 34 import org.jboss.netty.channel.Channels;
35 +import org.jboss.netty.channel.group.ChannelGroup;
36 +import org.jboss.netty.channel.group.DefaultChannelGroup;
35 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; 37 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
36 import org.onlab.onos.sdnip.RouteListener; 38 import org.onlab.onos.sdnip.RouteListener;
37 import org.onlab.onos.sdnip.RouteUpdate; 39 import org.onlab.onos.sdnip.RouteUpdate;
...@@ -46,7 +48,10 @@ import org.slf4j.LoggerFactory; ...@@ -46,7 +48,10 @@ import org.slf4j.LoggerFactory;
46 public class BgpSessionManager { 48 public class BgpSessionManager {
47 private static final Logger log = 49 private static final Logger log =
48 LoggerFactory.getLogger(BgpSessionManager.class); 50 LoggerFactory.getLogger(BgpSessionManager.class);
51 + boolean isShutdown = true;
49 private Channel serverChannel; // Listener for incoming BGP connections 52 private Channel serverChannel; // Listener for incoming BGP connections
53 + private ServerBootstrap serverBootstrap;
54 + private ChannelGroup allChannels = new DefaultChannelGroup();
50 private ConcurrentMap<SocketAddress, BgpSession> bgpSessions = 55 private ConcurrentMap<SocketAddress, BgpSession> bgpSessions =
51 new ConcurrentHashMap<>(); 56 new ConcurrentHashMap<>();
52 private Ip4Address myBgpId; // Same BGP ID for all peers 57 private Ip4Address myBgpId; // Same BGP ID for all peers
...@@ -85,6 +90,24 @@ public class BgpSessionManager { ...@@ -85,6 +90,24 @@ public class BgpSessionManager {
85 } 90 }
86 91
87 /** 92 /**
93 + * Adds the channel for a BGP session.
94 + *
95 + * @param channel the channel to add
96 + */
97 + void addSessionChannel(Channel channel) {
98 + allChannels.add(channel);
99 + }
100 +
101 + /**
102 + * Removes the channel for a BGP session.
103 + *
104 + * @param channel the channel to remove
105 + */
106 + void removeSessionChannel(Channel channel) {
107 + allChannels.remove(channel);
108 + }
109 +
110 + /**
88 * Processes the connection from a BGP peer. 111 * Processes the connection from a BGP peer.
89 * 112 *
90 * @param bgpSession the BGP session for the peer 113 * @param bgpSession the BGP session for the peer
...@@ -160,6 +183,7 @@ public class BgpSessionManager { ...@@ -160,6 +183,7 @@ public class BgpSessionManager {
160 */ 183 */
161 public void startUp(int listenPortNumber) { 184 public void startUp(int listenPortNumber) {
162 log.debug("BGP Session Manager startUp()"); 185 log.debug("BGP Session Manager startUp()");
186 + isShutdown = false;
163 187
164 ChannelFactory channelFactory = 188 ChannelFactory channelFactory =
165 new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), 189 new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),
...@@ -183,13 +207,14 @@ public class BgpSessionManager { ...@@ -183,13 +207,14 @@ public class BgpSessionManager {
183 InetSocketAddress listenAddress = 207 InetSocketAddress listenAddress =
184 new InetSocketAddress(listenPortNumber); 208 new InetSocketAddress(listenPortNumber);
185 209
186 - ServerBootstrap serverBootstrap = new ServerBootstrap(channelFactory); 210 + serverBootstrap = new ServerBootstrap(channelFactory);
187 // serverBootstrap.setOptions("reuseAddr", true); 211 // serverBootstrap.setOptions("reuseAddr", true);
188 serverBootstrap.setOption("child.keepAlive", true); 212 serverBootstrap.setOption("child.keepAlive", true);
189 serverBootstrap.setOption("child.tcpNoDelay", true); 213 serverBootstrap.setOption("child.tcpNoDelay", true);
190 serverBootstrap.setPipelineFactory(pipelineFactory); 214 serverBootstrap.setPipelineFactory(pipelineFactory);
191 try { 215 try {
192 serverChannel = serverBootstrap.bind(listenAddress); 216 serverChannel = serverBootstrap.bind(listenAddress);
217 + allChannels.add(serverChannel);
193 } catch (ChannelException e) { 218 } catch (ChannelException e) {
194 log.debug("Exception binding to BGP port {}: ", 219 log.debug("Exception binding to BGP port {}: ",
195 listenAddress.getPort(), e); 220 listenAddress.getPort(), e);
...@@ -200,10 +225,9 @@ public class BgpSessionManager { ...@@ -200,10 +225,9 @@ public class BgpSessionManager {
200 * Shuts down the BGP Session Manager operation. 225 * Shuts down the BGP Session Manager operation.
201 */ 226 */
202 public void shutDown() { 227 public void shutDown() {
203 - // TODO: Complete the implementation: remove routes, etc. 228 + isShutdown = true;
204 - if (serverChannel != null) { 229 + allChannels.close().awaitUninterruptibly();
205 - serverChannel.close(); 230 + serverBootstrap.releaseExternalResources();
206 - }
207 } 231 }
208 232
209 /** 233 /**
...@@ -223,6 +247,9 @@ public class BgpSessionManager { ...@@ -223,6 +247,9 @@ public class BgpSessionManager {
223 synchronized void routeUpdates(BgpSession bgpSession, 247 synchronized void routeUpdates(BgpSession bgpSession,
224 Collection<BgpRouteEntry> addedBgpRouteEntries, 248 Collection<BgpRouteEntry> addedBgpRouteEntries,
225 Collection<BgpRouteEntry> deletedBgpRouteEntries) { 249 Collection<BgpRouteEntry> deletedBgpRouteEntries) {
250 + if (isShutdown) {
251 + return; // Ignore any leftover updates if shutdown
252 + }
226 // Process the deleted route entries 253 // Process the deleted route entries
227 for (BgpRouteEntry bgpRouteEntry : deletedBgpRouteEntries) { 254 for (BgpRouteEntry bgpRouteEntry : deletedBgpRouteEntries) {
228 processDeletedRoute(bgpSession, bgpRouteEntry); 255 processDeletedRoute(bgpSession, bgpRouteEntry);
......