Added IPv6 routing support to SDN-IP, and integrated it with BGP:
* The routing entries as received from BGP can be either IPv4 or IPv6 * The CLI prints the IPv4 and IPv6 routes * The BGP peering is still over IPv4, so configuration-wise the IPv6 routes from the eBGP peers have to be configured to use the IPv4 peering. * The integration/testing with the IPv6 Network Discovery Protocol is not done yet. * The integration/testing with IPv6 intents is not done yet. Also: * Moved nested class BgpSessionManager.BgpRouteSelector out of the BgpSessionManager class. * Code cleanup. Change-Id: I9f2dbe4395a72d353bbf215a8a14b01b53c3423f
Showing
17 changed files
with
739 additions
and
406 deletions
... | @@ -29,7 +29,7 @@ import java.util.concurrent.Executors; | ... | @@ -29,7 +29,7 @@ import java.util.concurrent.Executors; |
29 | import java.util.concurrent.Semaphore; | 29 | import java.util.concurrent.Semaphore; |
30 | 30 | ||
31 | import org.apache.commons.lang3.tuple.Pair; | 31 | import org.apache.commons.lang3.tuple.Pair; |
32 | -import org.onlab.packet.Ip4Prefix; | 32 | +import org.onlab.packet.IpPrefix; |
33 | import org.onosproject.core.ApplicationId; | 33 | import org.onosproject.core.ApplicationId; |
34 | import org.onosproject.net.flow.criteria.Criteria.IPCriterion; | 34 | import org.onosproject.net.flow.criteria.Criteria.IPCriterion; |
35 | import org.onosproject.net.flow.criteria.Criterion; | 35 | import org.onosproject.net.flow.criteria.Criterion; |
... | @@ -55,7 +55,7 @@ public class IntentSynchronizer { | ... | @@ -55,7 +55,7 @@ public class IntentSynchronizer { |
55 | private final ApplicationId appId; | 55 | private final ApplicationId appId; |
56 | private final IntentService intentService; | 56 | private final IntentService intentService; |
57 | private final Map<IntentKey, PointToPointIntent> peerIntents; | 57 | private final Map<IntentKey, PointToPointIntent> peerIntents; |
58 | - private final Map<Ip4Prefix, MultiPointToSinglePointIntent> routeIntents; | 58 | + private final Map<IpPrefix, MultiPointToSinglePointIntent> routeIntents; |
59 | 59 | ||
60 | // | 60 | // |
61 | // State to deal with SDN-IP Leader election and pushing Intents | 61 | // State to deal with SDN-IP Leader election and pushing Intents |
... | @@ -182,7 +182,7 @@ public class IntentSynchronizer { | ... | @@ -182,7 +182,7 @@ public class IntentSynchronizer { |
182 | public Collection<MultiPointToSinglePointIntent> getRouteIntents() { | 182 | public Collection<MultiPointToSinglePointIntent> getRouteIntents() { |
183 | List<MultiPointToSinglePointIntent> result = new LinkedList<>(); | 183 | List<MultiPointToSinglePointIntent> result = new LinkedList<>(); |
184 | 184 | ||
185 | - for (Map.Entry<Ip4Prefix, MultiPointToSinglePointIntent> entry : | 185 | + for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry : |
186 | routeIntents.entrySet()) { | 186 | routeIntents.entrySet()) { |
187 | result.add(entry.getValue()); | 187 | result.add(entry.getValue()); |
188 | } | 188 | } |
... | @@ -247,12 +247,12 @@ public class IntentSynchronizer { | ... | @@ -247,12 +247,12 @@ public class IntentSynchronizer { |
247 | * Updates multi-point-to-single-point route intents. | 247 | * Updates multi-point-to-single-point route intents. |
248 | * | 248 | * |
249 | * @param submitIntents the intents to submit | 249 | * @param submitIntents the intents to submit |
250 | - * @param withdrawPrefixes the IPv4 matching prefixes for the intents | 250 | + * @param withdrawPrefixes the IPv4 or IPv6 matching prefixes for the |
251 | - * to withdraw | 251 | + * intents to withdraw |
252 | */ | 252 | */ |
253 | void updateRouteIntents( | 253 | void updateRouteIntents( |
254 | - Collection<Pair<Ip4Prefix, MultiPointToSinglePointIntent>> submitIntents, | 254 | + Collection<Pair<IpPrefix, MultiPointToSinglePointIntent>> submitIntents, |
255 | - Collection<Ip4Prefix> withdrawPrefixes) { | 255 | + Collection<IpPrefix> withdrawPrefixes) { |
256 | 256 | ||
257 | // | 257 | // |
258 | // NOTE: Semantically, we MUST withdraw existing intents before | 258 | // NOTE: Semantically, we MUST withdraw existing intents before |
... | @@ -269,7 +269,7 @@ public class IntentSynchronizer { | ... | @@ -269,7 +269,7 @@ public class IntentSynchronizer { |
269 | // | 269 | // |
270 | IntentOperations.Builder withdrawBuilder = | 270 | IntentOperations.Builder withdrawBuilder = |
271 | IntentOperations.builder(appId); | 271 | IntentOperations.builder(appId); |
272 | - for (Ip4Prefix prefix : withdrawPrefixes) { | 272 | + for (IpPrefix prefix : withdrawPrefixes) { |
273 | intent = routeIntents.remove(prefix); | 273 | intent = routeIntents.remove(prefix); |
274 | if (intent == null) { | 274 | if (intent == null) { |
275 | log.trace("SDN-IP No intent in routeIntents to delete " + | 275 | log.trace("SDN-IP No intent in routeIntents to delete " + |
... | @@ -287,9 +287,9 @@ public class IntentSynchronizer { | ... | @@ -287,9 +287,9 @@ public class IntentSynchronizer { |
287 | // | 287 | // |
288 | IntentOperations.Builder submitBuilder = | 288 | IntentOperations.Builder submitBuilder = |
289 | IntentOperations.builder(appId); | 289 | IntentOperations.builder(appId); |
290 | - for (Pair<Ip4Prefix, MultiPointToSinglePointIntent> pair : | 290 | + for (Pair<IpPrefix, MultiPointToSinglePointIntent> pair : |
291 | submitIntents) { | 291 | submitIntents) { |
292 | - Ip4Prefix prefix = pair.getLeft(); | 292 | + IpPrefix prefix = pair.getLeft(); |
293 | intent = pair.getRight(); | 293 | intent = pair.getRight(); |
294 | MultiPointToSinglePointIntent oldIntent = | 294 | MultiPointToSinglePointIntent oldIntent = |
295 | routeIntents.put(prefix, intent); | 295 | routeIntents.put(prefix, intent); |
... | @@ -382,18 +382,23 @@ public class IntentSynchronizer { | ... | @@ -382,18 +382,23 @@ public class IntentSynchronizer { |
382 | // Find the IP prefix | 382 | // Find the IP prefix |
383 | Criterion c = | 383 | Criterion c = |
384 | mp2pIntent.selector().getCriterion(Criterion.Type.IPV4_DST); | 384 | mp2pIntent.selector().getCriterion(Criterion.Type.IPV4_DST); |
385 | + if (c == null) { | ||
386 | + // Try IPv6 | ||
387 | + c = | ||
388 | + mp2pIntent.selector().getCriterion(Criterion.Type.IPV6_DST); | ||
389 | + } | ||
385 | if (c != null && c instanceof IPCriterion) { | 390 | if (c != null && c instanceof IPCriterion) { |
386 | IPCriterion ipCriterion = (IPCriterion) c; | 391 | IPCriterion ipCriterion = (IPCriterion) c; |
387 | - Ip4Prefix ip4Prefix = ipCriterion.ip().getIp4Prefix(); | 392 | + IpPrefix ipPrefix = ipCriterion.ip(); |
388 | - if (ip4Prefix == null) { | 393 | + if (ipPrefix == null) { |
389 | continue; | 394 | continue; |
390 | } | 395 | } |
391 | log.trace("SDN-IP Intent Synchronizer: updating " + | 396 | log.trace("SDN-IP Intent Synchronizer: updating " + |
392 | "in-memory Route Intent for prefix {}", | 397 | "in-memory Route Intent for prefix {}", |
393 | - ip4Prefix); | 398 | + ipPrefix); |
394 | - routeIntents.put(ip4Prefix, mp2pIntent); | 399 | + routeIntents.put(ipPrefix, mp2pIntent); |
395 | } else { | 400 | } else { |
396 | - log.warn("SDN-IP no IPV4_DST criterion found for Intent {}", | 401 | + log.warn("SDN-IP no IPV4_DST or IPV6_DST criterion found for Intent {}", |
397 | mp2pIntent.id()); | 402 | mp2pIntent.id()); |
398 | } | 403 | } |
399 | continue; | 404 | continue; | ... | ... |
... | @@ -19,8 +19,8 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -19,8 +19,8 @@ import static com.google.common.base.Preconditions.checkNotNull; |
19 | 19 | ||
20 | import java.util.Objects; | 20 | import java.util.Objects; |
21 | 21 | ||
22 | -import org.onlab.packet.Ip4Address; | 22 | +import org.onlab.packet.IpAddress; |
23 | -import org.onlab.packet.Ip4Prefix; | 23 | +import org.onlab.packet.IpPrefix; |
24 | 24 | ||
25 | import com.google.common.base.MoreObjects; | 25 | import com.google.common.base.MoreObjects; |
26 | 26 | ||
... | @@ -28,8 +28,8 @@ import com.google.common.base.MoreObjects; | ... | @@ -28,8 +28,8 @@ import com.google.common.base.MoreObjects; |
28 | * Represents a route entry for an IP prefix. | 28 | * Represents a route entry for an IP prefix. |
29 | */ | 29 | */ |
30 | public class RouteEntry { | 30 | public class RouteEntry { |
31 | - private final Ip4Prefix prefix; // The IP prefix | 31 | + private final IpPrefix prefix; // The IP prefix |
32 | - private final Ip4Address nextHop; // Next-hop IP address | 32 | + private final IpAddress nextHop; // Next-hop IP address |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * Class constructor. | 35 | * Class constructor. |
... | @@ -37,17 +37,26 @@ public class RouteEntry { | ... | @@ -37,17 +37,26 @@ public class RouteEntry { |
37 | * @param prefix the IP prefix of the route | 37 | * @param prefix the IP prefix of the route |
38 | * @param nextHop the next hop IP address for the route | 38 | * @param nextHop the next hop IP address for the route |
39 | */ | 39 | */ |
40 | - public RouteEntry(Ip4Prefix prefix, Ip4Address nextHop) { | 40 | + public RouteEntry(IpPrefix prefix, IpAddress nextHop) { |
41 | this.prefix = checkNotNull(prefix); | 41 | this.prefix = checkNotNull(prefix); |
42 | this.nextHop = checkNotNull(nextHop); | 42 | this.nextHop = checkNotNull(nextHop); |
43 | } | 43 | } |
44 | 44 | ||
45 | /** | 45 | /** |
46 | + * Returns the IP version of the route. | ||
47 | + * | ||
48 | + * @return the IP version of the route | ||
49 | + */ | ||
50 | + public IpAddress.Version version() { | ||
51 | + return nextHop.version(); | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
46 | * Returns the IP prefix of the route. | 55 | * Returns the IP prefix of the route. |
47 | * | 56 | * |
48 | * @return the IP prefix of the route | 57 | * @return the IP prefix of the route |
49 | */ | 58 | */ |
50 | - public Ip4Prefix prefix() { | 59 | + public IpPrefix prefix() { |
51 | return prefix; | 60 | return prefix; |
52 | } | 61 | } |
53 | 62 | ||
... | @@ -56,27 +65,32 @@ public class RouteEntry { | ... | @@ -56,27 +65,32 @@ public class RouteEntry { |
56 | * | 65 | * |
57 | * @return the next hop IP address for the route | 66 | * @return the next hop IP address for the route |
58 | */ | 67 | */ |
59 | - public Ip4Address nextHop() { | 68 | + public IpAddress nextHop() { |
60 | return nextHop; | 69 | return nextHop; |
61 | } | 70 | } |
62 | 71 | ||
63 | /** | 72 | /** |
64 | - * Creates the binary string representation of an IPv4 prefix. | 73 | + * Creates the binary string representation of an IP prefix. |
74 | + * The prefix can be either IPv4 or IPv6. | ||
65 | * The string length is equal to the prefix length. | 75 | * The string length is equal to the prefix length. |
66 | * | 76 | * |
67 | - * @param ip4Prefix the IPv4 prefix to use | 77 | + * @param ipPrefix the IP prefix to use |
68 | * @return the binary string representation | 78 | * @return the binary string representation |
69 | */ | 79 | */ |
70 | - static String createBinaryString(Ip4Prefix ip4Prefix) { | 80 | + static String createBinaryString(IpPrefix ipPrefix) { |
71 | - if (ip4Prefix.prefixLength() == 0) { | 81 | + if (ipPrefix.prefixLength() == 0) { |
72 | return ""; | 82 | return ""; |
73 | } | 83 | } |
74 | 84 | ||
75 | - StringBuilder result = new StringBuilder(ip4Prefix.prefixLength()); | 85 | + byte[] octets = ipPrefix.address().toOctets(); |
76 | - long value = ip4Prefix.address().toInt() & 0xffffffffL; | 86 | + StringBuilder result = new StringBuilder(ipPrefix.prefixLength()); |
77 | - for (int i = 0; i < ip4Prefix.prefixLength(); i++) { | 87 | + for (int i = 0; i < ipPrefix.prefixLength(); i++) { |
78 | - long mask = 1 << (Ip4Prefix.MAX_MASK_LENGTH - 1 - i); | 88 | + int byteOffset = i / Byte.SIZE; |
79 | - result.append(((value & mask) == 0) ? "0" : "1"); | 89 | + int bitOffset = i % Byte.SIZE; |
90 | + int mask = 1 << (Byte.SIZE - 1 - bitOffset); | ||
91 | + byte value = octets[byteOffset]; | ||
92 | + boolean isSet = ((value & mask) != 0); | ||
93 | + result.append(isSet ? "1" : "0"); | ||
80 | } | 94 | } |
81 | return result.toString(); | 95 | return result.toString(); |
82 | } | 96 | } | ... | ... |
... | @@ -30,9 +30,9 @@ import java.util.concurrent.LinkedBlockingQueue; | ... | @@ -30,9 +30,9 @@ import java.util.concurrent.LinkedBlockingQueue; |
30 | 30 | ||
31 | import org.apache.commons.lang3.tuple.Pair; | 31 | import org.apache.commons.lang3.tuple.Pair; |
32 | import org.onlab.packet.Ethernet; | 32 | import org.onlab.packet.Ethernet; |
33 | -import org.onlab.packet.Ip4Address; | ||
34 | -import org.onlab.packet.Ip4Prefix; | ||
35 | import org.onlab.packet.IpAddress; | 33 | import org.onlab.packet.IpAddress; |
34 | +import org.onlab.packet.IpPrefix; | ||
35 | +import org.onlab.packet.Ip4Address; | ||
36 | import org.onlab.packet.MacAddress; | 36 | import org.onlab.packet.MacAddress; |
37 | import org.onosproject.core.ApplicationId; | 37 | import org.onosproject.core.ApplicationId; |
38 | import org.onosproject.net.ConnectPoint; | 38 | import org.onosproject.net.ConnectPoint; |
... | @@ -67,23 +67,20 @@ import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; | ... | @@ -67,23 +67,20 @@ import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; |
67 | public class Router implements RouteListener { | 67 | public class Router implements RouteListener { |
68 | 68 | ||
69 | private static final Logger log = LoggerFactory.getLogger(Router.class); | 69 | private static final Logger log = LoggerFactory.getLogger(Router.class); |
70 | - // For routes announced by local BGP daemon in SDN network, | ||
71 | - // the next hop will be 0.0.0.0. | ||
72 | - private static final Ip4Address LOCAL_NEXT_HOP = | ||
73 | - Ip4Address.valueOf("0.0.0.0"); | ||
74 | 70 | ||
75 | // Store all route updates in a radix tree. | 71 | // Store all route updates in a radix tree. |
76 | // The key in this tree is the binary string of prefix of the route. | 72 | // The key in this tree is the binary string of prefix of the route. |
77 | - private InvertedRadixTree<RouteEntry> ribTable; | 73 | + private InvertedRadixTree<RouteEntry> ribTable4; |
74 | + private InvertedRadixTree<RouteEntry> ribTable6; | ||
78 | 75 | ||
79 | // Stores all incoming route updates in a queue. | 76 | // Stores all incoming route updates in a queue. |
80 | private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue; | 77 | private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue; |
81 | 78 | ||
82 | - // The Ip4Address is the next hop address of each route update. | 79 | + // The IpAddress is the next hop address of each route update. |
83 | - private final SetMultimap<Ip4Address, RouteEntry> routesWaitingOnArp; | 80 | + private final SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp; |
84 | 81 | ||
85 | // The IPv4 address to MAC address mapping | 82 | // The IPv4 address to MAC address mapping |
86 | - private final Map<Ip4Address, MacAddress> ip2Mac; | 83 | + private final Map<IpAddress, MacAddress> ip2Mac; |
87 | 84 | ||
88 | private final ApplicationId appId; | 85 | private final ApplicationId appId; |
89 | private final IntentSynchronizer intentSynchronizer; | 86 | private final IntentSynchronizer intentSynchronizer; |
... | @@ -114,11 +111,13 @@ public class Router implements RouteListener { | ... | @@ -114,11 +111,13 @@ public class Router implements RouteListener { |
114 | 111 | ||
115 | this.hostListener = new InternalHostListener(); | 112 | this.hostListener = new InternalHostListener(); |
116 | 113 | ||
117 | - ribTable = new ConcurrentInvertedRadixTree<>( | 114 | + ribTable4 = new ConcurrentInvertedRadixTree<>( |
115 | + new DefaultByteArrayNodeFactory()); | ||
116 | + ribTable6 = new ConcurrentInvertedRadixTree<>( | ||
118 | new DefaultByteArrayNodeFactory()); | 117 | new DefaultByteArrayNodeFactory()); |
119 | routeUpdatesQueue = new LinkedBlockingQueue<>(); | 118 | routeUpdatesQueue = new LinkedBlockingQueue<>(); |
120 | routesWaitingOnArp = Multimaps.synchronizedSetMultimap( | 119 | routesWaitingOnArp = Multimaps.synchronizedSetMultimap( |
121 | - HashMultimap.<Ip4Address, RouteEntry>create()); | 120 | + HashMultimap.<IpAddress, RouteEntry>create()); |
122 | ip2Mac = new ConcurrentHashMap<>(); | 121 | ip2Mac = new ConcurrentHashMap<>(); |
123 | 122 | ||
124 | bgpUpdatesExecutor = Executors.newSingleThreadExecutor( | 123 | bgpUpdatesExecutor = Executors.newSingleThreadExecutor( |
... | @@ -151,7 +150,9 @@ public class Router implements RouteListener { | ... | @@ -151,7 +150,9 @@ public class Router implements RouteListener { |
151 | 150 | ||
152 | synchronized (this) { | 151 | synchronized (this) { |
153 | // Cleanup all local state | 152 | // Cleanup all local state |
154 | - ribTable = new ConcurrentInvertedRadixTree<>( | 153 | + ribTable4 = new ConcurrentInvertedRadixTree<>( |
154 | + new DefaultByteArrayNodeFactory()); | ||
155 | + ribTable6 = new ConcurrentInvertedRadixTree<>( | ||
155 | new DefaultByteArrayNodeFactory()); | 156 | new DefaultByteArrayNodeFactory()); |
156 | routeUpdatesQueue.clear(); | 157 | routeUpdatesQueue.clear(); |
157 | routesWaitingOnArp.clear(); | 158 | routesWaitingOnArp.clear(); |
... | @@ -195,15 +196,103 @@ public class Router implements RouteListener { | ... | @@ -195,15 +196,103 @@ public class Router implements RouteListener { |
195 | } | 196 | } |
196 | 197 | ||
197 | /** | 198 | /** |
199 | + * Gets all IPv4 routes from the RIB. | ||
200 | + * | ||
201 | + * @return all IPv4 routes from the RIB | ||
202 | + */ | ||
203 | + public Collection<RouteEntry> getRoutes4() { | ||
204 | + Iterator<KeyValuePair<RouteEntry>> it = | ||
205 | + ribTable4.getKeyValuePairsForKeysStartingWith("").iterator(); | ||
206 | + | ||
207 | + List<RouteEntry> routes = new LinkedList<>(); | ||
208 | + | ||
209 | + while (it.hasNext()) { | ||
210 | + KeyValuePair<RouteEntry> entry = it.next(); | ||
211 | + routes.add(entry.getValue()); | ||
212 | + } | ||
213 | + | ||
214 | + return routes; | ||
215 | + } | ||
216 | + | ||
217 | + /** | ||
218 | + * Gets all IPv6 routes from the RIB. | ||
219 | + * | ||
220 | + * @return all IPv6 routes from the RIB | ||
221 | + */ | ||
222 | + public Collection<RouteEntry> getRoutes6() { | ||
223 | + Iterator<KeyValuePair<RouteEntry>> it = | ||
224 | + ribTable6.getKeyValuePairsForKeysStartingWith("").iterator(); | ||
225 | + | ||
226 | + List<RouteEntry> routes = new LinkedList<>(); | ||
227 | + | ||
228 | + while (it.hasNext()) { | ||
229 | + KeyValuePair<RouteEntry> entry = it.next(); | ||
230 | + routes.add(entry.getValue()); | ||
231 | + } | ||
232 | + | ||
233 | + return routes; | ||
234 | + } | ||
235 | + | ||
236 | + /** | ||
237 | + * Finds a route in the RIB for a prefix. The prefix can be either IPv4 or | ||
238 | + * IPv6. | ||
239 | + * | ||
240 | + * @param prefix the prefix to use | ||
241 | + * @return the route if found, otherwise null | ||
242 | + */ | ||
243 | + RouteEntry findRibRoute(IpPrefix prefix) { | ||
244 | + String binaryString = RouteEntry.createBinaryString(prefix); | ||
245 | + if (prefix.version() == Ip4Address.VERSION) { | ||
246 | + // IPv4 | ||
247 | + return ribTable4.getValueForExactKey(binaryString); | ||
248 | + } | ||
249 | + // IPv6 | ||
250 | + return ribTable6.getValueForExactKey(binaryString); | ||
251 | + } | ||
252 | + | ||
253 | + /** | ||
254 | + * Adds a route to the RIB. The route can be either IPv4 or IPv6. | ||
255 | + * | ||
256 | + * @param routeEntry the route entry to use | ||
257 | + */ | ||
258 | + void addRibRoute(RouteEntry routeEntry) { | ||
259 | + if (routeEntry.prefix().version() == Ip4Address.VERSION) { | ||
260 | + // IPv4 | ||
261 | + ribTable4.put(RouteEntry.createBinaryString(routeEntry.prefix()), | ||
262 | + routeEntry); | ||
263 | + } else { | ||
264 | + // IPv6 | ||
265 | + ribTable6.put(RouteEntry.createBinaryString(routeEntry.prefix()), | ||
266 | + routeEntry); | ||
267 | + } | ||
268 | + } | ||
269 | + | ||
270 | + /** | ||
271 | + * Removes a route for a prefix from the RIB. The prefix can be either IPv4 | ||
272 | + * or IPv6. | ||
273 | + * | ||
274 | + * @param prefix the prefix to use | ||
275 | + * @return true if the rotue was found and removed, otherwise false | ||
276 | + */ | ||
277 | + boolean removeRibRoute(IpPrefix prefix) { | ||
278 | + if (prefix.version() == Ip4Address.VERSION) { | ||
279 | + // IPv4 | ||
280 | + return ribTable4.remove(RouteEntry.createBinaryString(prefix)); | ||
281 | + } | ||
282 | + // IPv6 | ||
283 | + return ribTable6.remove(RouteEntry.createBinaryString(prefix)); | ||
284 | + } | ||
285 | + | ||
286 | + /** | ||
198 | * Processes route updates. | 287 | * Processes route updates. |
199 | * | 288 | * |
200 | * @param routeUpdates the route updates to process | 289 | * @param routeUpdates the route updates to process |
201 | */ | 290 | */ |
202 | void processRouteUpdates(Collection<RouteUpdate> routeUpdates) { | 291 | void processRouteUpdates(Collection<RouteUpdate> routeUpdates) { |
203 | synchronized (this) { | 292 | synchronized (this) { |
204 | - Collection<Pair<Ip4Prefix, MultiPointToSinglePointIntent>> | 293 | + Collection<Pair<IpPrefix, MultiPointToSinglePointIntent>> |
205 | submitIntents = new LinkedList<>(); | 294 | submitIntents = new LinkedList<>(); |
206 | - Collection<Ip4Prefix> withdrawPrefixes = new LinkedList<>(); | 295 | + Collection<IpPrefix> withdrawPrefixes = new LinkedList<>(); |
207 | MultiPointToSinglePointIntent intent; | 296 | MultiPointToSinglePointIntent intent; |
208 | 297 | ||
209 | for (RouteUpdate update : routeUpdates) { | 298 | for (RouteUpdate update : routeUpdates) { |
... | @@ -249,28 +338,32 @@ public class Router implements RouteListener { | ... | @@ -249,28 +338,32 @@ public class Router implements RouteListener { |
249 | */ | 338 | */ |
250 | private MultiPointToSinglePointIntent processRouteAdd( | 339 | private MultiPointToSinglePointIntent processRouteAdd( |
251 | RouteEntry routeEntry, | 340 | RouteEntry routeEntry, |
252 | - Collection<Ip4Prefix> withdrawPrefixes) { | 341 | + Collection<IpPrefix> withdrawPrefixes) { |
253 | log.debug("Processing route add: {}", routeEntry); | 342 | log.debug("Processing route add: {}", routeEntry); |
254 | 343 | ||
255 | - Ip4Prefix prefix = routeEntry.prefix(); | 344 | + // Find the old next-hop if we are updating an old route entry |
256 | - Ip4Address nextHop = null; | 345 | + IpAddress oldNextHop = null; |
257 | - RouteEntry foundRouteEntry = | 346 | + RouteEntry oldRouteEntry = findRibRoute(routeEntry.prefix()); |
258 | - ribTable.put(RouteEntry.createBinaryString(prefix), routeEntry); | 347 | + if (oldRouteEntry != null) { |
259 | - if (foundRouteEntry != null) { | 348 | + oldNextHop = oldRouteEntry.nextHop(); |
260 | - nextHop = foundRouteEntry.nextHop(); | ||
261 | } | 349 | } |
262 | 350 | ||
263 | - if (nextHop != null && !nextHop.equals(routeEntry.nextHop())) { | 351 | + // Add the new route to the RIB |
264 | - // There was an existing nexthop for this prefix. This update | 352 | + addRibRoute(routeEntry); |
265 | - // supersedes that, so we need to remove the old flows for this | 353 | + |
266 | - // prefix from the switches | 354 | + if (oldNextHop != null) { |
267 | - withdrawPrefixes.add(routeEntry.prefix()); | 355 | + if (oldNextHop.equals(routeEntry.nextHop())) { |
356 | + return null; // No change | ||
268 | } | 357 | } |
269 | - if (nextHop != null && nextHop.equals(routeEntry.nextHop())) { | 358 | + // |
270 | - return null; | 359 | + // Update an existing nexthop for the prefix. |
360 | + // We need to remove the old flows for this prefix from the | ||
361 | + // switches before the new flows are added. | ||
362 | + // | ||
363 | + withdrawPrefixes.add(routeEntry.prefix()); | ||
271 | } | 364 | } |
272 | 365 | ||
273 | - if (routeEntry.nextHop().equals(LOCAL_NEXT_HOP)) { | 366 | + if (routeEntry.nextHop().isZero()) { |
274 | // Route originated by SDN domain | 367 | // Route originated by SDN domain |
275 | // We don't handle these at the moment | 368 | // We don't handle these at the moment |
276 | log.debug("Own route {} to {}", | 369 | log.debug("Own route {} to {}", |
... | @@ -321,8 +414,8 @@ public class Router implements RouteListener { | ... | @@ -321,8 +414,8 @@ public class Router implements RouteListener { |
321 | * @return the generated intent, or null if no intent should be submitted | 414 | * @return the generated intent, or null if no intent should be submitted |
322 | */ | 415 | */ |
323 | private MultiPointToSinglePointIntent generateRouteIntent( | 416 | private MultiPointToSinglePointIntent generateRouteIntent( |
324 | - Ip4Prefix prefix, | 417 | + IpPrefix prefix, |
325 | - Ip4Address nextHopIpAddress, | 418 | + IpAddress nextHopIpAddress, |
326 | MacAddress nextHopMacAddress) { | 419 | MacAddress nextHopMacAddress) { |
327 | 420 | ||
328 | // Find the attachment point (egress interface) of the next hop | 421 | // Find the attachment point (egress interface) of the next hop |
... | @@ -362,10 +455,18 @@ public class Router implements RouteListener { | ... | @@ -362,10 +455,18 @@ public class Router implements RouteListener { |
362 | } | 455 | } |
363 | 456 | ||
364 | // Match the destination IP prefix at the first hop | 457 | // Match the destination IP prefix at the first hop |
365 | - TrafficSelector selector = DefaultTrafficSelector.builder() | 458 | + TrafficSelector selector; |
459 | + if (prefix.version() == Ip4Address.VERSION) { | ||
460 | + selector = DefaultTrafficSelector.builder() | ||
366 | .matchEthType(Ethernet.TYPE_IPV4) | 461 | .matchEthType(Ethernet.TYPE_IPV4) |
367 | .matchIPDst(prefix) | 462 | .matchIPDst(prefix) |
368 | .build(); | 463 | .build(); |
464 | + } else { | ||
465 | + selector = DefaultTrafficSelector.builder() | ||
466 | + .matchEthType(Ethernet.TYPE_IPV6) | ||
467 | + .matchIPDst(prefix) | ||
468 | + .build(); | ||
469 | + } | ||
369 | 470 | ||
370 | // Rewrite the destination MAC address | 471 | // Rewrite the destination MAC address |
371 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 472 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
... | @@ -389,11 +490,11 @@ public class Router implements RouteListener { | ... | @@ -389,11 +490,11 @@ public class Router implements RouteListener { |
389 | * intents will be withdrawn | 490 | * intents will be withdrawn |
390 | */ | 491 | */ |
391 | private void processRouteDelete(RouteEntry routeEntry, | 492 | private void processRouteDelete(RouteEntry routeEntry, |
392 | - Collection<Ip4Prefix> withdrawPrefixes) { | 493 | + Collection<IpPrefix> withdrawPrefixes) { |
393 | log.debug("Processing route delete: {}", routeEntry); | 494 | log.debug("Processing route delete: {}", routeEntry); |
394 | - Ip4Prefix prefix = routeEntry.prefix(); | 495 | + boolean isRemoved = removeRibRoute(routeEntry.prefix()); |
395 | 496 | ||
396 | - if (ribTable.remove(RouteEntry.createBinaryString(prefix))) { | 497 | + if (isRemoved) { |
397 | // | 498 | // |
398 | // Only withdraw intents if an entry was actually removed from the | 499 | // Only withdraw intents if an entry was actually removed from the |
399 | // tree. If no entry was removed, the <prefix, nexthop> wasn't | 500 | // tree. If no entry was removed, the <prefix, nexthop> wasn't |
... | @@ -415,14 +516,17 @@ public class Router implements RouteListener { | ... | @@ -415,14 +516,17 @@ public class Router implements RouteListener { |
415 | * @param ipAddress the IP address that an event was received for | 516 | * @param ipAddress the IP address that an event was received for |
416 | * @param macAddress the most recently known MAC address for the IP address | 517 | * @param macAddress the most recently known MAC address for the IP address |
417 | */ | 518 | */ |
418 | - private void updateMac(Ip4Address ipAddress, MacAddress macAddress) { | 519 | + private void updateMac(IpAddress ipAddress, MacAddress macAddress) { |
419 | - log.debug("Received updated MAC info: {} => {}", ipAddress, macAddress); | 520 | + log.debug("Received updated MAC info: {} => {}", ipAddress, |
521 | + macAddress); | ||
420 | 522 | ||
421 | - // We synchronize on this to prevent changes to the radix tree | 523 | + // |
524 | + // We synchronize on "this" to prevent changes to the Radix tree | ||
422 | // while we're pushing intents. If the tree changes, the | 525 | // while we're pushing intents. If the tree changes, the |
423 | - // tree and intents could get out of sync. | 526 | + // tree and the intents could get out of sync. |
527 | + // | ||
424 | synchronized (this) { | 528 | synchronized (this) { |
425 | - Collection<Pair<Ip4Prefix, MultiPointToSinglePointIntent>> | 529 | + Collection<Pair<IpPrefix, MultiPointToSinglePointIntent>> |
426 | submitIntents = new LinkedList<>(); | 530 | submitIntents = new LinkedList<>(); |
427 | MultiPointToSinglePointIntent intent; | 531 | MultiPointToSinglePointIntent intent; |
428 | 532 | ||
... | @@ -431,10 +535,7 @@ public class Router implements RouteListener { | ... | @@ -431,10 +535,7 @@ public class Router implements RouteListener { |
431 | 535 | ||
432 | for (RouteEntry routeEntry : routesToPush) { | 536 | for (RouteEntry routeEntry : routesToPush) { |
433 | // These will always be adds | 537 | // These will always be adds |
434 | - Ip4Prefix prefix = routeEntry.prefix(); | 538 | + RouteEntry foundRouteEntry = findRibRoute(routeEntry.prefix()); |
435 | - String binaryString = RouteEntry.createBinaryString(prefix); | ||
436 | - RouteEntry foundRouteEntry = | ||
437 | - ribTable.getValueForExactKey(binaryString); | ||
438 | if (foundRouteEntry != null && | 539 | if (foundRouteEntry != null && |
439 | foundRouteEntry.nextHop().equals(routeEntry.nextHop())) { | 540 | foundRouteEntry.nextHop().equals(routeEntry.nextHop())) { |
440 | // We only push prefix flows if the prefix is still in the | 541 | // We only push prefix flows if the prefix is still in the |
... | @@ -442,10 +543,11 @@ public class Router implements RouteListener { | ... | @@ -442,10 +543,11 @@ public class Router implements RouteListener { |
442 | // update. | 543 | // update. |
443 | // The prefix could have been removed while we were waiting | 544 | // The prefix could have been removed while we were waiting |
444 | // for the ARP, or the next hop could have changed. | 545 | // for the ARP, or the next hop could have changed. |
445 | - intent = generateRouteIntent(prefix, ipAddress, | 546 | + intent = generateRouteIntent(routeEntry.prefix(), |
446 | - macAddress); | 547 | + ipAddress, macAddress); |
447 | if (intent != null) { | 548 | if (intent != null) { |
448 | - submitIntents.add(Pair.of(prefix, intent)); | 549 | + submitIntents.add(Pair.of(routeEntry.prefix(), |
550 | + intent)); | ||
449 | } | 551 | } |
450 | } else { | 552 | } else { |
451 | log.debug("{} has been revoked before the MAC was resolved", | 553 | log.debug("{} has been revoked before the MAC was resolved", |
... | @@ -454,7 +556,7 @@ public class Router implements RouteListener { | ... | @@ -454,7 +556,7 @@ public class Router implements RouteListener { |
454 | } | 556 | } |
455 | 557 | ||
456 | if (!submitIntents.isEmpty()) { | 558 | if (!submitIntents.isEmpty()) { |
457 | - Collection<Ip4Prefix> withdrawPrefixes = new LinkedList<>(); | 559 | + Collection<IpPrefix> withdrawPrefixes = new LinkedList<>(); |
458 | intentSynchronizer.updateRouteIntents(submitIntents, | 560 | intentSynchronizer.updateRouteIntents(submitIntents, |
459 | withdrawPrefixes); | 561 | withdrawPrefixes); |
460 | } | 562 | } |
... | @@ -464,25 +566,6 @@ public class Router implements RouteListener { | ... | @@ -464,25 +566,6 @@ public class Router implements RouteListener { |
464 | } | 566 | } |
465 | 567 | ||
466 | /** | 568 | /** |
467 | - * Gets the SDN-IP routes. | ||
468 | - * | ||
469 | - * @return the SDN-IP routes | ||
470 | - */ | ||
471 | - public Collection<RouteEntry> getRoutes() { | ||
472 | - Iterator<KeyValuePair<RouteEntry>> it = | ||
473 | - ribTable.getKeyValuePairsForKeysStartingWith("").iterator(); | ||
474 | - | ||
475 | - List<RouteEntry> routes = new LinkedList<>(); | ||
476 | - | ||
477 | - while (it.hasNext()) { | ||
478 | - KeyValuePair<RouteEntry> entry = it.next(); | ||
479 | - routes.add(entry.getValue()); | ||
480 | - } | ||
481 | - | ||
482 | - return routes; | ||
483 | - } | ||
484 | - | ||
485 | - /** | ||
486 | * Listener for host events. | 569 | * Listener for host events. |
487 | */ | 570 | */ |
488 | class InternalHostListener implements HostListener { | 571 | class InternalHostListener implements HostListener { |
... | @@ -495,21 +578,13 @@ public class Router implements RouteListener { | ... | @@ -495,21 +578,13 @@ public class Router implements RouteListener { |
495 | case HOST_ADDED: | 578 | case HOST_ADDED: |
496 | // FALLTHROUGH | 579 | // FALLTHROUGH |
497 | case HOST_UPDATED: | 580 | case HOST_UPDATED: |
498 | - for (IpAddress ip : host.ipAddresses()) { | 581 | + for (IpAddress ipAddress : host.ipAddresses()) { |
499 | - Ip4Address ip4Address = ip.getIp4Address(); | 582 | + updateMac(ipAddress, host.mac()); |
500 | - if (ip4Address == null) { | ||
501 | - continue; | ||
502 | - } | ||
503 | - updateMac(ip4Address, host.mac()); | ||
504 | } | 583 | } |
505 | break; | 584 | break; |
506 | case HOST_REMOVED: | 585 | case HOST_REMOVED: |
507 | - for (IpAddress ip : host.ipAddresses()) { | 586 | + for (IpAddress ipAddress : host.ipAddresses()) { |
508 | - Ip4Address ip4Address = ip.getIp4Address(); | 587 | + ip2Mac.remove(ipAddress); |
509 | - if (ip4Address == null) { | ||
510 | - continue; | ||
511 | - } | ||
512 | - ip2Mac.remove(ip4Address); | ||
513 | } | 588 | } |
514 | break; | 589 | break; |
515 | default: | 590 | default: | ... | ... |
... | @@ -164,13 +164,23 @@ public class SdnIp implements SdnIpService { | ... | @@ -164,13 +164,23 @@ public class SdnIp implements SdnIpService { |
164 | } | 164 | } |
165 | 165 | ||
166 | @Override | 166 | @Override |
167 | - public Collection<BgpRouteEntry> getBgpRoutes() { | 167 | + public Collection<BgpRouteEntry> getBgpRoutes4() { |
168 | - return bgpSessionManager.getBgpRoutes(); | 168 | + return bgpSessionManager.getBgpRoutes4(); |
169 | } | 169 | } |
170 | 170 | ||
171 | @Override | 171 | @Override |
172 | - public Collection<RouteEntry> getRoutes() { | 172 | + public Collection<BgpRouteEntry> getBgpRoutes6() { |
173 | - return router.getRoutes(); | 173 | + return bgpSessionManager.getBgpRoutes6(); |
174 | + } | ||
175 | + | ||
176 | + @Override | ||
177 | + public Collection<RouteEntry> getRoutes4() { | ||
178 | + return router.getRoutes4(); | ||
179 | + } | ||
180 | + | ||
181 | + @Override | ||
182 | + public Collection<RouteEntry> getRoutes6() { | ||
183 | + return router.getRoutes6(); | ||
174 | } | 184 | } |
175 | 185 | ||
176 | @Override | 186 | @Override | ... | ... |
... | @@ -32,18 +32,32 @@ public interface SdnIpService { | ... | @@ -32,18 +32,32 @@ public interface SdnIpService { |
32 | public Collection<BgpSession> getBgpSessions(); | 32 | public Collection<BgpSession> getBgpSessions(); |
33 | 33 | ||
34 | /** | 34 | /** |
35 | - * Gets the BGP routes. | 35 | + * Gets the selected IPv4 BGP routes among all BGP sessions. |
36 | * | 36 | * |
37 | - * @return the BGP routes | 37 | + * @return the selected IPv4 BGP routes among all BGP sessions |
38 | */ | 38 | */ |
39 | - public Collection<BgpRouteEntry> getBgpRoutes(); | 39 | + public Collection<BgpRouteEntry> getBgpRoutes4(); |
40 | 40 | ||
41 | /** | 41 | /** |
42 | - * Gets all the routes known to SDN-IP. | 42 | + * Gets the selected IPv6 BGP routes among all BGP sessions. |
43 | * | 43 | * |
44 | - * @return the SDN-IP routes | 44 | + * @return the selected IPv6 BGP routes among all BGP sessions |
45 | */ | 45 | */ |
46 | - public Collection<RouteEntry> getRoutes(); | 46 | + public Collection<BgpRouteEntry> getBgpRoutes6(); |
47 | + | ||
48 | + /** | ||
49 | + * Gets all IPv4 routes known to SDN-IP. | ||
50 | + * | ||
51 | + * @return the SDN-IP IPv4 routes | ||
52 | + */ | ||
53 | + public Collection<RouteEntry> getRoutes4(); | ||
54 | + | ||
55 | + /** | ||
56 | + * Gets all IPv6 routes known to SDN-IP. | ||
57 | + * | ||
58 | + * @return the SDN-IP IPv6 routes | ||
59 | + */ | ||
60 | + public Collection<RouteEntry> getRoutes6(); | ||
47 | 61 | ||
48 | /** | 62 | /** |
49 | * Changes whether this SDN-IP instance is the primary or not based on the | 63 | * Changes whether this SDN-IP instance is the primary or not based on the | ... | ... |
... | @@ -20,8 +20,9 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -20,8 +20,9 @@ import static com.google.common.base.Preconditions.checkNotNull; |
20 | import java.util.ArrayList; | 20 | import java.util.ArrayList; |
21 | import java.util.Objects; | 21 | import java.util.Objects; |
22 | 22 | ||
23 | +import org.onlab.packet.IpAddress; | ||
24 | +import org.onlab.packet.IpPrefix; | ||
23 | import org.onlab.packet.Ip4Address; | 25 | import org.onlab.packet.Ip4Address; |
24 | -import org.onlab.packet.Ip4Prefix; | ||
25 | import org.onosproject.sdnip.RouteEntry; | 26 | import org.onosproject.sdnip.RouteEntry; |
26 | import org.onosproject.sdnip.bgp.BgpConstants.Update; | 27 | import org.onosproject.sdnip.bgp.BgpConstants.Update; |
27 | 28 | ||
... | @@ -48,8 +49,8 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -48,8 +49,8 @@ public class BgpRouteEntry extends RouteEntry { |
48 | * @param asPath the AS path | 49 | * @param asPath the AS path |
49 | * @param localPref the route local preference | 50 | * @param localPref the route local preference |
50 | */ | 51 | */ |
51 | - public BgpRouteEntry(BgpSession bgpSession, Ip4Prefix prefix, | 52 | + public BgpRouteEntry(BgpSession bgpSession, IpPrefix prefix, |
52 | - Ip4Address nextHop, byte origin, | 53 | + IpAddress nextHop, byte origin, |
53 | BgpRouteEntry.AsPath asPath, long localPref) { | 54 | BgpRouteEntry.AsPath asPath, long localPref) { |
54 | super(prefix, nextHop); | 55 | super(prefix, nextHop); |
55 | this.bgpSession = checkNotNull(bgpSession); | 56 | this.bgpSession = checkNotNull(bgpSession); | ... | ... |
1 | +/* | ||
2 | + * Copyright 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.sdnip.bgp; | ||
17 | + | ||
18 | +import java.util.Collection; | ||
19 | +import java.util.LinkedList; | ||
20 | + | ||
21 | +import org.onlab.packet.IpPrefix; | ||
22 | +import org.onosproject.sdnip.RouteUpdate; | ||
23 | +import org.slf4j.Logger; | ||
24 | +import org.slf4j.LoggerFactory; | ||
25 | + | ||
26 | +/** | ||
27 | + * Class to receive and process the BGP routes from each BGP Session/Peer. | ||
28 | + */ | ||
29 | +class BgpRouteSelector { | ||
30 | + private static final Logger log = | ||
31 | + LoggerFactory.getLogger(BgpRouteSelector.class); | ||
32 | + | ||
33 | + private BgpSessionManager bgpSessionManager; | ||
34 | + | ||
35 | + /** | ||
36 | + * Constructor. | ||
37 | + * | ||
38 | + * @param bgpSessionManager the BGP Session Manager to use | ||
39 | + */ | ||
40 | + BgpRouteSelector(BgpSessionManager bgpSessionManager) { | ||
41 | + this.bgpSessionManager = bgpSessionManager; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Processes route entry updates: added/updated and deleted route | ||
46 | + * entries. | ||
47 | + * | ||
48 | + * @param bgpSession the BGP session the route entry updates were | ||
49 | + * received on | ||
50 | + * @param addedBgpRouteEntries the added/updated route entries to process | ||
51 | + * @param deletedBgpRouteEntries the deleted route entries to process | ||
52 | + */ | ||
53 | + synchronized void routeUpdates(BgpSession bgpSession, | ||
54 | + Collection<BgpRouteEntry> addedBgpRouteEntries, | ||
55 | + Collection<BgpRouteEntry> deletedBgpRouteEntries) { | ||
56 | + Collection<RouteUpdate> routeUpdates = new LinkedList<>(); | ||
57 | + RouteUpdate routeUpdate; | ||
58 | + | ||
59 | + if (bgpSessionManager.isShutdown()) { | ||
60 | + return; // Ignore any leftover updates if shutdown | ||
61 | + } | ||
62 | + // Process the deleted route entries | ||
63 | + for (BgpRouteEntry bgpRouteEntry : deletedBgpRouteEntries) { | ||
64 | + routeUpdate = processDeletedRoute(bgpSession, bgpRouteEntry); | ||
65 | + if (routeUpdate != null) { | ||
66 | + routeUpdates.add(routeUpdate); | ||
67 | + } | ||
68 | + } | ||
69 | + | ||
70 | + // Process the added/updated route entries | ||
71 | + for (BgpRouteEntry bgpRouteEntry : addedBgpRouteEntries) { | ||
72 | + routeUpdate = processAddedRoute(bgpSession, bgpRouteEntry); | ||
73 | + if (routeUpdate != null) { | ||
74 | + routeUpdates.add(routeUpdate); | ||
75 | + } | ||
76 | + } | ||
77 | + bgpSessionManager.getRouteListener().update(routeUpdates); | ||
78 | + } | ||
79 | + | ||
80 | + /** | ||
81 | + * Processes an added/updated route entry. | ||
82 | + * | ||
83 | + * @param bgpSession the BGP session the route entry update was received on | ||
84 | + * @param bgpRouteEntry the added/updated route entry | ||
85 | + * @return the result route update that should be forwarded to the | ||
86 | + * Route Listener, or null if no route update should be forwarded | ||
87 | + */ | ||
88 | + private RouteUpdate processAddedRoute(BgpSession bgpSession, | ||
89 | + BgpRouteEntry bgpRouteEntry) { | ||
90 | + RouteUpdate routeUpdate; | ||
91 | + BgpRouteEntry bestBgpRouteEntry = | ||
92 | + bgpSessionManager.findBgpRoute(bgpRouteEntry.prefix()); | ||
93 | + | ||
94 | + // | ||
95 | + // Install the new route entry if it is better than the | ||
96 | + // current best route. | ||
97 | + // | ||
98 | + if ((bestBgpRouteEntry == null) || | ||
99 | + bgpRouteEntry.isBetterThan(bestBgpRouteEntry)) { | ||
100 | + bgpSessionManager.addBgpRoute(bgpRouteEntry); | ||
101 | + routeUpdate = | ||
102 | + new RouteUpdate(RouteUpdate.Type.UPDATE, bgpRouteEntry); | ||
103 | + return routeUpdate; | ||
104 | + } | ||
105 | + | ||
106 | + // | ||
107 | + // If the route entry arrived on the same BGP Session as | ||
108 | + // the current best route, then elect the next best route | ||
109 | + // and install it. | ||
110 | + // | ||
111 | + if (bestBgpRouteEntry.getBgpSession() != | ||
112 | + bgpRouteEntry.getBgpSession()) { | ||
113 | + return null; // Nothing to do | ||
114 | + } | ||
115 | + | ||
116 | + // Find the next best route | ||
117 | + bestBgpRouteEntry = findBestBgpRoute(bgpRouteEntry.prefix()); | ||
118 | + if (bestBgpRouteEntry == null) { | ||
119 | + // | ||
120 | + // TODO: Shouldn't happen. Install the new route as a | ||
121 | + // pre-caution. | ||
122 | + // | ||
123 | + log.debug("BGP next best route for prefix {} is missing. " + | ||
124 | + "Adding the route that is currently processed.", | ||
125 | + bgpRouteEntry.prefix()); | ||
126 | + bestBgpRouteEntry = bgpRouteEntry; | ||
127 | + } | ||
128 | + | ||
129 | + // Install the next best route | ||
130 | + bgpSessionManager.addBgpRoute(bestBgpRouteEntry); | ||
131 | + routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, | ||
132 | + bestBgpRouteEntry); | ||
133 | + return routeUpdate; | ||
134 | + } | ||
135 | + | ||
136 | + /** | ||
137 | + * Processes a deleted route entry. | ||
138 | + * | ||
139 | + * @param bgpSession the BGP session the route entry update was received on | ||
140 | + * @param bgpRouteEntry the deleted route entry | ||
141 | + * @return the result route update that should be forwarded to the | ||
142 | + * Route Listener, or null if no route update should be forwarded | ||
143 | + */ | ||
144 | + private RouteUpdate processDeletedRoute(BgpSession bgpSession, | ||
145 | + BgpRouteEntry bgpRouteEntry) { | ||
146 | + RouteUpdate routeUpdate; | ||
147 | + BgpRouteEntry bestBgpRouteEntry = | ||
148 | + bgpSessionManager.findBgpRoute(bgpRouteEntry.prefix()); | ||
149 | + | ||
150 | + // | ||
151 | + // Remove the route entry only if it was the best one. | ||
152 | + // Install the the next best route if it exists. | ||
153 | + // | ||
154 | + // NOTE: We intentionally use "==" instead of method equals(), | ||
155 | + // because we need to check whether this is same object. | ||
156 | + // | ||
157 | + if (bgpRouteEntry != bestBgpRouteEntry) { | ||
158 | + return null; // Nothing to do | ||
159 | + } | ||
160 | + | ||
161 | + // | ||
162 | + // Find the next best route | ||
163 | + // | ||
164 | + bestBgpRouteEntry = findBestBgpRoute(bgpRouteEntry.prefix()); | ||
165 | + if (bestBgpRouteEntry != null) { | ||
166 | + // Install the next best route | ||
167 | + bgpSessionManager.addBgpRoute(bestBgpRouteEntry); | ||
168 | + routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, | ||
169 | + bestBgpRouteEntry); | ||
170 | + return routeUpdate; | ||
171 | + } | ||
172 | + | ||
173 | + // | ||
174 | + // No route found. Remove the route entry | ||
175 | + // | ||
176 | + bgpSessionManager.removeBgpRoute(bgpRouteEntry.prefix()); | ||
177 | + routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, bgpRouteEntry); | ||
178 | + return routeUpdate; | ||
179 | + } | ||
180 | + | ||
181 | + /** | ||
182 | + * Finds the best route entry among all BGP Sessions. | ||
183 | + * | ||
184 | + * @param prefix the prefix of the route | ||
185 | + * @return the best route if found, otherwise null | ||
186 | + */ | ||
187 | + private BgpRouteEntry findBestBgpRoute(IpPrefix prefix) { | ||
188 | + BgpRouteEntry bestRoute = null; | ||
189 | + | ||
190 | + // Iterate across all BGP Sessions and select the best route | ||
191 | + for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) { | ||
192 | + BgpRouteEntry route = bgpSession.findBgpRoute(prefix); | ||
193 | + if (route == null) { | ||
194 | + continue; | ||
195 | + } | ||
196 | + if ((bestRoute == null) || route.isBetterThan(bestRoute)) { | ||
197 | + bestRoute = route; | ||
198 | + } | ||
199 | + } | ||
200 | + return bestRoute; | ||
201 | + } | ||
202 | +} |
... | @@ -20,7 +20,6 @@ import java.net.InetSocketAddress; | ... | @@ -20,7 +20,6 @@ import java.net.InetSocketAddress; |
20 | import java.net.SocketAddress; | 20 | import java.net.SocketAddress; |
21 | import java.util.Collection; | 21 | import java.util.Collection; |
22 | import java.util.Collections; | 22 | import java.util.Collections; |
23 | -import java.util.Map; | ||
24 | import java.util.concurrent.ConcurrentHashMap; | 23 | import java.util.concurrent.ConcurrentHashMap; |
25 | import java.util.concurrent.ConcurrentMap; | 24 | import java.util.concurrent.ConcurrentMap; |
26 | import java.util.concurrent.TimeUnit; | 25 | import java.util.concurrent.TimeUnit; |
... | @@ -34,6 +33,7 @@ import org.jboss.netty.util.HashedWheelTimer; | ... | @@ -34,6 +33,7 @@ import org.jboss.netty.util.HashedWheelTimer; |
34 | import org.jboss.netty.util.Timeout; | 33 | import org.jboss.netty.util.Timeout; |
35 | import org.jboss.netty.util.Timer; | 34 | import org.jboss.netty.util.Timer; |
36 | import org.jboss.netty.util.TimerTask; | 35 | import org.jboss.netty.util.TimerTask; |
36 | +import org.onlab.packet.IpPrefix; | ||
37 | import org.onlab.packet.Ip4Address; | 37 | import org.onlab.packet.Ip4Address; |
38 | import org.onlab.packet.Ip4Prefix; | 38 | import org.onlab.packet.Ip4Prefix; |
39 | import org.onlab.packet.Ip6Prefix; | 39 | import org.onlab.packet.Ip6Prefix; |
... | @@ -120,44 +120,113 @@ public class BgpSession extends SimpleChannelHandler { | ... | @@ -120,44 +120,113 @@ public class BgpSession extends SimpleChannelHandler { |
120 | } | 120 | } |
121 | 121 | ||
122 | /** | 122 | /** |
123 | - * Gets the BGP RIB-IN IPv4 routing entries. | 123 | + * Gets the IPv4 BGP RIB-IN routing entries. |
124 | * | 124 | * |
125 | - * @return the BGP RIB-IN IPv4 routing entries | 125 | + * @return the IPv4 BGP RIB-IN routing entries |
126 | */ | 126 | */ |
127 | - public Map<Ip4Prefix, BgpRouteEntry> bgpRibIn4() { | 127 | + public Collection<BgpRouteEntry> getBgpRibIn4() { |
128 | - return bgpRibIn4; | 128 | + return bgpRibIn4.values(); |
129 | } | 129 | } |
130 | 130 | ||
131 | /** | 131 | /** |
132 | - * Gets the BGP RIB-IN IPv6 routing entries. | 132 | + * Gets the IPv6 BGP RIB-IN routing entries. |
133 | * | 133 | * |
134 | - * @return the BGP RIB-IN IPv6 routing entries | 134 | + * @return the IPv6 BGP RIB-IN routing entries |
135 | */ | 135 | */ |
136 | - public Map<Ip6Prefix, BgpRouteEntry> bgpRibIn6() { | 136 | + public Collection<BgpRouteEntry> getBgpRibIn6() { |
137 | - return bgpRibIn6; | 137 | + return bgpRibIn6.values(); |
138 | } | 138 | } |
139 | 139 | ||
140 | /** | 140 | /** |
141 | - * Finds a BGP IPv4 routing entry in the BGP RIB-IN. | 141 | + * Finds an IPv4 BGP routing entry for a prefix in the IPv4 BGP RIB-IN. |
142 | * | 142 | * |
143 | * @param prefix the IPv4 prefix of the route to search for | 143 | * @param prefix the IPv4 prefix of the route to search for |
144 | * @return the IPv4 BGP routing entry if found, otherwise null | 144 | * @return the IPv4 BGP routing entry if found, otherwise null |
145 | */ | 145 | */ |
146 | - public BgpRouteEntry findBgpRouteEntry(Ip4Prefix prefix) { | 146 | + public BgpRouteEntry findBgpRoute(Ip4Prefix prefix) { |
147 | return bgpRibIn4.get(prefix); | 147 | return bgpRibIn4.get(prefix); |
148 | } | 148 | } |
149 | 149 | ||
150 | /** | 150 | /** |
151 | - * Finds a BGP IPv6 routing entry in the BGP RIB-IN. | 151 | + * Finds an IPv6 BGP routing entry for a prefix in the IPv6 BGP RIB-IN. |
152 | * | 152 | * |
153 | * @param prefix the IPv6 prefix of the route to search for | 153 | * @param prefix the IPv6 prefix of the route to search for |
154 | * @return the IPv6 BGP routing entry if found, otherwise null | 154 | * @return the IPv6 BGP routing entry if found, otherwise null |
155 | */ | 155 | */ |
156 | - public BgpRouteEntry findBgpRouteEntry(Ip6Prefix prefix) { | 156 | + public BgpRouteEntry findBgpRoute(Ip6Prefix prefix) { |
157 | return bgpRibIn6.get(prefix); | 157 | return bgpRibIn6.get(prefix); |
158 | } | 158 | } |
159 | 159 | ||
160 | /** | 160 | /** |
161 | + * Finds a BGP routing entry for a prefix in the BGP RIB-IN. The prefix | ||
162 | + * can be either IPv4 or IPv6. | ||
163 | + * | ||
164 | + * @param prefix the IP prefix of the route to search for | ||
165 | + * @return the BGP routing entry if found, otherwise null | ||
166 | + */ | ||
167 | + public BgpRouteEntry findBgpRoute(IpPrefix prefix) { | ||
168 | + if (prefix.version() == Ip4Address.VERSION) { | ||
169 | + // IPv4 prefix | ||
170 | + Ip4Prefix ip4Prefix = prefix.getIp4Prefix(); | ||
171 | + return bgpRibIn4.get(ip4Prefix); | ||
172 | + } | ||
173 | + | ||
174 | + // IPv6 prefix | ||
175 | + Ip6Prefix ip6Prefix = prefix.getIp6Prefix(); | ||
176 | + return bgpRibIn6.get(ip6Prefix); | ||
177 | + } | ||
178 | + | ||
179 | + /** | ||
180 | + * Adds a BGP route. The route can be either IPv4 or IPv6. | ||
181 | + * | ||
182 | + * @param bgpRouteEntry the BGP route entry to use | ||
183 | + */ | ||
184 | + void addBgpRoute(BgpRouteEntry bgpRouteEntry) { | ||
185 | + if (bgpRouteEntry.version() == Ip4Address.VERSION) { | ||
186 | + // IPv4 route | ||
187 | + Ip4Prefix ip4Prefix = bgpRouteEntry.prefix().getIp4Prefix(); | ||
188 | + bgpRibIn4.put(ip4Prefix, bgpRouteEntry); | ||
189 | + } else { | ||
190 | + // IPv6 route | ||
191 | + Ip6Prefix ip6Prefix = bgpRouteEntry.prefix().getIp6Prefix(); | ||
192 | + bgpRibIn6.put(ip6Prefix, bgpRouteEntry); | ||
193 | + } | ||
194 | + } | ||
195 | + | ||
196 | + /** | ||
197 | + * Removes an IPv4 BGP route for a prefix. | ||
198 | + * | ||
199 | + * @param prefix the prefix to use | ||
200 | + * @return true if the route was found and removed, otherwise false | ||
201 | + */ | ||
202 | + boolean removeBgpRoute(Ip4Prefix prefix) { | ||
203 | + return (bgpRibIn4.remove(prefix) != null); | ||
204 | + } | ||
205 | + | ||
206 | + /** | ||
207 | + * Removes an IPv6 BGP route for a prefix. | ||
208 | + * | ||
209 | + * @param prefix the prefix to use | ||
210 | + * @return true if the route was found and removed, otherwise false | ||
211 | + */ | ||
212 | + boolean removeBgpRoute(Ip6Prefix prefix) { | ||
213 | + return (bgpRibIn6.remove(prefix) != null); | ||
214 | + } | ||
215 | + | ||
216 | + /** | ||
217 | + * Removes a BGP route for a prefix. The prefix can be either IPv4 or IPv6. | ||
218 | + * | ||
219 | + * @param prefix the prefix to use | ||
220 | + * @return true if the route was found and removed, otherwise false | ||
221 | + */ | ||
222 | + boolean removeBgpRoute(IpPrefix prefix) { | ||
223 | + if (prefix.version() == Ip4Address.VERSION) { | ||
224 | + return (bgpRibIn4.remove(prefix.getIp4Prefix()) != null); // IPv4 | ||
225 | + } | ||
226 | + return (bgpRibIn6.remove(prefix.getIp6Prefix()) != null); // IPv6 | ||
227 | + } | ||
228 | + | ||
229 | + /** | ||
161 | * Gets the BGP session remote address. | 230 | * Gets the BGP session remote address. |
162 | * | 231 | * |
163 | * @return the BGP session remote address | 232 | * @return the BGP session remote address |
... | @@ -622,7 +691,7 @@ public class BgpSession extends SimpleChannelHandler { | ... | @@ -622,7 +691,7 @@ public class BgpSession extends SimpleChannelHandler { |
622 | bgpRibIn6 = new ConcurrentHashMap<>(); | 691 | bgpRibIn6 = new ConcurrentHashMap<>(); |
623 | 692 | ||
624 | // Push the updates to the BGP Merged RIB | 693 | // Push the updates to the BGP Merged RIB |
625 | - BgpSessionManager.BgpRouteSelector bgpRouteSelector = | 694 | + BgpRouteSelector bgpRouteSelector = |
626 | bgpSessionManager.getBgpRouteSelector(); | 695 | bgpSessionManager.getBgpRouteSelector(); |
627 | Collection<BgpRouteEntry> addedRoutes = Collections.emptyList(); | 696 | Collection<BgpRouteEntry> addedRoutes = Collections.emptyList(); |
628 | bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes4); | 697 | bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes4); | ... | ... |
... | @@ -22,7 +22,6 @@ import java.net.InetAddress; | ... | @@ -22,7 +22,6 @@ import java.net.InetAddress; |
22 | import java.net.InetSocketAddress; | 22 | import java.net.InetSocketAddress; |
23 | import java.net.SocketAddress; | 23 | import java.net.SocketAddress; |
24 | import java.util.Collection; | 24 | import java.util.Collection; |
25 | -import java.util.LinkedList; | ||
26 | import java.util.concurrent.ConcurrentHashMap; | 25 | import java.util.concurrent.ConcurrentHashMap; |
27 | import java.util.concurrent.ConcurrentMap; | 26 | import java.util.concurrent.ConcurrentMap; |
28 | import java.util.concurrent.Executors; | 27 | import java.util.concurrent.Executors; |
... | @@ -37,10 +36,11 @@ import org.jboss.netty.channel.Channels; | ... | @@ -37,10 +36,11 @@ import org.jboss.netty.channel.Channels; |
37 | import org.jboss.netty.channel.group.ChannelGroup; | 36 | import org.jboss.netty.channel.group.ChannelGroup; |
38 | import org.jboss.netty.channel.group.DefaultChannelGroup; | 37 | import org.jboss.netty.channel.group.DefaultChannelGroup; |
39 | import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; | 38 | import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; |
40 | -import org.onosproject.sdnip.RouteListener; | ||
41 | -import org.onosproject.sdnip.RouteUpdate; | ||
42 | import org.onlab.packet.Ip4Address; | 39 | import org.onlab.packet.Ip4Address; |
40 | +import org.onlab.packet.IpPrefix; | ||
43 | import org.onlab.packet.Ip4Prefix; | 41 | import org.onlab.packet.Ip4Prefix; |
42 | +import org.onlab.packet.Ip6Prefix; | ||
43 | +import org.onosproject.sdnip.RouteListener; | ||
44 | import org.slf4j.Logger; | 44 | import org.slf4j.Logger; |
45 | import org.slf4j.LoggerFactory; | 45 | import org.slf4j.LoggerFactory; |
46 | 46 | ||
... | @@ -50,6 +50,7 @@ import org.slf4j.LoggerFactory; | ... | @@ -50,6 +50,7 @@ import org.slf4j.LoggerFactory; |
50 | public class BgpSessionManager { | 50 | public class BgpSessionManager { |
51 | private static final Logger log = | 51 | private static final Logger log = |
52 | LoggerFactory.getLogger(BgpSessionManager.class); | 52 | LoggerFactory.getLogger(BgpSessionManager.class); |
53 | + | ||
53 | boolean isShutdown = true; | 54 | boolean isShutdown = true; |
54 | private Channel serverChannel; // Listener for incoming BGP connections | 55 | private Channel serverChannel; // Listener for incoming BGP connections |
55 | private ServerBootstrap serverBootstrap; | 56 | private ServerBootstrap serverBootstrap; |
... | @@ -58,8 +59,10 @@ public class BgpSessionManager { | ... | @@ -58,8 +59,10 @@ public class BgpSessionManager { |
58 | new ConcurrentHashMap<>(); | 59 | new ConcurrentHashMap<>(); |
59 | private Ip4Address myBgpId; // Same BGP ID for all peers | 60 | private Ip4Address myBgpId; // Same BGP ID for all peers |
60 | 61 | ||
61 | - private BgpRouteSelector bgpRouteSelector = new BgpRouteSelector(); | 62 | + private BgpRouteSelector bgpRouteSelector = new BgpRouteSelector(this); |
62 | - private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRoutes = | 63 | + private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRoutes4 = |
64 | + new ConcurrentHashMap<>(); | ||
65 | + private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRoutes6 = | ||
63 | new ConcurrentHashMap<>(); | 66 | new ConcurrentHashMap<>(); |
64 | 67 | ||
65 | private final RouteListener routeListener; | 68 | private final RouteListener routeListener; |
... | @@ -74,6 +77,24 @@ public class BgpSessionManager { | ... | @@ -74,6 +77,24 @@ public class BgpSessionManager { |
74 | } | 77 | } |
75 | 78 | ||
76 | /** | 79 | /** |
80 | + * Checks whether the BGP Session Manager is shutdown. | ||
81 | + * | ||
82 | + * @return true if the BGP Session Manager is shutdown, otherwise false | ||
83 | + */ | ||
84 | + boolean isShutdown() { | ||
85 | + return this.isShutdown; | ||
86 | + } | ||
87 | + | ||
88 | + /** | ||
89 | + * Gets the route listener. | ||
90 | + * | ||
91 | + * @return the route listener to use | ||
92 | + */ | ||
93 | + RouteListener getRouteListener() { | ||
94 | + return routeListener; | ||
95 | + } | ||
96 | + | ||
97 | + /** | ||
77 | * Gets the BGP sessions. | 98 | * Gets the BGP sessions. |
78 | * | 99 | * |
79 | * @return the BGP sessions | 100 | * @return the BGP sessions |
... | @@ -83,12 +104,62 @@ public class BgpSessionManager { | ... | @@ -83,12 +104,62 @@ public class BgpSessionManager { |
83 | } | 104 | } |
84 | 105 | ||
85 | /** | 106 | /** |
86 | - * Gets the BGP routes. | 107 | + * Gets the selected IPv4 BGP routes among all BGP sessions. |
108 | + * | ||
109 | + * @return the selected IPv4 BGP routes among all BGP sessions | ||
110 | + */ | ||
111 | + public Collection<BgpRouteEntry> getBgpRoutes4() { | ||
112 | + return bgpRoutes4.values(); | ||
113 | + } | ||
114 | + | ||
115 | + /** | ||
116 | + * Gets the selected IPv6 BGP routes among all BGP sessions. | ||
87 | * | 117 | * |
88 | - * @return the BGP routes | 118 | + * @return the selected IPv6 BGP routes among all BGP sessions |
89 | */ | 119 | */ |
90 | - public Collection<BgpRouteEntry> getBgpRoutes() { | 120 | + public Collection<BgpRouteEntry> getBgpRoutes6() { |
91 | - return bgpRoutes.values(); | 121 | + return bgpRoutes6.values(); |
122 | + } | ||
123 | + | ||
124 | + /** | ||
125 | + * Finds a BGP route for a prefix. The prefix can be either IPv4 or IPv6. | ||
126 | + * | ||
127 | + * @param prefix the prefix to use | ||
128 | + * @return the BGP route if found, otherwise null | ||
129 | + */ | ||
130 | + BgpRouteEntry findBgpRoute(IpPrefix prefix) { | ||
131 | + if (prefix.version() == Ip4Address.VERSION) { | ||
132 | + return bgpRoutes4.get(prefix.getIp4Prefix()); // IPv4 | ||
133 | + } | ||
134 | + return bgpRoutes6.get(prefix.getIp6Prefix()); // IPv6 | ||
135 | + } | ||
136 | + | ||
137 | + /** | ||
138 | + * Adds a BGP route. The route can be either IPv4 or IPv6. | ||
139 | + * | ||
140 | + * @param bgpRouteEntry the BGP route entry to use | ||
141 | + */ | ||
142 | + void addBgpRoute(BgpRouteEntry bgpRouteEntry) { | ||
143 | + if (bgpRouteEntry.version() == Ip4Address.VERSION) { | ||
144 | + bgpRoutes4.put(bgpRouteEntry.prefix().getIp4Prefix(), // IPv4 | ||
145 | + bgpRouteEntry); | ||
146 | + } else { | ||
147 | + bgpRoutes6.put(bgpRouteEntry.prefix().getIp6Prefix(), // IPv6 | ||
148 | + bgpRouteEntry); | ||
149 | + } | ||
150 | + } | ||
151 | + | ||
152 | + /** | ||
153 | + * Removes a BGP route for a prefix. The prefix can be either IPv4 or IPv6. | ||
154 | + * | ||
155 | + * @param prefix the prefix to use | ||
156 | + * @return true if the route was found and removed, otherwise false | ||
157 | + */ | ||
158 | + boolean removeBgpRoute(IpPrefix prefix) { | ||
159 | + if (prefix.version() == Ip4Address.VERSION) { | ||
160 | + return (bgpRoutes4.remove(prefix.getIp4Prefix()) != null); // IPv4 | ||
161 | + } | ||
162 | + return (bgpRoutes6.remove(prefix.getIp6Prefix()) != null); // IPv6 | ||
92 | } | 163 | } |
93 | 164 | ||
94 | /** | 165 | /** |
... | @@ -187,8 +258,8 @@ public class BgpSessionManager { | ... | @@ -187,8 +258,8 @@ public class BgpSessionManager { |
187 | log.debug("BGP Session Manager start."); | 258 | log.debug("BGP Session Manager start."); |
188 | isShutdown = false; | 259 | isShutdown = false; |
189 | 260 | ||
190 | - ChannelFactory channelFactory = | 261 | + ChannelFactory channelFactory = new NioServerSocketChannelFactory( |
191 | - new NioServerSocketChannelFactory(Executors.newCachedThreadPool(namedThreads("BGP-SM-boss-%d")), | 262 | + Executors.newCachedThreadPool(namedThreads("BGP-SM-boss-%d")), |
192 | Executors.newCachedThreadPool(namedThreads("BGP-SM-worker-%d"))); | 263 | Executors.newCachedThreadPool(namedThreads("BGP-SM-worker-%d"))); |
193 | ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() { | 264 | ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() { |
194 | @Override | 265 | @Override |
... | @@ -231,172 +302,4 @@ public class BgpSessionManager { | ... | @@ -231,172 +302,4 @@ public class BgpSessionManager { |
231 | allChannels.close().awaitUninterruptibly(); | 302 | allChannels.close().awaitUninterruptibly(); |
232 | serverBootstrap.releaseExternalResources(); | 303 | serverBootstrap.releaseExternalResources(); |
233 | } | 304 | } |
234 | - | ||
235 | - /** | ||
236 | - * Class to receive and process the BGP routes from each BGP Session/Peer. | ||
237 | - */ | ||
238 | - class BgpRouteSelector { | ||
239 | - /** | ||
240 | - * Processes route entry updates: added/updated and deleted route | ||
241 | - * entries. | ||
242 | - * | ||
243 | - * @param bgpSession the BGP session the route entry updates were | ||
244 | - * received on | ||
245 | - * @param addedBgpRouteEntries the added/updated route entries to | ||
246 | - * process | ||
247 | - * @param deletedBgpRouteEntries the deleted route entries to process | ||
248 | - */ | ||
249 | - synchronized void routeUpdates(BgpSession bgpSession, | ||
250 | - Collection<BgpRouteEntry> addedBgpRouteEntries, | ||
251 | - Collection<BgpRouteEntry> deletedBgpRouteEntries) { | ||
252 | - Collection<RouteUpdate> routeUpdates = new LinkedList<>(); | ||
253 | - RouteUpdate routeUpdate; | ||
254 | - | ||
255 | - if (isShutdown) { | ||
256 | - return; // Ignore any leftover updates if shutdown | ||
257 | - } | ||
258 | - // Process the deleted route entries | ||
259 | - for (BgpRouteEntry bgpRouteEntry : deletedBgpRouteEntries) { | ||
260 | - routeUpdate = processDeletedRoute(bgpSession, bgpRouteEntry); | ||
261 | - if (routeUpdate != null) { | ||
262 | - routeUpdates.add(routeUpdate); | ||
263 | - } | ||
264 | - } | ||
265 | - | ||
266 | - // Process the added/updated route entries | ||
267 | - for (BgpRouteEntry bgpRouteEntry : addedBgpRouteEntries) { | ||
268 | - routeUpdate = processAddedRoute(bgpSession, bgpRouteEntry); | ||
269 | - if (routeUpdate != null) { | ||
270 | - routeUpdates.add(routeUpdate); | ||
271 | - } | ||
272 | - } | ||
273 | - routeListener.update(routeUpdates); | ||
274 | - } | ||
275 | - | ||
276 | - /** | ||
277 | - * Processes an added/updated route entry. | ||
278 | - * | ||
279 | - * @param bgpSession the BGP session the route entry update was | ||
280 | - * received on | ||
281 | - * @param bgpRouteEntry the added/updated route entry | ||
282 | - * @return the result route update that should be forwarded to the | ||
283 | - * Route Listener, or null if no route update should be forwarded | ||
284 | - */ | ||
285 | - private RouteUpdate processAddedRoute(BgpSession bgpSession, | ||
286 | - BgpRouteEntry bgpRouteEntry) { | ||
287 | - RouteUpdate routeUpdate; | ||
288 | - BgpRouteEntry bestBgpRouteEntry = | ||
289 | - bgpRoutes.get(bgpRouteEntry.prefix()); | ||
290 | - | ||
291 | - // | ||
292 | - // Install the new route entry if it is better than the | ||
293 | - // current best route. | ||
294 | - // | ||
295 | - if ((bestBgpRouteEntry == null) || | ||
296 | - bgpRouteEntry.isBetterThan(bestBgpRouteEntry)) { | ||
297 | - bgpRoutes.put(bgpRouteEntry.prefix(), bgpRouteEntry); | ||
298 | - routeUpdate = | ||
299 | - new RouteUpdate(RouteUpdate.Type.UPDATE, bgpRouteEntry); | ||
300 | - return routeUpdate; | ||
301 | - } | ||
302 | - | ||
303 | - // | ||
304 | - // If the route entry arrived on the same BGP Session as | ||
305 | - // the current best route, then elect the next best route | ||
306 | - // and install it. | ||
307 | - // | ||
308 | - if (bestBgpRouteEntry.getBgpSession() != | ||
309 | - bgpRouteEntry.getBgpSession()) { | ||
310 | - return null; // Nothing to do | ||
311 | - } | ||
312 | - | ||
313 | - // Find the next best route | ||
314 | - bestBgpRouteEntry = findBestBgpRoute(bgpRouteEntry.prefix()); | ||
315 | - if (bestBgpRouteEntry == null) { | ||
316 | - // | ||
317 | - // TODO: Shouldn't happen. Install the new route as a | ||
318 | - // pre-caution. | ||
319 | - // | ||
320 | - log.debug("BGP next best route for prefix {} is missing. " + | ||
321 | - "Adding the route that is currently processed.", | ||
322 | - bgpRouteEntry.prefix()); | ||
323 | - bestBgpRouteEntry = bgpRouteEntry; | ||
324 | - } | ||
325 | - // Install the next best route | ||
326 | - bgpRoutes.put(bestBgpRouteEntry.prefix(), bestBgpRouteEntry); | ||
327 | - routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, | ||
328 | - bestBgpRouteEntry); | ||
329 | - return routeUpdate; | ||
330 | - } | ||
331 | - | ||
332 | - /** | ||
333 | - * Processes a deleted route entry. | ||
334 | - * | ||
335 | - * @param bgpSession the BGP session the route entry update was | ||
336 | - * received on | ||
337 | - * @param bgpRouteEntry the deleted route entry | ||
338 | - * @return the result route update that should be forwarded to the | ||
339 | - * Route Listener, or null if no route update should be forwarded | ||
340 | - */ | ||
341 | - private RouteUpdate processDeletedRoute(BgpSession bgpSession, | ||
342 | - BgpRouteEntry bgpRouteEntry) { | ||
343 | - RouteUpdate routeUpdate; | ||
344 | - BgpRouteEntry bestBgpRouteEntry = | ||
345 | - bgpRoutes.get(bgpRouteEntry.prefix()); | ||
346 | - | ||
347 | - // | ||
348 | - // Remove the route entry only if it was the best one. | ||
349 | - // Install the the next best route if it exists. | ||
350 | - // | ||
351 | - // NOTE: We intentionally use "==" instead of method equals(), | ||
352 | - // because we need to check whether this is same object. | ||
353 | - // | ||
354 | - if (bgpRouteEntry != bestBgpRouteEntry) { | ||
355 | - return null; // Nothing to do | ||
356 | - } | ||
357 | - | ||
358 | - // | ||
359 | - // Find the next best route | ||
360 | - // | ||
361 | - bestBgpRouteEntry = findBestBgpRoute(bgpRouteEntry.prefix()); | ||
362 | - if (bestBgpRouteEntry != null) { | ||
363 | - // Install the next best route | ||
364 | - bgpRoutes.put(bestBgpRouteEntry.prefix(), | ||
365 | - bestBgpRouteEntry); | ||
366 | - routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, | ||
367 | - bestBgpRouteEntry); | ||
368 | - return routeUpdate; | ||
369 | - } | ||
370 | - | ||
371 | - // | ||
372 | - // No route found. Remove the route entry | ||
373 | - // | ||
374 | - bgpRoutes.remove(bgpRouteEntry.prefix()); | ||
375 | - routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, | ||
376 | - bgpRouteEntry); | ||
377 | - return routeUpdate; | ||
378 | - } | ||
379 | - | ||
380 | - /** | ||
381 | - * Finds the best route entry among all BGP Sessions. | ||
382 | - * | ||
383 | - * @param prefix the prefix of the route | ||
384 | - * @return the best route if found, otherwise null | ||
385 | - */ | ||
386 | - private BgpRouteEntry findBestBgpRoute(Ip4Prefix prefix) { | ||
387 | - BgpRouteEntry bestRoute = null; | ||
388 | - | ||
389 | - // Iterate across all BGP Sessions and select the best route | ||
390 | - for (BgpSession bgpSession : bgpSessions.values()) { | ||
391 | - BgpRouteEntry route = bgpSession.findBgpRouteEntry(prefix); | ||
392 | - if (route == null) { | ||
393 | - continue; | ||
394 | - } | ||
395 | - if ((bestRoute == null) || route.isBetterThan(bestRoute)) { | ||
396 | - bestRoute = route; | ||
397 | - } | ||
398 | - } | ||
399 | - return bestRoute; | ||
400 | - } | ||
401 | - } | ||
402 | } | 305 | } | ... | ... |
... | @@ -25,8 +25,8 @@ import org.jboss.netty.buffer.ChannelBuffer; | ... | @@ -25,8 +25,8 @@ import org.jboss.netty.buffer.ChannelBuffer; |
25 | import org.jboss.netty.buffer.ChannelBuffers; | 25 | import org.jboss.netty.buffer.ChannelBuffers; |
26 | import org.jboss.netty.channel.ChannelHandlerContext; | 26 | import org.jboss.netty.channel.ChannelHandlerContext; |
27 | import org.onlab.packet.Ip4Address; | 27 | import org.onlab.packet.Ip4Address; |
28 | -import org.onlab.packet.Ip6Address; | ||
29 | import org.onlab.packet.Ip4Prefix; | 28 | import org.onlab.packet.Ip4Prefix; |
29 | +import org.onlab.packet.Ip6Address; | ||
30 | import org.onlab.packet.Ip6Prefix; | 30 | import org.onlab.packet.Ip6Prefix; |
31 | import org.onosproject.sdnip.bgp.BgpConstants.Notifications.UpdateMessageError; | 31 | import org.onosproject.sdnip.bgp.BgpConstants.Notifications.UpdateMessageError; |
32 | import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.MultiprotocolExtensions; | 32 | import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.MultiprotocolExtensions; |
... | @@ -112,7 +112,7 @@ final class BgpUpdate { | ... | @@ -112,7 +112,7 @@ final class BgpUpdate { |
112 | for (Ip4Prefix prefix : withdrawnPrefixes) { | 112 | for (Ip4Prefix prefix : withdrawnPrefixes) { |
113 | log.debug("BGP RX UPDATE message WITHDRAWN from {}: {}", | 113 | log.debug("BGP RX UPDATE message WITHDRAWN from {}: {}", |
114 | bgpSession.getRemoteAddress(), prefix); | 114 | bgpSession.getRemoteAddress(), prefix); |
115 | - BgpRouteEntry bgpRouteEntry = bgpSession.bgpRibIn4().get(prefix); | 115 | + BgpRouteEntry bgpRouteEntry = bgpSession.findBgpRoute(prefix); |
116 | if (bgpRouteEntry != null) { | 116 | if (bgpRouteEntry != null) { |
117 | decodedBgpRoutes.deletedUnicastRoutes4.put(prefix, | 117 | decodedBgpRoutes.deletedUnicastRoutes4.put(prefix, |
118 | bgpRouteEntry); | 118 | bgpRouteEntry); |
... | @@ -134,35 +134,30 @@ final class BgpUpdate { | ... | @@ -134,35 +134,30 @@ final class BgpUpdate { |
134 | // | 134 | // |
135 | // Update the BGP RIB-IN | 135 | // Update the BGP RIB-IN |
136 | // | 136 | // |
137 | - Collection<BgpRouteEntry> bgpRoutes; | 137 | + for (Ip4Prefix ip4Prefix : |
138 | - // | 138 | + decodedBgpRoutes.deletedUnicastRoutes4.keySet()) { |
139 | - bgpRoutes = decodedBgpRoutes.deletedUnicastRoutes4.values(); | 139 | + bgpSession.removeBgpRoute(ip4Prefix); |
140 | - for (BgpRouteEntry bgpRouteEntry : bgpRoutes) { | ||
141 | - bgpSession.bgpRibIn4().remove(bgpRouteEntry.prefix()); | ||
142 | } | 140 | } |
143 | // | 141 | // |
144 | - bgpRoutes = decodedBgpRoutes.addedUnicastRoutes4.values(); | 142 | + for (BgpRouteEntry bgpRouteEntry : |
145 | - for (BgpRouteEntry bgpRouteEntry : bgpRoutes) { | 143 | + decodedBgpRoutes.addedUnicastRoutes4.values()) { |
146 | - bgpSession.bgpRibIn4().put(bgpRouteEntry.prefix(), bgpRouteEntry); | 144 | + bgpSession.addBgpRoute(bgpRouteEntry); |
147 | } | 145 | } |
148 | // | 146 | // |
149 | - bgpRoutes = decodedBgpRoutes.deletedUnicastRoutes6.values(); | 147 | + for (Ip6Prefix ip6Prefix : |
150 | - for (BgpRouteEntry bgpRouteEntry : bgpRoutes) { | 148 | + decodedBgpRoutes.deletedUnicastRoutes6.keySet()) { |
151 | - bgpSession.bgpRibIn6().remove(bgpRouteEntry.prefix()); | 149 | + bgpSession.removeBgpRoute(ip6Prefix); |
152 | } | 150 | } |
153 | // | 151 | // |
154 | - bgpRoutes = decodedBgpRoutes.addedUnicastRoutes6.values(); | 152 | + for (BgpRouteEntry bgpRouteEntry : |
155 | - // TODO: fix/enable for IPv6 | 153 | + decodedBgpRoutes.addedUnicastRoutes6.values()) { |
156 | - /* | 154 | + bgpSession.addBgpRoute(bgpRouteEntry); |
157 | - for (BgpRouteEntry bgpRouteEntry : bgpRoutes) { | ||
158 | - bgpSession.bgpRibIn6().put(bgpRouteEntry.prefix(), bgpRouteEntry); | ||
159 | } | 155 | } |
160 | - */ | ||
161 | 156 | ||
162 | // | 157 | // |
163 | // Push the updates to the BGP Merged RIB | 158 | // Push the updates to the BGP Merged RIB |
164 | // | 159 | // |
165 | - BgpSessionManager.BgpRouteSelector bgpRouteSelector = | 160 | + BgpRouteSelector bgpRouteSelector = |
166 | bgpSession.getBgpSessionManager().getBgpRouteSelector(); | 161 | bgpSession.getBgpSessionManager().getBgpRouteSelector(); |
167 | bgpRouteSelector.routeUpdates(bgpSession, | 162 | bgpRouteSelector.routeUpdates(bgpSession, |
168 | decodedBgpRoutes.addedUnicastRoutes4.values(), | 163 | decodedBgpRoutes.addedUnicastRoutes4.values(), |
... | @@ -408,7 +403,7 @@ final class BgpUpdate { | ... | @@ -408,7 +403,7 @@ final class BgpUpdate { |
408 | 403 | ||
409 | // The deleted IPv4 routes | 404 | // The deleted IPv4 routes |
410 | for (Ip4Prefix prefix : mpNlri.nlri4) { | 405 | for (Ip4Prefix prefix : mpNlri.nlri4) { |
411 | - bgpRouteEntry = bgpSession.bgpRibIn4().get(prefix); | 406 | + bgpRouteEntry = bgpSession.findBgpRoute(prefix); |
412 | if (bgpRouteEntry != null) { | 407 | if (bgpRouteEntry != null) { |
413 | decodedBgpRoutes.deletedUnicastRoutes4.put(prefix, | 408 | decodedBgpRoutes.deletedUnicastRoutes4.put(prefix, |
414 | bgpRouteEntry); | 409 | bgpRouteEntry); |
... | @@ -417,7 +412,7 @@ final class BgpUpdate { | ... | @@ -417,7 +412,7 @@ final class BgpUpdate { |
417 | 412 | ||
418 | // The deleted IPv6 routes | 413 | // The deleted IPv6 routes |
419 | for (Ip6Prefix prefix : mpNlri.nlri6) { | 414 | for (Ip6Prefix prefix : mpNlri.nlri6) { |
420 | - bgpRouteEntry = bgpSession.bgpRibIn6().get(prefix); | 415 | + bgpRouteEntry = bgpSession.findBgpRoute(prefix); |
421 | if (bgpRouteEntry != null) { | 416 | if (bgpRouteEntry != null) { |
422 | decodedBgpRoutes.deletedUnicastRoutes6.put(prefix, | 417 | decodedBgpRoutes.deletedUnicastRoutes6.put(prefix, |
423 | bgpRouteEntry); | 418 | bgpRouteEntry); |
... | @@ -456,8 +451,6 @@ final class BgpUpdate { | ... | @@ -456,8 +451,6 @@ final class BgpUpdate { |
456 | } | 451 | } |
457 | 452 | ||
458 | // The added IPv6 routes | 453 | // The added IPv6 routes |
459 | - // TODO: fix/enable for IPv6 | ||
460 | - /* | ||
461 | for (Ip6Prefix prefix : mpNlri.nlri6) { | 454 | for (Ip6Prefix prefix : mpNlri.nlri6) { |
462 | bgpRouteEntry = | 455 | bgpRouteEntry = |
463 | new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop6, | 456 | new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop6, |
... | @@ -479,7 +472,6 @@ final class BgpUpdate { | ... | @@ -479,7 +472,6 @@ final class BgpUpdate { |
479 | decodedBgpRoutes.addedUnicastRoutes6.put(prefix, | 472 | decodedBgpRoutes.addedUnicastRoutes6.put(prefix, |
480 | bgpRouteEntry); | 473 | bgpRouteEntry); |
481 | } | 474 | } |
482 | - */ | ||
483 | } | 475 | } |
484 | } | 476 | } |
485 | 477 | ... | ... |
... | @@ -46,7 +46,10 @@ public class BgpRoutesListCommand extends AbstractShellCommand { | ... | @@ -46,7 +46,10 @@ public class BgpRoutesListCommand extends AbstractShellCommand { |
46 | required = false, multiValued = false) | 46 | required = false, multiValued = false) |
47 | private String bgpNeighbor; | 47 | private String bgpNeighbor; |
48 | 48 | ||
49 | - private static final String FORMAT_SUMMARY = "Total BGP routes = %d"; | 49 | + private static final String FORMAT_SUMMARY_V4 = |
50 | + "Total BGP IPv4 routes = %d"; | ||
51 | + private static final String FORMAT_SUMMARY_V6 = | ||
52 | + "Total BGP IPv6 routes = %d"; | ||
50 | private static final String FORMAT_HEADER = | 53 | private static final String FORMAT_HEADER = |
51 | " Network Next Hop Origin LocalPref MED BGP-ID"; | 54 | " Network Next Hop Origin LocalPref MED BGP-ID"; |
52 | private static final String FORMAT_ROUTE_LINE1 = | 55 | private static final String FORMAT_ROUTE_LINE1 = |
... | @@ -60,7 +63,7 @@ public class BgpRoutesListCommand extends AbstractShellCommand { | ... | @@ -60,7 +63,7 @@ public class BgpRoutesListCommand extends AbstractShellCommand { |
60 | 63 | ||
61 | // Print summary of the routes | 64 | // Print summary of the routes |
62 | if (routesSummary) { | 65 | if (routesSummary) { |
63 | - printSummary(service.getBgpRoutes()); | 66 | + printSummary(service.getBgpRoutes4(), service.getBgpRoutes6()); |
64 | return; | 67 | return; |
65 | } | 68 | } |
66 | 69 | ||
... | @@ -81,43 +84,61 @@ public class BgpRoutesListCommand extends AbstractShellCommand { | ... | @@ -81,43 +84,61 @@ public class BgpRoutesListCommand extends AbstractShellCommand { |
81 | 84 | ||
82 | // Print the routes | 85 | // Print the routes |
83 | if (foundBgpSession != null) { | 86 | if (foundBgpSession != null) { |
84 | - printRoutes(foundBgpSession.bgpRibIn4().values()); | 87 | + printRoutes(foundBgpSession.getBgpRibIn4(), |
85 | - printRoutes(foundBgpSession.bgpRibIn6().values()); | 88 | + foundBgpSession.getBgpRibIn6()); |
86 | } else { | 89 | } else { |
87 | - printRoutes(service.getBgpRoutes()); | 90 | + printRoutes(service.getBgpRoutes4(), service.getBgpRoutes6()); |
88 | } | 91 | } |
89 | } | 92 | } |
90 | 93 | ||
91 | /** | 94 | /** |
92 | * Prints summary of the routes. | 95 | * Prints summary of the routes. |
93 | * | 96 | * |
94 | - * @param routes the routes | 97 | + * @param routes4 the IPv4 routes |
98 | + * @param routes6 the IPv6 routes | ||
95 | */ | 99 | */ |
96 | - private void printSummary(Collection<BgpRouteEntry> routes) { | 100 | + private void printSummary(Collection<BgpRouteEntry> routes4, |
101 | + Collection<BgpRouteEntry> routes6) { | ||
97 | if (outputJson()) { | 102 | if (outputJson()) { |
98 | ObjectMapper mapper = new ObjectMapper(); | 103 | ObjectMapper mapper = new ObjectMapper(); |
99 | ObjectNode result = mapper.createObjectNode(); | 104 | ObjectNode result = mapper.createObjectNode(); |
100 | - result.put("totalRoutes", routes.size()); | 105 | + result.put("totalRoutes4", routes4.size()); |
106 | + result.put("totalRoutes6", routes6.size()); | ||
101 | print("%s", result); | 107 | print("%s", result); |
102 | } else { | 108 | } else { |
103 | - print(FORMAT_SUMMARY, routes.size()); | 109 | + print(FORMAT_SUMMARY_V4, routes4.size()); |
110 | + print(FORMAT_SUMMARY_V6, routes6.size()); | ||
104 | } | 111 | } |
105 | } | 112 | } |
106 | 113 | ||
107 | /** | 114 | /** |
108 | * Prints all routes. | 115 | * Prints all routes. |
109 | * | 116 | * |
110 | - * @param routes the routes to print | 117 | + * @param routes4 the IPv4 routes to print |
118 | + * @param routes6 the IPv6 routes to print | ||
111 | */ | 119 | */ |
112 | - private void printRoutes(Collection<BgpRouteEntry> routes) { | 120 | + private void printRoutes(Collection<BgpRouteEntry> routes4, |
121 | + Collection<BgpRouteEntry> routes6) { | ||
113 | if (outputJson()) { | 122 | if (outputJson()) { |
114 | - print("%s", json(routes)); | 123 | + ObjectMapper mapper = new ObjectMapper(); |
124 | + ObjectNode result = mapper.createObjectNode(); | ||
125 | + result.put("routes4", json(routes4)); | ||
126 | + result.put("routes6", json(routes6)); | ||
127 | + print("%s", result); | ||
115 | } else { | 128 | } else { |
129 | + // The IPv4 routes | ||
116 | print(FORMAT_HEADER); | 130 | print(FORMAT_HEADER); |
117 | - for (BgpRouteEntry route : routes) { | 131 | + for (BgpRouteEntry route : routes4) { |
132 | + printRoute(route); | ||
133 | + } | ||
134 | + print(FORMAT_SUMMARY_V4, routes4.size()); | ||
135 | + print(""); // Empty separator line | ||
136 | + // The IPv6 routes | ||
137 | + print(FORMAT_HEADER); | ||
138 | + for (BgpRouteEntry route : routes6) { | ||
118 | printRoute(route); | 139 | printRoute(route); |
119 | } | 140 | } |
120 | - print(FORMAT_SUMMARY, routes.size()); | 141 | + print(FORMAT_SUMMARY_V6, routes6.size()); |
121 | } | 142 | } |
122 | } | 143 | } |
123 | 144 | ... | ... |
... | @@ -38,7 +38,10 @@ public class RoutesListCommand extends AbstractShellCommand { | ... | @@ -38,7 +38,10 @@ public class RoutesListCommand extends AbstractShellCommand { |
38 | required = false, multiValued = false) | 38 | required = false, multiValued = false) |
39 | private boolean routesSummary = false; | 39 | private boolean routesSummary = false; |
40 | 40 | ||
41 | - private static final String FORMAT_SUMMARY = "Total SDN-IP routes = %d"; | 41 | + private static final String FORMAT_SUMMARY_V4 = |
42 | + "Total SDN-IP IPv4 routes = %d"; | ||
43 | + private static final String FORMAT_SUMMARY_V6 = | ||
44 | + "Total SDN-IP IPv6 routes = %d"; | ||
42 | private static final String FORMAT_HEADER = | 45 | private static final String FORMAT_HEADER = |
43 | " Network Next Hop"; | 46 | " Network Next Hop"; |
44 | private static final String FORMAT_ROUTE = | 47 | private static final String FORMAT_ROUTE = |
... | @@ -50,44 +53,62 @@ public class RoutesListCommand extends AbstractShellCommand { | ... | @@ -50,44 +53,62 @@ public class RoutesListCommand extends AbstractShellCommand { |
50 | 53 | ||
51 | // Print summary of the routes | 54 | // Print summary of the routes |
52 | if (routesSummary) { | 55 | if (routesSummary) { |
53 | - printSummary(service.getRoutes()); | 56 | + printSummary(service.getRoutes4(), service.getRoutes6()); |
54 | return; | 57 | return; |
55 | } | 58 | } |
56 | 59 | ||
57 | // Print all routes | 60 | // Print all routes |
58 | - printRoutes(service.getRoutes()); | 61 | + printRoutes(service.getRoutes4(), service.getRoutes6()); |
59 | } | 62 | } |
60 | 63 | ||
61 | /** | 64 | /** |
62 | * Prints summary of the routes. | 65 | * Prints summary of the routes. |
63 | * | 66 | * |
64 | - * @param routes the routes | 67 | + * @param routes4 the IPv4 routes |
68 | + * @param routes6 the IPv6 routes | ||
65 | */ | 69 | */ |
66 | - private void printSummary(Collection<RouteEntry> routes) { | 70 | + private void printSummary(Collection<RouteEntry> routes4, |
71 | + Collection<RouteEntry> routes6) { | ||
67 | if (outputJson()) { | 72 | if (outputJson()) { |
68 | ObjectMapper mapper = new ObjectMapper(); | 73 | ObjectMapper mapper = new ObjectMapper(); |
69 | ObjectNode result = mapper.createObjectNode(); | 74 | ObjectNode result = mapper.createObjectNode(); |
70 | - result.put("totalRoutes", routes.size()); | 75 | + result.put("totalRoutes4", routes4.size()); |
76 | + result.put("totalRoutes6", routes6.size()); | ||
71 | print("%s", result); | 77 | print("%s", result); |
72 | } else { | 78 | } else { |
73 | - print(FORMAT_SUMMARY, routes.size()); | 79 | + print(FORMAT_SUMMARY_V4, routes4.size()); |
80 | + print(FORMAT_SUMMARY_V6, routes6.size()); | ||
74 | } | 81 | } |
75 | } | 82 | } |
76 | 83 | ||
77 | /** | 84 | /** |
78 | * Prints all routes. | 85 | * Prints all routes. |
79 | * | 86 | * |
80 | - * @param routes the routes to print | 87 | + * @param routes4 the IPv4 routes to print |
88 | + * @param routes6 the IPv6 routes to print | ||
81 | */ | 89 | */ |
82 | - private void printRoutes(Collection<RouteEntry> routes) { | 90 | + private void printRoutes(Collection<RouteEntry> routes4, |
91 | + Collection<RouteEntry> routes6) { | ||
83 | if (outputJson()) { | 92 | if (outputJson()) { |
84 | - print("%s", json(routes)); | 93 | + ObjectMapper mapper = new ObjectMapper(); |
94 | + ObjectNode result = mapper.createObjectNode(); | ||
95 | + result.put("routes4", json(routes4)); | ||
96 | + result.put("routes6", json(routes6)); | ||
97 | + print("%s", result); | ||
85 | } else { | 98 | } else { |
99 | + // The IPv4 routes | ||
86 | print(FORMAT_HEADER); | 100 | print(FORMAT_HEADER); |
87 | - for (RouteEntry route : routes) { | 101 | + for (RouteEntry route : routes4) { |
102 | + printRoute(route); | ||
103 | + } | ||
104 | + print(FORMAT_SUMMARY_V4, routes4.size()); | ||
105 | + print(""); // Empty separator line | ||
106 | + // The IPv6 routes | ||
107 | + print(FORMAT_HEADER); | ||
108 | + for (RouteEntry route : routes6) { | ||
88 | printRoute(route); | 109 | printRoute(route); |
89 | } | 110 | } |
90 | - print(FORMAT_SUMMARY, routes.size()); | 111 | + print(FORMAT_SUMMARY_V6, routes6.size()); |
91 | } | 112 | } |
92 | } | 113 | } |
93 | 114 | ... | ... |
... | @@ -61,8 +61,8 @@ import org.onosproject.net.provider.ProviderId; | ... | @@ -61,8 +61,8 @@ import org.onosproject.net.provider.ProviderId; |
61 | import org.onosproject.sdnip.config.Interface; | 61 | import org.onosproject.sdnip.config.Interface; |
62 | import org.onlab.packet.Ethernet; | 62 | import org.onlab.packet.Ethernet; |
63 | import org.onlab.packet.IpAddress; | 63 | import org.onlab.packet.IpAddress; |
64 | -import org.onlab.packet.Ip4Address; | ||
65 | import org.onlab.packet.IpPrefix; | 64 | import org.onlab.packet.IpPrefix; |
65 | +import org.onlab.packet.Ip4Address; | ||
66 | import org.onlab.packet.Ip4Prefix; | 66 | import org.onlab.packet.Ip4Prefix; |
67 | import org.onlab.packet.MacAddress; | 67 | import org.onlab.packet.MacAddress; |
68 | import org.onlab.packet.VlanId; | 68 | import org.onlab.packet.VlanId; |
... | @@ -308,9 +308,9 @@ public class IntentSyncTest extends AbstractIntentTest { | ... | @@ -308,9 +308,9 @@ public class IntentSyncTest extends AbstractIntentTest { |
308 | routeEntry6); | 308 | routeEntry6); |
309 | ribTable.put(RouteEntry.createBinaryString(routeEntry7.prefix()), | 309 | ribTable.put(RouteEntry.createBinaryString(routeEntry7.prefix()), |
310 | routeEntry7); | 310 | routeEntry7); |
311 | - TestUtils.setField(router, "ribTable", ribTable); | 311 | + TestUtils.setField(router, "ribTable4", ribTable); |
312 | 312 | ||
313 | - ConcurrentHashMap<Ip4Prefix, MultiPointToSinglePointIntent> | 313 | + ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent> |
314 | routeIntents = new ConcurrentHashMap<>(); | 314 | routeIntents = new ConcurrentHashMap<>(); |
315 | routeIntents.put(routeEntry1.prefix(), intent1); | 315 | routeIntents.put(routeEntry1.prefix(), intent1); |
316 | routeIntents.put(routeEntry3.prefix(), intent3); | 316 | routeIntents.put(routeEntry3.prefix(), intent3); |
... | @@ -364,12 +364,12 @@ public class IntentSyncTest extends AbstractIntentTest { | ... | @@ -364,12 +364,12 @@ public class IntentSyncTest extends AbstractIntentTest { |
364 | intentSynchronizer.synchronizeIntents(); | 364 | intentSynchronizer.synchronizeIntents(); |
365 | 365 | ||
366 | // Verify | 366 | // Verify |
367 | - assertEquals(router.getRoutes().size(), 6); | 367 | + assertEquals(router.getRoutes4().size(), 6); |
368 | - assertTrue(router.getRoutes().contains(routeEntry1)); | 368 | + assertTrue(router.getRoutes4().contains(routeEntry1)); |
369 | - assertTrue(router.getRoutes().contains(routeEntry3)); | 369 | + assertTrue(router.getRoutes4().contains(routeEntry3)); |
370 | - assertTrue(router.getRoutes().contains(routeEntry4Update)); | 370 | + assertTrue(router.getRoutes4().contains(routeEntry4Update)); |
371 | - assertTrue(router.getRoutes().contains(routeEntry5)); | 371 | + assertTrue(router.getRoutes4().contains(routeEntry5)); |
372 | - assertTrue(router.getRoutes().contains(routeEntry6)); | 372 | + assertTrue(router.getRoutes4().contains(routeEntry6)); |
373 | 373 | ||
374 | assertEquals(intentSynchronizer.getRouteIntents().size(), 6); | 374 | assertEquals(intentSynchronizer.getRouteIntents().size(), 6); |
375 | assertTrue(intentSynchronizer.getRouteIntents().contains(intent1)); | 375 | assertTrue(intentSynchronizer.getRouteIntents().contains(intent1)); |
... | @@ -390,12 +390,17 @@ public class IntentSyncTest extends AbstractIntentTest { | ... | @@ -390,12 +390,17 @@ public class IntentSyncTest extends AbstractIntentTest { |
390 | * @param egressPoint to which packets should be sent | 390 | * @param egressPoint to which packets should be sent |
391 | * @return the constructed MultiPointToSinglePointIntent | 391 | * @return the constructed MultiPointToSinglePointIntent |
392 | */ | 392 | */ |
393 | - private MultiPointToSinglePointIntent intentBuilder(Ip4Prefix ipPrefix, | 393 | + private MultiPointToSinglePointIntent intentBuilder(IpPrefix ipPrefix, |
394 | String nextHopMacAddress, ConnectPoint egressPoint) { | 394 | String nextHopMacAddress, ConnectPoint egressPoint) { |
395 | 395 | ||
396 | TrafficSelector.Builder selectorBuilder = | 396 | TrafficSelector.Builder selectorBuilder = |
397 | DefaultTrafficSelector.builder(); | 397 | DefaultTrafficSelector.builder(); |
398 | - selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipPrefix); | 398 | + if (ipPrefix.version() == Ip4Address.VERSION) { |
399 | + selectorBuilder.matchEthType(Ethernet.TYPE_IPV4); // IPv4 | ||
400 | + } else { | ||
401 | + selectorBuilder.matchEthType(Ethernet.TYPE_IPV6); // IPv6 | ||
402 | + } | ||
403 | + selectorBuilder.matchIPDst(ipPrefix); | ||
399 | 404 | ||
400 | TrafficTreatment.Builder treatmentBuilder = | 405 | TrafficTreatment.Builder treatmentBuilder = |
401 | DefaultTrafficTreatment.builder(); | 406 | DefaultTrafficTreatment.builder(); | ... | ... |
... | @@ -63,8 +63,8 @@ import org.onosproject.sdnip.config.Interface; | ... | @@ -63,8 +63,8 @@ import org.onosproject.sdnip.config.Interface; |
63 | import org.onosproject.sdnip.config.SdnIpConfigurationService; | 63 | import org.onosproject.sdnip.config.SdnIpConfigurationService; |
64 | import org.onlab.packet.Ethernet; | 64 | import org.onlab.packet.Ethernet; |
65 | import org.onlab.packet.IpAddress; | 65 | import org.onlab.packet.IpAddress; |
66 | -import org.onlab.packet.Ip4Address; | ||
67 | import org.onlab.packet.IpPrefix; | 66 | import org.onlab.packet.IpPrefix; |
67 | +import org.onlab.packet.Ip4Address; | ||
68 | import org.onlab.packet.Ip4Prefix; | 68 | import org.onlab.packet.Ip4Prefix; |
69 | import org.onlab.packet.MacAddress; | 69 | import org.onlab.packet.MacAddress; |
70 | import org.onlab.packet.VlanId; | 70 | import org.onlab.packet.VlanId; |
... | @@ -239,8 +239,8 @@ public class RouterAsyncArpTest extends AbstractIntentTest { | ... | @@ -239,8 +239,8 @@ public class RouterAsyncArpTest extends AbstractIntentTest { |
239 | new HostEvent(HostEvent.Type.HOST_ADDED, host)); | 239 | new HostEvent(HostEvent.Type.HOST_ADDED, host)); |
240 | 240 | ||
241 | // Verify | 241 | // Verify |
242 | - assertEquals(router.getRoutes().size(), 1); | 242 | + assertEquals(router.getRoutes4().size(), 1); |
243 | - assertTrue(router.getRoutes().contains(routeEntry)); | 243 | + assertTrue(router.getRoutes4().contains(routeEntry)); |
244 | assertEquals(intentSynchronizer.getRouteIntents().size(), 1); | 244 | assertEquals(intentSynchronizer.getRouteIntents().size(), 1); |
245 | Intent firstIntent = | 245 | Intent firstIntent = |
246 | intentSynchronizer.getRouteIntents().iterator().next(); | 246 | intentSynchronizer.getRouteIntents().iterator().next(); |
... | @@ -333,8 +333,8 @@ public class RouterAsyncArpTest extends AbstractIntentTest { | ... | @@ -333,8 +333,8 @@ public class RouterAsyncArpTest extends AbstractIntentTest { |
333 | new HostEvent(HostEvent.Type.HOST_ADDED, host)); | 333 | new HostEvent(HostEvent.Type.HOST_ADDED, host)); |
334 | 334 | ||
335 | // Verify | 335 | // Verify |
336 | - assertEquals(router.getRoutes().size(), 1); | 336 | + assertEquals(router.getRoutes4().size(), 1); |
337 | - assertTrue(router.getRoutes().contains(routeEntryUpdate)); | 337 | + assertTrue(router.getRoutes4().contains(routeEntryUpdate)); |
338 | assertEquals(intentSynchronizer.getRouteIntents().size(), 1); | 338 | assertEquals(intentSynchronizer.getRouteIntents().size(), 1); |
339 | Intent firstIntent = | 339 | Intent firstIntent = |
340 | intentSynchronizer.getRouteIntents().iterator().next(); | 340 | intentSynchronizer.getRouteIntents().iterator().next(); |
... | @@ -380,7 +380,7 @@ public class RouterAsyncArpTest extends AbstractIntentTest { | ... | @@ -380,7 +380,7 @@ public class RouterAsyncArpTest extends AbstractIntentTest { |
380 | router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | 380 | router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); |
381 | 381 | ||
382 | // Verify | 382 | // Verify |
383 | - assertEquals(router.getRoutes().size(), 0); | 383 | + assertEquals(router.getRoutes4().size(), 0); |
384 | assertEquals(intentSynchronizer.getRouteIntents().size(), 0); | 384 | assertEquals(intentSynchronizer.getRouteIntents().size(), 0); |
385 | verify(intentService); | 385 | verify(intentService); |
386 | } | 386 | } |
... | @@ -424,7 +424,7 @@ public class RouterAsyncArpTest extends AbstractIntentTest { | ... | @@ -424,7 +424,7 @@ public class RouterAsyncArpTest extends AbstractIntentTest { |
424 | new DefaultByteArrayNodeFactory()); | 424 | new DefaultByteArrayNodeFactory()); |
425 | ribTable.put(RouteEntry.createBinaryString(routeEntry.prefix()), | 425 | ribTable.put(RouteEntry.createBinaryString(routeEntry.prefix()), |
426 | routeEntry); | 426 | routeEntry); |
427 | - TestUtils.setField(router, "ribTable", ribTable); | 427 | + TestUtils.setField(router, "ribTable4", ribTable); |
428 | } | 428 | } |
429 | 429 | ||
430 | /** | 430 | /** |
... | @@ -436,7 +436,7 @@ public class RouterAsyncArpTest extends AbstractIntentTest { | ... | @@ -436,7 +436,7 @@ public class RouterAsyncArpTest extends AbstractIntentTest { |
436 | MultiPointToSinglePointIntent intent) | 436 | MultiPointToSinglePointIntent intent) |
437 | throws TestUtilsException { | 437 | throws TestUtilsException { |
438 | 438 | ||
439 | - ConcurrentHashMap<Ip4Prefix, MultiPointToSinglePointIntent> | 439 | + ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent> |
440 | routeIntents = new ConcurrentHashMap<>(); | 440 | routeIntents = new ConcurrentHashMap<>(); |
441 | routeIntents.put(routeEntry.prefix(), intent); | 441 | routeIntents.put(routeEntry.prefix(), intent); |
442 | TestUtils.setField(intentSynchronizer, "routeIntents", routeIntents); | 442 | TestUtils.setField(intentSynchronizer, "routeIntents", routeIntents); | ... | ... |
... | @@ -36,10 +36,10 @@ import org.junit.Test; | ... | @@ -36,10 +36,10 @@ import org.junit.Test; |
36 | import org.onlab.junit.TestUtils; | 36 | import org.onlab.junit.TestUtils; |
37 | import org.onlab.junit.TestUtils.TestUtilsException; | 37 | import org.onlab.junit.TestUtils.TestUtilsException; |
38 | import org.onlab.packet.Ethernet; | 38 | import org.onlab.packet.Ethernet; |
39 | -import org.onlab.packet.Ip4Address; | ||
40 | -import org.onlab.packet.Ip4Prefix; | ||
41 | import org.onlab.packet.IpAddress; | 39 | import org.onlab.packet.IpAddress; |
42 | import org.onlab.packet.IpPrefix; | 40 | import org.onlab.packet.IpPrefix; |
41 | +import org.onlab.packet.Ip4Address; | ||
42 | +import org.onlab.packet.Ip4Prefix; | ||
43 | import org.onlab.packet.MacAddress; | 43 | import org.onlab.packet.MacAddress; |
44 | import org.onlab.packet.VlanId; | 44 | import org.onlab.packet.VlanId; |
45 | import org.onosproject.core.ApplicationId; | 45 | import org.onosproject.core.ApplicationId; |
... | @@ -278,8 +278,8 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -278,8 +278,8 @@ public class RouterTest extends AbstractIntentTest { |
278 | router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | 278 | router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); |
279 | 279 | ||
280 | // Verify | 280 | // Verify |
281 | - assertEquals(router.getRoutes().size(), 1); | 281 | + assertEquals(router.getRoutes4().size(), 1); |
282 | - assertTrue(router.getRoutes().contains(routeEntry)); | 282 | + assertTrue(router.getRoutes4().contains(routeEntry)); |
283 | assertEquals(intentSynchronizer.getRouteIntents().size(), 1); | 283 | assertEquals(intentSynchronizer.getRouteIntents().size(), 1); |
284 | Intent firstIntent = | 284 | Intent firstIntent = |
285 | intentSynchronizer.getRouteIntents().iterator().next(); | 285 | intentSynchronizer.getRouteIntents().iterator().next(); |
... | @@ -349,8 +349,8 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -349,8 +349,8 @@ public class RouterTest extends AbstractIntentTest { |
349 | router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | 349 | router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); |
350 | 350 | ||
351 | // Verify | 351 | // Verify |
352 | - assertEquals(router.getRoutes().size(), 1); | 352 | + assertEquals(router.getRoutes4().size(), 1); |
353 | - assertTrue(router.getRoutes().contains(routeEntryUpdate)); | 353 | + assertTrue(router.getRoutes4().contains(routeEntryUpdate)); |
354 | assertEquals(intentSynchronizer.getRouteIntents().size(), 1); | 354 | assertEquals(intentSynchronizer.getRouteIntents().size(), 1); |
355 | Intent firstIntent = | 355 | Intent firstIntent = |
356 | intentSynchronizer.getRouteIntents().iterator().next(); | 356 | intentSynchronizer.getRouteIntents().iterator().next(); |
... | @@ -393,7 +393,7 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -393,7 +393,7 @@ public class RouterTest extends AbstractIntentTest { |
393 | router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | 393 | router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); |
394 | 394 | ||
395 | // Verify | 395 | // Verify |
396 | - assertEquals(router.getRoutes().size(), 0); | 396 | + assertEquals(router.getRoutes4().size(), 0); |
397 | assertEquals(intentSynchronizer.getRouteIntents().size(), 0); | 397 | assertEquals(intentSynchronizer.getRouteIntents().size(), 0); |
398 | verify(intentService); | 398 | verify(intentService); |
399 | } | 399 | } |
... | @@ -422,8 +422,8 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -422,8 +422,8 @@ public class RouterTest extends AbstractIntentTest { |
422 | router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | 422 | router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); |
423 | 423 | ||
424 | // Verify | 424 | // Verify |
425 | - assertEquals(router.getRoutes().size(), 1); | 425 | + assertEquals(router.getRoutes4().size(), 1); |
426 | - assertTrue(router.getRoutes().contains(routeEntry)); | 426 | + assertTrue(router.getRoutes4().contains(routeEntry)); |
427 | assertEquals(intentSynchronizer.getRouteIntents().size(), 0); | 427 | assertEquals(intentSynchronizer.getRouteIntents().size(), 0); |
428 | verify(intentService); | 428 | verify(intentService); |
429 | } | 429 | } | ... | ... |
... | @@ -59,10 +59,10 @@ import org.onosproject.sdnip.config.BgpPeer; | ... | @@ -59,10 +59,10 @@ import org.onosproject.sdnip.config.BgpPeer; |
59 | import org.onosproject.sdnip.config.Interface; | 59 | import org.onosproject.sdnip.config.Interface; |
60 | import org.onosproject.sdnip.config.SdnIpConfigurationService; | 60 | import org.onosproject.sdnip.config.SdnIpConfigurationService; |
61 | import org.onlab.packet.Ethernet; | 61 | import org.onlab.packet.Ethernet; |
62 | -import org.onlab.packet.Ip4Address; | ||
63 | -import org.onlab.packet.Ip4Prefix; | ||
64 | import org.onlab.packet.IpAddress; | 62 | import org.onlab.packet.IpAddress; |
65 | import org.onlab.packet.IpPrefix; | 63 | import org.onlab.packet.IpPrefix; |
64 | +import org.onlab.packet.Ip4Address; | ||
65 | +import org.onlab.packet.Ip4Prefix; | ||
66 | import org.onlab.packet.MacAddress; | 66 | import org.onlab.packet.MacAddress; |
67 | 67 | ||
68 | import com.google.common.collect.Sets; | 68 | import com.google.common.collect.Sets; |
... | @@ -226,7 +226,7 @@ public class SdnIpTest extends AbstractIntentTest { | ... | @@ -226,7 +226,7 @@ public class SdnIpTest extends AbstractIntentTest { |
226 | reset(intentService); | 226 | reset(intentService); |
227 | 227 | ||
228 | for (RouteUpdate update : routeUpdates) { | 228 | for (RouteUpdate update : routeUpdates) { |
229 | - Ip4Address nextHopAddress = update.routeEntry().nextHop(); | 229 | + IpAddress nextHopAddress = update.routeEntry().nextHop(); |
230 | 230 | ||
231 | // Find out the egress ConnectPoint | 231 | // Find out the egress ConnectPoint |
232 | ConnectPoint egressConnectPoint = getConnectPoint(nextHopAddress); | 232 | ConnectPoint egressConnectPoint = getConnectPoint(nextHopAddress); |
... | @@ -255,7 +255,7 @@ public class SdnIpTest extends AbstractIntentTest { | ... | @@ -255,7 +255,7 @@ public class SdnIpTest extends AbstractIntentTest { |
255 | 255 | ||
256 | latch.await(5000, TimeUnit.MILLISECONDS); | 256 | latch.await(5000, TimeUnit.MILLISECONDS); |
257 | 257 | ||
258 | - assertEquals(router.getRoutes().size(), numRoutes); | 258 | + assertEquals(router.getRoutes4().size(), numRoutes); |
259 | assertEquals(intentSynchronizer.getRouteIntents().size(), | 259 | assertEquals(intentSynchronizer.getRouteIntents().size(), |
260 | numRoutes); | 260 | numRoutes); |
261 | 261 | ||
... | @@ -286,7 +286,7 @@ public class SdnIpTest extends AbstractIntentTest { | ... | @@ -286,7 +286,7 @@ public class SdnIpTest extends AbstractIntentTest { |
286 | reset(intentService); | 286 | reset(intentService); |
287 | 287 | ||
288 | for (RouteUpdate update : routeUpdates) { | 288 | for (RouteUpdate update : routeUpdates) { |
289 | - Ip4Address nextHopAddress = update.routeEntry().nextHop(); | 289 | + IpAddress nextHopAddress = update.routeEntry().nextHop(); |
290 | 290 | ||
291 | // Find out the egress ConnectPoint | 291 | // Find out the egress ConnectPoint |
292 | ConnectPoint egressConnectPoint = getConnectPoint(nextHopAddress); | 292 | ConnectPoint egressConnectPoint = getConnectPoint(nextHopAddress); |
... | @@ -333,7 +333,7 @@ public class SdnIpTest extends AbstractIntentTest { | ... | @@ -333,7 +333,7 @@ public class SdnIpTest extends AbstractIntentTest { |
333 | 333 | ||
334 | deleteCount.await(5000, TimeUnit.MILLISECONDS); | 334 | deleteCount.await(5000, TimeUnit.MILLISECONDS); |
335 | 335 | ||
336 | - assertEquals(0, router.getRoutes().size()); | 336 | + assertEquals(0, router.getRoutes4().size()); |
337 | assertEquals(0, intentSynchronizer.getRouteIntents().size()); | 337 | assertEquals(0, intentSynchronizer.getRouteIntents().size()); |
338 | verify(intentService); | 338 | verify(intentService); |
339 | } | 339 | } | ... | ... |
... | @@ -303,7 +303,7 @@ public class BgpSessionManagerTest { | ... | @@ -303,7 +303,7 @@ public class BgpSessionManagerTest { |
303 | private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession, | 303 | private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession, |
304 | long expectedRoutes) | 304 | long expectedRoutes) |
305 | throws InterruptedException { | 305 | throws InterruptedException { |
306 | - Collection<BgpRouteEntry> bgpRibIn = bgpSession.bgpRibIn4().values(); | 306 | + Collection<BgpRouteEntry> bgpRibIn = bgpSession.getBgpRibIn4(); |
307 | 307 | ||
308 | final int maxChecks = 500; // Max wait of 5 seconds | 308 | final int maxChecks = 500; // Max wait of 5 seconds |
309 | for (int i = 0; i < maxChecks; i++) { | 309 | for (int i = 0; i < maxChecks; i++) { |
... | @@ -311,7 +311,7 @@ public class BgpSessionManagerTest { | ... | @@ -311,7 +311,7 @@ public class BgpSessionManagerTest { |
311 | break; | 311 | break; |
312 | } | 312 | } |
313 | Thread.sleep(10); | 313 | Thread.sleep(10); |
314 | - bgpRibIn = bgpSession.bgpRibIn4().values(); | 314 | + bgpRibIn = bgpSession.getBgpRibIn4(); |
315 | } | 315 | } |
316 | 316 | ||
317 | return bgpRibIn; | 317 | return bgpRibIn; |
... | @@ -329,7 +329,8 @@ public class BgpSessionManagerTest { | ... | @@ -329,7 +329,8 @@ public class BgpSessionManagerTest { |
329 | */ | 329 | */ |
330 | private Collection<BgpRouteEntry> waitForBgpRoutes(long expectedRoutes) | 330 | private Collection<BgpRouteEntry> waitForBgpRoutes(long expectedRoutes) |
331 | throws InterruptedException { | 331 | throws InterruptedException { |
332 | - Collection<BgpRouteEntry> bgpRoutes = bgpSessionManager.getBgpRoutes(); | 332 | + Collection<BgpRouteEntry> bgpRoutes = |
333 | + bgpSessionManager.getBgpRoutes4(); | ||
333 | 334 | ||
334 | final int maxChecks = 500; // Max wait of 5 seconds | 335 | final int maxChecks = 500; // Max wait of 5 seconds |
335 | for (int i = 0; i < maxChecks; i++) { | 336 | for (int i = 0; i < maxChecks; i++) { |
... | @@ -337,7 +338,7 @@ public class BgpSessionManagerTest { | ... | @@ -337,7 +338,7 @@ public class BgpSessionManagerTest { |
337 | break; | 338 | break; |
338 | } | 339 | } |
339 | Thread.sleep(10); | 340 | Thread.sleep(10); |
340 | - bgpRoutes = bgpSessionManager.getBgpRoutes(); | 341 | + bgpRoutes = bgpSessionManager.getBgpRoutes4(); |
341 | } | 342 | } |
342 | 343 | ||
343 | return bgpRoutes; | 344 | return bgpRoutes; | ... | ... |
-
Please register or login to post a comment