diff options
author | 2015-11-03 14:08:10 -0800 | |
---|---|---|
committer | 2015-11-03 14:08:10 -0800 | |
commit | 643ee33289bd2cb9e6afbfb09b4ed72d467ba1c2 (patch) | |
tree | c2c376a44a359544fe3d4c45eb0cc0e2ec4a7080 /framework/src/onos/core/net/src/test | |
parent | 46eeb79b54345bdafb6055b8ee4bad4ce8b01274 (diff) |
This updates ONOS src tree to commit id
03fa5e571cabbd001ddb1598847e1150b11c7333
Change-Id: I13b554026d6f902933e35887d29bd5fdb669c0bd
Signed-off-by: Ashlee Young <ashlee@wildernessvoice.com>
Diffstat (limited to 'framework/src/onos/core/net/src/test')
3 files changed, 496 insertions, 14 deletions
diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java new file mode 100644 index 00000000..06b2c81e --- /dev/null +++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java @@ -0,0 +1,100 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.net.intent.impl.compiler; + +import com.google.common.collect.ImmutableList; +import org.onlab.packet.MplsLabel; +import org.onosproject.net.newresource.ResourceAllocation; +import org.onosproject.net.newresource.ResourceConsumer; +import org.onosproject.net.newresource.ResourcePath; +import org.onosproject.net.newresource.ResourceService; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +class MockResourceService implements ResourceService { + + private final Map<ResourcePath, ResourceConsumer> assignment = new HashMap<>(); + + @Override + public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<ResourcePath> resources) { + assignment.putAll( + resources.stream().collect(Collectors.toMap(x -> x, x -> consumer)) + ); + + return resources.stream() + .map(x -> new ResourceAllocation(x, consumer)) + .collect(Collectors.toList()); + } + + @Override + public boolean release(List<ResourceAllocation> allocations) { + allocations.forEach(x -> assignment.remove(x.resource())); + + return true; + } + + @Override + public boolean release(ResourceConsumer consumer) { + List<ResourcePath> resources = assignment.entrySet().stream() + .filter(x -> x.getValue().equals(consumer)) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + List<ResourceAllocation> allocations = resources.stream() + .map(x -> new ResourceAllocation(x, consumer)) + .collect(Collectors.toList()); + + return release(allocations); + } + + @Override + public Optional<ResourceAllocation> getResourceAllocation(ResourcePath resource) { + return Optional.ofNullable(assignment.get(resource)) + .map(x -> new ResourceAllocation(resource, x)); + } + + @Override + public <T> Collection<ResourceAllocation> getResourceAllocations(ResourcePath parent, Class<T> cls) { + return assignment.entrySet().stream() + .filter(x -> x.getKey().parent().isPresent()) + .filter(x -> x.getKey().parent().get().equals(parent)) + .map(x -> new ResourceAllocation(x.getKey(), x.getValue())) + .collect(Collectors.toList()); + } + + @Override + public Collection<ResourceAllocation> getResourceAllocations(ResourceConsumer consumer) { + return assignment.entrySet().stream() + .filter(x -> x.getValue().equals(consumer)) + .map(x -> new ResourceAllocation(x.getKey(), x.getValue())) + .collect(Collectors.toList()); + } + + @Override + public Collection<ResourcePath> getAvailableResources(ResourcePath parent) { + ResourcePath resource = ResourcePath.child(parent, MplsLabel.mplsLabel(10)); + return ImmutableList.of(resource); + } + + @Override + public boolean isAvailable(ResourcePath resource) { + return true; + } +} diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompilerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompilerTest.java index 771a9883..6cceee12 100644 --- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompilerTest.java +++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompilerTest.java @@ -41,10 +41,8 @@ import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.intent.FlowRuleIntent; import org.onosproject.net.intent.Intent; import org.onosproject.net.intent.IntentExtensionService; -import org.onosproject.net.intent.IntentTestsMocks; import org.onosproject.net.intent.MockIdGenerator; import org.onosproject.net.intent.MplsPathIntent; -import org.onosproject.store.trivial.SimpleLinkStore; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; @@ -52,6 +50,7 @@ import static org.easymock.EasyMock.replay; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; +import static org.onosproject.net.DefaultEdgeLink.createEdgeLink; import static org.onosproject.net.Link.Type.DIRECT; import static org.onosproject.net.NetTestTools.APP_ID; import static org.onosproject.net.NetTestTools.PID; @@ -61,10 +60,12 @@ public class MplsPathIntentCompilerTest { private final ApplicationId appId = new TestApplicationId("test"); + private final ConnectPoint d1pi = connectPoint("s1", 100); private final ConnectPoint d1p1 = connectPoint("s1", 0); private final ConnectPoint d2p0 = connectPoint("s2", 0); private final ConnectPoint d2p1 = connectPoint("s2", 1); private final ConnectPoint d3p1 = connectPoint("s3", 1); + private final ConnectPoint d3pe = connectPoint("s3", 100); private final TrafficSelector selector = DefaultTrafficSelector.builder().build(); private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); @@ -75,8 +76,10 @@ public class MplsPathIntentCompilerTest { Optional.of(MplsLabel.mplsLabel(20)); private final List<Link> links = Arrays.asList( + createEdgeLink(d1pi, true), new DefaultLink(PID, d1p1, d2p0, DIRECT), - new DefaultLink(PID, d2p1, d3p1, DIRECT) + new DefaultLink(PID, d2p1, d3p1, DIRECT), + createEdgeLink(d3pe, false) ); private IdGenerator idGenerator = new MockIdGenerator(); @@ -92,8 +95,7 @@ public class MplsPathIntentCompilerTest { expect(coreService.registerApplication("org.onosproject.net.intent")) .andReturn(appId); sut.coreService = coreService; - sut.linkStore = new SimpleLinkStore(); - sut.resourceService = new IntentTestsMocks.MockResourceService(); + sut.resourceService = new MockResourceService(); Intent.bindIdGenerator(idGenerator); @@ -128,7 +130,7 @@ public class MplsPathIntentCompilerTest { assertThat(compiled, hasSize(1)); Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules(); - assertThat(rules, hasSize(1)); + assertThat(rules, hasSize(3)); FlowRule rule = rules.stream() .filter(x -> x.deviceId().equals(d2p0.deviceId())) @@ -139,4 +141,5 @@ public class MplsPathIntentCompilerTest { sut.deactivate(); } + } diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java index 1a160d98..3e806a73 100644 --- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java +++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java @@ -21,11 +21,19 @@ import org.junit.Before; import org.junit.Test; import org.onlab.packet.ARP; import org.onlab.packet.Ethernet; +import org.onlab.packet.ICMP6; +import org.onlab.packet.IPacket; +import org.onlab.packet.IPv6; import org.onlab.packet.Ip4Address; import org.onlab.packet.Ip4Prefix; +import org.onlab.packet.Ip6Address; +import org.onlab.packet.Ip6Prefix; import org.onlab.packet.IpPrefix; import org.onlab.packet.MacAddress; import org.onlab.packet.VlanId; +import org.onlab.packet.ndp.NeighborAdvertisement; +import org.onlab.packet.ndp.NeighborDiscoveryOptions; +import org.onlab.packet.ndp.NeighborSolicitation; import org.onosproject.incubator.net.intf.Interface; import org.onosproject.incubator.net.intf.InterfaceService; import org.onosproject.net.ConnectPoint; @@ -66,9 +74,13 @@ import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; +import static org.hamcrest.Matchers.anyOf; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; /** @@ -83,6 +95,8 @@ public class ProxyArpManagerTest { private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1"); private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2"); + private static final Ip6Address IP3 = Ip6Address.valueOf("1000::1"); + private static final Ip6Address IP4 = Ip6Address.valueOf("1000::2"); private static final ProviderId PID = new ProviderId("of", "foo"); @@ -90,8 +104,14 @@ public class ProxyArpManagerTest { private static final VlanId VLAN2 = VlanId.vlanId((short) 2); private static final MacAddress MAC1 = MacAddress.valueOf("00:00:11:00:00:01"); private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02"); + private static final MacAddress MAC3 = MacAddress.valueOf("00:00:33:00:00:03"); + private static final MacAddress MAC4 = MacAddress.valueOf("00:00:44:00:00:04"); + private static final MacAddress SOLICITED_MAC3 = MacAddress.valueOf("33:33:FF:00:00:01"); private static final HostId HID1 = HostId.hostId(MAC1, VLAN1); private static final HostId HID2 = HostId.hostId(MAC2, VLAN1); + private static final HostId HID3 = HostId.hostId(MAC3, VLAN1); + private static final HostId HID4 = HostId.hostId(MAC4, VLAN1); + private static final HostId SOLICITED_HID3 = HostId.hostId(SOLICITED_MAC3, VLAN1); private static final DeviceId DID1 = getDeviceId(1); private static final DeviceId DID2 = getDeviceId(2); @@ -222,21 +242,29 @@ public class ProxyArpManagerTest { for (int i = 1; i <= NUM_ADDRESS_PORTS; i++) { ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1); - Ip4Prefix prefix1 = - Ip4Prefix.valueOf("10.0." + (2 * i - 1) + ".0/24"); - Ip4Address addr1 = - Ip4Address.valueOf("10.0." + (2 * i - 1) + ".1"); + + // Interface address for IPv4 + Ip4Prefix prefix1 = Ip4Prefix.valueOf("10.0." + (2 * i - 1) + ".0/24"); + Ip4Address addr1 = Ip4Address.valueOf("10.0." + (2 * i - 1) + ".1"); Ip4Prefix prefix2 = Ip4Prefix.valueOf("10.0." + (2 * i) + ".0/24"); Ip4Address addr2 = Ip4Address.valueOf("10.0." + (2 * i) + ".1"); InterfaceIpAddress ia1 = new InterfaceIpAddress(addr1, prefix1); InterfaceIpAddress ia2 = new InterfaceIpAddress(addr2, prefix2); - Interface intf1 = new Interface(cp, Sets.newHashSet(ia1), + + // Interface address for IPv6 + Ip6Prefix prefix3 = Ip6Prefix.valueOf((2 * i - 1) + "000::0/64"); + Ip6Address addr3 = Ip6Address.valueOf((2 * i - 1) + "000::1"); + Ip6Prefix prefix4 = Ip6Prefix.valueOf((2 * i) + "000::0/64"); + Ip6Address addr4 = Ip6Address.valueOf((2 * i) + "000::1"); + InterfaceIpAddress ia3 = new InterfaceIpAddress(addr3, prefix3); + InterfaceIpAddress ia4 = new InterfaceIpAddress(addr4, prefix4); + + Interface intf1 = new Interface(cp, Sets.newHashSet(ia1, ia3), MacAddress.valueOf(2 * i - 1), VlanId.vlanId((short) 1)); - Interface intf2 = new Interface(cp, Sets.newHashSet(ia2), + Interface intf2 = new Interface(cp, Sets.newHashSet(ia2, ia4), MacAddress.valueOf(2 * i), VlanId.NONE); - interfaces.add(intf1); interfaces.add(intf2); @@ -321,6 +349,41 @@ public class ProxyArpManagerTest { /** * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the + * destination host is known. + * Verifies the correct NDP reply is sent out the correct port. + */ + @Test + public void testReplyKnownIpv6() { + //Set the return value of isEdgePoint from the edgemanager. + isEdgePointReturn = true; + + Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN1, getLocation(4), + Collections.singleton(IP3)); + + Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5), + Collections.singleton(IP4)); + + expect(hostService.getHostsByIp(IP3)) + .andReturn(Collections.singleton(replyer)); + expect(hostService.getHost(HID4)).andReturn(requestor); + + replay(hostService); + replay(interfaceService); + + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, + MAC4, SOLICITED_MAC3, + IP4, IP3); + + proxyArp.reply(ndpRequest, getLocation(5)); + + assertEquals(1, packetService.packets.size()); + Ethernet ndpReply = buildNDP(ICMP6.NEIGHBOR_ADVERTISEMENT, + MAC3, MAC4, IP3, IP4); + verifyPacketOut(ndpReply, getLocation(5), packetService.packets.get(0)); + } + + /** + * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the * destination host is not known. * Verifies the ARP request is flooded out the correct edge ports. */ @@ -337,7 +400,6 @@ public class ProxyArpManagerTest { .andReturn(Collections.emptySet()); expect(hostService.getHost(HID2)).andReturn(requestor); - replay(hostService); replay(interfaceService); @@ -355,6 +417,41 @@ public class ProxyArpManagerTest { /** * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the + * destination host is not known. + * Verifies the NDP request is flooded out the correct edge ports. + */ + @Test + public void testReplyUnknownIpv6() { + isEdgePointReturn = true; + + Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5), + Collections.singleton(IP4)); + + expect(hostService.getHostsByIp(IP3)) + .andReturn(Collections.emptySet()); + expect(interfaceService.getInterfacesByIp(IP4)) + .andReturn(Collections.emptySet()); + expect(hostService.getHost(HID4)).andReturn(requestor); + + replay(hostService); + replay(interfaceService); + + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, + MAC4, SOLICITED_MAC3, + IP4, IP3); + + //Setup the set of edge ports to be used in the reply method + getEdgePointsNoArg = Lists.newLinkedList(); + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); + + proxyArp.reply(ndpRequest, getLocation(6)); + + verifyFlood(ndpRequest); + } + + /** + * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the * destination host is known for that IP address, but is not on the same * VLAN as the source host. * Verifies the ARP request is flooded out the correct edge ports. @@ -388,6 +485,46 @@ public class ProxyArpManagerTest { verifyFlood(arpRequest); } + /** + * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the + * destination host is known for that IP address, but is not on the same + * VLAN as the source host. + * Verifies the NDP request is flooded out the correct edge ports. + */ + @Test + public void testReplyDifferentVlanIpv6() { + + Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN2, getLocation(4), + Collections.singleton(IP3)); + + Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5), + Collections.singleton(IP4)); + + expect(hostService.getHostsByIp(IP3)) + .andReturn(Collections.singleton(replyer)); + expect(interfaceService.getInterfacesByIp(IP4)) + .andReturn(Collections.emptySet()); + expect(hostService.getHost(HID4)).andReturn(requestor); + + replay(hostService); + replay(interfaceService); + + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, + MAC4, SOLICITED_MAC3, + IP4, IP3); + + //Setup for flood test + getEdgePointsNoArg = Lists.newLinkedList(); + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); + proxyArp.reply(ndpRequest, getLocation(6)); + + verifyFlood(ndpRequest); + } + + /** + * Test ARP request from external network to an internal host. + */ @Test public void testReplyToRequestForUs() { Ip4Address theirIp = Ip4Address.valueOf("10.0.1.254"); @@ -422,6 +559,63 @@ public class ProxyArpManagerTest { verifyPacketOut(arpReply, LOC1, packetService.packets.get(0)); } + /** + * Test NDP request from external network to an internal host. + */ + @Test + public void testReplyToRequestForUsIpv6() { + Ip6Address theirIp = Ip6Address.valueOf("1000::ffff"); + Ip6Address ourFirstIp = Ip6Address.valueOf("1000::1"); + Ip6Address ourSecondIp = Ip6Address.valueOf("2000::1"); + MacAddress firstMac = MacAddress.valueOf(1L); + MacAddress secondMac = MacAddress.valueOf(2L); + + Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC1, + Collections.singleton(theirIp)); + + expect(hostService.getHost(HID2)).andReturn(requestor); + expect(hostService.getHostsByIp(ourFirstIp)) + .andReturn(Collections.singleton(requestor)); + replay(hostService); + replay(interfaceService); + + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, + MAC2, + MacAddress.valueOf("33:33:ff:00:00:01"), + theirIp, + ourFirstIp); + isEdgePointReturn = true; + proxyArp.reply(ndpRequest, LOC1); + assertEquals(1, packetService.packets.size()); + + Ethernet ndpReply = buildNDP(ICMP6.NEIGHBOR_ADVERTISEMENT, + firstMac, + MAC2, + ourFirstIp, + theirIp); + verifyPacketOut(ndpReply, LOC1, packetService.packets.get(0)); + + // Test a request for the second address on that port + packetService.packets.clear(); + ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, + MAC2, + MacAddress.valueOf("33:33:ff:00:00:01"), + theirIp, + ourSecondIp); + proxyArp.reply(ndpRequest, LOC1); + assertEquals(1, packetService.packets.size()); + + ndpReply = buildNDP(ICMP6.NEIGHBOR_ADVERTISEMENT, + secondMac, + MAC2, + ourSecondIp, + theirIp); + verifyPacketOut(ndpReply, LOC1, packetService.packets.get(0)); + } + + /** + * Request for a valid external IPv4 address but coming in the wrong port. + */ @Test public void testReplyExternalPortBadRequest() { replay(hostService); // no further host service expectations @@ -442,6 +636,38 @@ public class ProxyArpManagerTest { assertEquals(0, packetService.packets.size()); } + /** + * Request for a valid external IPv6 address but coming in the wrong port. + */ + @Test + public void testReplyExternalPortBadRequestIpv6() { + replay(hostService); // no further host service expectations + replay(interfaceService); + + Ip6Address theirIp = Ip6Address.valueOf("1000::ffff"); + + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, + MAC1, + MacAddress.valueOf("33:33:ff:00:00:01"), + theirIp, + Ip6Address.valueOf("3000::1")); + proxyArp.reply(ndpRequest, LOC1); + assertEquals(0, packetService.packets.size()); + + // Request for a valid internal IP address but coming in an external port + packetService.packets.clear(); + ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, + MAC1, + MacAddress.valueOf("33:33:ff:00:00:01"), + theirIp, + IP3); + proxyArp.reply(ndpRequest, LOC1); + assertEquals(0, packetService.packets.size()); + } + + /** + * Test ARP request from internal network to an external host. + */ @Test public void testReplyToRequestFromUs() { Ip4Address ourIp = Ip4Address.valueOf("10.0.1.1"); @@ -474,6 +700,48 @@ public class ProxyArpManagerTest { } /** + * Test NDP request from internal network to an external host. + */ + @Test + public void testReplyToRequestFromUsIpv6() { + Ip6Address ourIp = Ip6Address.valueOf("1000::1"); + MacAddress ourMac = MacAddress.valueOf(1L); + Ip6Address theirIp = Ip6Address.valueOf("1000::100"); + + expect(hostService.getHostsByIp(theirIp)).andReturn(Collections.emptySet()); + expect(interfaceService.getInterfacesByIp(ourIp)) + .andReturn(Collections.singleton(new Interface(getLocation(1), + Collections.singleton(new InterfaceIpAddress( + ourIp, + IpPrefix.valueOf("1000::1/64"))), + ourMac, + VLAN1))); + expect(hostService.getHost(HostId.hostId(ourMac, VLAN1))).andReturn(null); + replay(hostService); + replay(interfaceService); + + // This is a request from something inside our network (like a BGP + // daemon) to an external host. + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, + ourMac, + MacAddress.valueOf("33:33:ff:00:00:01"), + ourIp, + theirIp); + + //Ensure the packet is allowed through (it is not to an internal port) + isEdgePointReturn = true; + + proxyArp.reply(ndpRequest, getLocation(5)); + assertEquals(1, packetService.packets.size()); + verifyPacketOut(ndpRequest, getLocation(1), packetService.packets.get(0)); + + // The same request from a random external port should fail + packetService.packets.clear(); + proxyArp.reply(ndpRequest, getLocation(2)); + assertEquals(0, packetService.packets.size()); + } + + /** * Tests {@link ProxyArpManager#forward(Ethernet, ConnectPoint)} in the case where the * destination host is known. * Verifies the correct ARP request is sent out the correct port. @@ -502,6 +770,35 @@ public class ProxyArpManagerTest { /** * Tests {@link ProxyArpManager#forward(Ethernet, ConnectPoint)} in the case where the + * destination host is known. + * Verifies the correct ARP request is sent out the correct port. + */ + @Test + public void testForwardToHostIpv6() { + Host host1 = new DefaultHost(PID, HID3, MAC3, VLAN1, LOC1, + Collections.singleton(IP3)); + Host host2 = new DefaultHost(PID, HID4, MAC4, VLAN1, LOC2, + Collections.singleton(IP4)); + + expect(hostService.getHost(SOLICITED_HID3)).andReturn(host1); + expect(hostService.getHost(HID4)).andReturn(host2); + replay(hostService); + replay(interfaceService); + + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, + MAC4, SOLICITED_MAC3, + IP4, IP3); + + proxyArp.forward(ndpRequest, LOC2); + + assertEquals(1, packetService.packets.size()); + OutboundPacket packet = packetService.packets.get(0); + + verifyPacketOut(ndpRequest, LOC1, packet); + } + + /** + * Tests {@link ProxyArpManager#forward(Ethernet, ConnectPoint)} in the case where the * destination host is not known. * Verifies the correct ARP request is flooded out the correct edge ports. */ @@ -526,6 +823,33 @@ public class ProxyArpManagerTest { } /** + * Tests {@link ProxyArpManager#forward(Ethernet, ConnectPoint)} in the case where the + * destination host is not known. + * Verifies the correct NDP request is flooded out the correct edge ports. + */ + @Test + public void testForwardFloodIpv6() { + expect(hostService.getHost(SOLICITED_HID3)).andReturn(null); + replay(hostService); + replay(interfaceService); + + Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, + MAC4, SOLICITED_MAC3, + IP4, IP3); + + //populate the list of edges when so that when forward hits flood in the manager it contains the values + //that should continue on + getEdgePointsNoArg = Lists.newLinkedList(); + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("3"), PortNumber.portNumber(1))); + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); + getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); + + proxyArp.forward(ndpRequest, getLocation(6)); + + verifyFlood(ndpRequest); + } + + /** * Verifies that the given packet was flooded out all available edge ports, * except for the input port. * @@ -626,6 +950,61 @@ public class ProxyArpManagerTest { } /** + * Builds an NDP packet with the given parameters. + * + * @param type NeighborSolicitation or NeighborAdvertisement + * @param srcMac source MAC address + * @param dstMac destination MAC address, or null if this is a request + * @param srcIp source IP address + * @param dstIp destination IP address + * @return the NDP packet + */ + private Ethernet buildNDP(byte type, MacAddress srcMac, MacAddress dstMac, + Ip6Address srcIp, Ip6Address dstIp) { + assertThat(type, anyOf( + is(ICMP6.NEIGHBOR_SOLICITATION), + is(ICMP6.NEIGHBOR_ADVERTISEMENT) + )); + assertNotNull(srcMac); + assertNotNull(dstMac); + assertNotNull(srcIp); + assertNotNull(dstIp); + + IPacket ndp; + if (type == ICMP6.NEIGHBOR_SOLICITATION) { + ndp = new NeighborSolicitation().setTargetAddress(dstIp.toOctets()); + } else { + ndp = new NeighborAdvertisement() + .setSolicitedFlag((byte) 1) + .setOverrideFlag((byte) 1) + .setTargetAddress(srcIp.toOctets()) + .addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS, + srcMac.toBytes()); + } + + ICMP6 icmp6 = new ICMP6(); + icmp6.setIcmpType(type); + icmp6.setIcmpCode((byte) 0); + icmp6.setPayload(ndp); + + IPv6 ipv6 = new IPv6(); + ipv6.setDestinationAddress(dstIp.toOctets()); + ipv6.setSourceAddress(srcIp.toOctets()); + ipv6.setNextHeader(IPv6.PROTOCOL_ICMP6); + ipv6.setHopLimit((byte) 255); + ipv6.setPayload(icmp6); + + Ethernet eth = new Ethernet(); + eth.setDestinationMACAddress(dstMac); + eth.setSourceMACAddress(srcMac); + eth.setEtherType(Ethernet.TYPE_IPV6); + eth.setVlanID(VLAN1.toShort()); + eth.setPayload(ipv6); + + return eth; + } + + /** * Test PacketService implementation that simply stores OutboundPackets * passed to {@link #emit(OutboundPacket)} for later verification. */ |