Pavlin Radoslavov

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
...@@ -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) {
355 + if (oldNextHop.equals(routeEntry.nextHop())) {
356 + return null; // No change
357 + }
358 + //
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 + //
267 withdrawPrefixes.add(routeEntry.prefix()); 363 withdrawPrefixes.add(routeEntry.prefix());
268 } 364 }
269 - if (nextHop != null && nextHop.equals(routeEntry.nextHop())) {
270 - return null;
271 - }
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,26 +516,26 @@ public class Router implements RouteListener { ...@@ -415,26 +516,26 @@ 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
429 Set<RouteEntry> routesToPush = 533 Set<RouteEntry> routesToPush =
430 - routesWaitingOnArp.removeAll(ipAddress); 534 + routesWaitingOnArp.removeAll(ipAddress);
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
...@@ -551,7 +620,7 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -551,7 +620,7 @@ public class BgpSession extends SimpleChannelHandler {
551 620
552 @Override 621 @Override
553 public void channelClosed(ChannelHandlerContext ctx, 622 public void channelClosed(ChannelHandlerContext ctx,
554 - ChannelStateEvent channelEvent) { 623 + ChannelStateEvent channelEvent) {
555 bgpSessionManager.removeSessionChannel(channelEvent.getChannel()); 624 bgpSessionManager.removeSessionChannel(channelEvent.getChannel());
556 } 625 }
557 626
...@@ -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.
87 * 108 *
88 - * @return the BGP routes 109 + * @return the selected IPv4 BGP routes among all BGP sessions
89 */ 110 */
90 - public Collection<BgpRouteEntry> getBgpRoutes() { 111 + public Collection<BgpRouteEntry> getBgpRoutes4() {
91 - return bgpRoutes.values(); 112 + return bgpRoutes4.values();
113 + }
114 +
115 + /**
116 + * Gets the selected IPv6 BGP routes among all BGP sessions.
117 + *
118 + * @return the selected IPv6 BGP routes among all BGP sessions
119 + */
120 + public Collection<BgpRouteEntry> getBgpRoutes6() {
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,9 +258,9 @@ public class BgpSessionManager { ...@@ -187,9 +258,9 @@ 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
195 public ChannelPipeline getPipeline() throws Exception { 266 public ChannelPipeline getPipeline() throws Exception {
...@@ -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
130 + print(FORMAT_HEADER);
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
116 print(FORMAT_HEADER); 137 print(FORMAT_HEADER);
117 - for (BgpRouteEntry route : routes) { 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
100 + print(FORMAT_HEADER);
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
86 print(FORMAT_HEADER); 107 print(FORMAT_HEADER);
87 - for (RouteEntry route : routes) { 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,10 +308,10 @@ public class IntentSyncTest extends AbstractIntentTest { ...@@ -308,10 +308,10 @@ 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);
317 routeIntents.put(routeEntry4Update.prefix(), intent4Update); 317 routeIntents.put(routeEntry4Update.prefix(), intent4Update);
...@@ -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;
......