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 {
/** BGP UPDATE Attributes Type Code AGGREGATOR length. */
public static final int LENGTH = 6;
}
/**
* BGP UPDATE: MP_REACH_NLRI related constants.
*/
public static final class MpReachNlri {
/**
* Default constructor.
* <p>
* The constructor is private to prevent creating an instance of
* this utility class.
*/
private MpReachNlri() {
}
/** BGP UPDATE Attributes Type Code MP_REACH_NLRI. */
public static final int TYPE = 14;
/** BGP UPDATE Attributes Type Code MP_REACH_NLRI min length. */
public static final int MIN_LENGTH = 5;
}
/**
* BGP UPDATE: MP_UNREACH_NLRI related constants.
*/
public static final class MpUnreachNlri {
/**
* Default constructor.
* <p>
* The constructor is private to prevent creating an instance of
* this utility class.
*/
private MpUnreachNlri() {
}
/** BGP UPDATE Attributes Type Code MP_UNREACH_NLRI. */
public static final int TYPE = 15;
/** BGP UPDATE Attributes Type Code MP_UNREACH_NLRI min length. */
public static final int MIN_LENGTH = 3;
}
}
/**
......
......@@ -36,6 +36,7 @@ import org.jboss.netty.util.Timer;
import org.jboss.netty.util.TimerTask;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.Ip6Prefix;
import org.onosproject.sdnip.bgp.BgpConstants.Notifications;
import org.onosproject.sdnip.bgp.BgpConstants.Notifications.HoldTimerExpired;
import org.slf4j.Logger;
......@@ -62,6 +63,8 @@ public class BgpSession extends SimpleChannelHandler {
private long remoteAs4Octet; // 4 octets
private long remoteHoldtime; // 2 octets
private Ip4Address remoteBgpId; // 4 octets -> IPv4 address
private boolean remoteMpExtensions; // Peer Multiprotocol
// Extensions enabled: RFC 4760
private boolean remoteIpv4Unicast; // Peer IPv4/UNICAST AFI/SAFI
private boolean remoteIpv4Multicast; // Peer IPv4/MULTICAST AFI/SAFI
private boolean remoteIpv6Unicast; // Peer IPv6/UNICAST AFI/SAFI
......@@ -74,6 +77,8 @@ public class BgpSession extends SimpleChannelHandler {
private long localAs; // 2 octets
private long localHoldtime; // 2 octets
private Ip4Address localBgpId; // 4 octets -> IPv4 address
private boolean localMpExtensions; // Local Multiprotocol
// Extensions enabled: RFC 4760
private boolean localIpv4Unicast; // Local IPv4/UNICAST AFI/SAFI
private boolean localIpv4Multicast; // Local IPv4/MULTICAST AFI/SAFI
private boolean localIpv6Unicast; // Local IPv6/UNICAST AFI/SAFI
......@@ -88,7 +93,9 @@ public class BgpSession extends SimpleChannelHandler {
private volatile Timeout sessionTimeout; // Session timeout
// BGP RIB-IN routing entries from this peer
private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRibIn =
private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRibIn4 =
new ConcurrentHashMap<>();
private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRibIn6 =
new ConcurrentHashMap<>();
/**
......@@ -113,22 +120,41 @@ public class BgpSession extends SimpleChannelHandler {
}
/**
* Gets the BGP RIB-IN routing entries.
* Gets the BGP RIB-IN IPv4 routing entries.
*
* @return the BGP RIB-IN IPv4 routing entries
*/
public Map<Ip4Prefix, BgpRouteEntry> bgpRibIn4() {
return bgpRibIn4;
}
/**
* Gets the BGP RIB-IN IPv6 routing entries.
*
* @return the BGP RIB-IN routing entries
* @return the BGP RIB-IN IPv6 routing entries
*/
public Map<Ip4Prefix, BgpRouteEntry> bgpRibIn() {
return bgpRibIn;
public Map<Ip6Prefix, BgpRouteEntry> bgpRibIn6() {
return bgpRibIn6;
}
/**
* Finds a BGP routing entry in the BGP RIB-IN.
* Finds a BGP IPv4 routing entry in the BGP RIB-IN.
*
* @param prefix the prefix of the route to search for
* @return the BGP routing entry if found, otherwise null
* @param prefix the IPv4 prefix of the route to search for
* @return the IPv4 BGP routing entry if found, otherwise null
*/
public BgpRouteEntry findBgpRouteEntry(Ip4Prefix prefix) {
return bgpRibIn.get(prefix);
return bgpRibIn4.get(prefix);
}
/**
* Finds a BGP IPv6 routing entry in the BGP RIB-IN.
*
* @param prefix the IPv6 prefix of the route to search for
* @return the IPv6 BGP routing entry if found, otherwise null
*/
public BgpRouteEntry findBgpRouteEntry(Ip6Prefix prefix) {
return bgpRibIn6.get(prefix);
}
/**
......@@ -256,6 +282,16 @@ public class BgpSession extends SimpleChannelHandler {
}
/**
* Gets the BGP Multiprotocol Extensions for the session.
*
* @return true if the BGP Multiprotocol Extensions are enabled for the
* session, otherwise false
*/
public boolean getMpExtensions() {
return remoteMpExtensions && localMpExtensions;
}
/**
* Gets the BGP session remote AFI/SAFI configuration for IPv4 unicast.
*
* @return the BGP session remote AFI/SAFI configuration for IPv4 unicast
......@@ -268,10 +304,11 @@ public class BgpSession extends SimpleChannelHandler {
* Sets the BGP session remote AFI/SAFI configuration for IPv4 unicast.
*/
void setRemoteIpv4Unicast() {
this.remoteMpExtensions = true;
this.remoteIpv4Unicast = true;
// Copy the remote AFI/SAFI setting to the local configuration
// NOTE: Uncomment the line below if the AFI/SAFI is supported locally
// this.localIpv4Unicast = true;
this.localMpExtensions = true;
this.localIpv4Unicast = true;
}
/**
......@@ -287,10 +324,11 @@ public class BgpSession extends SimpleChannelHandler {
* Sets the BGP session remote AFI/SAFI configuration for IPv4 multicast.
*/
void setRemoteIpv4Multicast() {
this.remoteMpExtensions = true;
this.remoteIpv4Multicast = true;
// Copy the remote AFI/SAFI setting to the local configuration
// NOTE: Uncomment the line below if the AFI/SAFI is supported locally
// this.localIpv4Multicast = true;
this.localMpExtensions = true;
this.localIpv4Multicast = true;
}
/**
......@@ -306,10 +344,11 @@ public class BgpSession extends SimpleChannelHandler {
* Sets the BGP session remote AFI/SAFI configuration for IPv6 unicast.
*/
void setRemoteIpv6Unicast() {
this.remoteMpExtensions = true;
this.remoteIpv6Unicast = true;
// Copy the remote AFI/SAFI setting to the local configuration
// NOTE: Uncomment the line below if the AFI/SAFI is supported locally
// this.localIpv6Unicast = true;
this.localMpExtensions = true;
this.localIpv6Unicast = true;
}
/**
......@@ -325,10 +364,11 @@ public class BgpSession extends SimpleChannelHandler {
* Sets the BGP session remote AFI/SAFI configuration for IPv6 multicast.
*/
void setRemoteIpv6Multicast() {
this.remoteMpExtensions = true;
this.remoteIpv6Multicast = true;
// Copy the remote AFI/SAFI setting to the local configuration
// NOTE: Uncomment the line below if the AFI/SAFI is supported locally
// this.localIpv6Multicast = true;
this.localMpExtensions = true;
this.localIpv6Multicast = true;
}
/**
......@@ -576,14 +616,17 @@ public class BgpSession extends SimpleChannelHandler {
// for further processing. Otherwise, the BGP Decision Process
// will use those routes again.
//
Collection<BgpRouteEntry> deletedRoutes = bgpRibIn.values();
bgpRibIn = new ConcurrentHashMap<>();
Collection<BgpRouteEntry> deletedRoutes4 = bgpRibIn4.values();
Collection<BgpRouteEntry> deletedRoutes6 = bgpRibIn6.values();
bgpRibIn4 = new ConcurrentHashMap<>();
bgpRibIn6 = new ConcurrentHashMap<>();
// Push the updates to the BGP Merged RIB
BgpSessionManager.BgpRouteSelector bgpRouteSelector =
bgpSessionManager.getBgpRouteSelector();
Collection<BgpRouteEntry> addedRoutes = Collections.emptyList();
bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes);
bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes4);
bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes6);
bgpSessionManager.peerDisconnected(this);
}
......
......@@ -81,7 +81,8 @@ public class BgpRoutesListCommand extends AbstractShellCommand {
// Print the routes
if (foundBgpSession != null) {
printRoutes(foundBgpSession.bgpRibIn().values());
printRoutes(foundBgpSession.bgpRibIn4().values());
printRoutes(foundBgpSession.bgpRibIn6().values());
} else {
printRoutes(service.getBgpRoutes());
}
......
......@@ -303,7 +303,7 @@ public class BgpSessionManagerTest {
private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession,
long expectedRoutes)
throws InterruptedException {
Collection<BgpRouteEntry> bgpRibIn = bgpSession.bgpRibIn().values();
Collection<BgpRouteEntry> bgpRibIn = bgpSession.bgpRibIn4().values();
final int maxChecks = 500; // Max wait of 5 seconds
for (int i = 0; i < maxChecks; i++) {
......@@ -311,7 +311,7 @@ public class BgpSessionManagerTest {
break;
}
Thread.sleep(10);
bgpRibIn = bgpSession.bgpRibIn().values();
bgpRibIn = bgpSession.bgpRibIn4().values();
}
return bgpRibIn;
......