Committed by
Gerrit Code Review
Remove old and unused Router code (incl. tests).
Added deprecated tags to a bunch of other objects that will be removed in a future release Change-Id: Iee80a260951070c1f280aa1a7755f06349aacb4f
Showing
8 changed files
with
15 additions
and
1254 deletions
... | @@ -24,7 +24,10 @@ import java.util.Objects; | ... | @@ -24,7 +24,10 @@ import java.util.Objects; |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * An entry in the Forwarding Information Base (FIB). | 26 | * An entry in the Forwarding Information Base (FIB). |
27 | + * | ||
28 | + * @deprecated use RouteService instead | ||
27 | */ | 29 | */ |
30 | +@Deprecated | ||
28 | public class FibEntry { | 31 | public class FibEntry { |
29 | 32 | ||
30 | private final IpPrefix prefix; | 33 | private final IpPrefix prefix; | ... | ... |
... | @@ -19,7 +19,10 @@ import java.util.Collection; | ... | @@ -19,7 +19,10 @@ import java.util.Collection; |
19 | 19 | ||
20 | /** | 20 | /** |
21 | * A component that is able to process Forwarding Information Base (FIB) updates. | 21 | * A component that is able to process Forwarding Information Base (FIB) updates. |
22 | + * | ||
23 | + * @deprecated use RouteService instead | ||
22 | */ | 24 | */ |
25 | +@Deprecated | ||
23 | public interface FibListener { | 26 | public interface FibListener { |
24 | 27 | ||
25 | /** | 28 | /** | ... | ... |
... | @@ -21,7 +21,10 @@ import java.util.Objects; | ... | @@ -21,7 +21,10 @@ import java.util.Objects; |
21 | 21 | ||
22 | /** | 22 | /** |
23 | * Represents a change to the Forwarding Information Base (FIB). | 23 | * Represents a change to the Forwarding Information Base (FIB). |
24 | + * | ||
25 | + * @deprecated use RouteService instead | ||
24 | */ | 26 | */ |
27 | +@Deprecated | ||
25 | public class FibUpdate { | 28 | public class FibUpdate { |
26 | 29 | ||
27 | /** | 30 | /** | ... | ... |
... | @@ -25,7 +25,10 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -25,7 +25,10 @@ import static com.google.common.base.Preconditions.checkNotNull; |
25 | 25 | ||
26 | /** | 26 | /** |
27 | * Represents a route entry for an IP prefix. | 27 | * Represents a route entry for an IP prefix. |
28 | + * | ||
29 | + * @deprecated use RouteService instead | ||
28 | */ | 30 | */ |
31 | +@Deprecated | ||
29 | public class RouteEntry { | 32 | public class RouteEntry { |
30 | private final IpPrefix prefix; // The IP prefix | 33 | private final IpPrefix prefix; // The IP prefix |
31 | private final IpAddress nextHop; // Next-hop IP address | 34 | private final IpAddress nextHop; // Next-hop IP address | ... | ... |
... | @@ -23,7 +23,10 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -23,7 +23,10 @@ import static com.google.common.base.Preconditions.checkNotNull; |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * Represents a change in routing information. | 25 | * Represents a change in routing information. |
26 | + * | ||
27 | + * @deprecated use RouteService instead | ||
26 | */ | 28 | */ |
29 | +@Deprecated | ||
27 | public class RouteUpdate { | 30 | public class RouteUpdate { |
28 | private final Type type; // The route update type | 31 | private final Type type; // The route update type |
29 | private final RouteEntry routeEntry; // The updated route entry | 32 | private final RouteEntry routeEntry; // The updated route entry | ... | ... |
1 | -/* | ||
2 | - * Copyright 2014-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 | -package org.onosproject.routing.impl; | ||
17 | - | ||
18 | -import com.google.common.collect.HashMultimap; | ||
19 | -import com.google.common.collect.Multimaps; | ||
20 | -import com.google.common.collect.SetMultimap; | ||
21 | -import com.google.common.util.concurrent.ThreadFactoryBuilder; | ||
22 | -import com.googlecode.concurrenttrees.common.KeyValuePair; | ||
23 | -import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory; | ||
24 | -import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree; | ||
25 | -import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; | ||
26 | -import org.apache.felix.scr.annotations.Activate; | ||
27 | -import org.apache.felix.scr.annotations.Component; | ||
28 | -import org.apache.felix.scr.annotations.Deactivate; | ||
29 | -import org.apache.felix.scr.annotations.Reference; | ||
30 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
31 | -import org.apache.felix.scr.annotations.Service; | ||
32 | -import org.onlab.packet.Ip4Address; | ||
33 | -import org.onlab.packet.Ip6Address; | ||
34 | -import org.onlab.packet.IpAddress; | ||
35 | -import org.onlab.packet.IpPrefix; | ||
36 | -import org.onlab.packet.MacAddress; | ||
37 | -import org.onosproject.core.CoreService; | ||
38 | -import org.onosproject.net.Host; | ||
39 | -import org.onosproject.net.host.HostEvent; | ||
40 | -import org.onosproject.net.host.HostListener; | ||
41 | -import org.onosproject.net.host.HostService; | ||
42 | -import org.onosproject.routing.RouteSourceService; | ||
43 | -import org.onosproject.routing.FibEntry; | ||
44 | -import org.onosproject.routing.FibListener; | ||
45 | -import org.onosproject.routing.FibUpdate; | ||
46 | -import org.onosproject.routing.RouteEntry; | ||
47 | -import org.onosproject.routing.RouteListener; | ||
48 | -import org.onosproject.routing.RouteUpdate; | ||
49 | -import org.onosproject.routing.RoutingService; | ||
50 | -import org.onosproject.routing.config.RoutingConfigurationService; | ||
51 | -import org.slf4j.Logger; | ||
52 | -import org.slf4j.LoggerFactory; | ||
53 | - | ||
54 | -import java.util.Collection; | ||
55 | -import java.util.Collections; | ||
56 | -import java.util.Iterator; | ||
57 | -import java.util.LinkedList; | ||
58 | -import java.util.List; | ||
59 | -import java.util.Map; | ||
60 | -import java.util.Set; | ||
61 | -import java.util.concurrent.BlockingQueue; | ||
62 | -import java.util.concurrent.ConcurrentHashMap; | ||
63 | -import java.util.concurrent.ExecutorService; | ||
64 | -import java.util.concurrent.Executors; | ||
65 | -import java.util.concurrent.LinkedBlockingQueue; | ||
66 | - | ||
67 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
68 | -import static org.onosproject.routing.RouteEntry.createBinaryString; | ||
69 | - | ||
70 | -/** | ||
71 | - * This class processes route updates and maintains a Routing Information Base | ||
72 | - * (RIB). After route updates have been processed and next hops have been | ||
73 | - * resolved, FIB updates are sent to any listening FIB components. | ||
74 | - * <p> | ||
75 | - * This implementation has been superseded by the RouteService and will be | ||
76 | - * removed soon. | ||
77 | - * </p> | ||
78 | - */ | ||
79 | -@Deprecated | ||
80 | -@Component(immediate = true, enabled = false) | ||
81 | -@Service | ||
82 | -public class DefaultRouter implements RoutingService { | ||
83 | - | ||
84 | - private static final Logger log = LoggerFactory.getLogger(DefaultRouter.class); | ||
85 | - | ||
86 | - // Route entries are stored in a radix tree. | ||
87 | - // The key in this tree is the binary string of prefix of the route. | ||
88 | - private InvertedRadixTree<RouteEntry> ribTable4; | ||
89 | - private InvertedRadixTree<RouteEntry> ribTable6; | ||
90 | - | ||
91 | - // Stores all incoming route updates in a queue. | ||
92 | - private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue = | ||
93 | - new LinkedBlockingQueue<>(); | ||
94 | - | ||
95 | - // Next-hop IP address to route entry mapping for next hops pending MAC | ||
96 | - // resolution | ||
97 | - private SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp; | ||
98 | - | ||
99 | - // The IPv4 address to MAC address mapping | ||
100 | - private final Map<IpAddress, MacAddress> ip2Mac = new ConcurrentHashMap<>(); | ||
101 | - | ||
102 | - private FibListener fibComponent; | ||
103 | - | ||
104 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
105 | - protected CoreService coreService; | ||
106 | - | ||
107 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
108 | - protected HostService hostService; | ||
109 | - | ||
110 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
111 | - protected RouteSourceService routeSourceService; | ||
112 | - | ||
113 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
114 | - protected RoutingConfigurationService routingConfigurationService; | ||
115 | - | ||
116 | - private ExecutorService bgpUpdatesExecutor; | ||
117 | - private final HostListener hostListener = new InternalHostListener(); | ||
118 | - | ||
119 | - @Activate | ||
120 | - public void activate() { | ||
121 | - ribTable4 = new ConcurrentInvertedRadixTree<>( | ||
122 | - new DefaultByteArrayNodeFactory()); | ||
123 | - ribTable6 = new ConcurrentInvertedRadixTree<>( | ||
124 | - new DefaultByteArrayNodeFactory()); | ||
125 | - | ||
126 | - routesWaitingOnArp = Multimaps.synchronizedSetMultimap( | ||
127 | - HashMultimap.create()); | ||
128 | - | ||
129 | - coreService.registerApplication(ROUTER_APP_ID); | ||
130 | - | ||
131 | - bgpUpdatesExecutor = Executors.newSingleThreadExecutor( | ||
132 | - new ThreadFactoryBuilder() | ||
133 | - .setNameFormat("rib-updates-%d").build()); | ||
134 | - } | ||
135 | - | ||
136 | - @Deactivate | ||
137 | - public void deactivate() { | ||
138 | - log.debug("Stopped"); | ||
139 | - } | ||
140 | - | ||
141 | - @Override | ||
142 | - public void addFibListener(FibListener fibListener) { | ||
143 | - this.fibComponent = checkNotNull(fibListener); | ||
144 | - } | ||
145 | - | ||
146 | - @Override | ||
147 | - public void start() { | ||
148 | - this.hostService.addListener(hostListener); | ||
149 | - | ||
150 | - routeSourceService.start(new InternalRouteListener()); | ||
151 | - | ||
152 | - bgpUpdatesExecutor.execute(this::doUpdatesThread); | ||
153 | - } | ||
154 | - | ||
155 | - @Override | ||
156 | - public void stop() { | ||
157 | - routeSourceService.stop(); | ||
158 | - | ||
159 | - this.hostService.removeListener(hostListener); | ||
160 | - | ||
161 | - // Stop the thread(s) | ||
162 | - bgpUpdatesExecutor.shutdownNow(); | ||
163 | - | ||
164 | - synchronized (this) { | ||
165 | - // Cleanup all local state | ||
166 | - ribTable4 = new ConcurrentInvertedRadixTree<>( | ||
167 | - new DefaultByteArrayNodeFactory()); | ||
168 | - ribTable6 = new ConcurrentInvertedRadixTree<>( | ||
169 | - new DefaultByteArrayNodeFactory()); | ||
170 | - routeUpdatesQueue.clear(); | ||
171 | - routesWaitingOnArp.clear(); | ||
172 | - ip2Mac.clear(); | ||
173 | - } | ||
174 | - } | ||
175 | - | ||
176 | - /** | ||
177 | - * Entry point for route updates. | ||
178 | - * | ||
179 | - * @param routeUpdates collection of route updates to process | ||
180 | - */ | ||
181 | - private void update(Collection<RouteUpdate> routeUpdates) { | ||
182 | - try { | ||
183 | - routeUpdatesQueue.put(routeUpdates); | ||
184 | - } catch (InterruptedException e) { | ||
185 | - log.error("Interrupted while putting on routeUpdatesQueue", e); | ||
186 | - Thread.currentThread().interrupt(); | ||
187 | - } | ||
188 | - } | ||
189 | - | ||
190 | - /** | ||
191 | - * Thread for handling route updates. | ||
192 | - */ | ||
193 | - private void doUpdatesThread() { | ||
194 | - boolean interrupted = false; | ||
195 | - try { | ||
196 | - while (!interrupted) { | ||
197 | - try { | ||
198 | - Collection<RouteUpdate> routeUpdates = | ||
199 | - routeUpdatesQueue.take(); | ||
200 | - processRouteUpdates(routeUpdates); | ||
201 | - } catch (InterruptedException e) { | ||
202 | - log.error("Interrupted while taking from updates queue", e); | ||
203 | - interrupted = true; | ||
204 | - } catch (Exception e) { | ||
205 | - log.error("exception", e); | ||
206 | - } | ||
207 | - } | ||
208 | - } finally { | ||
209 | - if (interrupted) { | ||
210 | - Thread.currentThread().interrupt(); | ||
211 | - } | ||
212 | - } | ||
213 | - } | ||
214 | - | ||
215 | - /** | ||
216 | - * Gets all IPv4 routes from the RIB. | ||
217 | - * | ||
218 | - * @return all IPv4 routes from the RIB | ||
219 | - */ | ||
220 | - @Override | ||
221 | - public Collection<RouteEntry> getRoutes4() { | ||
222 | - Iterator<KeyValuePair<RouteEntry>> it = | ||
223 | - ribTable4.getKeyValuePairsForKeysStartingWith("").iterator(); | ||
224 | - | ||
225 | - List<RouteEntry> routes = new LinkedList<>(); | ||
226 | - | ||
227 | - while (it.hasNext()) { | ||
228 | - KeyValuePair<RouteEntry> entry = it.next(); | ||
229 | - routes.add(entry.getValue()); | ||
230 | - } | ||
231 | - | ||
232 | - return routes; | ||
233 | - } | ||
234 | - | ||
235 | - /** | ||
236 | - * Gets all IPv6 routes from the RIB. | ||
237 | - * | ||
238 | - * @return all IPv6 routes from the RIB | ||
239 | - */ | ||
240 | - @Override | ||
241 | - public Collection<RouteEntry> getRoutes6() { | ||
242 | - Iterator<KeyValuePair<RouteEntry>> it = | ||
243 | - ribTable6.getKeyValuePairsForKeysStartingWith("").iterator(); | ||
244 | - | ||
245 | - List<RouteEntry> routes = new LinkedList<>(); | ||
246 | - | ||
247 | - while (it.hasNext()) { | ||
248 | - KeyValuePair<RouteEntry> entry = it.next(); | ||
249 | - routes.add(entry.getValue()); | ||
250 | - } | ||
251 | - | ||
252 | - return routes; | ||
253 | - } | ||
254 | - | ||
255 | - /** | ||
256 | - * Finds a route in the RIB for a prefix. The prefix can be either IPv4 or | ||
257 | - * IPv6. | ||
258 | - * | ||
259 | - * @param prefix the prefix to use | ||
260 | - * @return the route if found, otherwise null | ||
261 | - */ | ||
262 | - RouteEntry findRibRoute(IpPrefix prefix) { | ||
263 | - String binaryString = createBinaryString(prefix); | ||
264 | - if (prefix.isIp4()) { | ||
265 | - // IPv4 | ||
266 | - return ribTable4.getValueForExactKey(binaryString); | ||
267 | - } | ||
268 | - // IPv6 | ||
269 | - return ribTable6.getValueForExactKey(binaryString); | ||
270 | - } | ||
271 | - | ||
272 | - /** | ||
273 | - * Adds a route to the RIB. The route can be either IPv4 or IPv6. | ||
274 | - * | ||
275 | - * @param routeEntry the route entry to use | ||
276 | - */ | ||
277 | - void addRibRoute(RouteEntry routeEntry) { | ||
278 | - if (routeEntry.isIp4()) { | ||
279 | - // IPv4 | ||
280 | - ribTable4.put(createBinaryString(routeEntry.prefix()), routeEntry); | ||
281 | - } else { | ||
282 | - // IPv6 | ||
283 | - ribTable6.put(createBinaryString(routeEntry.prefix()), routeEntry); | ||
284 | - } | ||
285 | - } | ||
286 | - | ||
287 | - /** | ||
288 | - * Removes a route for a prefix from the RIB. The prefix can be either IPv4 | ||
289 | - * or IPv6. | ||
290 | - * | ||
291 | - * @param prefix the prefix to use | ||
292 | - * @return true if the route was found and removed, otherwise false | ||
293 | - */ | ||
294 | - boolean removeRibRoute(IpPrefix prefix) { | ||
295 | - if (prefix.isIp4()) { | ||
296 | - // IPv4 | ||
297 | - return ribTable4.remove(createBinaryString(prefix)); | ||
298 | - } | ||
299 | - // IPv6 | ||
300 | - return ribTable6.remove(createBinaryString(prefix)); | ||
301 | - } | ||
302 | - | ||
303 | - /** | ||
304 | - * Processes route updates. | ||
305 | - * | ||
306 | - * @param routeUpdates the route updates to process | ||
307 | - */ | ||
308 | - void processRouteUpdates(Collection<RouteUpdate> routeUpdates) { | ||
309 | - synchronized (this) { | ||
310 | - Collection<IpPrefix> withdrawPrefixes = new LinkedList<>(); | ||
311 | - Collection<FibUpdate> fibUpdates = new LinkedList<>(); | ||
312 | - Collection<FibUpdate> fibWithdraws = new LinkedList<>(); | ||
313 | - | ||
314 | - for (RouteUpdate update : routeUpdates) { | ||
315 | - switch (update.type()) { | ||
316 | - case UPDATE: | ||
317 | - | ||
318 | - FibEntry fib = processRouteAdd(update.routeEntry(), | ||
319 | - withdrawPrefixes); | ||
320 | - if (fib != null) { | ||
321 | - fibUpdates.add(new FibUpdate(FibUpdate.Type.UPDATE, fib)); | ||
322 | - } | ||
323 | - | ||
324 | - break; | ||
325 | - case DELETE: | ||
326 | - processRouteDelete(update.routeEntry(), withdrawPrefixes); | ||
327 | - | ||
328 | - break; | ||
329 | - default: | ||
330 | - log.error("Unknown update Type: {}", update.type()); | ||
331 | - break; | ||
332 | - } | ||
333 | - } | ||
334 | - | ||
335 | - withdrawPrefixes.forEach(p -> fibWithdraws.add(new FibUpdate( | ||
336 | - FibUpdate.Type.DELETE, new FibEntry(p, null, null)))); | ||
337 | - | ||
338 | - if (!fibUpdates.isEmpty() || !fibWithdraws.isEmpty()) { | ||
339 | - fibComponent.update(fibUpdates, fibWithdraws); | ||
340 | - } | ||
341 | - } | ||
342 | - } | ||
343 | - | ||
344 | - /** | ||
345 | - * Processes adding a route entry. | ||
346 | - * <p> | ||
347 | - * The route entry is added to the radix tree. If there was an existing | ||
348 | - * next hop for this prefix, but the next hop was different, then the | ||
349 | - * old route entry is deleted. | ||
350 | - * </p> | ||
351 | - * <p> | ||
352 | - * NOTE: Currently, we don't handle routes if the next hop is within the | ||
353 | - * SDN domain. | ||
354 | - * </p> | ||
355 | - * | ||
356 | - * @param routeEntry the route entry to add | ||
357 | - * @param withdrawPrefixes the collection of accumulated prefixes whose | ||
358 | - * intents will be withdrawn | ||
359 | - * @return the corresponding FIB entry change, or null | ||
360 | - */ | ||
361 | - private FibEntry processRouteAdd(RouteEntry routeEntry, | ||
362 | - Collection<IpPrefix> withdrawPrefixes) { | ||
363 | - log.debug("Processing route add: {}", routeEntry); | ||
364 | - | ||
365 | - // Find the old next-hop if we are updating an old route entry | ||
366 | - IpAddress oldNextHop = null; | ||
367 | - RouteEntry oldRouteEntry = findRibRoute(routeEntry.prefix()); | ||
368 | - if (oldRouteEntry != null) { | ||
369 | - oldNextHop = oldRouteEntry.nextHop(); | ||
370 | - } | ||
371 | - | ||
372 | - // Add the new route to the RIB | ||
373 | - addRibRoute(routeEntry); | ||
374 | - | ||
375 | - if (oldNextHop != null) { | ||
376 | - if (oldNextHop.equals(routeEntry.nextHop())) { | ||
377 | - return null; // No change | ||
378 | - } | ||
379 | - // | ||
380 | - // Update an existing nexthop for the prefix. | ||
381 | - // We need to remove the old flows for this prefix from the | ||
382 | - // switches before the new flows are added. | ||
383 | - // | ||
384 | - withdrawPrefixes.add(routeEntry.prefix()); | ||
385 | - } | ||
386 | - | ||
387 | - if (routingConfigurationService.isIpPrefixLocal(routeEntry.prefix())) { | ||
388 | - // Route originated by local SDN domain | ||
389 | - // We don't handle these here, reactive routing APP will handle | ||
390 | - // these | ||
391 | - log.debug("Own route {} to {}", | ||
392 | - routeEntry.prefix(), routeEntry.nextHop()); | ||
393 | - return null; | ||
394 | - } | ||
395 | - | ||
396 | - // | ||
397 | - // Find the MAC address of next hop router for this route entry. | ||
398 | - // If the MAC address can not be found in ARP cache, then this prefix | ||
399 | - // will be put in routesWaitingOnArp queue. Otherwise, generate | ||
400 | - // a new route intent. | ||
401 | - // | ||
402 | - | ||
403 | - // Monitor the IP address for updates of the MAC address | ||
404 | - hostService.startMonitoringIp(routeEntry.nextHop()); | ||
405 | - | ||
406 | - // Check if we know the MAC address of the next hop | ||
407 | - MacAddress nextHopMacAddress = ip2Mac.get(routeEntry.nextHop()); | ||
408 | - if (nextHopMacAddress == null) { | ||
409 | - Set<Host> hosts = hostService.getHostsByIp(routeEntry.nextHop()); | ||
410 | - if (!hosts.isEmpty()) { | ||
411 | - nextHopMacAddress = hosts.iterator().next().mac(); | ||
412 | - } | ||
413 | - if (nextHopMacAddress != null) { | ||
414 | - ip2Mac.put(routeEntry.nextHop(), nextHopMacAddress); | ||
415 | - } | ||
416 | - } | ||
417 | - if (nextHopMacAddress == null) { | ||
418 | - routesWaitingOnArp.put(routeEntry.nextHop(), routeEntry); | ||
419 | - return null; | ||
420 | - } | ||
421 | - return new FibEntry(routeEntry.prefix(), routeEntry.nextHop(), | ||
422 | - nextHopMacAddress); | ||
423 | - } | ||
424 | - | ||
425 | - /** | ||
426 | - * Processes the deletion of a route entry. | ||
427 | - * <p> | ||
428 | - * The prefix for the routing entry is removed from radix tree. | ||
429 | - * If the operation is successful, the prefix is added to the collection | ||
430 | - * of prefixes whose intents that will be withdrawn. | ||
431 | - * </p> | ||
432 | - * | ||
433 | - * @param routeEntry the route entry to delete | ||
434 | - * @param withdrawPrefixes the collection of accumulated prefixes whose | ||
435 | - * intents will be withdrawn | ||
436 | - */ | ||
437 | - private void processRouteDelete(RouteEntry routeEntry, | ||
438 | - Collection<IpPrefix> withdrawPrefixes) { | ||
439 | - log.debug("Processing route delete: {}", routeEntry); | ||
440 | - boolean isRemoved = removeRibRoute(routeEntry.prefix()); | ||
441 | - | ||
442 | - if (isRemoved) { | ||
443 | - // | ||
444 | - // Only withdraw intents if an entry was actually removed from the | ||
445 | - // tree. If no entry was removed, the <prefix, nexthop> wasn't | ||
446 | - // there so it's probably already been removed and we don't | ||
447 | - // need to do anything. | ||
448 | - // | ||
449 | - withdrawPrefixes.add(routeEntry.prefix()); | ||
450 | - } | ||
451 | - | ||
452 | - routesWaitingOnArp.remove(routeEntry.nextHop(), routeEntry); | ||
453 | - } | ||
454 | - | ||
455 | - /** | ||
456 | - * Signals the Router that the MAC to IP mapping has potentially been | ||
457 | - * updated. This has the effect of updating the MAC address for any | ||
458 | - * installed prefixes if it has changed, as well as installing any pending | ||
459 | - * prefixes that were waiting for MAC resolution. | ||
460 | - * | ||
461 | - * @param ipAddress the IP address that an event was received for | ||
462 | - * @param macAddress the most recently known MAC address for the IP address | ||
463 | - */ | ||
464 | - private void updateMac(IpAddress ipAddress, MacAddress macAddress) { | ||
465 | - log.debug("Received updated MAC info: {} => {}", ipAddress, | ||
466 | - macAddress); | ||
467 | - | ||
468 | - // | ||
469 | - // We synchronize on "this" to prevent changes to the Radix tree | ||
470 | - // while we're pushing intents. If the tree changes, the | ||
471 | - // tree and the intents could get out of sync. | ||
472 | - // | ||
473 | - synchronized (this) { | ||
474 | - Collection<FibUpdate> submitFibEntries = new LinkedList<>(); | ||
475 | - | ||
476 | - Set<RouteEntry> routesToPush = | ||
477 | - routesWaitingOnArp.removeAll(ipAddress); | ||
478 | - | ||
479 | - for (RouteEntry routeEntry : routesToPush) { | ||
480 | - // These will always be adds | ||
481 | - RouteEntry foundRouteEntry = findRibRoute(routeEntry.prefix()); | ||
482 | - if (foundRouteEntry != null && | ||
483 | - foundRouteEntry.nextHop().equals(routeEntry.nextHop())) { | ||
484 | - // We only push FIB updates if the prefix is still in the | ||
485 | - // radix tree and the next hop is the same as our entry. | ||
486 | - // The prefix could have been removed while we were waiting | ||
487 | - // for the ARP, or the next hop could have changed. | ||
488 | - submitFibEntries.add(new FibUpdate(FibUpdate.Type.UPDATE, | ||
489 | - new FibEntry(routeEntry.prefix(), | ||
490 | - ipAddress, macAddress))); | ||
491 | - } else { | ||
492 | - log.debug("{} has been revoked before the MAC was resolved", | ||
493 | - routeEntry); | ||
494 | - } | ||
495 | - } | ||
496 | - | ||
497 | - if (!submitFibEntries.isEmpty()) { | ||
498 | - fibComponent.update(submitFibEntries, Collections.emptyList()); | ||
499 | - } | ||
500 | - | ||
501 | - ip2Mac.put(ipAddress, macAddress); | ||
502 | - } | ||
503 | - } | ||
504 | - | ||
505 | - /** | ||
506 | - * Listener for host events. | ||
507 | - */ | ||
508 | - class InternalHostListener implements HostListener { | ||
509 | - @Override | ||
510 | - public void event(HostEvent event) { | ||
511 | - log.debug("Received HostEvent {}", event); | ||
512 | - | ||
513 | - Host host = event.subject(); | ||
514 | - switch (event.type()) { | ||
515 | - case HOST_ADDED: | ||
516 | - // FALLTHROUGH | ||
517 | - case HOST_UPDATED: | ||
518 | - for (IpAddress ipAddress : host.ipAddresses()) { | ||
519 | - updateMac(ipAddress, host.mac()); | ||
520 | - } | ||
521 | - break; | ||
522 | - case HOST_REMOVED: | ||
523 | - for (IpAddress ipAddress : host.ipAddresses()) { | ||
524 | - ip2Mac.remove(ipAddress); | ||
525 | - } | ||
526 | - break; | ||
527 | - default: | ||
528 | - break; | ||
529 | - } | ||
530 | - } | ||
531 | - } | ||
532 | - | ||
533 | - /** | ||
534 | - * Listener for route events. | ||
535 | - */ | ||
536 | - private class InternalRouteListener implements RouteListener { | ||
537 | - @Override | ||
538 | - public void update(Collection<RouteUpdate> routeUpdates) { | ||
539 | - DefaultRouter.this.update(routeUpdates); | ||
540 | - } | ||
541 | - } | ||
542 | - | ||
543 | - @Override | ||
544 | - public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) { | ||
545 | - RouteEntry routeEntry = null; | ||
546 | - Iterable<RouteEntry> routeEntries; | ||
547 | - | ||
548 | - if (ipAddress.isIp4()) { | ||
549 | - routeEntries = ribTable4.getValuesForKeysPrefixing( | ||
550 | - createBinaryString( | ||
551 | - IpPrefix.valueOf(ipAddress, Ip4Address.BIT_LENGTH))); | ||
552 | - } else { | ||
553 | - routeEntries = ribTable6.getValuesForKeysPrefixing( | ||
554 | - createBinaryString( | ||
555 | - IpPrefix.valueOf(ipAddress, Ip6Address.BIT_LENGTH))); | ||
556 | - } | ||
557 | - if (routeEntries == null) { | ||
558 | - return null; | ||
559 | - } | ||
560 | - Iterator<RouteEntry> it = routeEntries.iterator(); | ||
561 | - while (it.hasNext()) { | ||
562 | - routeEntry = it.next(); | ||
563 | - } | ||
564 | - return routeEntry; | ||
565 | - } | ||
566 | - | ||
567 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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 | -package org.onosproject.routing.impl; | ||
17 | - | ||
18 | -import com.google.common.collect.Sets; | ||
19 | - | ||
20 | -import org.junit.After; | ||
21 | -import org.junit.Before; | ||
22 | -import org.junit.Test; | ||
23 | -import org.onlab.packet.Ip4Address; | ||
24 | -import org.onlab.packet.Ip4Prefix; | ||
25 | -import org.onlab.packet.IpAddress; | ||
26 | -import org.onlab.packet.IpPrefix; | ||
27 | -import org.onlab.packet.MacAddress; | ||
28 | -import org.onlab.packet.VlanId; | ||
29 | -import org.onosproject.core.CoreService; | ||
30 | -import org.onosproject.net.ConnectPoint; | ||
31 | -import org.onosproject.net.DefaultHost; | ||
32 | -import org.onosproject.net.DeviceId; | ||
33 | -import org.onosproject.net.Host; | ||
34 | -import org.onosproject.net.HostId; | ||
35 | -import org.onosproject.net.HostLocation; | ||
36 | -import org.onosproject.net.PortNumber; | ||
37 | -import org.onosproject.net.host.HostEvent; | ||
38 | -import org.onosproject.net.host.HostListener; | ||
39 | -import org.onosproject.net.host.HostService; | ||
40 | -import org.onosproject.net.provider.ProviderId; | ||
41 | -import org.onosproject.routing.config.RoutingConfigurationService; | ||
42 | -import org.onosproject.routing.impl.DefaultRouter.InternalHostListener; | ||
43 | -import org.onosproject.routing.RouteSourceService; | ||
44 | -import org.onosproject.routing.FibEntry; | ||
45 | -import org.onosproject.routing.FibListener; | ||
46 | -import org.onosproject.routing.FibUpdate; | ||
47 | -import org.onosproject.routing.RouteEntry; | ||
48 | -import org.onosproject.routing.RouteListener; | ||
49 | -import org.onosproject.routing.RouteUpdate; | ||
50 | - | ||
51 | -import java.util.Collections; | ||
52 | - | ||
53 | -import static org.easymock.EasyMock.*; | ||
54 | - | ||
55 | -/** | ||
56 | -* This class tests adding a route and updating a route. | ||
57 | -* The HostService module answers the MAC address asynchronously. | ||
58 | -*/ | ||
59 | -public class RouterAsyncArpTest { | ||
60 | - | ||
61 | - private HostService hostService; | ||
62 | - private FibListener fibListener; | ||
63 | - private RoutingConfigurationService routingConfigurationService; | ||
64 | - | ||
65 | - private static final ConnectPoint SW1_ETH1 = new ConnectPoint( | ||
66 | - DeviceId.deviceId("of:0000000000000001"), | ||
67 | - PortNumber.portNumber(1)); | ||
68 | - | ||
69 | - private static final ConnectPoint SW2_ETH1 = new ConnectPoint( | ||
70 | - DeviceId.deviceId("of:0000000000000002"), | ||
71 | - PortNumber.portNumber(1)); | ||
72 | - | ||
73 | - private static final ConnectPoint SW3_ETH1 = new ConnectPoint( | ||
74 | - DeviceId.deviceId("of:0000000000000003"), | ||
75 | - PortNumber.portNumber(1)); | ||
76 | - | ||
77 | - private DefaultRouter router; | ||
78 | - private InternalHostListener internalHostListener; | ||
79 | - | ||
80 | - @Before | ||
81 | - public void setUp() throws Exception { | ||
82 | - hostService = createMock(HostService.class); | ||
83 | - routingConfigurationService = | ||
84 | - createMock(RoutingConfigurationService.class); | ||
85 | - | ||
86 | - RouteSourceService routeSourceService = createMock(RouteSourceService.class); | ||
87 | - routeSourceService.start(anyObject(RouteListener.class)); | ||
88 | - routeSourceService.stop(); | ||
89 | - replay(routeSourceService); | ||
90 | - | ||
91 | - fibListener = createMock(FibListener.class); | ||
92 | - | ||
93 | - router = new DefaultRouter(); | ||
94 | - router.coreService = createNiceMock(CoreService.class); | ||
95 | - router.hostService = hostService; | ||
96 | - router.routingConfigurationService = routingConfigurationService; | ||
97 | - router.routeSourceService = routeSourceService; | ||
98 | - router.activate(); | ||
99 | - | ||
100 | - router.addFibListener(fibListener); | ||
101 | - router.start(); | ||
102 | - | ||
103 | - internalHostListener = router.new InternalHostListener(); | ||
104 | - } | ||
105 | - | ||
106 | - @After | ||
107 | - public void tearDown() { | ||
108 | - // Called during shutdown | ||
109 | - reset(hostService); | ||
110 | - hostService.removeListener(anyObject(HostListener.class)); | ||
111 | - | ||
112 | - router.stop(); | ||
113 | - } | ||
114 | - | ||
115 | - /** | ||
116 | - * Tests adding a route entry with asynchronous HostService replies. | ||
117 | - */ | ||
118 | - @Test | ||
119 | - public void testRouteAdd() { | ||
120 | - // Construct a route entry | ||
121 | - IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24"); | ||
122 | - IpAddress nextHopIp = Ip4Address.valueOf("192.168.10.1"); | ||
123 | - | ||
124 | - RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp); | ||
125 | - | ||
126 | - // Host service will reply with no hosts when asked | ||
127 | - reset(hostService); | ||
128 | - expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn( | ||
129 | - Collections.emptySet()).anyTimes(); | ||
130 | - hostService.startMonitoringIp(IpAddress.valueOf("192.168.10.1")); | ||
131 | - replay(hostService); | ||
132 | - | ||
133 | - reset(routingConfigurationService); | ||
134 | - expect(routingConfigurationService.isIpPrefixLocal( | ||
135 | - anyObject(IpPrefix.class))).andReturn(false); | ||
136 | - replay(routingConfigurationService); | ||
137 | - | ||
138 | - // Initially when we add the route, no FIB update will be sent | ||
139 | - replay(fibListener); | ||
140 | - | ||
141 | - router.processRouteUpdates(Collections.singletonList( | ||
142 | - new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry))); | ||
143 | - | ||
144 | - verify(fibListener); | ||
145 | - | ||
146 | - | ||
147 | - // Now when we send the event, we expect the FIB update to be sent | ||
148 | - reset(fibListener); | ||
149 | - FibEntry fibEntry = new FibEntry(prefix, nextHopIp, | ||
150 | - MacAddress.valueOf("00:00:00:00:00:01")); | ||
151 | - | ||
152 | - fibListener.update(Collections.singletonList(new FibUpdate( | ||
153 | - FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList()); | ||
154 | - replay(fibListener); | ||
155 | - | ||
156 | - Host host = new DefaultHost(ProviderId.NONE, HostId.NONE, | ||
157 | - MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE, | ||
158 | - new HostLocation( | ||
159 | - SW1_ETH1.deviceId(), | ||
160 | - SW1_ETH1.port(), 1), | ||
161 | - Sets.newHashSet(IpAddress.valueOf("192.168.10.1"))); | ||
162 | - | ||
163 | - // Send in the host event | ||
164 | - internalHostListener.event( | ||
165 | - new HostEvent(HostEvent.Type.HOST_ADDED, host)); | ||
166 | - | ||
167 | - verify(fibListener); | ||
168 | - } | ||
169 | - | ||
170 | - /** | ||
171 | - * Tests updating a route entry with asynchronous HostService replies. | ||
172 | - */ | ||
173 | - @Test | ||
174 | - public void testRouteUpdate() { | ||
175 | - // Add a route | ||
176 | - testRouteAdd(); | ||
177 | - | ||
178 | - // Construct a route entry | ||
179 | - IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24"); | ||
180 | - IpAddress nextHopIp = Ip4Address.valueOf("192.168.20.1"); | ||
181 | - | ||
182 | - RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp); | ||
183 | - | ||
184 | - // Host service will reply with no hosts when asked | ||
185 | - reset(hostService); | ||
186 | - expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn( | ||
187 | - Collections.emptySet()).anyTimes(); | ||
188 | - hostService.startMonitoringIp(IpAddress.valueOf("192.168.20.1")); | ||
189 | - replay(hostService); | ||
190 | - | ||
191 | - reset(routingConfigurationService); | ||
192 | - expect(routingConfigurationService.isIpPrefixLocal( | ||
193 | - anyObject(IpPrefix.class))).andReturn(false); | ||
194 | - replay(routingConfigurationService); | ||
195 | - | ||
196 | - // Initially when we add the route, the DELETE FIB update will be sent | ||
197 | - // but the UPDATE FIB update will come later when the MAC is resolved | ||
198 | - reset(fibListener); | ||
199 | - | ||
200 | - fibListener.update(Collections.emptyList(), Collections.singletonList(new FibUpdate( | ||
201 | - FibUpdate.Type.DELETE, new FibEntry(prefix, null, null)))); | ||
202 | - replay(fibListener); | ||
203 | - | ||
204 | - router.processRouteUpdates(Collections.singletonList( | ||
205 | - new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry))); | ||
206 | - | ||
207 | - verify(fibListener); | ||
208 | - | ||
209 | - | ||
210 | - // Now when we send the event, we expect the FIB update to be sent | ||
211 | - reset(fibListener); | ||
212 | - FibEntry fibEntry = new FibEntry(prefix, nextHopIp, | ||
213 | - MacAddress.valueOf("00:00:00:00:00:02")); | ||
214 | - | ||
215 | - fibListener.update(Collections.singletonList(new FibUpdate( | ||
216 | - FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList()); | ||
217 | - replay(fibListener); | ||
218 | - | ||
219 | - Host host = new DefaultHost(ProviderId.NONE, HostId.NONE, | ||
220 | - MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE, | ||
221 | - new HostLocation( | ||
222 | - SW1_ETH1.deviceId(), | ||
223 | - SW1_ETH1.port(), 1), | ||
224 | - Sets.newHashSet(IpAddress.valueOf("192.168.20.1"))); | ||
225 | - | ||
226 | - // Send in the host event | ||
227 | - internalHostListener.event( | ||
228 | - new HostEvent(HostEvent.Type.HOST_ADDED, host)); | ||
229 | - | ||
230 | - verify(fibListener); | ||
231 | - } | ||
232 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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 | -package org.onosproject.routing.impl; | ||
17 | - | ||
18 | -import com.google.common.collect.Sets; | ||
19 | - | ||
20 | -import org.junit.After; | ||
21 | -import org.junit.Before; | ||
22 | -import org.junit.Test; | ||
23 | -import org.onlab.packet.Ip4Address; | ||
24 | -import org.onlab.packet.Ip4Prefix; | ||
25 | -import org.onlab.packet.Ip6Address; | ||
26 | -import org.onlab.packet.Ip6Prefix; | ||
27 | -import org.onlab.packet.IpAddress; | ||
28 | -import org.onlab.packet.IpPrefix; | ||
29 | -import org.onlab.packet.MacAddress; | ||
30 | -import org.onlab.packet.VlanId; | ||
31 | -import org.onosproject.core.CoreService; | ||
32 | -import org.onosproject.net.ConnectPoint; | ||
33 | -import org.onosproject.net.DefaultHost; | ||
34 | -import org.onosproject.net.DeviceId; | ||
35 | -import org.onosproject.net.Host; | ||
36 | -import org.onosproject.net.HostId; | ||
37 | -import org.onosproject.net.HostLocation; | ||
38 | -import org.onosproject.net.PortNumber; | ||
39 | -import org.onosproject.net.host.HostListener; | ||
40 | -import org.onosproject.net.host.HostService; | ||
41 | -import org.onosproject.net.provider.ProviderId; | ||
42 | -import org.onosproject.routing.RouteSourceService; | ||
43 | -import org.onosproject.routing.FibEntry; | ||
44 | -import org.onosproject.routing.FibListener; | ||
45 | -import org.onosproject.routing.FibUpdate; | ||
46 | -import org.onosproject.routing.RouteEntry; | ||
47 | -import org.onosproject.routing.RouteListener; | ||
48 | -import org.onosproject.routing.RouteUpdate; | ||
49 | -import org.onosproject.routing.config.RoutingConfigurationService; | ||
50 | - | ||
51 | -import java.util.Collections; | ||
52 | - | ||
53 | -import static org.easymock.EasyMock.*; | ||
54 | -import static org.junit.Assert.assertEquals; | ||
55 | -import static org.junit.Assert.assertTrue; | ||
56 | - | ||
57 | -/** | ||
58 | - * This class tests adding a route, updating a route, deleting a route, | ||
59 | - * and adding a route whose next hop is the local BGP speaker. | ||
60 | - * <p/> | ||
61 | - * The HostService answers requests synchronously. | ||
62 | - */ | ||
63 | -public class RouterTest { | ||
64 | - | ||
65 | - private HostService hostService; | ||
66 | - private RoutingConfigurationService routingConfigurationService; | ||
67 | - | ||
68 | - private FibListener fibListener; | ||
69 | - | ||
70 | - private static final ConnectPoint SW1_ETH1 = new ConnectPoint( | ||
71 | - DeviceId.deviceId("of:0000000000000001"), | ||
72 | - PortNumber.portNumber(1)); | ||
73 | - | ||
74 | - private static final ConnectPoint SW2_ETH1 = new ConnectPoint( | ||
75 | - DeviceId.deviceId("of:0000000000000002"), | ||
76 | - PortNumber.portNumber(1)); | ||
77 | - | ||
78 | - private static final ConnectPoint SW3_ETH1 = new ConnectPoint( | ||
79 | - DeviceId.deviceId("of:0000000000000003"), | ||
80 | - PortNumber.portNumber(1)); | ||
81 | - | ||
82 | - private static final ConnectPoint SW4_ETH1 = new ConnectPoint( | ||
83 | - DeviceId.deviceId("of:0000000000000004"), | ||
84 | - PortNumber.portNumber(1)); | ||
85 | - | ||
86 | - private static final ConnectPoint SW5_ETH1 = new ConnectPoint( | ||
87 | - DeviceId.deviceId("of:0000000000000005"), | ||
88 | - PortNumber.portNumber(1)); | ||
89 | - | ||
90 | - private static final ConnectPoint SW6_ETH1 = new ConnectPoint( | ||
91 | - DeviceId.deviceId("of:0000000000000006"), | ||
92 | - PortNumber.portNumber(1)); | ||
93 | - private DefaultRouter router; | ||
94 | - | ||
95 | - @Before | ||
96 | - public void setUp() throws Exception { | ||
97 | - setUpHostService(); | ||
98 | - routingConfigurationService = | ||
99 | - createMock(RoutingConfigurationService.class); | ||
100 | - | ||
101 | - RouteSourceService routeSourceService = createMock(RouteSourceService.class); | ||
102 | - routeSourceService.start(anyObject(RouteListener.class)); | ||
103 | - routeSourceService.stop(); | ||
104 | - replay(routeSourceService); | ||
105 | - | ||
106 | - fibListener = createMock(FibListener.class); | ||
107 | - | ||
108 | - router = new DefaultRouter(); | ||
109 | - router.coreService = createNiceMock(CoreService.class); | ||
110 | - router.hostService = hostService; | ||
111 | - router.routingConfigurationService = routingConfigurationService; | ||
112 | - router.routeSourceService = routeSourceService; | ||
113 | - router.activate(); | ||
114 | - | ||
115 | - router.addFibListener(fibListener); | ||
116 | - router.start(); | ||
117 | - } | ||
118 | - | ||
119 | - @After | ||
120 | - public void tearDown() { | ||
121 | - router.stop(); | ||
122 | - } | ||
123 | - | ||
124 | - /** | ||
125 | - * Sets up the host service with details of some hosts. | ||
126 | - */ | ||
127 | - private void setUpHostService() { | ||
128 | - hostService = createMock(HostService.class); | ||
129 | - | ||
130 | - hostService.addListener(anyObject(HostListener.class)); | ||
131 | - expectLastCall().anyTimes(); | ||
132 | - | ||
133 | - IpAddress host1Address = IpAddress.valueOf("192.168.10.1"); | ||
134 | - Host host1 = new DefaultHost(ProviderId.NONE, HostId.NONE, | ||
135 | - MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE, | ||
136 | - new HostLocation(SW1_ETH1, 1), | ||
137 | - Sets.newHashSet(host1Address)); | ||
138 | - | ||
139 | - expect(hostService.getHostsByIp(host1Address)) | ||
140 | - .andReturn(Sets.newHashSet(host1)).anyTimes(); | ||
141 | - hostService.startMonitoringIp(host1Address); | ||
142 | - expectLastCall().anyTimes(); | ||
143 | - | ||
144 | - IpAddress host2Address = IpAddress.valueOf("192.168.20.1"); | ||
145 | - Host host2 = new DefaultHost(ProviderId.NONE, HostId.NONE, | ||
146 | - MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE, | ||
147 | - new HostLocation(SW2_ETH1, 1), | ||
148 | - Sets.newHashSet(host2Address)); | ||
149 | - | ||
150 | - expect(hostService.getHostsByIp(host2Address)) | ||
151 | - .andReturn(Sets.newHashSet(host2)).anyTimes(); | ||
152 | - hostService.startMonitoringIp(host2Address); | ||
153 | - expectLastCall().anyTimes(); | ||
154 | - | ||
155 | - // Next hop on a VLAN | ||
156 | - IpAddress host3Address = IpAddress.valueOf("192.168.40.1"); | ||
157 | - Host host3 = new DefaultHost(ProviderId.NONE, HostId.NONE, | ||
158 | - MacAddress.valueOf("00:00:00:00:00:03"), VlanId.vlanId((short) 1), | ||
159 | - new HostLocation(SW3_ETH1, 1), | ||
160 | - Sets.newHashSet(host3Address)); | ||
161 | - | ||
162 | - expect(hostService.getHostsByIp(host3Address)) | ||
163 | - .andReturn(Sets.newHashSet(host3)).anyTimes(); | ||
164 | - hostService.startMonitoringIp(host3Address); | ||
165 | - expectLastCall().anyTimes(); | ||
166 | - | ||
167 | - IpAddress host4Address = IpAddress.valueOf("1000::1"); | ||
168 | - Host host4 = new DefaultHost(ProviderId.NONE, HostId.NONE, | ||
169 | - MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE, | ||
170 | - new HostLocation(SW4_ETH1, 1), | ||
171 | - Sets.newHashSet(host4Address)); | ||
172 | - | ||
173 | - expect(hostService.getHostsByIp(host4Address)) | ||
174 | - .andReturn(Sets.newHashSet(host4)).anyTimes(); | ||
175 | - hostService.startMonitoringIp(host4Address); | ||
176 | - expectLastCall().anyTimes(); | ||
177 | - | ||
178 | - IpAddress host5Address = IpAddress.valueOf("2000::1"); | ||
179 | - Host host5 = new DefaultHost(ProviderId.NONE, HostId.NONE, | ||
180 | - MacAddress.valueOf("00:00:00:00:00:05"), VlanId.NONE, | ||
181 | - new HostLocation(SW5_ETH1, 1), | ||
182 | - Sets.newHashSet(host5Address)); | ||
183 | - | ||
184 | - expect(hostService.getHostsByIp(host5Address)) | ||
185 | - .andReturn(Sets.newHashSet(host5)).anyTimes(); | ||
186 | - hostService.startMonitoringIp(host5Address); | ||
187 | - expectLastCall().anyTimes(); | ||
188 | - | ||
189 | - // Next hop on a VLAN | ||
190 | - IpAddress host6Address = IpAddress.valueOf("3000::1"); | ||
191 | - Host host6 = new DefaultHost(ProviderId.NONE, HostId.NONE, | ||
192 | - MacAddress.valueOf("00:00:00:00:00:06"), VlanId.vlanId((short) 1), | ||
193 | - new HostLocation(SW6_ETH1, 1), | ||
194 | - Sets.newHashSet(host6Address)); | ||
195 | - | ||
196 | - expect(hostService.getHostsByIp(host6Address)) | ||
197 | - .andReturn(Sets.newHashSet(host6)).anyTimes(); | ||
198 | - hostService.startMonitoringIp(host6Address); | ||
199 | - expectLastCall().anyTimes(); | ||
200 | - | ||
201 | - | ||
202 | - // Called during shutdown | ||
203 | - hostService.removeListener(anyObject(HostListener.class)); | ||
204 | - | ||
205 | - replay(hostService); | ||
206 | - } | ||
207 | - | ||
208 | - /** | ||
209 | - * Tests adding a IPv4 route entry. | ||
210 | - */ | ||
211 | - @Test | ||
212 | - public void testIpv4RouteAdd() { | ||
213 | - // Construct a route entry | ||
214 | - IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24"); | ||
215 | - IpAddress nextHopIp = Ip4Address.valueOf("192.168.10.1"); | ||
216 | - | ||
217 | - RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp); | ||
218 | - | ||
219 | - // Expected FIB entry | ||
220 | - FibEntry fibEntry = new FibEntry(prefix, nextHopIp, | ||
221 | - MacAddress.valueOf("00:00:00:00:00:01")); | ||
222 | - | ||
223 | - fibListener.update(Collections.singletonList(new FibUpdate( | ||
224 | - FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList()); | ||
225 | - | ||
226 | - replay(fibListener); | ||
227 | - | ||
228 | - router.processRouteUpdates(Collections.singletonList( | ||
229 | - new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry))); | ||
230 | - | ||
231 | - verify(fibListener); | ||
232 | - } | ||
233 | - | ||
234 | - | ||
235 | - /** | ||
236 | - * Tests adding a IPv6 route entry. | ||
237 | - */ | ||
238 | - @Test | ||
239 | - public void testIpv6RouteAdd() { | ||
240 | - // Construct a route entry | ||
241 | - IpPrefix prefix = Ip6Prefix.valueOf("4000::/64"); | ||
242 | - IpAddress nextHopIp = Ip6Address.valueOf("1000::1"); | ||
243 | - | ||
244 | - RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp); | ||
245 | - | ||
246 | - // Expected FIB entry | ||
247 | - FibEntry fibEntry = new FibEntry(prefix, nextHopIp, | ||
248 | - MacAddress.valueOf("00:00:00:00:00:04")); | ||
249 | - | ||
250 | - fibListener.update(Collections.singletonList(new FibUpdate( | ||
251 | - FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList()); | ||
252 | - | ||
253 | - replay(fibListener); | ||
254 | - | ||
255 | - router.processRouteUpdates(Collections.singletonList( | ||
256 | - new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry))); | ||
257 | - | ||
258 | - verify(fibListener); | ||
259 | - } | ||
260 | - | ||
261 | - | ||
262 | - /** | ||
263 | - * Tests updating a IPv4 route entry. | ||
264 | - */ | ||
265 | - @Test | ||
266 | - public void testRouteUpdate() { | ||
267 | - // Firstly add a route | ||
268 | - testIpv4RouteAdd(); | ||
269 | - | ||
270 | - // Route entry with updated next hop for the original prefix | ||
271 | - RouteEntry routeEntryUpdate = new RouteEntry( | ||
272 | - Ip4Prefix.valueOf("1.1.1.0/24"), | ||
273 | - Ip4Address.valueOf("192.168.20.1")); | ||
274 | - | ||
275 | - // The old FIB entry will be withdrawn | ||
276 | - FibEntry withdrawFibEntry = new FibEntry( | ||
277 | - Ip4Prefix.valueOf("1.1.1.0/24"), null, null); | ||
278 | - | ||
279 | - // A new FIB entry will be added | ||
280 | - FibEntry updateFibEntry = new FibEntry( | ||
281 | - Ip4Prefix.valueOf("1.1.1.0/24"), | ||
282 | - Ip4Address.valueOf("192.168.20.1"), | ||
283 | - MacAddress.valueOf("00:00:00:00:00:02")); | ||
284 | - | ||
285 | - reset(fibListener); | ||
286 | - fibListener.update(Collections.singletonList(new FibUpdate( | ||
287 | - FibUpdate.Type.UPDATE, updateFibEntry)), | ||
288 | - Collections.singletonList(new FibUpdate( | ||
289 | - FibUpdate.Type.DELETE, withdrawFibEntry))); | ||
290 | - replay(fibListener); | ||
291 | - | ||
292 | - reset(routingConfigurationService); | ||
293 | - expect(routingConfigurationService.isIpPrefixLocal( | ||
294 | - anyObject(IpPrefix.class))).andReturn(false); | ||
295 | - replay(routingConfigurationService); | ||
296 | - | ||
297 | - router.processRouteUpdates(Collections.singletonList(new RouteUpdate( | ||
298 | - RouteUpdate.Type.UPDATE, routeEntryUpdate))); | ||
299 | - | ||
300 | - verify(fibListener); | ||
301 | - } | ||
302 | - | ||
303 | - /** | ||
304 | - * Tests updating a IPv6 route entry. | ||
305 | - */ | ||
306 | - @Test | ||
307 | - public void testIpv6RouteUpdate() { | ||
308 | - // Firstly add a route | ||
309 | - testIpv6RouteAdd(); | ||
310 | - | ||
311 | - // Route entry with updated next hop for the original prefix | ||
312 | - RouteEntry routeEntryUpdate = new RouteEntry( | ||
313 | - Ip6Prefix.valueOf("4000::/64"), | ||
314 | - Ip6Address.valueOf("2000::1")); | ||
315 | - | ||
316 | - // The old FIB entry will be withdrawn | ||
317 | - FibEntry withdrawFibEntry = new FibEntry( | ||
318 | - Ip6Prefix.valueOf("4000::/64"), null, null); | ||
319 | - | ||
320 | - // A new FIB entry will be added | ||
321 | - FibEntry updateFibEntry = new FibEntry( | ||
322 | - Ip6Prefix.valueOf("4000::/64"), | ||
323 | - Ip6Address.valueOf("2000::1"), | ||
324 | - MacAddress.valueOf("00:00:00:00:00:05")); | ||
325 | - | ||
326 | - reset(fibListener); | ||
327 | - fibListener.update(Collections.singletonList(new FibUpdate( | ||
328 | - FibUpdate.Type.UPDATE, updateFibEntry)), | ||
329 | - Collections.singletonList(new FibUpdate( | ||
330 | - FibUpdate.Type.DELETE, withdrawFibEntry))); | ||
331 | - replay(fibListener); | ||
332 | - | ||
333 | - reset(routingConfigurationService); | ||
334 | - expect(routingConfigurationService.isIpPrefixLocal( | ||
335 | - anyObject(IpPrefix.class))).andReturn(false); | ||
336 | - replay(routingConfigurationService); | ||
337 | - | ||
338 | - router.processRouteUpdates(Collections.singletonList(new RouteUpdate( | ||
339 | - RouteUpdate.Type.UPDATE, routeEntryUpdate))); | ||
340 | - | ||
341 | - verify(fibListener); | ||
342 | - } | ||
343 | - | ||
344 | - /** | ||
345 | - * Tests deleting a IPv4 route entry. | ||
346 | - */ | ||
347 | - @Test | ||
348 | - public void testIpv4RouteDelete() { | ||
349 | - // Firstly add a route | ||
350 | - testIpv4RouteAdd(); | ||
351 | - | ||
352 | - RouteEntry deleteRouteEntry = new RouteEntry( | ||
353 | - Ip4Prefix.valueOf("1.1.1.0/24"), | ||
354 | - Ip4Address.valueOf("192.168.10.1")); | ||
355 | - | ||
356 | - FibEntry deleteFibEntry = new FibEntry( | ||
357 | - Ip4Prefix.valueOf("1.1.1.0/24"), null, null); | ||
358 | - | ||
359 | - reset(fibListener); | ||
360 | - fibListener.update(Collections.emptyList(), Collections.singletonList( | ||
361 | - new FibUpdate(FibUpdate.Type.DELETE, deleteFibEntry))); | ||
362 | - | ||
363 | - replay(fibListener); | ||
364 | - | ||
365 | - router.processRouteUpdates(Collections.singletonList( | ||
366 | - new RouteUpdate(RouteUpdate.Type.DELETE, deleteRouteEntry))); | ||
367 | - | ||
368 | - verify(fibListener); | ||
369 | - } | ||
370 | - | ||
371 | - /** | ||
372 | - * Tests deleting a IPv6 route entry. | ||
373 | - */ | ||
374 | - @Test | ||
375 | - public void testIpv6RouteDelete() { | ||
376 | - // Firstly add a route | ||
377 | - testIpv6RouteAdd(); | ||
378 | - | ||
379 | - RouteEntry deleteRouteEntry = new RouteEntry( | ||
380 | - Ip6Prefix.valueOf("4000::/64"), | ||
381 | - Ip6Address.valueOf("1000::1")); | ||
382 | - | ||
383 | - FibEntry deleteFibEntry = new FibEntry( | ||
384 | - Ip6Prefix.valueOf("4000::/64"), null, null); | ||
385 | - | ||
386 | - reset(fibListener); | ||
387 | - fibListener.update(Collections.emptyList(), Collections.singletonList( | ||
388 | - new FibUpdate(FibUpdate.Type.DELETE, deleteFibEntry))); | ||
389 | - | ||
390 | - replay(fibListener); | ||
391 | - | ||
392 | - router.processRouteUpdates(Collections.singletonList( | ||
393 | - new RouteUpdate(RouteUpdate.Type.DELETE, deleteRouteEntry))); | ||
394 | - | ||
395 | - verify(fibListener); | ||
396 | - } | ||
397 | - | ||
398 | - /** | ||
399 | - * Tests adding a IPv4 route whose next hop is the local BGP speaker. | ||
400 | - */ | ||
401 | - @Test | ||
402 | - public void testIpv4LocalRouteAdd() { | ||
403 | - // Construct a route entry, the next hop is the local BGP speaker | ||
404 | - RouteEntry routeEntry = new RouteEntry( | ||
405 | - Ip4Prefix.valueOf("1.1.1.0/24"), | ||
406 | - Ip4Address.valueOf("0.0.0.0")); | ||
407 | - | ||
408 | - // No methods on the FIB listener should be called | ||
409 | - replay(fibListener); | ||
410 | - | ||
411 | - reset(routingConfigurationService); | ||
412 | - expect(routingConfigurationService.isIpPrefixLocal( | ||
413 | - anyObject(IpPrefix.class))).andReturn(true); | ||
414 | - replay(routingConfigurationService); | ||
415 | - | ||
416 | - // Call the processRouteUpdates() method in Router class | ||
417 | - RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, | ||
418 | - routeEntry); | ||
419 | - router.processRouteUpdates(Collections.singletonList(routeUpdate)); | ||
420 | - | ||
421 | - // Verify | ||
422 | - assertEquals(1, router.getRoutes4().size()); | ||
423 | - assertTrue(router.getRoutes4().contains(routeEntry)); | ||
424 | - verify(fibListener); | ||
425 | - } | ||
426 | - | ||
427 | - /** | ||
428 | - * Tests adding a IPv6 route whose next hop is the local BGP speaker. | ||
429 | - */ | ||
430 | - @Test | ||
431 | - public void testIpv6LocalRouteAdd() { | ||
432 | - // Construct a route entry, the next hop is the local BGP speaker | ||
433 | - RouteEntry routeEntry = new RouteEntry( | ||
434 | - Ip6Prefix.valueOf("4000::/64"), | ||
435 | - Ip6Address.valueOf("::")); | ||
436 | - | ||
437 | - // No methods on the FIB listener should be called | ||
438 | - replay(fibListener); | ||
439 | - | ||
440 | - reset(routingConfigurationService); | ||
441 | - expect(routingConfigurationService.isIpPrefixLocal( | ||
442 | - anyObject(IpPrefix.class))).andReturn(true); | ||
443 | - replay(routingConfigurationService); | ||
444 | - | ||
445 | - // Call the processRouteUpdates() method in Router class | ||
446 | - RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, | ||
447 | - routeEntry); | ||
448 | - router.processRouteUpdates(Collections.singletonList(routeUpdate)); | ||
449 | - | ||
450 | - // Verify | ||
451 | - assertEquals(1, router.getRoutes6().size()); | ||
452 | - assertTrue(router.getRoutes6().contains(routeEntry)); | ||
453 | - verify(fibListener); | ||
454 | - } | ||
455 | -} |
-
Please register or login to post a comment