Committed by
Gerrit Code Review
ProxyArp: Reply directly when we know an external target host
Change-Id: I38773dcdcae05506c678c2006d1f63306af6b383
Showing
2 changed files
with
43 additions
and
42 deletions
| ... | @@ -146,47 +146,25 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -146,47 +146,25 @@ public class ProxyArpManager implements ProxyArpService { |
| 146 | 146 | ||
| 147 | VlanId vlan = VlanId.vlanId(eth.getVlanID()); | 147 | VlanId vlan = VlanId.vlanId(eth.getVlanID()); |
| 148 | 148 | ||
| 149 | - // If the request came from outside the network, only reply if it was | ||
| 150 | - // for one of our external addresses. | ||
| 151 | if (isOutsidePort(inPort)) { | 149 | if (isOutsidePort(inPort)) { |
| 150 | + // If the request came from outside the network, only reply if it was | ||
| 151 | + // for one of our external addresses. | ||
| 152 | Set<PortAddresses> addressSet = | 152 | Set<PortAddresses> addressSet = |
| 153 | - hostService.getAddressBindingsForPort(inPort); | 153 | + hostService.getAddressBindingsForPort(inPort); |
| 154 | 154 | ||
| 155 | for (PortAddresses addresses : addressSet) { | 155 | for (PortAddresses addresses : addressSet) { |
| 156 | for (InterfaceIpAddress ia : addresses.ipAddresses()) { | 156 | for (InterfaceIpAddress ia : addresses.ipAddresses()) { |
| 157 | if (ia.ipAddress().equals(targetAddress)) { | 157 | if (ia.ipAddress().equals(targetAddress)) { |
| 158 | Ethernet arpReply = | 158 | Ethernet arpReply = |
| 159 | - buildArpReply(targetAddress, addresses.mac(), eth); | 159 | + buildArpReply(targetAddress, addresses.mac(), eth); |
| 160 | sendTo(arpReply, inPort); | 160 | sendTo(arpReply, inPort); |
| 161 | } | 161 | } |
| 162 | } | 162 | } |
| 163 | } | 163 | } |
| 164 | return; | 164 | return; |
| 165 | - } else { | ||
| 166 | - // If the source address matches one of our external addresses | ||
| 167 | - // it could be a request from an internal host to an external | ||
| 168 | - // address. Forward it over to the correct ports. | ||
| 169 | - Ip4Address source = | ||
| 170 | - Ip4Address.valueOf(arp.getSenderProtocolAddress()); | ||
| 171 | - Set<PortAddresses> sourceAddresses = findPortsInSubnet(source); | ||
| 172 | - boolean matched = false; | ||
| 173 | - for (PortAddresses pa : sourceAddresses) { | ||
| 174 | - for (InterfaceIpAddress ia : pa.ipAddresses()) { | ||
| 175 | - if (ia.ipAddress().equals(source) && | ||
| 176 | - pa.vlan().equals(vlan)) { | ||
| 177 | - matched = true; | ||
| 178 | - sendTo(eth, pa.connectPoint()); | ||
| 179 | - break; | ||
| 180 | - } | ||
| 181 | - } | ||
| 182 | - } | ||
| 183 | - | ||
| 184 | - if (matched) { | ||
| 185 | - return; | ||
| 186 | - } | ||
| 187 | } | 165 | } |
| 188 | 166 | ||
| 189 | - // Continue with normal proxy ARP case | 167 | + // See if we have the target host in the host store |
| 190 | 168 | ||
| 191 | Set<Host> hosts = hostService.getHostsByIp(targetAddress); | 169 | Set<Host> hosts = hostService.getHostsByIp(targetAddress); |
| 192 | 170 | ||
| ... | @@ -201,20 +179,41 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -201,20 +179,41 @@ public class ProxyArpManager implements ProxyArpService { |
| 201 | } | 179 | } |
| 202 | } | 180 | } |
| 203 | 181 | ||
| 204 | - if (src == null || dst == null) { | 182 | + if (src != null && dst != null) { |
| 205 | - // | 183 | + // We know the target host so we can respond |
| 206 | - // The request couldn't be resolved. | 184 | + Ethernet arpReply = buildArpReply(targetAddress, dst.mac(), eth); |
| 207 | - // Flood the request on all ports except the incoming ports. | 185 | + sendTo(arpReply, inPort); |
| 208 | - // | 186 | + return; |
| 209 | - flood(eth, inPort); | 187 | + } |
| 188 | + | ||
| 189 | + // If the source address matches one of our external addresses | ||
| 190 | + // it could be a request from an internal host to an external | ||
| 191 | + // address. Forward it over to the correct port. | ||
| 192 | + Ip4Address source = | ||
| 193 | + Ip4Address.valueOf(arp.getSenderProtocolAddress()); | ||
| 194 | + Set<PortAddresses> sourceAddresses = findPortsInSubnet(source); | ||
| 195 | + boolean matched = false; | ||
| 196 | + for (PortAddresses pa : sourceAddresses) { | ||
| 197 | + for (InterfaceIpAddress ia : pa.ipAddresses()) { | ||
| 198 | + if (ia.ipAddress().equals(source) && | ||
| 199 | + pa.vlan().equals(vlan)) { | ||
| 200 | + matched = true; | ||
| 201 | + sendTo(eth, pa.connectPoint()); | ||
| 202 | + break; | ||
| 203 | + } | ||
| 204 | + } | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + if (matched) { | ||
| 210 | return; | 208 | return; |
| 211 | } | 209 | } |
| 212 | 210 | ||
| 213 | // | 211 | // |
| 214 | - // Reply on the port the request was received on | 212 | + // The request couldn't be resolved. |
| 213 | + // Flood the request on all ports except the incoming port. | ||
| 215 | // | 214 | // |
| 216 | - Ethernet arpReply = buildArpReply(targetAddress, dst.mac(), eth); | 215 | + flood(eth, inPort); |
| 217 | - sendTo(arpReply, inPort); | 216 | + return; |
| 218 | } | 217 | } |
| 219 | 218 | ||
| 220 | private void replyNdp(Ethernet eth, ConnectPoint inPort) { | 219 | private void replyNdp(Ethernet eth, ConnectPoint inPort) { | ... | ... |
| ... | @@ -242,8 +242,8 @@ public class ProxyArpManagerTest { | ... | @@ -242,8 +242,8 @@ public class ProxyArpManagerTest { |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | /** | 244 | /** |
| 245 | - * Tests {@link ProxyArpManager#isKnown(Ip4Address)} in the case where the | 245 | + * Tests {@link ProxyArpManager#isKnown(org.onlab.packet.IpAddress)} in the |
| 246 | - * IP address is not known. | 246 | + * case where the IP address is not known. |
| 247 | * Verifies the method returns false. | 247 | * Verifies the method returns false. |
| 248 | */ | 248 | */ |
| 249 | @Test | 249 | @Test |
| ... | @@ -255,8 +255,8 @@ public class ProxyArpManagerTest { | ... | @@ -255,8 +255,8 @@ public class ProxyArpManagerTest { |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | /** | 257 | /** |
| 258 | - * Tests {@link ProxyArpManager#isKnown(Ip4Address)} in the case where the | 258 | + * Tests {@link ProxyArpManager#isKnown(org.onlab.packet.IpAddress)} in the |
| 259 | - * IP address is known. | 259 | + * case where the IP address is known. |
| 260 | * Verifies the method returns true. | 260 | * Verifies the method returns true. |
| 261 | */ | 261 | */ |
| 262 | @Test | 262 | @Test |
| ... | @@ -403,12 +403,14 @@ public class ProxyArpManagerTest { | ... | @@ -403,12 +403,14 @@ public class ProxyArpManagerTest { |
| 403 | 403 | ||
| 404 | @Test | 404 | @Test |
| 405 | public void testReplyToRequestFromUs() { | 405 | public void testReplyToRequestFromUs() { |
| 406 | - replay(hostService); // no further host service expectations | ||
| 407 | - | ||
| 408 | Ip4Address ourIp = Ip4Address.valueOf("10.0.1.1"); | 406 | Ip4Address ourIp = Ip4Address.valueOf("10.0.1.1"); |
| 409 | MacAddress ourMac = MacAddress.valueOf(1L); | 407 | MacAddress ourMac = MacAddress.valueOf(1L); |
| 410 | Ip4Address theirIp = Ip4Address.valueOf("10.0.1.100"); | 408 | Ip4Address theirIp = Ip4Address.valueOf("10.0.1.100"); |
| 411 | 409 | ||
| 410 | + expect(hostService.getHostsByIp(theirIp)).andReturn(Collections.emptySet()); | ||
| 411 | + expect(hostService.getHost(HostId.hostId(ourMac, VLAN1))).andReturn(null); | ||
| 412 | + replay(hostService); | ||
| 413 | + | ||
| 412 | // This is a request from something inside our network (like a BGP | 414 | // This is a request from something inside our network (like a BGP |
| 413 | // daemon) to an external host. | 415 | // daemon) to an external host. |
| 414 | Ethernet arpRequest = buildArp(ARP.OP_REQUEST, ourMac, null, ourIp, theirIp); | 416 | Ethernet arpRequest = buildArp(ARP.OP_REQUEST, ourMac, null, ourIp, theirIp); | ... | ... |
-
Please register or login to post a comment