[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
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java b/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java
index 2b0ef98..8204a10 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java
@@ -89,14 +89,17 @@
     /**
      * 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 @@
             boolean isSet = ((value & mask) != 0);
             result.append(isSet ? "1" : "0");
         }
-        return result.toString();
+
+        return "0" + result.toString();
     }
 
     @Override
diff --git a/apps/routing-api/src/test/java/org/onosproject/routing/RouteEntryTest.java b/apps/routing-api/src/test/java/org/onosproject/routing/RouteEntryTest.java
index b89eb2d..981d6a0 100644
--- a/apps/routing-api/src/test/java/org/onosproject/routing/RouteEntryTest.java
+++ b/apps/routing-api/src/test/java/org/onosproject/routing/RouteEntryTest.java
@@ -121,52 +121,52 @@
         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());
     }
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
index c0001bd..9113e01 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
@@ -83,7 +83,8 @@
 
 
     @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 @@
             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,10 +184,19 @@
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
         if (prefix.isIp4()) {
             selector.matchEthType(Ethernet.TYPE_IPV4);
-            selector.matchIPDst(prefix);
+            // 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);
-            selector.matchIPv6Dst(prefix);
+            // 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