ProxyArp: Reply directly when we know an external target host
Change-Id: I38773dcdcae05506c678c2006d1f63306af6b383
diff --git a/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java b/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
index 7b1f2a4..161518c 100644
--- a/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
+++ b/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
@@ -146,47 +146,25 @@
VlanId vlan = VlanId.vlanId(eth.getVlanID());
- // If the request came from outside the network, only reply if it was
- // for one of our external addresses.
if (isOutsidePort(inPort)) {
+ // If the request came from outside the network, only reply if it was
+ // for one of our external addresses.
Set<PortAddresses> addressSet =
- hostService.getAddressBindingsForPort(inPort);
+ hostService.getAddressBindingsForPort(inPort);
for (PortAddresses addresses : addressSet) {
for (InterfaceIpAddress ia : addresses.ipAddresses()) {
if (ia.ipAddress().equals(targetAddress)) {
Ethernet arpReply =
- buildArpReply(targetAddress, addresses.mac(), eth);
+ buildArpReply(targetAddress, addresses.mac(), eth);
sendTo(arpReply, inPort);
}
}
}
return;
- } else {
- // If the source address matches one of our external addresses
- // it could be a request from an internal host to an external
- // address. Forward it over to the correct ports.
- Ip4Address source =
- Ip4Address.valueOf(arp.getSenderProtocolAddress());
- Set<PortAddresses> sourceAddresses = findPortsInSubnet(source);
- boolean matched = false;
- for (PortAddresses pa : sourceAddresses) {
- for (InterfaceIpAddress ia : pa.ipAddresses()) {
- if (ia.ipAddress().equals(source) &&
- pa.vlan().equals(vlan)) {
- matched = true;
- sendTo(eth, pa.connectPoint());
- break;
- }
- }
- }
-
- if (matched) {
- return;
- }
}
- // Continue with normal proxy ARP case
+ // See if we have the target host in the host store
Set<Host> hosts = hostService.getHostsByIp(targetAddress);
@@ -201,20 +179,41 @@
}
}
- if (src == null || dst == null) {
- //
- // The request couldn't be resolved.
- // Flood the request on all ports except the incoming ports.
- //
- flood(eth, inPort);
+ if (src != null && dst != null) {
+ // We know the target host so we can respond
+ Ethernet arpReply = buildArpReply(targetAddress, dst.mac(), eth);
+ sendTo(arpReply, inPort);
+ return;
+ }
+
+ // If the source address matches one of our external addresses
+ // it could be a request from an internal host to an external
+ // address. Forward it over to the correct port.
+ Ip4Address source =
+ Ip4Address.valueOf(arp.getSenderProtocolAddress());
+ Set<PortAddresses> sourceAddresses = findPortsInSubnet(source);
+ boolean matched = false;
+ for (PortAddresses pa : sourceAddresses) {
+ for (InterfaceIpAddress ia : pa.ipAddresses()) {
+ if (ia.ipAddress().equals(source) &&
+ pa.vlan().equals(vlan)) {
+ matched = true;
+ sendTo(eth, pa.connectPoint());
+ break;
+ }
+ }
+ }
+
+ if (matched) {
return;
}
//
- // Reply on the port the request was received on
+ // The request couldn't be resolved.
+ // Flood the request on all ports except the incoming port.
//
- Ethernet arpReply = buildArpReply(targetAddress, dst.mac(), eth);
- sendTo(arpReply, inPort);
+ flood(eth, inPort);
+ return;
}
private void replyNdp(Ethernet eth, ConnectPoint inPort) {
diff --git a/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java b/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java
index 6d90971..09f4f14 100644
--- a/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java
@@ -242,8 +242,8 @@
}
/**
- * Tests {@link ProxyArpManager#isKnown(Ip4Address)} in the case where the
- * IP address is not known.
+ * Tests {@link ProxyArpManager#isKnown(org.onlab.packet.IpAddress)} in the
+ * case where the IP address is not known.
* Verifies the method returns false.
*/
@Test
@@ -255,8 +255,8 @@
}
/**
- * Tests {@link ProxyArpManager#isKnown(Ip4Address)} in the case where the
- * IP address is known.
+ * Tests {@link ProxyArpManager#isKnown(org.onlab.packet.IpAddress)} in the
+ * case where the IP address is known.
* Verifies the method returns true.
*/
@Test
@@ -403,12 +403,14 @@
@Test
public void testReplyToRequestFromUs() {
- replay(hostService); // no further host service expectations
-
Ip4Address ourIp = Ip4Address.valueOf("10.0.1.1");
MacAddress ourMac = MacAddress.valueOf(1L);
Ip4Address theirIp = Ip4Address.valueOf("10.0.1.100");
+ expect(hostService.getHostsByIp(theirIp)).andReturn(Collections.emptySet());
+ expect(hostService.getHost(HostId.hostId(ourMac, VLAN1))).andReturn(null);
+ replay(hostService);
+
// This is a request from something inside our network (like a BGP
// daemon) to an external host.
Ethernet arpRequest = buildArp(ARP.OP_REQUEST, ourMac, null, ourIp, theirIp);