Committed by
Gerrit Code Review
Don't flood ARP packets out the port they came in on.
Also renamed ProxyArpService#known(Ip4Address) to ProxyArpService#isKnown(Ip4Address) Fixes ONOS-722. Change-Id: I136c65e58693926e87b822cb0f4ec1c4ba0e3780
Showing
3 changed files
with
26 additions
and
22 deletions
| ... | @@ -15,10 +15,10 @@ | ... | @@ -15,10 +15,10 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.net.proxyarp; | 16 | package org.onosproject.net.proxyarp; |
| 17 | 17 | ||
| 18 | -import org.onosproject.net.ConnectPoint; | ||
| 19 | -import org.onosproject.net.packet.PacketContext; | ||
| 20 | import org.onlab.packet.Ethernet; | 18 | import org.onlab.packet.Ethernet; |
| 21 | import org.onlab.packet.Ip4Address; | 19 | import org.onlab.packet.Ip4Address; |
| 20 | +import org.onosproject.net.ConnectPoint; | ||
| 21 | +import org.onosproject.net.packet.PacketContext; | ||
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * Service for processing arp requests on behalf of applications. | 24 | * Service for processing arp requests on behalf of applications. |
| ... | @@ -32,7 +32,7 @@ public interface ProxyArpService { | ... | @@ -32,7 +32,7 @@ public interface ProxyArpService { |
| 32 | * @param addr an IPv4 address | 32 | * @param addr an IPv4 address |
| 33 | * @return true if know, false otherwise | 33 | * @return true if know, false otherwise |
| 34 | */ | 34 | */ |
| 35 | - boolean known(Ip4Address addr); | 35 | + boolean isKnown(Ip4Address addr); |
| 36 | 36 | ||
| 37 | /** | 37 | /** |
| 38 | * Sends a reply for a given request. If the host is not known then the arp | 38 | * Sends a reply for a given request. If the host is not known then the arp |
| ... | @@ -48,8 +48,9 @@ public interface ProxyArpService { | ... | @@ -48,8 +48,9 @@ public interface ProxyArpService { |
| 48 | * destination is not known. | 48 | * destination is not known. |
| 49 | * | 49 | * |
| 50 | * @param eth an ethernet frame containing an ARP request. | 50 | * @param eth an ethernet frame containing an ARP request. |
| 51 | + * @param inPort the port the request was received on | ||
| 51 | */ | 52 | */ |
| 52 | - void forward(Ethernet eth); | 53 | + void forward(Ethernet eth, ConnectPoint inPort); |
| 53 | 54 | ||
| 54 | /** | 55 | /** |
| 55 | * Handles a arp packet. | 56 | * Handles a arp packet. | ... | ... |
| ... | @@ -116,7 +116,7 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -116,7 +116,7 @@ public class ProxyArpManager implements ProxyArpService { |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | @Override | 118 | @Override |
| 119 | - public boolean known(Ip4Address addr) { | 119 | + public boolean isKnown(Ip4Address addr) { |
| 120 | checkNotNull(addr, MAC_ADDR_NULL); | 120 | checkNotNull(addr, MAC_ADDR_NULL); |
| 121 | Set<Host> hosts = hostService.getHostsByIp(addr); | 121 | Set<Host> hosts = hostService.getHostsByIp(addr); |
| 122 | return !hosts.isEmpty(); | 122 | return !hosts.isEmpty(); |
| ... | @@ -189,7 +189,7 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -189,7 +189,7 @@ public class ProxyArpManager implements ProxyArpService { |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | if (src == null || dst == null) { | 191 | if (src == null || dst == null) { |
| 192 | - flood(eth); | 192 | + flood(eth, inPort); |
| 193 | return; | 193 | return; |
| 194 | } | 194 | } |
| 195 | 195 | ||
| ... | @@ -263,7 +263,7 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -263,7 +263,7 @@ public class ProxyArpManager implements ProxyArpService { |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | @Override | 265 | @Override |
| 266 | - public void forward(Ethernet eth) { | 266 | + public void forward(Ethernet eth, ConnectPoint inPort) { |
| 267 | checkNotNull(eth, REQUEST_NULL); | 267 | checkNotNull(eth, REQUEST_NULL); |
| 268 | checkArgument(eth.getEtherType() == Ethernet.TYPE_ARP, | 268 | checkArgument(eth.getEtherType() == Ethernet.TYPE_ARP, |
| 269 | REQUEST_NOT_ARP); | 269 | REQUEST_NOT_ARP); |
| ... | @@ -274,7 +274,7 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -274,7 +274,7 @@ public class ProxyArpManager implements ProxyArpService { |
| 274 | VlanId.vlanId(eth.getVlanID()))); | 274 | VlanId.vlanId(eth.getVlanID()))); |
| 275 | 275 | ||
| 276 | if (h == null) { | 276 | if (h == null) { |
| 277 | - flood(eth); | 277 | + flood(eth, inPort); |
| 278 | } else { | 278 | } else { |
| 279 | TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder(); | 279 | TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder(); |
| 280 | builder.setOutput(h.location().port()); | 280 | builder.setOutput(h.location().port()); |
| ... | @@ -291,7 +291,7 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -291,7 +291,7 @@ public class ProxyArpManager implements ProxyArpService { |
| 291 | if (ethPkt != null && ethPkt.getEtherType() == Ethernet.TYPE_ARP) { | 291 | if (ethPkt != null && ethPkt.getEtherType() == Ethernet.TYPE_ARP) { |
| 292 | ARP arp = (ARP) ethPkt.getPayload(); | 292 | ARP arp = (ARP) ethPkt.getPayload(); |
| 293 | if (arp.getOpCode() == ARP.OP_REPLY) { | 293 | if (arp.getOpCode() == ARP.OP_REPLY) { |
| 294 | - forward(ethPkt); | 294 | + forward(ethPkt, context.inPacket().receivedFrom()); |
| 295 | } else if (arp.getOpCode() == ARP.OP_REQUEST) { | 295 | } else if (arp.getOpCode() == ARP.OP_REQUEST) { |
| 296 | reply(ethPkt, context.inPacket().receivedFrom()); | 296 | reply(ethPkt, context.inPacket().receivedFrom()); |
| 297 | } | 297 | } |
| ... | @@ -305,14 +305,14 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -305,14 +305,14 @@ public class ProxyArpManager implements ProxyArpService { |
| 305 | * Flood the arp request at all edges in the network. | 305 | * Flood the arp request at all edges in the network. |
| 306 | * @param request the arp request. | 306 | * @param request the arp request. |
| 307 | */ | 307 | */ |
| 308 | - private void flood(Ethernet request) { | 308 | + private void flood(Ethernet request, ConnectPoint inPort) { |
| 309 | TrafficTreatment.Builder builder = null; | 309 | TrafficTreatment.Builder builder = null; |
| 310 | ByteBuffer buf = ByteBuffer.wrap(request.serialize()); | 310 | ByteBuffer buf = ByteBuffer.wrap(request.serialize()); |
| 311 | 311 | ||
| 312 | synchronized (externalPorts) { | 312 | synchronized (externalPorts) { |
| 313 | for (Entry<Device, PortNumber> entry : externalPorts.entries()) { | 313 | for (Entry<Device, PortNumber> entry : externalPorts.entries()) { |
| 314 | ConnectPoint cp = new ConnectPoint(entry.getKey().id(), entry.getValue()); | 314 | ConnectPoint cp = new ConnectPoint(entry.getKey().id(), entry.getValue()); |
| 315 | - if (isOutsidePort(cp)) { | 315 | + if (isOutsidePort(cp) || cp.equals(inPort)) { |
| 316 | continue; | 316 | continue; |
| 317 | } | 317 | } |
| 318 | 318 | ... | ... |
| ... | @@ -239,7 +239,7 @@ public class ProxyArpManagerTest { | ... | @@ -239,7 +239,7 @@ public class ProxyArpManagerTest { |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | /** | 241 | /** |
| 242 | - * Tests {@link ProxyArpManager#known(Ip4Address)} in the case where the | 242 | + * Tests {@link ProxyArpManager#isKnown(Ip4Address)} in the case where the |
| 243 | * IP address is not known. | 243 | * IP address is not known. |
| 244 | * Verifies the method returns false. | 244 | * Verifies the method returns false. |
| 245 | */ | 245 | */ |
| ... | @@ -248,11 +248,11 @@ public class ProxyArpManagerTest { | ... | @@ -248,11 +248,11 @@ public class ProxyArpManagerTest { |
| 248 | expect(hostService.getHostsByIp(IP1)).andReturn(Collections.<Host>emptySet()); | 248 | expect(hostService.getHostsByIp(IP1)).andReturn(Collections.<Host>emptySet()); |
| 249 | replay(hostService); | 249 | replay(hostService); |
| 250 | 250 | ||
| 251 | - assertFalse(proxyArp.known(IP1)); | 251 | + assertFalse(proxyArp.isKnown(IP1)); |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | /** | 254 | /** |
| 255 | - * Tests {@link ProxyArpManager#known(Ip4Address)} in the case where the | 255 | + * Tests {@link ProxyArpManager#isKnown(Ip4Address)} in the case where the |
| 256 | * IP address is known. | 256 | * IP address is known. |
| 257 | * Verifies the method returns true. | 257 | * Verifies the method returns true. |
| 258 | */ | 258 | */ |
| ... | @@ -265,7 +265,7 @@ public class ProxyArpManagerTest { | ... | @@ -265,7 +265,7 @@ public class ProxyArpManagerTest { |
| 265 | .andReturn(Sets.newHashSet(host1, host2)); | 265 | .andReturn(Sets.newHashSet(host1, host2)); |
| 266 | replay(hostService); | 266 | replay(hostService); |
| 267 | 267 | ||
| 268 | - assertTrue(proxyArp.known(IP1)); | 268 | + assertTrue(proxyArp.isKnown(IP1)); |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | /** | 271 | /** |
| ... | @@ -314,7 +314,7 @@ public class ProxyArpManagerTest { | ... | @@ -314,7 +314,7 @@ public class ProxyArpManagerTest { |
| 314 | 314 | ||
| 315 | Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1); | 315 | Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1); |
| 316 | 316 | ||
| 317 | - proxyArp.reply(arpRequest, getLocation(5)); | 317 | + proxyArp.reply(arpRequest, getLocation(6)); |
| 318 | 318 | ||
| 319 | verifyFlood(arpRequest); | 319 | verifyFlood(arpRequest); |
| 320 | } | 320 | } |
| ... | @@ -341,7 +341,7 @@ public class ProxyArpManagerTest { | ... | @@ -341,7 +341,7 @@ public class ProxyArpManagerTest { |
| 341 | 341 | ||
| 342 | Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1); | 342 | Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1); |
| 343 | 343 | ||
| 344 | - proxyArp.reply(arpRequest, getLocation(5)); | 344 | + proxyArp.reply(arpRequest, getLocation(6)); |
| 345 | 345 | ||
| 346 | verifyFlood(arpRequest); | 346 | verifyFlood(arpRequest); |
| 347 | } | 347 | } |
| ... | @@ -435,7 +435,7 @@ public class ProxyArpManagerTest { | ... | @@ -435,7 +435,7 @@ public class ProxyArpManagerTest { |
| 435 | 435 | ||
| 436 | Ethernet arpRequest = buildArp(ARP.OP_REPLY, MAC2, MAC1, IP2, IP1); | 436 | Ethernet arpRequest = buildArp(ARP.OP_REPLY, MAC2, MAC1, IP2, IP1); |
| 437 | 437 | ||
| 438 | - proxyArp.forward(arpRequest); | 438 | + proxyArp.forward(arpRequest, LOC2); |
| 439 | 439 | ||
| 440 | assertEquals(1, packetService.packets.size()); | 440 | assertEquals(1, packetService.packets.size()); |
| 441 | OutboundPacket packet = packetService.packets.get(0); | 441 | OutboundPacket packet = packetService.packets.get(0); |
| ... | @@ -455,18 +455,20 @@ public class ProxyArpManagerTest { | ... | @@ -455,18 +455,20 @@ public class ProxyArpManagerTest { |
| 455 | 455 | ||
| 456 | Ethernet arpRequest = buildArp(ARP.OP_REPLY, MAC2, MAC1, IP2, IP1); | 456 | Ethernet arpRequest = buildArp(ARP.OP_REPLY, MAC2, MAC1, IP2, IP1); |
| 457 | 457 | ||
| 458 | - proxyArp.forward(arpRequest); | 458 | + proxyArp.forward(arpRequest, getLocation(6)); |
| 459 | 459 | ||
| 460 | verifyFlood(arpRequest); | 460 | verifyFlood(arpRequest); |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | /** | 463 | /** |
| 464 | - * Verifies that the given packet was flooded out all available edge ports. | 464 | + * Verifies that the given packet was flooded out all available edge ports, |
| 465 | + * except for the input port. | ||
| 465 | * | 466 | * |
| 466 | * @param packet the packet that was expected to be flooded | 467 | * @param packet the packet that was expected to be flooded |
| 467 | */ | 468 | */ |
| 468 | private void verifyFlood(Ethernet packet) { | 469 | private void verifyFlood(Ethernet packet) { |
| 469 | - assertEquals(NUM_FLOOD_PORTS, packetService.packets.size()); | 470 | + // There should be 1 less than NUM_FLOOD_PORTS; the inPort should be excluded. |
| 471 | + assertEquals(NUM_FLOOD_PORTS - 1, packetService.packets.size()); | ||
| 470 | 472 | ||
| 471 | Collections.sort(packetService.packets, | 473 | Collections.sort(packetService.packets, |
| 472 | new Comparator<OutboundPacket>() { | 474 | new Comparator<OutboundPacket>() { |
| ... | @@ -476,7 +478,8 @@ public class ProxyArpManagerTest { | ... | @@ -476,7 +478,8 @@ public class ProxyArpManagerTest { |
| 476 | } | 478 | } |
| 477 | }); | 479 | }); |
| 478 | 480 | ||
| 479 | - for (int i = 0; i < NUM_FLOOD_PORTS; i++) { | 481 | + |
| 482 | + for (int i = 0; i < NUM_FLOOD_PORTS - 1; i++) { | ||
| 480 | ConnectPoint cp = new ConnectPoint(getDeviceId(NUM_ADDRESS_PORTS + i + 1), | 483 | ConnectPoint cp = new ConnectPoint(getDeviceId(NUM_ADDRESS_PORTS + i + 1), |
| 481 | PortNumber.portNumber(1)); | 484 | PortNumber.portNumber(1)); |
| 482 | 485 | ... | ... |
-
Please register or login to post a comment