Refactor the SDN-IP BGP code so the BGP routes are withdrawn if
the onos-app-sdnip feature is uninstalled. Change-Id: I49c40ee172a06d5809da69f736648fa639745975
Showing
3 changed files
with
69 additions
and
5 deletions
... | @@ -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); | ... | ... |
-
Please register or login to post a comment