Pingping Lin

[ONOS-3410] Let sdn-ip support default route

Default route is an important and frequntly used feature in BGP.
For example, network operators want to reduce the size of the route table.

The current sdn-ip does not support this feature. So this patch is to
let sdn-ip support this feature.

Change-Id: Ibb5afe3711522468e4902da2e090370db71b29da
......@@ -89,14 +89,17 @@ public class RouteEntry {
/**
* Creates the binary string representation of an IP prefix.
* The prefix can be either IPv4 or IPv6.
* The string length is equal to the prefix length.
* The string length is equal to the prefix length + 1.
*
* For each string, we put a extra "0" in the front. The purpose of
* doing this is to store the default route inside InvertedRadixTree.
*
* @param ipPrefix the IP prefix to use
* @return the binary string representation
*/
public static String createBinaryString(IpPrefix ipPrefix) {
if (ipPrefix.prefixLength() == 0) {
return "";
return "0";
}
byte[] octets = ipPrefix.address().toOctets();
......@@ -109,7 +112,8 @@ public class RouteEntry {
boolean isSet = ((value & mask) != 0);
result.append(isSet ? "1" : "0");
}
return result.toString();
return "0" + result.toString();
}
@Override
......
......@@ -121,52 +121,52 @@ public class RouteEntryTest {
Ip4Prefix prefix;
prefix = Ip4Prefix.valueOf("0.0.0.0/0");
assertThat(RouteEntry.createBinaryString(prefix), is(""));
assertThat(RouteEntry.createBinaryString(prefix), is("0"));
prefix = Ip4Prefix.valueOf("192.168.166.0/22");
assertThat(RouteEntry.createBinaryString(prefix),
is("1100000010101000101001"));
is("0" + "1100000010101000101001"));
prefix = Ip4Prefix.valueOf("192.168.166.0/23");
assertThat(RouteEntry.createBinaryString(prefix),
is("11000000101010001010011"));
is("0" + "11000000101010001010011"));
prefix = Ip4Prefix.valueOf("192.168.166.0/24");
assertThat(RouteEntry.createBinaryString(prefix),
is("110000001010100010100110"));
is("0" + "110000001010100010100110"));
prefix = Ip4Prefix.valueOf("130.162.10.1/25");
assertThat(RouteEntry.createBinaryString(prefix),
is("1000001010100010000010100"));
is("0" + "1000001010100010000010100"));
prefix = Ip4Prefix.valueOf("255.255.255.255/32");
assertThat(RouteEntry.createBinaryString(prefix),
is("11111111111111111111111111111111"));
is("0" + "11111111111111111111111111111111"));
Ip6Prefix prefix6;
Pattern pattern;
Matcher matcher;
prefix6 = Ip6Prefix.valueOf("::/0");
assertThat(RouteEntry.createBinaryString(prefix6), is(""));
assertThat(RouteEntry.createBinaryString(prefix6), is("0"));
prefix6 = Ip6Prefix.valueOf("2000::1000/112");
pattern = Pattern.compile("00100{108}");
pattern = Pattern.compile("0" + "00100{108}");
matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6));
assertTrue(matcher.matches());
prefix6 = Ip6Prefix.valueOf("2000::1000/116");
pattern = Pattern.compile("00100{108}0001");
pattern = Pattern.compile("0" + "00100{108}0001");
matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6));
assertTrue(matcher.matches());
prefix6 = Ip6Prefix.valueOf("2000::2000/116");
pattern = Pattern.compile("00100{108}0010");
pattern = Pattern.compile("0" + "00100{108}0010");
matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6));
assertTrue(matcher.matches());
prefix6 = Ip6Prefix.valueOf("2000::1234/128");
pattern = Pattern.compile("00100{108}0001001000110100");
pattern = Pattern.compile("0" + "00100{108}0001001000110100");
matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6));
assertTrue(matcher.matches());
}
......
......@@ -83,7 +83,8 @@ public class SdnIpFib implements FibListener {
@Override
public void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) {
public void update(Collection<FibUpdate> updates,
Collection<FibUpdate> withdraws) {
int submitCount = 0, withdrawCount = 0;
//
// NOTE: Semantically, we MUST withdraw existing intents before
......@@ -157,7 +158,8 @@ public class SdnIpFib implements FibListener {
MacAddress nextHopMacAddress) {
// Find the attachment point (egress interface) of the next hop
Interface egressInterface = interfaceService.getMatchingInterface(nextHopIpAddress);
Interface egressInterface =
interfaceService.getMatchingInterface(nextHopIpAddress);
if (egressInterface == null) {
log.warn("No outgoing interface found for {}",
nextHopIpAddress);
......@@ -182,12 +184,21 @@ public class SdnIpFib implements FibListener {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
if (prefix.isIp4()) {
selector.matchEthType(Ethernet.TYPE_IPV4);
// if it is default route, then we do not need match destination
// IP address
if (prefix.prefixLength() != 0) {
selector.matchIPDst(prefix);
}
} else {
selector.matchEthType(Ethernet.TYPE_IPV6);
// if it is default route, then we do not need match destination
// IP address
if (prefix.prefixLength() != 0) {
selector.matchIPv6Dst(prefix);
}
}
// Rewrite the destination MAC address
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
.setEthDst(nextHopMacAddress);
......