Committed by
Gerrit Code Review
[ONOS-1264] Add IPv6 unit test for ProxyArpManager
Change-Id: I1d4ec1f06508bd1bf1d54b299b0ae4ac1d5482d9
Showing
1 changed file
with
387 additions
and
8 deletions
| ... | @@ -21,11 +21,19 @@ import org.junit.Before; | ... | @@ -21,11 +21,19 @@ import org.junit.Before; |
| 21 | import org.junit.Test; | 21 | import org.junit.Test; |
| 22 | import org.onlab.packet.ARP; | 22 | import org.onlab.packet.ARP; |
| 23 | import org.onlab.packet.Ethernet; | 23 | import org.onlab.packet.Ethernet; |
| 24 | +import org.onlab.packet.ICMP6; | ||
| 25 | +import org.onlab.packet.IPacket; | ||
| 26 | +import org.onlab.packet.IPv6; | ||
| 24 | import org.onlab.packet.Ip4Address; | 27 | import org.onlab.packet.Ip4Address; |
| 25 | import org.onlab.packet.Ip4Prefix; | 28 | import org.onlab.packet.Ip4Prefix; |
| 29 | +import org.onlab.packet.Ip6Address; | ||
| 30 | +import org.onlab.packet.Ip6Prefix; | ||
| 26 | import org.onlab.packet.IpPrefix; | 31 | import org.onlab.packet.IpPrefix; |
| 27 | import org.onlab.packet.MacAddress; | 32 | import org.onlab.packet.MacAddress; |
| 28 | import org.onlab.packet.VlanId; | 33 | import org.onlab.packet.VlanId; |
| 34 | +import org.onlab.packet.ndp.NeighborAdvertisement; | ||
| 35 | +import org.onlab.packet.ndp.NeighborDiscoveryOptions; | ||
| 36 | +import org.onlab.packet.ndp.NeighborSolicitation; | ||
| 29 | import org.onosproject.incubator.net.intf.Interface; | 37 | import org.onosproject.incubator.net.intf.Interface; |
| 30 | import org.onosproject.incubator.net.intf.InterfaceService; | 38 | import org.onosproject.incubator.net.intf.InterfaceService; |
| 31 | import org.onosproject.net.ConnectPoint; | 39 | import org.onosproject.net.ConnectPoint; |
| ... | @@ -66,9 +74,13 @@ import static org.easymock.EasyMock.anyObject; | ... | @@ -66,9 +74,13 @@ import static org.easymock.EasyMock.anyObject; |
| 66 | import static org.easymock.EasyMock.createMock; | 74 | import static org.easymock.EasyMock.createMock; |
| 67 | import static org.easymock.EasyMock.expect; | 75 | import static org.easymock.EasyMock.expect; |
| 68 | import static org.easymock.EasyMock.replay; | 76 | import static org.easymock.EasyMock.replay; |
| 77 | +import static org.hamcrest.Matchers.anyOf; | ||
| 78 | +import static org.hamcrest.Matchers.is; | ||
| 69 | import static org.junit.Assert.assertArrayEquals; | 79 | import static org.junit.Assert.assertArrayEquals; |
| 70 | import static org.junit.Assert.assertEquals; | 80 | import static org.junit.Assert.assertEquals; |
| 71 | import static org.junit.Assert.assertFalse; | 81 | import static org.junit.Assert.assertFalse; |
| 82 | +import static org.junit.Assert.assertNotNull; | ||
| 83 | +import static org.junit.Assert.assertThat; | ||
| 72 | import static org.junit.Assert.assertTrue; | 84 | import static org.junit.Assert.assertTrue; |
| 73 | 85 | ||
| 74 | /** | 86 | /** |
| ... | @@ -83,6 +95,8 @@ public class ProxyArpManagerTest { | ... | @@ -83,6 +95,8 @@ public class ProxyArpManagerTest { |
| 83 | 95 | ||
| 84 | private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1"); | 96 | private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1"); |
| 85 | private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2"); | 97 | private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2"); |
| 98 | + private static final Ip6Address IP3 = Ip6Address.valueOf("1000::1"); | ||
| 99 | + private static final Ip6Address IP4 = Ip6Address.valueOf("1000::2"); | ||
| 86 | 100 | ||
| 87 | private static final ProviderId PID = new ProviderId("of", "foo"); | 101 | private static final ProviderId PID = new ProviderId("of", "foo"); |
| 88 | 102 | ||
| ... | @@ -90,8 +104,14 @@ public class ProxyArpManagerTest { | ... | @@ -90,8 +104,14 @@ public class ProxyArpManagerTest { |
| 90 | private static final VlanId VLAN2 = VlanId.vlanId((short) 2); | 104 | private static final VlanId VLAN2 = VlanId.vlanId((short) 2); |
| 91 | private static final MacAddress MAC1 = MacAddress.valueOf("00:00:11:00:00:01"); | 105 | private static final MacAddress MAC1 = MacAddress.valueOf("00:00:11:00:00:01"); |
| 92 | private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02"); | 106 | private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02"); |
| 107 | + private static final MacAddress MAC3 = MacAddress.valueOf("00:00:33:00:00:03"); | ||
| 108 | + private static final MacAddress MAC4 = MacAddress.valueOf("00:00:44:00:00:04"); | ||
| 109 | + private static final MacAddress SOLICITED_MAC3 = MacAddress.valueOf("33:33:FF:00:00:01"); | ||
| 93 | private static final HostId HID1 = HostId.hostId(MAC1, VLAN1); | 110 | private static final HostId HID1 = HostId.hostId(MAC1, VLAN1); |
| 94 | private static final HostId HID2 = HostId.hostId(MAC2, VLAN1); | 111 | private static final HostId HID2 = HostId.hostId(MAC2, VLAN1); |
| 112 | + private static final HostId HID3 = HostId.hostId(MAC3, VLAN1); | ||
| 113 | + private static final HostId HID4 = HostId.hostId(MAC4, VLAN1); | ||
| 114 | + private static final HostId SOLICITED_HID3 = HostId.hostId(SOLICITED_MAC3, VLAN1); | ||
| 95 | 115 | ||
| 96 | private static final DeviceId DID1 = getDeviceId(1); | 116 | private static final DeviceId DID1 = getDeviceId(1); |
| 97 | private static final DeviceId DID2 = getDeviceId(2); | 117 | private static final DeviceId DID2 = getDeviceId(2); |
| ... | @@ -222,21 +242,29 @@ public class ProxyArpManagerTest { | ... | @@ -222,21 +242,29 @@ public class ProxyArpManagerTest { |
| 222 | 242 | ||
| 223 | for (int i = 1; i <= NUM_ADDRESS_PORTS; i++) { | 243 | for (int i = 1; i <= NUM_ADDRESS_PORTS; i++) { |
| 224 | ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1); | 244 | ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1); |
| 225 | - Ip4Prefix prefix1 = | 245 | + |
| 226 | - Ip4Prefix.valueOf("10.0." + (2 * i - 1) + ".0/24"); | 246 | + // Interface address for IPv4 |
| 227 | - Ip4Address addr1 = | 247 | + Ip4Prefix prefix1 = Ip4Prefix.valueOf("10.0." + (2 * i - 1) + ".0/24"); |
| 228 | - Ip4Address.valueOf("10.0." + (2 * i - 1) + ".1"); | 248 | + Ip4Address addr1 = Ip4Address.valueOf("10.0." + (2 * i - 1) + ".1"); |
| 229 | Ip4Prefix prefix2 = Ip4Prefix.valueOf("10.0." + (2 * i) + ".0/24"); | 249 | Ip4Prefix prefix2 = Ip4Prefix.valueOf("10.0." + (2 * i) + ".0/24"); |
| 230 | Ip4Address addr2 = Ip4Address.valueOf("10.0." + (2 * i) + ".1"); | 250 | Ip4Address addr2 = Ip4Address.valueOf("10.0." + (2 * i) + ".1"); |
| 231 | InterfaceIpAddress ia1 = new InterfaceIpAddress(addr1, prefix1); | 251 | InterfaceIpAddress ia1 = new InterfaceIpAddress(addr1, prefix1); |
| 232 | InterfaceIpAddress ia2 = new InterfaceIpAddress(addr2, prefix2); | 252 | InterfaceIpAddress ia2 = new InterfaceIpAddress(addr2, prefix2); |
| 233 | - Interface intf1 = new Interface(cp, Sets.newHashSet(ia1), | 253 | + |
| 254 | + // Interface address for IPv6 | ||
| 255 | + Ip6Prefix prefix3 = Ip6Prefix.valueOf((2 * i - 1) + "000::0/64"); | ||
| 256 | + Ip6Address addr3 = Ip6Address.valueOf((2 * i - 1) + "000::1"); | ||
| 257 | + Ip6Prefix prefix4 = Ip6Prefix.valueOf((2 * i) + "000::0/64"); | ||
| 258 | + Ip6Address addr4 = Ip6Address.valueOf((2 * i) + "000::1"); | ||
| 259 | + InterfaceIpAddress ia3 = new InterfaceIpAddress(addr3, prefix3); | ||
| 260 | + InterfaceIpAddress ia4 = new InterfaceIpAddress(addr4, prefix4); | ||
| 261 | + | ||
| 262 | + Interface intf1 = new Interface(cp, Sets.newHashSet(ia1, ia3), | ||
| 234 | MacAddress.valueOf(2 * i - 1), | 263 | MacAddress.valueOf(2 * i - 1), |
| 235 | VlanId.vlanId((short) 1)); | 264 | VlanId.vlanId((short) 1)); |
| 236 | - Interface intf2 = new Interface(cp, Sets.newHashSet(ia2), | 265 | + Interface intf2 = new Interface(cp, Sets.newHashSet(ia2, ia4), |
| 237 | MacAddress.valueOf(2 * i), | 266 | MacAddress.valueOf(2 * i), |
| 238 | VlanId.NONE); | 267 | VlanId.NONE); |
| 239 | - | ||
| 240 | interfaces.add(intf1); | 268 | interfaces.add(intf1); |
| 241 | interfaces.add(intf2); | 269 | interfaces.add(intf2); |
| 242 | 270 | ||
| ... | @@ -321,6 +349,41 @@ public class ProxyArpManagerTest { | ... | @@ -321,6 +349,41 @@ public class ProxyArpManagerTest { |
| 321 | 349 | ||
| 322 | /** | 350 | /** |
| 323 | * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the | 351 | * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the |
| 352 | + * destination host is known. | ||
| 353 | + * Verifies the correct NDP reply is sent out the correct port. | ||
| 354 | + */ | ||
| 355 | + @Test | ||
| 356 | + public void testReplyKnownIpv6() { | ||
| 357 | + //Set the return value of isEdgePoint from the edgemanager. | ||
| 358 | + isEdgePointReturn = true; | ||
| 359 | + | ||
| 360 | + Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN1, getLocation(4), | ||
| 361 | + Collections.singleton(IP3)); | ||
| 362 | + | ||
| 363 | + Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5), | ||
| 364 | + Collections.singleton(IP4)); | ||
| 365 | + | ||
| 366 | + expect(hostService.getHostsByIp(IP3)) | ||
| 367 | + .andReturn(Collections.singleton(replyer)); | ||
| 368 | + expect(hostService.getHost(HID4)).andReturn(requestor); | ||
| 369 | + | ||
| 370 | + replay(hostService); | ||
| 371 | + replay(interfaceService); | ||
| 372 | + | ||
| 373 | + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, | ||
| 374 | + MAC4, SOLICITED_MAC3, | ||
| 375 | + IP4, IP3); | ||
| 376 | + | ||
| 377 | + proxyArp.reply(ndpRequest, getLocation(5)); | ||
| 378 | + | ||
| 379 | + assertEquals(1, packetService.packets.size()); | ||
| 380 | + Ethernet ndpReply = buildNDP(ICMP6.NEIGHBOR_ADVERTISEMENT, | ||
| 381 | + MAC3, MAC4, IP3, IP4); | ||
| 382 | + verifyPacketOut(ndpReply, getLocation(5), packetService.packets.get(0)); | ||
| 383 | + } | ||
| 384 | + | ||
| 385 | + /** | ||
| 386 | + * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the | ||
| 324 | * destination host is not known. | 387 | * destination host is not known. |
| 325 | * Verifies the ARP request is flooded out the correct edge ports. | 388 | * Verifies the ARP request is flooded out the correct edge ports. |
| 326 | */ | 389 | */ |
| ... | @@ -337,7 +400,6 @@ public class ProxyArpManagerTest { | ... | @@ -337,7 +400,6 @@ public class ProxyArpManagerTest { |
| 337 | .andReturn(Collections.emptySet()); | 400 | .andReturn(Collections.emptySet()); |
| 338 | expect(hostService.getHost(HID2)).andReturn(requestor); | 401 | expect(hostService.getHost(HID2)).andReturn(requestor); |
| 339 | 402 | ||
| 340 | - | ||
| 341 | replay(hostService); | 403 | replay(hostService); |
| 342 | replay(interfaceService); | 404 | replay(interfaceService); |
| 343 | 405 | ||
| ... | @@ -355,6 +417,41 @@ public class ProxyArpManagerTest { | ... | @@ -355,6 +417,41 @@ public class ProxyArpManagerTest { |
| 355 | 417 | ||
| 356 | /** | 418 | /** |
| 357 | * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the | 419 | * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the |
| 420 | + * destination host is not known. | ||
| 421 | + * Verifies the NDP request is flooded out the correct edge ports. | ||
| 422 | + */ | ||
| 423 | + @Test | ||
| 424 | + public void testReplyUnknownIpv6() { | ||
| 425 | + isEdgePointReturn = true; | ||
| 426 | + | ||
| 427 | + Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5), | ||
| 428 | + Collections.singleton(IP4)); | ||
| 429 | + | ||
| 430 | + expect(hostService.getHostsByIp(IP3)) | ||
| 431 | + .andReturn(Collections.emptySet()); | ||
| 432 | + expect(interfaceService.getInterfacesByIp(IP4)) | ||
| 433 | + .andReturn(Collections.emptySet()); | ||
| 434 | + expect(hostService.getHost(HID4)).andReturn(requestor); | ||
| 435 | + | ||
| 436 | + replay(hostService); | ||
| 437 | + replay(interfaceService); | ||
| 438 | + | ||
| 439 | + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, | ||
| 440 | + MAC4, SOLICITED_MAC3, | ||
| 441 | + IP4, IP3); | ||
| 442 | + | ||
| 443 | + //Setup the set of edge ports to be used in the reply method | ||
| 444 | + getEdgePointsNoArg = Lists.newLinkedList(); | ||
| 445 | + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); | ||
| 446 | + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); | ||
| 447 | + | ||
| 448 | + proxyArp.reply(ndpRequest, getLocation(6)); | ||
| 449 | + | ||
| 450 | + verifyFlood(ndpRequest); | ||
| 451 | + } | ||
| 452 | + | ||
| 453 | + /** | ||
| 454 | + * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the | ||
| 358 | * destination host is known for that IP address, but is not on the same | 455 | * destination host is known for that IP address, but is not on the same |
| 359 | * VLAN as the source host. | 456 | * VLAN as the source host. |
| 360 | * Verifies the ARP request is flooded out the correct edge ports. | 457 | * Verifies the ARP request is flooded out the correct edge ports. |
| ... | @@ -388,6 +485,46 @@ public class ProxyArpManagerTest { | ... | @@ -388,6 +485,46 @@ public class ProxyArpManagerTest { |
| 388 | verifyFlood(arpRequest); | 485 | verifyFlood(arpRequest); |
| 389 | } | 486 | } |
| 390 | 487 | ||
| 488 | + /** | ||
| 489 | + * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the | ||
| 490 | + * destination host is known for that IP address, but is not on the same | ||
| 491 | + * VLAN as the source host. | ||
| 492 | + * Verifies the NDP request is flooded out the correct edge ports. | ||
| 493 | + */ | ||
| 494 | + @Test | ||
| 495 | + public void testReplyDifferentVlanIpv6() { | ||
| 496 | + | ||
| 497 | + Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN2, getLocation(4), | ||
| 498 | + Collections.singleton(IP3)); | ||
| 499 | + | ||
| 500 | + Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5), | ||
| 501 | + Collections.singleton(IP4)); | ||
| 502 | + | ||
| 503 | + expect(hostService.getHostsByIp(IP3)) | ||
| 504 | + .andReturn(Collections.singleton(replyer)); | ||
| 505 | + expect(interfaceService.getInterfacesByIp(IP4)) | ||
| 506 | + .andReturn(Collections.emptySet()); | ||
| 507 | + expect(hostService.getHost(HID4)).andReturn(requestor); | ||
| 508 | + | ||
| 509 | + replay(hostService); | ||
| 510 | + replay(interfaceService); | ||
| 511 | + | ||
| 512 | + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, | ||
| 513 | + MAC4, SOLICITED_MAC3, | ||
| 514 | + IP4, IP3); | ||
| 515 | + | ||
| 516 | + //Setup for flood test | ||
| 517 | + getEdgePointsNoArg = Lists.newLinkedList(); | ||
| 518 | + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); | ||
| 519 | + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); | ||
| 520 | + proxyArp.reply(ndpRequest, getLocation(6)); | ||
| 521 | + | ||
| 522 | + verifyFlood(ndpRequest); | ||
| 523 | + } | ||
| 524 | + | ||
| 525 | + /** | ||
| 526 | + * Test ARP request from external network to an internal host. | ||
| 527 | + */ | ||
| 391 | @Test | 528 | @Test |
| 392 | public void testReplyToRequestForUs() { | 529 | public void testReplyToRequestForUs() { |
| 393 | Ip4Address theirIp = Ip4Address.valueOf("10.0.1.254"); | 530 | Ip4Address theirIp = Ip4Address.valueOf("10.0.1.254"); |
| ... | @@ -422,6 +559,63 @@ public class ProxyArpManagerTest { | ... | @@ -422,6 +559,63 @@ public class ProxyArpManagerTest { |
| 422 | verifyPacketOut(arpReply, LOC1, packetService.packets.get(0)); | 559 | verifyPacketOut(arpReply, LOC1, packetService.packets.get(0)); |
| 423 | } | 560 | } |
| 424 | 561 | ||
| 562 | + /** | ||
| 563 | + * Test NDP request from external network to an internal host. | ||
| 564 | + */ | ||
| 565 | + @Test | ||
| 566 | + public void testReplyToRequestForUsIpv6() { | ||
| 567 | + Ip6Address theirIp = Ip6Address.valueOf("1000::ffff"); | ||
| 568 | + Ip6Address ourFirstIp = Ip6Address.valueOf("1000::1"); | ||
| 569 | + Ip6Address ourSecondIp = Ip6Address.valueOf("2000::1"); | ||
| 570 | + MacAddress firstMac = MacAddress.valueOf(1L); | ||
| 571 | + MacAddress secondMac = MacAddress.valueOf(2L); | ||
| 572 | + | ||
| 573 | + Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC1, | ||
| 574 | + Collections.singleton(theirIp)); | ||
| 575 | + | ||
| 576 | + expect(hostService.getHost(HID2)).andReturn(requestor); | ||
| 577 | + expect(hostService.getHostsByIp(ourFirstIp)) | ||
| 578 | + .andReturn(Collections.singleton(requestor)); | ||
| 579 | + replay(hostService); | ||
| 580 | + replay(interfaceService); | ||
| 581 | + | ||
| 582 | + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, | ||
| 583 | + MAC2, | ||
| 584 | + MacAddress.valueOf("33:33:ff:00:00:01"), | ||
| 585 | + theirIp, | ||
| 586 | + ourFirstIp); | ||
| 587 | + isEdgePointReturn = true; | ||
| 588 | + proxyArp.reply(ndpRequest, LOC1); | ||
| 589 | + assertEquals(1, packetService.packets.size()); | ||
| 590 | + | ||
| 591 | + Ethernet ndpReply = buildNDP(ICMP6.NEIGHBOR_ADVERTISEMENT, | ||
| 592 | + firstMac, | ||
| 593 | + MAC2, | ||
| 594 | + ourFirstIp, | ||
| 595 | + theirIp); | ||
| 596 | + verifyPacketOut(ndpReply, LOC1, packetService.packets.get(0)); | ||
| 597 | + | ||
| 598 | + // Test a request for the second address on that port | ||
| 599 | + packetService.packets.clear(); | ||
| 600 | + ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, | ||
| 601 | + MAC2, | ||
| 602 | + MacAddress.valueOf("33:33:ff:00:00:01"), | ||
| 603 | + theirIp, | ||
| 604 | + ourSecondIp); | ||
| 605 | + proxyArp.reply(ndpRequest, LOC1); | ||
| 606 | + assertEquals(1, packetService.packets.size()); | ||
| 607 | + | ||
| 608 | + ndpReply = buildNDP(ICMP6.NEIGHBOR_ADVERTISEMENT, | ||
| 609 | + secondMac, | ||
| 610 | + MAC2, | ||
| 611 | + ourSecondIp, | ||
| 612 | + theirIp); | ||
| 613 | + verifyPacketOut(ndpReply, LOC1, packetService.packets.get(0)); | ||
| 614 | + } | ||
| 615 | + | ||
| 616 | + /** | ||
| 617 | + * Request for a valid external IPv4 address but coming in the wrong port. | ||
| 618 | + */ | ||
| 425 | @Test | 619 | @Test |
| 426 | public void testReplyExternalPortBadRequest() { | 620 | public void testReplyExternalPortBadRequest() { |
| 427 | replay(hostService); // no further host service expectations | 621 | replay(hostService); // no further host service expectations |
| ... | @@ -442,6 +636,38 @@ public class ProxyArpManagerTest { | ... | @@ -442,6 +636,38 @@ public class ProxyArpManagerTest { |
| 442 | assertEquals(0, packetService.packets.size()); | 636 | assertEquals(0, packetService.packets.size()); |
| 443 | } | 637 | } |
| 444 | 638 | ||
| 639 | + /** | ||
| 640 | + * Request for a valid external IPv6 address but coming in the wrong port. | ||
| 641 | + */ | ||
| 642 | + @Test | ||
| 643 | + public void testReplyExternalPortBadRequestIpv6() { | ||
| 644 | + replay(hostService); // no further host service expectations | ||
| 645 | + replay(interfaceService); | ||
| 646 | + | ||
| 647 | + Ip6Address theirIp = Ip6Address.valueOf("1000::ffff"); | ||
| 648 | + | ||
| 649 | + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, | ||
| 650 | + MAC1, | ||
| 651 | + MacAddress.valueOf("33:33:ff:00:00:01"), | ||
| 652 | + theirIp, | ||
| 653 | + Ip6Address.valueOf("3000::1")); | ||
| 654 | + proxyArp.reply(ndpRequest, LOC1); | ||
| 655 | + assertEquals(0, packetService.packets.size()); | ||
| 656 | + | ||
| 657 | + // Request for a valid internal IP address but coming in an external port | ||
| 658 | + packetService.packets.clear(); | ||
| 659 | + ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, | ||
| 660 | + MAC1, | ||
| 661 | + MacAddress.valueOf("33:33:ff:00:00:01"), | ||
| 662 | + theirIp, | ||
| 663 | + IP3); | ||
| 664 | + proxyArp.reply(ndpRequest, LOC1); | ||
| 665 | + assertEquals(0, packetService.packets.size()); | ||
| 666 | + } | ||
| 667 | + | ||
| 668 | + /** | ||
| 669 | + * Test ARP request from internal network to an external host. | ||
| 670 | + */ | ||
| 445 | @Test | 671 | @Test |
| 446 | public void testReplyToRequestFromUs() { | 672 | public void testReplyToRequestFromUs() { |
| 447 | Ip4Address ourIp = Ip4Address.valueOf("10.0.1.1"); | 673 | Ip4Address ourIp = Ip4Address.valueOf("10.0.1.1"); |
| ... | @@ -474,6 +700,48 @@ public class ProxyArpManagerTest { | ... | @@ -474,6 +700,48 @@ public class ProxyArpManagerTest { |
| 474 | } | 700 | } |
| 475 | 701 | ||
| 476 | /** | 702 | /** |
| 703 | + * Test NDP request from internal network to an external host. | ||
| 704 | + */ | ||
| 705 | + @Test | ||
| 706 | + public void testReplyToRequestFromUsIpv6() { | ||
| 707 | + Ip6Address ourIp = Ip6Address.valueOf("1000::1"); | ||
| 708 | + MacAddress ourMac = MacAddress.valueOf(1L); | ||
| 709 | + Ip6Address theirIp = Ip6Address.valueOf("1000::100"); | ||
| 710 | + | ||
| 711 | + expect(hostService.getHostsByIp(theirIp)).andReturn(Collections.emptySet()); | ||
| 712 | + expect(interfaceService.getInterfacesByIp(ourIp)) | ||
| 713 | + .andReturn(Collections.singleton(new Interface(getLocation(1), | ||
| 714 | + Collections.singleton(new InterfaceIpAddress( | ||
| 715 | + ourIp, | ||
| 716 | + IpPrefix.valueOf("1000::1/64"))), | ||
| 717 | + ourMac, | ||
| 718 | + VLAN1))); | ||
| 719 | + expect(hostService.getHost(HostId.hostId(ourMac, VLAN1))).andReturn(null); | ||
| 720 | + replay(hostService); | ||
| 721 | + replay(interfaceService); | ||
| 722 | + | ||
| 723 | + // This is a request from something inside our network (like a BGP | ||
| 724 | + // daemon) to an external host. | ||
| 725 | + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, | ||
| 726 | + ourMac, | ||
| 727 | + MacAddress.valueOf("33:33:ff:00:00:01"), | ||
| 728 | + ourIp, | ||
| 729 | + theirIp); | ||
| 730 | + | ||
| 731 | + //Ensure the packet is allowed through (it is not to an internal port) | ||
| 732 | + isEdgePointReturn = true; | ||
| 733 | + | ||
| 734 | + proxyArp.reply(ndpRequest, getLocation(5)); | ||
| 735 | + assertEquals(1, packetService.packets.size()); | ||
| 736 | + verifyPacketOut(ndpRequest, getLocation(1), packetService.packets.get(0)); | ||
| 737 | + | ||
| 738 | + // The same request from a random external port should fail | ||
| 739 | + packetService.packets.clear(); | ||
| 740 | + proxyArp.reply(ndpRequest, getLocation(2)); | ||
| 741 | + assertEquals(0, packetService.packets.size()); | ||
| 742 | + } | ||
| 743 | + | ||
| 744 | + /** | ||
| 477 | * Tests {@link ProxyArpManager#forward(Ethernet, ConnectPoint)} in the case where the | 745 | * Tests {@link ProxyArpManager#forward(Ethernet, ConnectPoint)} in the case where the |
| 478 | * destination host is known. | 746 | * destination host is known. |
| 479 | * Verifies the correct ARP request is sent out the correct port. | 747 | * Verifies the correct ARP request is sent out the correct port. |
| ... | @@ -502,6 +770,35 @@ public class ProxyArpManagerTest { | ... | @@ -502,6 +770,35 @@ public class ProxyArpManagerTest { |
| 502 | 770 | ||
| 503 | /** | 771 | /** |
| 504 | * Tests {@link ProxyArpManager#forward(Ethernet, ConnectPoint)} in the case where the | 772 | * Tests {@link ProxyArpManager#forward(Ethernet, ConnectPoint)} in the case where the |
| 773 | + * destination host is known. | ||
| 774 | + * Verifies the correct ARP request is sent out the correct port. | ||
| 775 | + */ | ||
| 776 | + @Test | ||
| 777 | + public void testForwardToHostIpv6() { | ||
| 778 | + Host host1 = new DefaultHost(PID, HID3, MAC3, VLAN1, LOC1, | ||
| 779 | + Collections.singleton(IP3)); | ||
| 780 | + Host host2 = new DefaultHost(PID, HID4, MAC4, VLAN1, LOC2, | ||
| 781 | + Collections.singleton(IP4)); | ||
| 782 | + | ||
| 783 | + expect(hostService.getHost(SOLICITED_HID3)).andReturn(host1); | ||
| 784 | + expect(hostService.getHost(HID4)).andReturn(host2); | ||
| 785 | + replay(hostService); | ||
| 786 | + replay(interfaceService); | ||
| 787 | + | ||
| 788 | + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, | ||
| 789 | + MAC4, SOLICITED_MAC3, | ||
| 790 | + IP4, IP3); | ||
| 791 | + | ||
| 792 | + proxyArp.forward(ndpRequest, LOC2); | ||
| 793 | + | ||
| 794 | + assertEquals(1, packetService.packets.size()); | ||
| 795 | + OutboundPacket packet = packetService.packets.get(0); | ||
| 796 | + | ||
| 797 | + verifyPacketOut(ndpRequest, LOC1, packet); | ||
| 798 | + } | ||
| 799 | + | ||
| 800 | + /** | ||
| 801 | + * Tests {@link ProxyArpManager#forward(Ethernet, ConnectPoint)} in the case where the | ||
| 505 | * destination host is not known. | 802 | * destination host is not known. |
| 506 | * Verifies the correct ARP request is flooded out the correct edge ports. | 803 | * Verifies the correct ARP request is flooded out the correct edge ports. |
| 507 | */ | 804 | */ |
| ... | @@ -526,6 +823,33 @@ public class ProxyArpManagerTest { | ... | @@ -526,6 +823,33 @@ public class ProxyArpManagerTest { |
| 526 | } | 823 | } |
| 527 | 824 | ||
| 528 | /** | 825 | /** |
| 826 | + * Tests {@link ProxyArpManager#forward(Ethernet, ConnectPoint)} in the case where the | ||
| 827 | + * destination host is not known. | ||
| 828 | + * Verifies the correct NDP request is flooded out the correct edge ports. | ||
| 829 | + */ | ||
| 830 | + @Test | ||
| 831 | + public void testForwardFloodIpv6() { | ||
| 832 | + expect(hostService.getHost(SOLICITED_HID3)).andReturn(null); | ||
| 833 | + replay(hostService); | ||
| 834 | + replay(interfaceService); | ||
| 835 | + | ||
| 836 | + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, | ||
| 837 | + MAC4, SOLICITED_MAC3, | ||
| 838 | + IP4, IP3); | ||
| 839 | + | ||
| 840 | + //populate the list of edges when so that when forward hits flood in the manager it contains the values | ||
| 841 | + //that should continue on | ||
| 842 | + getEdgePointsNoArg = Lists.newLinkedList(); | ||
| 843 | + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("3"), PortNumber.portNumber(1))); | ||
| 844 | + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); | ||
| 845 | + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); | ||
| 846 | + | ||
| 847 | + proxyArp.forward(ndpRequest, getLocation(6)); | ||
| 848 | + | ||
| 849 | + verifyFlood(ndpRequest); | ||
| 850 | + } | ||
| 851 | + | ||
| 852 | + /** | ||
| 529 | * Verifies that the given packet was flooded out all available edge ports, | 853 | * Verifies that the given packet was flooded out all available edge ports, |
| 530 | * except for the input port. | 854 | * except for the input port. |
| 531 | * | 855 | * |
| ... | @@ -626,6 +950,61 @@ public class ProxyArpManagerTest { | ... | @@ -626,6 +950,61 @@ public class ProxyArpManagerTest { |
| 626 | } | 950 | } |
| 627 | 951 | ||
| 628 | /** | 952 | /** |
| 953 | + * Builds an NDP packet with the given parameters. | ||
| 954 | + * | ||
| 955 | + * @param type NeighborSolicitation or NeighborAdvertisement | ||
| 956 | + * @param srcMac source MAC address | ||
| 957 | + * @param dstMac destination MAC address, or null if this is a request | ||
| 958 | + * @param srcIp source IP address | ||
| 959 | + * @param dstIp destination IP address | ||
| 960 | + * @return the NDP packet | ||
| 961 | + */ | ||
| 962 | + private Ethernet buildNDP(byte type, MacAddress srcMac, MacAddress dstMac, | ||
| 963 | + Ip6Address srcIp, Ip6Address dstIp) { | ||
| 964 | + assertThat(type, anyOf( | ||
| 965 | + is(ICMP6.NEIGHBOR_SOLICITATION), | ||
| 966 | + is(ICMP6.NEIGHBOR_ADVERTISEMENT) | ||
| 967 | + )); | ||
| 968 | + assertNotNull(srcMac); | ||
| 969 | + assertNotNull(dstMac); | ||
| 970 | + assertNotNull(srcIp); | ||
| 971 | + assertNotNull(dstIp); | ||
| 972 | + | ||
| 973 | + IPacket ndp; | ||
| 974 | + if (type == ICMP6.NEIGHBOR_SOLICITATION) { | ||
| 975 | + ndp = new NeighborSolicitation().setTargetAddress(dstIp.toOctets()); | ||
| 976 | + } else { | ||
| 977 | + ndp = new NeighborAdvertisement() | ||
| 978 | + .setSolicitedFlag((byte) 1) | ||
| 979 | + .setOverrideFlag((byte) 1) | ||
| 980 | + .setTargetAddress(srcIp.toOctets()) | ||
| 981 | + .addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS, | ||
| 982 | + srcMac.toBytes()); | ||
| 983 | + } | ||
| 984 | + | ||
| 985 | + ICMP6 icmp6 = new ICMP6(); | ||
| 986 | + icmp6.setIcmpType(type); | ||
| 987 | + icmp6.setIcmpCode((byte) 0); | ||
| 988 | + icmp6.setPayload(ndp); | ||
| 989 | + | ||
| 990 | + IPv6 ipv6 = new IPv6(); | ||
| 991 | + ipv6.setDestinationAddress(dstIp.toOctets()); | ||
| 992 | + ipv6.setSourceAddress(srcIp.toOctets()); | ||
| 993 | + ipv6.setNextHeader(IPv6.PROTOCOL_ICMP6); | ||
| 994 | + ipv6.setHopLimit((byte) 255); | ||
| 995 | + ipv6.setPayload(icmp6); | ||
| 996 | + | ||
| 997 | + Ethernet eth = new Ethernet(); | ||
| 998 | + eth.setDestinationMACAddress(dstMac); | ||
| 999 | + eth.setSourceMACAddress(srcMac); | ||
| 1000 | + eth.setEtherType(Ethernet.TYPE_IPV6); | ||
| 1001 | + eth.setVlanID(VLAN1.toShort()); | ||
| 1002 | + eth.setPayload(ipv6); | ||
| 1003 | + | ||
| 1004 | + return eth; | ||
| 1005 | + } | ||
| 1006 | + | ||
| 1007 | + /** | ||
| 629 | * Test PacketService implementation that simply stores OutboundPackets | 1008 | * Test PacketService implementation that simply stores OutboundPackets |
| 630 | * passed to {@link #emit(OutboundPacket)} for later verification. | 1009 | * passed to {@link #emit(OutboundPacket)} for later verification. |
| 631 | */ | 1010 | */ | ... | ... |
-
Please register or login to post a comment