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 { ...@@ -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,12 +184,21 @@ public class SdnIpFib implements FibListener { ...@@ -182,12 +184,21 @@ 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);
187 + // if it is default route, then we do not need match destination
188 + // IP address
189 + if (prefix.prefixLength() != 0) {
185 selector.matchIPDst(prefix); 190 selector.matchIPDst(prefix);
191 + }
186 } else { 192 } else {
187 selector.matchEthType(Ethernet.TYPE_IPV6); 193 selector.matchEthType(Ethernet.TYPE_IPV6);
194 + // if it is default route, then we do not need match destination
195 + // IP address
196 + if (prefix.prefixLength() != 0) {
188 selector.matchIPv6Dst(prefix); 197 selector.matchIPv6Dst(prefix);
189 } 198 }
190 199
200 + }
201 +
191 // Rewrite the destination MAC address 202 // Rewrite the destination MAC address
192 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() 203 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
193 .setEthDst(nextHopMacAddress); 204 .setEthDst(nextHopMacAddress);
......