Charles Chan
Committed by Gerrit Code Review

[ONOS-1264] Add IPv6 unit test for ProxyArpManager

Change-Id: I1d4ec1f06508bd1bf1d54b299b0ae4ac1d5482d9
...@@ -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 */
......