Jonathan Hart
Committed by Pavlin Radoslavov

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

Change-Id: I892d14d7181b5f50e05c6b1b6bcce514700273c5
...@@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
20 import static org.slf4j.LoggerFactory.getLogger; 20 import static org.slf4j.LoggerFactory.getLogger;
21 21
22 import java.nio.ByteBuffer; 22 import java.nio.ByteBuffer;
23 +import java.util.HashSet;
23 import java.util.List; 24 import java.util.List;
24 import java.util.Map.Entry; 25 import java.util.Map.Entry;
25 import java.util.Set; 26 import java.util.Set;
...@@ -55,8 +56,8 @@ import org.onlab.onos.net.packet.PacketService; ...@@ -55,8 +56,8 @@ import org.onlab.onos.net.packet.PacketService;
55 import org.onlab.onos.net.proxyarp.ProxyArpService; 56 import org.onlab.onos.net.proxyarp.ProxyArpService;
56 import org.onlab.packet.ARP; 57 import org.onlab.packet.ARP;
57 import org.onlab.packet.Ethernet; 58 import org.onlab.packet.Ethernet;
58 -import org.onlab.packet.IpAddress;
59 import org.onlab.packet.Ip4Address; 59 import org.onlab.packet.Ip4Address;
60 +import org.onlab.packet.IpAddress;
60 import org.onlab.packet.MacAddress; 61 import org.onlab.packet.MacAddress;
61 import org.onlab.packet.VlanId; 62 import org.onlab.packet.VlanId;
62 import org.slf4j.Logger; 63 import org.slf4j.Logger;
...@@ -150,18 +151,23 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -150,18 +151,23 @@ public class ProxyArpManager implements ProxyArpService {
150 } else { 151 } else {
151 // If the source address matches one of our external addresses 152 // If the source address matches one of our external addresses
152 // it could be a request from an internal host to an external 153 // it could be a request from an internal host to an external
153 - // address. Forward it over to the correct port. 154 + // address. Forward it over to the correct ports.
154 Ip4Address source = 155 Ip4Address source =
155 Ip4Address.valueOf(arp.getSenderProtocolAddress()); 156 Ip4Address.valueOf(arp.getSenderProtocolAddress());
156 - PortAddresses sourceAddresses = findPortInSubnet(source); 157 + Set<PortAddresses> sourceAddresses = findPortsInSubnet(source);
157 - if (sourceAddresses != null) { 158 + boolean matched = false;
158 - for (InterfaceIpAddress ia : sourceAddresses.ipAddresses()) { 159 + for (PortAddresses pa : sourceAddresses) {
160 + for (InterfaceIpAddress ia : pa.ipAddresses()) {
159 if (ia.ipAddress().equals(source)) { 161 if (ia.ipAddress().equals(source)) {
160 - sendTo(eth, sourceAddresses.connectPoint()); 162 + matched = true;
161 - return; 163 + sendTo(eth, pa.connectPoint());
162 } 164 }
163 } 165 }
164 } 166 }
167 +
168 + if (matched) {
169 + return;
170 + }
165 } 171 }
166 172
167 // Continue with normal proxy ARP case 173 // Continue with normal proxy ARP case
...@@ -223,21 +229,21 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -223,21 +229,21 @@ public class ProxyArpManager implements ProxyArpService {
223 } 229 }
224 230
225 /** 231 /**
226 - * Finds the port with an address in the subnet of the target address, if 232 + * Finds ports with an address in the subnet of the target address.
227 - * one exists.
228 * 233 *
229 * @param target the target address to find a matching port for 234 * @param target the target address to find a matching port for
230 - * @return a PortAddresses object if one was found, otherwise null 235 + * @return a set of PortAddresses describing ports in the subnet
231 */ 236 */
232 - private PortAddresses findPortInSubnet(Ip4Address target) { 237 + private Set<PortAddresses> findPortsInSubnet(Ip4Address target) {
238 + Set<PortAddresses> result = new HashSet<PortAddresses>();
233 for (PortAddresses addresses : hostService.getAddressBindings()) { 239 for (PortAddresses addresses : hostService.getAddressBindings()) {
234 for (InterfaceIpAddress ia : addresses.ipAddresses()) { 240 for (InterfaceIpAddress ia : addresses.ipAddresses()) {
235 if (ia.subnetAddress().contains(target)) { 241 if (ia.subnetAddress().contains(target)) {
236 - return addresses; 242 + result.add(addresses);
237 } 243 }
238 } 244 }
239 } 245 }
240 - return null; 246 + return result;
241 } 247 }
242 248
243 /** 249 /**
......