Fix for proxy ARP to allow multiple ports on the same external subnet

Change-Id: I892d14d7181b5f50e05c6b1b6bcce514700273c5
diff --git a/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java b/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java
index c0a3f16..80d461a 100644
--- a/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java
@@ -20,6 +20,7 @@
 import static org.slf4j.LoggerFactory.getLogger;
 
 import java.nio.ByteBuffer;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -55,8 +56,8 @@
 import org.onlab.onos.net.proxyarp.ProxyArpService;
 import org.onlab.packet.ARP;
 import org.onlab.packet.Ethernet;
-import org.onlab.packet.IpAddress;
 import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 import org.slf4j.Logger;
@@ -150,18 +151,23 @@
         } 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 port.
+            // address. Forward it over to the correct ports.
             Ip4Address source =
                 Ip4Address.valueOf(arp.getSenderProtocolAddress());
-            PortAddresses sourceAddresses = findPortInSubnet(source);
-            if (sourceAddresses != null) {
-                for (InterfaceIpAddress ia : sourceAddresses.ipAddresses()) {
+            Set<PortAddresses> sourceAddresses = findPortsInSubnet(source);
+            boolean matched = false;
+            for (PortAddresses pa : sourceAddresses) {
+                for (InterfaceIpAddress ia : pa.ipAddresses()) {
                     if (ia.ipAddress().equals(source)) {
-                        sendTo(eth, sourceAddresses.connectPoint());
-                        return;
+                        matched = true;
+                        sendTo(eth, pa.connectPoint());
                     }
                 }
             }
+
+            if (matched) {
+                return;
+            }
         }
 
         // Continue with normal proxy ARP case
@@ -223,21 +229,21 @@
     }
 
     /**
-     * Finds the port with an address in the subnet of the target address, if
-     * one exists.
+     * Finds ports with an address in the subnet of the target address.
      *
      * @param target the target address to find a matching port for
-     * @return a PortAddresses object if one was found, otherwise null
+     * @return a set of PortAddresses describing ports in the subnet
      */
-    private PortAddresses findPortInSubnet(Ip4Address target) {
+    private Set<PortAddresses> findPortsInSubnet(Ip4Address target) {
+        Set<PortAddresses> result = new HashSet<PortAddresses>();
         for (PortAddresses addresses : hostService.getAddressBindings()) {
             for (InterfaceIpAddress ia : addresses.ipAddresses()) {
                 if (ia.subnetAddress().contains(target)) {
-                    return addresses;
+                    result.add(addresses);
                 }
             }
         }
-        return null;
+        return result;
     }
 
     /**