Pavlin Radoslavov

Work toward IPv6 support in BGP: implement decoding of the

BGP UPDATE attributes: MP_REACH_NLRI and MP_UNREACH_NLRI (RFC 4760).

Note: currently, the IPv6 NLRI is decoded, but it not used.

This work is in the context of ONOS-422.

Change-Id: Ia61b94dedfe0b1a7d7f563e805a3086f56d4da03
...@@ -376,6 +376,46 @@ public final class BgpConstants { ...@@ -376,6 +376,46 @@ public final class BgpConstants {
376 /** BGP UPDATE Attributes Type Code AGGREGATOR length. */ 376 /** BGP UPDATE Attributes Type Code AGGREGATOR length. */
377 public static final int LENGTH = 6; 377 public static final int LENGTH = 6;
378 } 378 }
379 +
380 + /**
381 + * BGP UPDATE: MP_REACH_NLRI related constants.
382 + */
383 + public static final class MpReachNlri {
384 + /**
385 + * Default constructor.
386 + * <p>
387 + * The constructor is private to prevent creating an instance of
388 + * this utility class.
389 + */
390 + private MpReachNlri() {
391 + }
392 +
393 + /** BGP UPDATE Attributes Type Code MP_REACH_NLRI. */
394 + public static final int TYPE = 14;
395 +
396 + /** BGP UPDATE Attributes Type Code MP_REACH_NLRI min length. */
397 + public static final int MIN_LENGTH = 5;
398 + }
399 +
400 + /**
401 + * BGP UPDATE: MP_UNREACH_NLRI related constants.
402 + */
403 + public static final class MpUnreachNlri {
404 + /**
405 + * Default constructor.
406 + * <p>
407 + * The constructor is private to prevent creating an instance of
408 + * this utility class.
409 + */
410 + private MpUnreachNlri() {
411 + }
412 +
413 + /** BGP UPDATE Attributes Type Code MP_UNREACH_NLRI. */
414 + public static final int TYPE = 15;
415 +
416 + /** BGP UPDATE Attributes Type Code MP_UNREACH_NLRI min length. */
417 + public static final int MIN_LENGTH = 3;
418 + }
379 } 419 }
380 420
381 /** 421 /**
......
...@@ -36,6 +36,7 @@ import org.jboss.netty.util.Timer; ...@@ -36,6 +36,7 @@ import org.jboss.netty.util.Timer;
36 import org.jboss.netty.util.TimerTask; 36 import org.jboss.netty.util.TimerTask;
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.onosproject.sdnip.bgp.BgpConstants.Notifications; 40 import org.onosproject.sdnip.bgp.BgpConstants.Notifications;
40 import org.onosproject.sdnip.bgp.BgpConstants.Notifications.HoldTimerExpired; 41 import org.onosproject.sdnip.bgp.BgpConstants.Notifications.HoldTimerExpired;
41 import org.slf4j.Logger; 42 import org.slf4j.Logger;
...@@ -62,6 +63,8 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -62,6 +63,8 @@ public class BgpSession extends SimpleChannelHandler {
62 private long remoteAs4Octet; // 4 octets 63 private long remoteAs4Octet; // 4 octets
63 private long remoteHoldtime; // 2 octets 64 private long remoteHoldtime; // 2 octets
64 private Ip4Address remoteBgpId; // 4 octets -> IPv4 address 65 private Ip4Address remoteBgpId; // 4 octets -> IPv4 address
66 + private boolean remoteMpExtensions; // Peer Multiprotocol
67 + // Extensions enabled: RFC 4760
65 private boolean remoteIpv4Unicast; // Peer IPv4/UNICAST AFI/SAFI 68 private boolean remoteIpv4Unicast; // Peer IPv4/UNICAST AFI/SAFI
66 private boolean remoteIpv4Multicast; // Peer IPv4/MULTICAST AFI/SAFI 69 private boolean remoteIpv4Multicast; // Peer IPv4/MULTICAST AFI/SAFI
67 private boolean remoteIpv6Unicast; // Peer IPv6/UNICAST AFI/SAFI 70 private boolean remoteIpv6Unicast; // Peer IPv6/UNICAST AFI/SAFI
...@@ -74,6 +77,8 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -74,6 +77,8 @@ public class BgpSession extends SimpleChannelHandler {
74 private long localAs; // 2 octets 77 private long localAs; // 2 octets
75 private long localHoldtime; // 2 octets 78 private long localHoldtime; // 2 octets
76 private Ip4Address localBgpId; // 4 octets -> IPv4 address 79 private Ip4Address localBgpId; // 4 octets -> IPv4 address
80 + private boolean localMpExtensions; // Local Multiprotocol
81 + // Extensions enabled: RFC 4760
77 private boolean localIpv4Unicast; // Local IPv4/UNICAST AFI/SAFI 82 private boolean localIpv4Unicast; // Local IPv4/UNICAST AFI/SAFI
78 private boolean localIpv4Multicast; // Local IPv4/MULTICAST AFI/SAFI 83 private boolean localIpv4Multicast; // Local IPv4/MULTICAST AFI/SAFI
79 private boolean localIpv6Unicast; // Local IPv6/UNICAST AFI/SAFI 84 private boolean localIpv6Unicast; // Local IPv6/UNICAST AFI/SAFI
...@@ -88,7 +93,9 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -88,7 +93,9 @@ public class BgpSession extends SimpleChannelHandler {
88 private volatile Timeout sessionTimeout; // Session timeout 93 private volatile Timeout sessionTimeout; // Session timeout
89 94
90 // BGP RIB-IN routing entries from this peer 95 // BGP RIB-IN routing entries from this peer
91 - private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRibIn = 96 + private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRibIn4 =
97 + new ConcurrentHashMap<>();
98 + private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRibIn6 =
92 new ConcurrentHashMap<>(); 99 new ConcurrentHashMap<>();
93 100
94 /** 101 /**
...@@ -113,22 +120,41 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -113,22 +120,41 @@ public class BgpSession extends SimpleChannelHandler {
113 } 120 }
114 121
115 /** 122 /**
116 - * Gets the BGP RIB-IN routing entries. 123 + * Gets the BGP RIB-IN IPv4 routing entries.
124 + *
125 + * @return the BGP RIB-IN IPv4 routing entries
126 + */
127 + public Map<Ip4Prefix, BgpRouteEntry> bgpRibIn4() {
128 + return bgpRibIn4;
129 + }
130 +
131 + /**
132 + * Gets the BGP RIB-IN IPv6 routing entries.
117 * 133 *
118 - * @return the BGP RIB-IN routing entries 134 + * @return the BGP RIB-IN IPv6 routing entries
119 */ 135 */
120 - public Map<Ip4Prefix, BgpRouteEntry> bgpRibIn() { 136 + public Map<Ip6Prefix, BgpRouteEntry> bgpRibIn6() {
121 - return bgpRibIn; 137 + return bgpRibIn6;
122 } 138 }
123 139
124 /** 140 /**
125 - * Finds a BGP routing entry in the BGP RIB-IN. 141 + * Finds a BGP IPv4 routing entry in the BGP RIB-IN.
126 * 142 *
127 - * @param prefix the prefix of the route to search for 143 + * @param prefix the IPv4 prefix of the route to search for
128 - * @return the BGP routing entry if found, otherwise null 144 + * @return the IPv4 BGP routing entry if found, otherwise null
129 */ 145 */
130 public BgpRouteEntry findBgpRouteEntry(Ip4Prefix prefix) { 146 public BgpRouteEntry findBgpRouteEntry(Ip4Prefix prefix) {
131 - return bgpRibIn.get(prefix); 147 + return bgpRibIn4.get(prefix);
148 + }
149 +
150 + /**
151 + * Finds a BGP IPv6 routing entry in the BGP RIB-IN.
152 + *
153 + * @param prefix the IPv6 prefix of the route to search for
154 + * @return the IPv6 BGP routing entry if found, otherwise null
155 + */
156 + public BgpRouteEntry findBgpRouteEntry(Ip6Prefix prefix) {
157 + return bgpRibIn6.get(prefix);
132 } 158 }
133 159
134 /** 160 /**
...@@ -256,6 +282,16 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -256,6 +282,16 @@ public class BgpSession extends SimpleChannelHandler {
256 } 282 }
257 283
258 /** 284 /**
285 + * Gets the BGP Multiprotocol Extensions for the session.
286 + *
287 + * @return true if the BGP Multiprotocol Extensions are enabled for the
288 + * session, otherwise false
289 + */
290 + public boolean getMpExtensions() {
291 + return remoteMpExtensions && localMpExtensions;
292 + }
293 +
294 + /**
259 * Gets the BGP session remote AFI/SAFI configuration for IPv4 unicast. 295 * Gets the BGP session remote AFI/SAFI configuration for IPv4 unicast.
260 * 296 *
261 * @return the BGP session remote AFI/SAFI configuration for IPv4 unicast 297 * @return the BGP session remote AFI/SAFI configuration for IPv4 unicast
...@@ -268,10 +304,11 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -268,10 +304,11 @@ public class BgpSession extends SimpleChannelHandler {
268 * Sets the BGP session remote AFI/SAFI configuration for IPv4 unicast. 304 * Sets the BGP session remote AFI/SAFI configuration for IPv4 unicast.
269 */ 305 */
270 void setRemoteIpv4Unicast() { 306 void setRemoteIpv4Unicast() {
307 + this.remoteMpExtensions = true;
271 this.remoteIpv4Unicast = true; 308 this.remoteIpv4Unicast = true;
272 // Copy the remote AFI/SAFI setting to the local configuration 309 // Copy the remote AFI/SAFI setting to the local configuration
273 - // NOTE: Uncomment the line below if the AFI/SAFI is supported locally 310 + this.localMpExtensions = true;
274 - // this.localIpv4Unicast = true; 311 + this.localIpv4Unicast = true;
275 } 312 }
276 313
277 /** 314 /**
...@@ -287,10 +324,11 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -287,10 +324,11 @@ public class BgpSession extends SimpleChannelHandler {
287 * Sets the BGP session remote AFI/SAFI configuration for IPv4 multicast. 324 * Sets the BGP session remote AFI/SAFI configuration for IPv4 multicast.
288 */ 325 */
289 void setRemoteIpv4Multicast() { 326 void setRemoteIpv4Multicast() {
327 + this.remoteMpExtensions = true;
290 this.remoteIpv4Multicast = true; 328 this.remoteIpv4Multicast = true;
291 // Copy the remote AFI/SAFI setting to the local configuration 329 // Copy the remote AFI/SAFI setting to the local configuration
292 - // NOTE: Uncomment the line below if the AFI/SAFI is supported locally 330 + this.localMpExtensions = true;
293 - // this.localIpv4Multicast = true; 331 + this.localIpv4Multicast = true;
294 } 332 }
295 333
296 /** 334 /**
...@@ -306,10 +344,11 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -306,10 +344,11 @@ public class BgpSession extends SimpleChannelHandler {
306 * Sets the BGP session remote AFI/SAFI configuration for IPv6 unicast. 344 * Sets the BGP session remote AFI/SAFI configuration for IPv6 unicast.
307 */ 345 */
308 void setRemoteIpv6Unicast() { 346 void setRemoteIpv6Unicast() {
347 + this.remoteMpExtensions = true;
309 this.remoteIpv6Unicast = true; 348 this.remoteIpv6Unicast = true;
310 // Copy the remote AFI/SAFI setting to the local configuration 349 // Copy the remote AFI/SAFI setting to the local configuration
311 - // NOTE: Uncomment the line below if the AFI/SAFI is supported locally 350 + this.localMpExtensions = true;
312 - // this.localIpv6Unicast = true; 351 + this.localIpv6Unicast = true;
313 } 352 }
314 353
315 /** 354 /**
...@@ -325,10 +364,11 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -325,10 +364,11 @@ public class BgpSession extends SimpleChannelHandler {
325 * Sets the BGP session remote AFI/SAFI configuration for IPv6 multicast. 364 * Sets the BGP session remote AFI/SAFI configuration for IPv6 multicast.
326 */ 365 */
327 void setRemoteIpv6Multicast() { 366 void setRemoteIpv6Multicast() {
367 + this.remoteMpExtensions = true;
328 this.remoteIpv6Multicast = true; 368 this.remoteIpv6Multicast = true;
329 // Copy the remote AFI/SAFI setting to the local configuration 369 // Copy the remote AFI/SAFI setting to the local configuration
330 - // NOTE: Uncomment the line below if the AFI/SAFI is supported locally 370 + this.localMpExtensions = true;
331 - // this.localIpv6Multicast = true; 371 + this.localIpv6Multicast = true;
332 } 372 }
333 373
334 /** 374 /**
...@@ -576,14 +616,17 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -576,14 +616,17 @@ public class BgpSession extends SimpleChannelHandler {
576 // for further processing. Otherwise, the BGP Decision Process 616 // for further processing. Otherwise, the BGP Decision Process
577 // will use those routes again. 617 // will use those routes again.
578 // 618 //
579 - Collection<BgpRouteEntry> deletedRoutes = bgpRibIn.values(); 619 + Collection<BgpRouteEntry> deletedRoutes4 = bgpRibIn4.values();
580 - bgpRibIn = new ConcurrentHashMap<>(); 620 + Collection<BgpRouteEntry> deletedRoutes6 = bgpRibIn6.values();
621 + bgpRibIn4 = new ConcurrentHashMap<>();
622 + bgpRibIn6 = new ConcurrentHashMap<>();
581 623
582 // Push the updates to the BGP Merged RIB 624 // Push the updates to the BGP Merged RIB
583 BgpSessionManager.BgpRouteSelector bgpRouteSelector = 625 BgpSessionManager.BgpRouteSelector bgpRouteSelector =
584 bgpSessionManager.getBgpRouteSelector(); 626 bgpSessionManager.getBgpRouteSelector();
585 Collection<BgpRouteEntry> addedRoutes = Collections.emptyList(); 627 Collection<BgpRouteEntry> addedRoutes = Collections.emptyList();
586 - bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes); 628 + bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes4);
629 + bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes6);
587 630
588 bgpSessionManager.peerDisconnected(this); 631 bgpSessionManager.peerDisconnected(this);
589 } 632 }
......
...@@ -81,7 +81,8 @@ public class BgpRoutesListCommand extends AbstractShellCommand { ...@@ -81,7 +81,8 @@ public class BgpRoutesListCommand extends AbstractShellCommand {
81 81
82 // Print the routes 82 // Print the routes
83 if (foundBgpSession != null) { 83 if (foundBgpSession != null) {
84 - printRoutes(foundBgpSession.bgpRibIn().values()); 84 + printRoutes(foundBgpSession.bgpRibIn4().values());
85 + printRoutes(foundBgpSession.bgpRibIn6().values());
85 } else { 86 } else {
86 printRoutes(service.getBgpRoutes()); 87 printRoutes(service.getBgpRoutes());
87 } 88 }
......
...@@ -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.bgpRibIn().values(); 306 + Collection<BgpRouteEntry> bgpRibIn = bgpSession.bgpRibIn4().values();
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.bgpRibIn().values(); 314 + bgpRibIn = bgpSession.bgpRibIn4().values();
315 } 315 }
316 316
317 return bgpRibIn; 317 return bgpRibIn;
......