[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
Showing
3 changed files
with
33 additions
and
18 deletions
| ... | @@ -89,14 +89,17 @@ public class RouteEntry { | ... | @@ -89,14 +89,17 @@ public class RouteEntry { |
| 89 | /** | 89 | /** |
| 90 | * Creates the binary string representation of an IP prefix. | 90 | * Creates the binary string representation of an IP prefix. |
| 91 | * The prefix can be either IPv4 or IPv6. | 91 | * The prefix can be either IPv4 or IPv6. |
| 92 | - * The string length is equal to the prefix length. | 92 | + * The string length is equal to the prefix length + 1. |
| 93 | + * | ||
| 94 | + * For each string, we put a extra "0" in the front. The purpose of | ||
| 95 | + * doing this is to store the default route inside InvertedRadixTree. | ||
| 93 | * | 96 | * |
| 94 | * @param ipPrefix the IP prefix to use | 97 | * @param ipPrefix the IP prefix to use |
| 95 | * @return the binary string representation | 98 | * @return the binary string representation |
| 96 | */ | 99 | */ |
| 97 | public static String createBinaryString(IpPrefix ipPrefix) { | 100 | public static String createBinaryString(IpPrefix ipPrefix) { |
| 98 | if (ipPrefix.prefixLength() == 0) { | 101 | if (ipPrefix.prefixLength() == 0) { |
| 99 | - return ""; | 102 | + return "0"; |
| 100 | } | 103 | } |
| 101 | 104 | ||
| 102 | byte[] octets = ipPrefix.address().toOctets(); | 105 | byte[] octets = ipPrefix.address().toOctets(); |
| ... | @@ -109,7 +112,8 @@ public class RouteEntry { | ... | @@ -109,7 +112,8 @@ public class RouteEntry { |
| 109 | boolean isSet = ((value & mask) != 0); | 112 | boolean isSet = ((value & mask) != 0); |
| 110 | result.append(isSet ? "1" : "0"); | 113 | result.append(isSet ? "1" : "0"); |
| 111 | } | 114 | } |
| 112 | - return result.toString(); | 115 | + |
| 116 | + return "0" + result.toString(); | ||
| 113 | } | 117 | } |
| 114 | 118 | ||
| 115 | @Override | 119 | @Override | ... | ... |
| ... | @@ -121,52 +121,52 @@ public class RouteEntryTest { | ... | @@ -121,52 +121,52 @@ public class RouteEntryTest { |
| 121 | Ip4Prefix prefix; | 121 | Ip4Prefix prefix; |
| 122 | 122 | ||
| 123 | prefix = Ip4Prefix.valueOf("0.0.0.0/0"); | 123 | prefix = Ip4Prefix.valueOf("0.0.0.0/0"); |
| 124 | - assertThat(RouteEntry.createBinaryString(prefix), is("")); | 124 | + assertThat(RouteEntry.createBinaryString(prefix), is("0")); |
| 125 | 125 | ||
| 126 | prefix = Ip4Prefix.valueOf("192.168.166.0/22"); | 126 | prefix = Ip4Prefix.valueOf("192.168.166.0/22"); |
| 127 | assertThat(RouteEntry.createBinaryString(prefix), | 127 | assertThat(RouteEntry.createBinaryString(prefix), |
| 128 | - is("1100000010101000101001")); | 128 | + is("0" + "1100000010101000101001")); |
| 129 | 129 | ||
| 130 | prefix = Ip4Prefix.valueOf("192.168.166.0/23"); | 130 | prefix = Ip4Prefix.valueOf("192.168.166.0/23"); |
| 131 | assertThat(RouteEntry.createBinaryString(prefix), | 131 | assertThat(RouteEntry.createBinaryString(prefix), |
| 132 | - is("11000000101010001010011")); | 132 | + is("0" + "11000000101010001010011")); |
| 133 | 133 | ||
| 134 | prefix = Ip4Prefix.valueOf("192.168.166.0/24"); | 134 | prefix = Ip4Prefix.valueOf("192.168.166.0/24"); |
| 135 | assertThat(RouteEntry.createBinaryString(prefix), | 135 | assertThat(RouteEntry.createBinaryString(prefix), |
| 136 | - is("110000001010100010100110")); | 136 | + is("0" + "110000001010100010100110")); |
| 137 | 137 | ||
| 138 | prefix = Ip4Prefix.valueOf("130.162.10.1/25"); | 138 | prefix = Ip4Prefix.valueOf("130.162.10.1/25"); |
| 139 | assertThat(RouteEntry.createBinaryString(prefix), | 139 | assertThat(RouteEntry.createBinaryString(prefix), |
| 140 | - is("1000001010100010000010100")); | 140 | + is("0" + "1000001010100010000010100")); |
| 141 | 141 | ||
| 142 | prefix = Ip4Prefix.valueOf("255.255.255.255/32"); | 142 | prefix = Ip4Prefix.valueOf("255.255.255.255/32"); |
| 143 | assertThat(RouteEntry.createBinaryString(prefix), | 143 | assertThat(RouteEntry.createBinaryString(prefix), |
| 144 | - is("11111111111111111111111111111111")); | 144 | + is("0" + "11111111111111111111111111111111")); |
| 145 | 145 | ||
| 146 | Ip6Prefix prefix6; | 146 | Ip6Prefix prefix6; |
| 147 | Pattern pattern; | 147 | Pattern pattern; |
| 148 | Matcher matcher; | 148 | Matcher matcher; |
| 149 | 149 | ||
| 150 | prefix6 = Ip6Prefix.valueOf("::/0"); | 150 | prefix6 = Ip6Prefix.valueOf("::/0"); |
| 151 | - assertThat(RouteEntry.createBinaryString(prefix6), is("")); | 151 | + assertThat(RouteEntry.createBinaryString(prefix6), is("0")); |
| 152 | 152 | ||
| 153 | prefix6 = Ip6Prefix.valueOf("2000::1000/112"); | 153 | prefix6 = Ip6Prefix.valueOf("2000::1000/112"); |
| 154 | - pattern = Pattern.compile("00100{108}"); | 154 | + pattern = Pattern.compile("0" + "00100{108}"); |
| 155 | matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); | 155 | matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); |
| 156 | assertTrue(matcher.matches()); | 156 | assertTrue(matcher.matches()); |
| 157 | 157 | ||
| 158 | prefix6 = Ip6Prefix.valueOf("2000::1000/116"); | 158 | prefix6 = Ip6Prefix.valueOf("2000::1000/116"); |
| 159 | - pattern = Pattern.compile("00100{108}0001"); | 159 | + pattern = Pattern.compile("0" + "00100{108}0001"); |
| 160 | matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); | 160 | matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); |
| 161 | assertTrue(matcher.matches()); | 161 | assertTrue(matcher.matches()); |
| 162 | 162 | ||
| 163 | prefix6 = Ip6Prefix.valueOf("2000::2000/116"); | 163 | prefix6 = Ip6Prefix.valueOf("2000::2000/116"); |
| 164 | - pattern = Pattern.compile("00100{108}0010"); | 164 | + pattern = Pattern.compile("0" + "00100{108}0010"); |
| 165 | matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); | 165 | matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); |
| 166 | assertTrue(matcher.matches()); | 166 | assertTrue(matcher.matches()); |
| 167 | 167 | ||
| 168 | prefix6 = Ip6Prefix.valueOf("2000::1234/128"); | 168 | prefix6 = Ip6Prefix.valueOf("2000::1234/128"); |
| 169 | - pattern = Pattern.compile("00100{108}0001001000110100"); | 169 | + pattern = Pattern.compile("0" + "00100{108}0001001000110100"); |
| 170 | matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); | 170 | matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); |
| 171 | assertTrue(matcher.matches()); | 171 | assertTrue(matcher.matches()); |
| 172 | } | 172 | } | ... | ... |
| ... | @@ -83,7 +83,8 @@ public class SdnIpFib implements FibListener { | ... | @@ -83,7 +83,8 @@ public class SdnIpFib implements FibListener { |
| 83 | 83 | ||
| 84 | 84 | ||
| 85 | @Override | 85 | @Override |
| 86 | - public void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) { | 86 | + public void update(Collection<FibUpdate> updates, |
| 87 | + Collection<FibUpdate> withdraws) { | ||
| 87 | int submitCount = 0, withdrawCount = 0; | 88 | int submitCount = 0, withdrawCount = 0; |
| 88 | // | 89 | // |
| 89 | // NOTE: Semantically, we MUST withdraw existing intents before | 90 | // NOTE: Semantically, we MUST withdraw existing intents before |
| ... | @@ -157,7 +158,8 @@ public class SdnIpFib implements FibListener { | ... | @@ -157,7 +158,8 @@ public class SdnIpFib implements FibListener { |
| 157 | MacAddress nextHopMacAddress) { | 158 | MacAddress nextHopMacAddress) { |
| 158 | 159 | ||
| 159 | // Find the attachment point (egress interface) of the next hop | 160 | // Find the attachment point (egress interface) of the next hop |
| 160 | - Interface egressInterface = interfaceService.getMatchingInterface(nextHopIpAddress); | 161 | + Interface egressInterface = |
| 162 | + interfaceService.getMatchingInterface(nextHopIpAddress); | ||
| 161 | if (egressInterface == null) { | 163 | if (egressInterface == null) { |
| 162 | log.warn("No outgoing interface found for {}", | 164 | log.warn("No outgoing interface found for {}", |
| 163 | nextHopIpAddress); | 165 | nextHopIpAddress); |
| ... | @@ -182,10 +184,19 @@ public class SdnIpFib implements FibListener { | ... | @@ -182,10 +184,19 @@ public class SdnIpFib implements FibListener { |
| 182 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 184 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| 183 | if (prefix.isIp4()) { | 185 | if (prefix.isIp4()) { |
| 184 | selector.matchEthType(Ethernet.TYPE_IPV4); | 186 | selector.matchEthType(Ethernet.TYPE_IPV4); |
| 185 | - selector.matchIPDst(prefix); | 187 | + // if it is default route, then we do not need match destination |
| 188 | + // IP address | ||
| 189 | + if (prefix.prefixLength() != 0) { | ||
| 190 | + selector.matchIPDst(prefix); | ||
| 191 | + } | ||
| 186 | } else { | 192 | } else { |
| 187 | selector.matchEthType(Ethernet.TYPE_IPV6); | 193 | selector.matchEthType(Ethernet.TYPE_IPV6); |
| 188 | - selector.matchIPv6Dst(prefix); | 194 | + // if it is default route, then we do not need match destination |
| 195 | + // IP address | ||
| 196 | + if (prefix.prefixLength() != 0) { | ||
| 197 | + selector.matchIPv6Dst(prefix); | ||
| 198 | + } | ||
| 199 | + | ||
| 189 | } | 200 | } |
| 190 | 201 | ||
| 191 | // Rewrite the destination MAC address | 202 | // Rewrite the destination MAC address | ... | ... |
-
Please register or login to post a comment