[ONOS-641] Update unit tests to include IPv6 as well
- HostMonitorTest
Add more IPv6 related test cases
- HostLocationProviderTest
Add more test cases, including:
NS/NA
RS/RA
DAD
IPv6 unicast
IPv6 multicast
IPv4
- HostLocationProvider
Minor indent fix
Change-Id: Id4c3af430862c61872ccaa98beac3a47313206ac
diff --git a/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java b/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java
index d167197..3cd2ca2 100644
--- a/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java
+++ b/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java
@@ -23,10 +23,12 @@
import org.junit.Test;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv6;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
+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;
@@ -64,14 +66,22 @@
public class HostMonitorTest {
- private static final IpAddress TARGET_IP_ADDR =
+ private static final IpAddress TARGET_IPV4_ADDR =
IpAddress.valueOf("10.0.0.1");
- private static final IpAddress SOURCE_ADDR =
+ private static final IpAddress SOURCE_IPV4_ADDR =
IpAddress.valueOf("10.0.0.99");
private static final InterfaceIpAddress IA1 =
- new InterfaceIpAddress(SOURCE_ADDR, IpPrefix.valueOf("10.0.0.0/24"));
+ new InterfaceIpAddress(SOURCE_IPV4_ADDR, IpPrefix.valueOf("10.0.0.0/24"));
private MacAddress sourceMac = MacAddress.valueOf(1L);
+ private static final IpAddress TARGET_IPV6_ADDR =
+ IpAddress.valueOf("1000::1");
+ private static final IpAddress SOURCE_IPV6_ADDR =
+ IpAddress.valueOf("1000::f");
+ private static final InterfaceIpAddress IA2 =
+ new InterfaceIpAddress(SOURCE_IPV6_ADDR, IpPrefix.valueOf("1000::/64"));
+ private MacAddress sourceMac2 = MacAddress.valueOf(2L);
+
private EdgePortService edgePortService;
private HostMonitor hostMonitor;
@@ -90,7 +100,7 @@
}
@Test
- public void testMonitorHostExists() throws Exception {
+ public void testMonitorIpv4HostExists() throws Exception {
ProviderId id = new ProviderId("fake://", "id");
Host host = createMock(Host.class);
@@ -98,7 +108,7 @@
replay(host);
HostManager hostManager = createMock(HostManager.class);
- expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
+ expect(hostManager.getHostsByIp(TARGET_IPV4_ADDR))
.andReturn(Collections.singleton(host));
replay(hostManager);
@@ -111,7 +121,7 @@
hostMonitor = new HostMonitor(null, hostManager, null, edgePortService);
hostMonitor.registerHostProvider(hostProvider);
- hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
+ hostMonitor.addMonitoringFor(TARGET_IPV4_ADDR);
hostMonitor.run(null);
@@ -119,7 +129,36 @@
}
@Test
- public void testMonitorHostDoesNotExist() throws Exception {
+ public void testMonitorIpv6HostExists() throws Exception {
+ ProviderId id = new ProviderId("fake://", "id");
+
+ Host host = createMock(Host.class);
+ expect(host.providerId()).andReturn(id);
+ replay(host);
+
+ HostManager hostManager = createMock(HostManager.class);
+ expect(hostManager.getHostsByIp(TARGET_IPV6_ADDR))
+ .andReturn(Collections.singleton(host));
+ replay(hostManager);
+
+ HostProvider hostProvider = createMock(HostProvider.class);
+ expect(hostProvider.id()).andReturn(id).anyTimes();
+ hostProvider.triggerProbe(host);
+ expectLastCall().once();
+ replay(hostProvider);
+
+ hostMonitor = new HostMonitor(null, hostManager, null, edgePortService);
+
+ hostMonitor.registerHostProvider(hostProvider);
+ hostMonitor.addMonitoringFor(TARGET_IPV6_ADDR);
+
+ hostMonitor.run(null);
+
+ verify(hostProvider);
+ }
+
+ @Test
+ public void testMonitorIpv4HostDoesNotExist() throws Exception {
HostManager hostManager = createMock(HostManager.class);
@@ -140,12 +179,12 @@
ConnectPoint cp = new ConnectPoint(devId, portNum);
- expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
+ expect(hostManager.getHostsByIp(TARGET_IPV4_ADDR))
.andReturn(Collections.emptySet()).anyTimes();
replay(hostManager);
InterfaceService interfaceService = createMock(InterfaceService.class);
- expect(interfaceService.getMatchingInterface(TARGET_IP_ADDR))
+ expect(interfaceService.getMatchingInterface(TARGET_IPV4_ADDR))
.andReturn(new Interface(cp, Collections.singleton(IA1), sourceMac, VlanId.NONE))
.anyTimes();
replay(interfaceService);
@@ -156,7 +195,7 @@
// Run the test
hostMonitor = new HostMonitor(packetService, hostManager, interfaceService, edgePortService);
- hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
+ hostMonitor.addMonitoringFor(TARGET_IPV4_ADDR);
hostMonitor.run(null);
@@ -178,16 +217,85 @@
Ethernet eth = Ethernet.deserializer().deserialize(pktData, 0, pktData.length);
assertEquals(Ethernet.VLAN_UNTAGGED, eth.getVlanID());
ARP arp = (ARP) eth.getPayload();
- assertArrayEquals(SOURCE_ADDR.toOctets(),
+ assertArrayEquals(SOURCE_IPV4_ADDR.toOctets(),
arp.getSenderProtocolAddress());
assertArrayEquals(sourceMac.toBytes(),
arp.getSenderHardwareAddress());
- assertArrayEquals(TARGET_IP_ADDR.toOctets(),
+ assertArrayEquals(TARGET_IPV4_ADDR.toOctets(),
arp.getTargetProtocolAddress());
}
@Test
- public void testMonitorHostDoesNotExistWithVlan() throws Exception {
+ public void testMonitorIpv6HostDoesNotExist() throws Exception {
+
+ HostManager hostManager = createMock(HostManager.class);
+
+ DeviceId devId = DeviceId.deviceId("fake");
+
+ Device device = createMock(Device.class);
+ expect(device.id()).andReturn(devId).anyTimes();
+ replay(device);
+
+ PortNumber portNum = PortNumber.portNumber(2L);
+
+ Port port = createMock(Port.class);
+ expect(port.number()).andReturn(portNum).anyTimes();
+ replay(port);
+
+ TestDeviceService deviceService = new TestDeviceService();
+ deviceService.addDevice(device, Collections.singleton(port));
+
+ ConnectPoint cp = new ConnectPoint(devId, portNum);
+
+ expect(hostManager.getHostsByIp(TARGET_IPV6_ADDR))
+ .andReturn(Collections.emptySet()).anyTimes();
+ replay(hostManager);
+
+ InterfaceService interfaceService = createMock(InterfaceService.class);
+ expect(interfaceService.getMatchingInterface(TARGET_IPV6_ADDR))
+ .andReturn(new Interface(cp, Collections.singleton(IA2), sourceMac2, VlanId.NONE))
+ .anyTimes();
+ replay(interfaceService);
+
+ TestPacketService packetService = new TestPacketService();
+
+
+ // Run the test
+ hostMonitor = new HostMonitor(packetService, hostManager, interfaceService, edgePortService);
+
+ hostMonitor.addMonitoringFor(TARGET_IPV6_ADDR);
+ hostMonitor.run(null);
+
+
+ // Check that a packet was sent to our PacketService and that it has
+ // the properties we expect
+ assertEquals(1, packetService.packets.size());
+ OutboundPacket packet = packetService.packets.get(0);
+
+ // Check the output port is correct
+ assertEquals(1, packet.treatment().immediate().size());
+ Instruction instruction = packet.treatment().immediate().get(0);
+ assertTrue(instruction instanceof OutputInstruction);
+ OutputInstruction oi = (OutputInstruction) instruction;
+ assertEquals(portNum, oi.port());
+
+ // Check the output packet is correct (well the important bits anyway)
+ final byte[] pktData = new byte[packet.data().remaining()];
+ packet.data().get(pktData);
+ Ethernet eth = Ethernet.deserializer().deserialize(pktData, 0, pktData.length);
+ assertEquals(Ethernet.VLAN_UNTAGGED, eth.getVlanID());
+ IPv6 ipv6 = (IPv6) eth.getPayload();
+ assertArrayEquals(SOURCE_IPV6_ADDR.toOctets(), ipv6.getSourceAddress());
+
+ NeighborSolicitation ns =
+ (NeighborSolicitation) ipv6.getPayload().getPayload();
+ assertArrayEquals(sourceMac2.toBytes(), ns.getOptions().get(0).data());
+
+ assertArrayEquals(TARGET_IPV6_ADDR.toOctets(), ns.getTargetAddress());
+ }
+
+ @Test
+ public void testMonitorIpv4HostDoesNotExistWithVlan() throws Exception {
HostManager hostManager = createMock(HostManager.class);
@@ -209,12 +317,12 @@
ConnectPoint cp = new ConnectPoint(devId, portNum);
- expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
+ expect(hostManager.getHostsByIp(TARGET_IPV4_ADDR))
.andReturn(Collections.emptySet()).anyTimes();
replay(hostManager);
InterfaceService interfaceService = createMock(InterfaceService.class);
- expect(interfaceService.getMatchingInterface(TARGET_IP_ADDR))
+ expect(interfaceService.getMatchingInterface(TARGET_IPV4_ADDR))
.andReturn(new Interface(cp, Collections.singleton(IA1), sourceMac, VlanId.vlanId(vlan)))
.anyTimes();
replay(interfaceService);
@@ -225,7 +333,7 @@
// Run the test
hostMonitor = new HostMonitor(packetService, hostManager, interfaceService, edgePortService);
- hostMonitor.addMonitoringFor(TARGET_IP_ADDR);
+ hostMonitor.addMonitoringFor(TARGET_IPV4_ADDR);
hostMonitor.run(null);
@@ -247,14 +355,84 @@
Ethernet eth = Ethernet.deserializer().deserialize(pktData, 0, pktData.length);
assertEquals(vlan, eth.getVlanID());
ARP arp = (ARP) eth.getPayload();
- assertArrayEquals(SOURCE_ADDR.toOctets(),
+ assertArrayEquals(SOURCE_IPV4_ADDR.toOctets(),
arp.getSenderProtocolAddress());
assertArrayEquals(sourceMac.toBytes(),
arp.getSenderHardwareAddress());
- assertArrayEquals(TARGET_IP_ADDR.toOctets(),
+ assertArrayEquals(TARGET_IPV4_ADDR.toOctets(),
arp.getTargetProtocolAddress());
}
+ @Test
+ public void testMonitorIpv6HostDoesNotExistWithVlan() throws Exception {
+
+ HostManager hostManager = createMock(HostManager.class);
+
+ DeviceId devId = DeviceId.deviceId("fake");
+ short vlan = 5;
+
+ Device device = createMock(Device.class);
+ expect(device.id()).andReturn(devId).anyTimes();
+ replay(device);
+
+ PortNumber portNum = PortNumber.portNumber(1L);
+
+ Port port = createMock(Port.class);
+ expect(port.number()).andReturn(portNum).anyTimes();
+ replay(port);
+
+ TestDeviceService deviceService = new TestDeviceService();
+ deviceService.addDevice(device, Collections.singleton(port));
+
+ ConnectPoint cp = new ConnectPoint(devId, portNum);
+
+ expect(hostManager.getHostsByIp(TARGET_IPV6_ADDR))
+ .andReturn(Collections.emptySet()).anyTimes();
+ replay(hostManager);
+
+ InterfaceService interfaceService = createMock(InterfaceService.class);
+ expect(interfaceService.getMatchingInterface(TARGET_IPV6_ADDR))
+ .andReturn(new Interface(cp, Collections.singleton(IA2), sourceMac2, VlanId.vlanId(vlan)))
+ .anyTimes();
+ replay(interfaceService);
+
+ TestPacketService packetService = new TestPacketService();
+
+
+ // Run the test
+ hostMonitor = new HostMonitor(packetService, hostManager, interfaceService, edgePortService);
+
+ hostMonitor.addMonitoringFor(TARGET_IPV6_ADDR);
+ hostMonitor.run(null);
+
+
+ // Check that a packet was sent to our PacketService and that it has
+ // the properties we expect
+ assertEquals(1, packetService.packets.size());
+ OutboundPacket packet = packetService.packets.get(0);
+
+ // Check the output port is correct
+ assertEquals(1, packet.treatment().immediate().size());
+ Instruction instruction = packet.treatment().immediate().get(0);
+ assertTrue(instruction instanceof OutputInstruction);
+ OutputInstruction oi = (OutputInstruction) instruction;
+ assertEquals(portNum, oi.port());
+
+ // Check the output packet is correct (well the important bits anyway)
+ final byte[] pktData = new byte[packet.data().remaining()];
+ packet.data().get(pktData);
+ Ethernet eth = Ethernet.deserializer().deserialize(pktData, 0, pktData.length);
+ assertEquals(vlan, eth.getVlanID());
+ IPv6 ipv6 = (IPv6) eth.getPayload();
+ assertArrayEquals(SOURCE_IPV6_ADDR.toOctets(), ipv6.getSourceAddress());
+
+ NeighborSolicitation ns =
+ (NeighborSolicitation) ipv6.getPayload().getPayload();
+ assertArrayEquals(sourceMac2.toBytes(), ns.getOptions().get(0).data());
+
+ assertArrayEquals(TARGET_IPV6_ADDR.toOctets(), ns.getTargetAddress());
+ }
+
class TestPacketService extends PacketServiceAdapter {
List<OutboundPacket> packets = new ArrayList<>();
diff --git a/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java b/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java
index 9a82363..93f6bf8 100644
--- a/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java
+++ b/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java
@@ -335,15 +335,15 @@
arp.getSenderProtocolAddress());
updateLocationIP(hid, srcMac, vlan, hloc, ip);
- // IPv4: update location only
+ // IPv4: update location only
} else if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
updateLocation(hid, srcMac, vlan, hloc);
- //
- // NeighborAdvertisement and NeighborSolicitation: possible
- // new hosts, update both location and IP.
- //
- // IPv6: update location only
+ //
+ // NeighborAdvertisement and NeighborSolicitation: possible
+ // new hosts, update both location and IP.
+ //
+ // IPv6: update location only
} else if (eth.getEtherType() == Ethernet.TYPE_IPV6) {
IPv6 ipv6 = (IPv6) eth.getPayload();
IpAddress ip = IpAddress.valueOf(IpAddress.Version.INET6,
diff --git a/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java b/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java
index db1eb0f..6cbb623 100644
--- a/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java
+++ b/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java
@@ -23,9 +23,17 @@
import org.onlab.packet.ARP;
import org.onlab.packet.ChassisId;
import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
+import org.onlab.packet.ndp.NeighborAdvertisement;
+import org.onlab.packet.ndp.NeighborSolicitation;
+import org.onlab.packet.ndp.RouterAdvertisement;
+import org.onlab.packet.ndp.RouterSolicitation;
import org.onosproject.cfg.ComponentConfigAdapter;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
@@ -66,6 +74,7 @@
import java.util.Set;
import static org.easymock.EasyMock.*;
+import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
import static org.onlab.packet.VlanId.vlanId;
import static org.onosproject.net.Device.Type.SWITCH;
@@ -75,27 +84,42 @@
import static org.onosproject.net.device.DeviceEvent.Type.*;
public class HostLocationProviderTest {
-
private static final Integer INPORT = 10;
private static final String DEV1 = "of:1";
private static final String DEV2 = "of:2";
private static final String DEV3 = "of:3";
+ private static final String DEV4 = "of:4";
+ private static final String DEV5 = "of:5";
+ private static final String DEV6 = "of:6";
private static final VlanId VLAN = vlanId();
+
+ // IPv4 Host
private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
private static final MacAddress BCMAC = MacAddress.valueOf("ff:ff:ff:ff:ff:ff");
private static final byte[] IP = new byte[]{10, 0, 0, 1};
-
private static final IpAddress IP_ADDRESS =
IpAddress.valueOf(IpAddress.Version.INET, IP);
private static final HostLocation LOCATION =
new HostLocation(deviceId(DEV1), portNumber(INPORT), 0L);
-
private static final DefaultHost HOST =
new DefaultHost(ProviderId.NONE, hostId(MAC), MAC,
vlanId(VlanId.UNTAGGED), LOCATION,
ImmutableSet.of(IP_ADDRESS));
+ // IPv6 Host
+ private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02");
+ private static final MacAddress BCMAC2 = MacAddress.valueOf("33:33:00:00:00:01");
+ private static final byte[] IP2 = Ip6Address.valueOf("1000::1").toOctets();
+ private static final IpAddress IP_ADDRESS2 =
+ IpAddress.valueOf(IpAddress.Version.INET6, IP2);
+ private static final HostLocation LOCATION2 =
+ new HostLocation(deviceId(DEV4), portNumber(INPORT), 0L);
+ private static final DefaultHost HOST2 =
+ new DefaultHost(ProviderId.NONE, hostId(MAC2), MAC2,
+ vlanId(VlanId.UNTAGGED), LOCATION2,
+ ImmutableSet.of(IP_ADDRESS2));
+
private static final ComponentContextAdapter CTX_FOR_REMOVE =
new ComponentContextAdapter() {
@Override
@@ -157,51 +181,189 @@
@Test
public void events() {
// new host
- testProcessor.process(new TestPacketContext(DEV1));
+ testProcessor.process(new TestArpPacketContext(DEV1));
assertNotNull("new host expected", providerService.added);
assertNull("host motion unexpected", providerService.moved);
// the host moved to new switch
- testProcessor.process(new TestPacketContext(DEV2));
+ testProcessor.process(new TestArpPacketContext(DEV2));
assertNotNull("host motion expected", providerService.moved);
// the host was misheard on a spine
- testProcessor.process(new TestPacketContext(DEV3));
+ testProcessor.process(new TestArpPacketContext(DEV3));
+ assertNull("host misheard on spine switch", providerService.spine);
+
+ providerService.clear();
+
+ // new host
+ testProcessor.process(new TestNAPacketContext(DEV4));
+ assertNotNull("new host expected", providerService.added);
+ assertNull("host motion unexpected", providerService.moved);
+
+ // the host moved to new switch
+ testProcessor.process(new TestNAPacketContext(DEV5));
+ assertNotNull("host motion expected", providerService.moved);
+
+ // the host was misheard on a spine
+ testProcessor.process(new TestNAPacketContext(DEV6));
assertNull("host misheard on spine switch", providerService.spine);
}
@Test
public void removeHostByDeviceRemove() {
provider.modified(CTX_FOR_REMOVE);
- testProcessor.process(new TestPacketContext(DEV1));
+ testProcessor.process(new TestArpPacketContext(DEV1));
+ testProcessor.process(new TestNAPacketContext(DEV4));
+
Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
"m", "h", "s", "n", new ChassisId(0L));
deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
assertEquals("incorrect remove count", 1, providerService.removeCount);
+
+ device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
+ "m", "h", "s", "n", new ChassisId(0L));
+ deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
+ assertEquals("incorrect remove count", 2, providerService.removeCount);
}
@Test
public void removeHostByDeviceOffline() {
provider.modified(CTX_FOR_REMOVE);
- testProcessor.process(new TestPacketContext(DEV1));
+ testProcessor.process(new TestArpPacketContext(DEV1));
+ testProcessor.process(new TestArpPacketContext(DEV4));
+
Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
"m", "h", "s", "n", new ChassisId(0L));
deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
assertEquals("incorrect remove count", 1, providerService.removeCount);
+
+ device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
+ "m", "h", "s", "n", new ChassisId(0L));
+ deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
+ assertEquals("incorrect remove count", 2, providerService.removeCount);
}
@Test
public void removeHostByDevicePortDown() {
provider.modified(CTX_FOR_REMOVE);
- testProcessor.process(new TestPacketContext(DEV1));
+ testProcessor.process(new TestArpPacketContext(DEV1));
+ testProcessor.process(new TestArpPacketContext(DEV4));
+
Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
"m", "h", "s", "n", new ChassisId(0L));
deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
- new DefaultPort(device, portNumber(INPORT),
- false)));
+ new DefaultPort(device, portNumber(INPORT), false)));
assertEquals("incorrect remove count", 1, providerService.removeCount);
+
+ device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
+ "m", "h", "s", "n", new ChassisId(0L));
+ deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
+ new DefaultPort(device, portNumber(INPORT), false)));
+ assertEquals("incorrect remove count", 2, providerService.removeCount);
}
+ /**
+ * When receiving ARP, updates location and IP.
+ */
+ @Test
+ public void testReceiveArp() {
+ testProcessor.process(new TestArpPacketContext(DEV1));
+ HostDescription descr = providerService.added;
+ assertThat(descr.location(), is(LOCATION));
+ assertThat(descr.hwAddress(), is(MAC));
+ assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS));
+ assertThat(descr.vlan(), is(VLAN));
+ }
+
+ /**
+ * When receiving IPv4, updates location only.
+ */
+ @Test
+ public void testReceiveIpv4() {
+ testProcessor.process(new TestIpv4PacketContext(DEV1));
+ HostDescription descr = providerService.added;
+ assertThat(descr.location(), is(LOCATION));
+ assertThat(descr.hwAddress(), is(MAC));
+ assertThat(descr.ipAddress().size(), is(0));
+ assertThat(descr.vlan(), is(VLAN));
+ }
+
+ /**
+ * When receiving NeighborAdvertisement, updates location and IP.
+ */
+ @Test
+ public void testReceiveNA() {
+ testProcessor.process(new TestNAPacketContext(DEV4));
+ assertNotNull(providerService.added);
+ HostDescription descr = providerService.added;
+ assertThat(descr.location(), is(LOCATION2));
+ assertThat(descr.hwAddress(), is(MAC2));
+ assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
+ assertThat(descr.vlan(), is(VLAN));
+ }
+
+ /**
+ * When receiving NeighborSolicitation, updates location and IP.
+ */
+ @Test
+ public void testReceiveNS() {
+ testProcessor.process(new TestNSPacketContext(DEV4));
+ HostDescription descr = providerService.added;
+ assertThat(descr.location(), is(LOCATION2));
+ assertThat(descr.hwAddress(), is(MAC2));
+ assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
+ assertThat(descr.vlan(), is(VLAN));
+ }
+
+ /**
+ * When receiving RouterAdvertisement, ignores it.
+ */
+ @Test
+ public void testReceivesRA() {
+ testProcessor.process(new TestRAPacketContext(DEV4));
+ assertNull(providerService.added);
+ }
+
+ /**
+ * When receiving RouterSolicitation, ignores it.
+ */
+ @Test
+ public void testReceiveRS() {
+ testProcessor.process(new TestRSPacketContext(DEV4));
+ assertNull(providerService.added);
+ }
+
+ /**
+ * When receiving Duplicate Address Detection (DAD), ignores it.
+ */
+ @Test
+ public void testReceiveDAD() {
+ testProcessor.process(new TestDADPacketContext(DEV4));
+ assertNull(providerService.added);
+ }
+
+ /**
+ * When receiving IPv6 multicast packet, ignores it.
+ */
+ @Test
+ public void testReceiveIpv6Multicast() {
+ testProcessor.process(new TestIpv6McastPacketContext(DEV4));
+ assertNull(providerService.added);
+ }
+
+ /**
+ * When receiving IPv6 unicast packet, updates location only.
+ */
+ @Test
+ public void testReceiveIpv6Unicast() {
+ testProcessor.process(new TestIpv6PacketContext(DEV4));
+ assertNotNull(providerService.added);
+ HostDescription descr = providerService.added;
+ assertThat(descr.location(), is(LOCATION2));
+ assertThat(descr.hwAddress(), is(MAC2));
+ assertThat(descr.ipAddress().size(), is(0));
+ assertThat(descr.vlan(), is(VLAN));
+ }
@After
public void tearDown() {
@@ -233,24 +395,30 @@
extends AbstractProviderService<HostProvider>
implements HostProviderService {
- DeviceId added = null;
- DeviceId moved = null;
- DeviceId spine = null;
+ HostDescription added = null;
+ HostDescription moved = null;
+ HostDescription spine = null;
public int removeCount;
+ public void clear() {
+ added = null;
+ moved = null;
+ spine = null;
+ removeCount = 0;
+ }
+
protected TestHostProviderService(HostProvider provider) {
super(provider);
}
@Override
public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
- DeviceId descr = hostDescription.location().deviceId();
if (added == null) {
- added = descr;
- } else if ((moved == null) && !descr.equals(added)) {
- moved = descr;
+ added = hostDescription;
+ } else if ((moved == null) && !hostDescription.equals(added)) {
+ moved = hostDescription;
} else {
- spine = descr;
+ spine = hostDescription;
}
}
@@ -272,24 +440,26 @@
}
}
-
private class TestTopologyService extends TopologyServiceAdapter {
@Override
public boolean isInfrastructure(Topology topology,
ConnectPoint connectPoint) {
//simulate DPID3 as an infrastructure switch
- if ((connectPoint.deviceId()).equals(deviceId(DEV3))) {
+ if ((connectPoint.deviceId()).equals(deviceId(DEV3)) ||
+ connectPoint.deviceId().equals(deviceId(DEV6))) {
return true;
}
return false;
}
}
- private class TestPacketContext implements PacketContext {
-
+ /**
+ * Generates ARP packet.
+ */
+ private class TestArpPacketContext implements PacketContext {
private final String deviceId;
- public TestPacketContext(String deviceId) {
+ public TestArpPacketContext(String deviceId) {
this.deviceId = deviceId;
}
@@ -344,6 +514,490 @@
}
}
+ /**
+ * Generates IPv6 Unicast packet.
+ */
+ private class TestIpv4PacketContext implements PacketContext {
+ private final String deviceId;
+
+ public TestIpv4PacketContext(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ @Override
+ public long time() {
+ return 0;
+ }
+
+ @Override
+ public InboundPacket inPacket() {
+ IPv4 ipv4 = new IPv4();
+ ipv4.setDestinationAddress("10.0.0.1");
+ ipv4.setSourceAddress(IP_ADDRESS.toString());
+ Ethernet eth = new Ethernet();
+ eth.setEtherType(Ethernet.TYPE_IPV4)
+ .setVlanID(VLAN.toShort())
+ .setSourceMACAddress(MAC)
+ .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
+ .setPayload(ipv4);
+ ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
+ portNumber(INPORT));
+ return new DefaultInboundPacket(receivedFrom, eth,
+ ByteBuffer.wrap(eth.serialize()));
+ }
+
+ @Override
+ public OutboundPacket outPacket() {
+ return null;
+ }
+
+ @Override
+ public TrafficTreatment.Builder treatmentBuilder() {
+ return null;
+ }
+
+ @Override
+ public void send() {
+
+ }
+
+ @Override
+ public boolean block() {
+ return false;
+ }
+
+ @Override
+ public boolean isHandled() {
+ return false;
+ }
+ }
+
+ /**
+ * Generates NeighborAdvertisement packet.
+ */
+ private class TestNAPacketContext implements PacketContext {
+ private final String deviceId;
+
+ public TestNAPacketContext(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ @Override
+ public long time() {
+ return 0;
+ }
+
+ @Override
+ public InboundPacket inPacket() {
+ NeighborAdvertisement na = new NeighborAdvertisement();
+ ICMP6 icmp6 = new ICMP6();
+ icmp6.setPayload(na);
+ IPv6 ipv6 = new IPv6();
+ ipv6.setPayload(icmp6);
+ ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
+ ipv6.setSourceAddress(IP2);
+ Ethernet eth = new Ethernet();
+ eth.setEtherType(Ethernet.TYPE_IPV6)
+ .setVlanID(VLAN.toShort())
+ .setSourceMACAddress(MAC2.toBytes())
+ .setDestinationMACAddress(BCMAC2)
+ .setPayload(ipv6);
+ ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
+ portNumber(INPORT));
+ return new DefaultInboundPacket(receivedFrom, eth,
+ ByteBuffer.wrap(eth.serialize()));
+ }
+
+ @Override
+ public OutboundPacket outPacket() {
+ return null;
+ }
+
+ @Override
+ public TrafficTreatment.Builder treatmentBuilder() {
+ return null;
+ }
+
+ @Override
+ public void send() {
+
+ }
+
+ @Override
+ public boolean block() {
+ return false;
+ }
+
+ @Override
+ public boolean isHandled() {
+ return false;
+ }
+ }
+
+ /**
+ * Generates NeighborSolicitation packet.
+ */
+ private class TestNSPacketContext implements PacketContext {
+ private final String deviceId;
+
+ public TestNSPacketContext(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ @Override
+ public long time() {
+ return 0;
+ }
+
+ @Override
+ public InboundPacket inPacket() {
+ NeighborSolicitation ns = new NeighborSolicitation();
+ ICMP6 icmp6 = new ICMP6();
+ icmp6.setPayload(ns);
+ IPv6 ipv6 = new IPv6();
+ ipv6.setPayload(icmp6);
+ ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1:ff00:0000").toOctets());
+ ipv6.setSourceAddress(IP2);
+ Ethernet eth = new Ethernet();
+ eth.setEtherType(Ethernet.TYPE_IPV6)
+ .setVlanID(VLAN.toShort())
+ .setSourceMACAddress(MAC2.toBytes())
+ .setDestinationMACAddress(BCMAC2)
+ .setPayload(ipv6);
+ ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
+ portNumber(INPORT));
+ return new DefaultInboundPacket(receivedFrom, eth,
+ ByteBuffer.wrap(eth.serialize()));
+ }
+
+ @Override
+ public OutboundPacket outPacket() {
+ return null;
+ }
+
+ @Override
+ public TrafficTreatment.Builder treatmentBuilder() {
+ return null;
+ }
+
+ @Override
+ public void send() {
+
+ }
+
+ @Override
+ public boolean block() {
+ return false;
+ }
+
+ @Override
+ public boolean isHandled() {
+ return false;
+ }
+ }
+
+ /**
+ * Generates Duplicate Address Detection packet.
+ */
+ private class TestDADPacketContext implements PacketContext {
+ private final String deviceId;
+
+ public TestDADPacketContext(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ @Override
+ public long time() {
+ return 0;
+ }
+
+ @Override
+ public InboundPacket inPacket() {
+ NeighborSolicitation ns = new NeighborSolicitation();
+ ICMP6 icmp6 = new ICMP6();
+ icmp6.setPayload(ns);
+ IPv6 ipv6 = new IPv6();
+ ipv6.setPayload(icmp6);
+ ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
+ ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
+ Ethernet eth = new Ethernet();
+ eth.setEtherType(Ethernet.TYPE_IPV6)
+ .setVlanID(VLAN.toShort())
+ .setSourceMACAddress(MAC2.toBytes())
+ .setDestinationMACAddress(BCMAC2)
+ .setPayload(ipv6);
+ ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
+ portNumber(INPORT));
+ return new DefaultInboundPacket(receivedFrom, eth,
+ ByteBuffer.wrap(eth.serialize()));
+ }
+
+ @Override
+ public OutboundPacket outPacket() {
+ return null;
+ }
+
+ @Override
+ public TrafficTreatment.Builder treatmentBuilder() {
+ return null;
+ }
+
+ @Override
+ public void send() {
+
+ }
+
+ @Override
+ public boolean block() {
+ return false;
+ }
+
+ @Override
+ public boolean isHandled() {
+ return false;
+ }
+ }
+
+ /**
+ * Generates Router Solicitation packet.
+ */
+ private class TestRSPacketContext implements PacketContext {
+ private final String deviceId;
+
+ public TestRSPacketContext(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ @Override
+ public long time() {
+ return 0;
+ }
+
+ @Override
+ public InboundPacket inPacket() {
+ RouterSolicitation ns = new RouterSolicitation();
+ ICMP6 icmp6 = new ICMP6();
+ icmp6.setPayload(ns);
+ IPv6 ipv6 = new IPv6();
+ ipv6.setPayload(icmp6);
+ ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::2").toOctets());
+ ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
+ Ethernet eth = new Ethernet();
+ eth.setEtherType(Ethernet.TYPE_IPV6)
+ .setVlanID(VLAN.toShort())
+ .setSourceMACAddress(MAC2.toBytes())
+ .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:02"))
+ .setPayload(ipv6);
+ ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
+ portNumber(INPORT));
+ return new DefaultInboundPacket(receivedFrom, eth,
+ ByteBuffer.wrap(eth.serialize()));
+ }
+
+ @Override
+ public OutboundPacket outPacket() {
+ return null;
+ }
+
+ @Override
+ public TrafficTreatment.Builder treatmentBuilder() {
+ return null;
+ }
+
+ @Override
+ public void send() {
+
+ }
+
+ @Override
+ public boolean block() {
+ return false;
+ }
+
+ @Override
+ public boolean isHandled() {
+ return false;
+ }
+ }
+
+ /**
+ * Generates Router Advertisement packet.
+ */
+ private class TestRAPacketContext implements PacketContext {
+ private final String deviceId;
+
+ public TestRAPacketContext(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ @Override
+ public long time() {
+ return 0;
+ }
+
+ @Override
+ public InboundPacket inPacket() {
+ RouterAdvertisement ns = new RouterAdvertisement();
+ ICMP6 icmp6 = new ICMP6();
+ icmp6.setPayload(ns);
+ IPv6 ipv6 = new IPv6();
+ ipv6.setPayload(icmp6);
+ ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
+ ipv6.setSourceAddress(IP2);
+ Ethernet eth = new Ethernet();
+ eth.setEtherType(Ethernet.TYPE_IPV6)
+ .setVlanID(VLAN.toShort())
+ .setSourceMACAddress(MAC2.toBytes())
+ .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
+ .setPayload(ipv6);
+ ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
+ portNumber(INPORT));
+ return new DefaultInboundPacket(receivedFrom, eth,
+ ByteBuffer.wrap(eth.serialize()));
+ }
+
+ @Override
+ public OutboundPacket outPacket() {
+ return null;
+ }
+
+ @Override
+ public TrafficTreatment.Builder treatmentBuilder() {
+ return null;
+ }
+
+ @Override
+ public void send() {
+
+ }
+
+ @Override
+ public boolean block() {
+ return false;
+ }
+
+ @Override
+ public boolean isHandled() {
+ return false;
+ }
+ }
+
+ /**
+ * Generates IPv6 Multicast packet.
+ */
+ private class TestIpv6McastPacketContext implements PacketContext {
+ private final String deviceId;
+
+ public TestIpv6McastPacketContext(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ @Override
+ public long time() {
+ return 0;
+ }
+
+ @Override
+ public InboundPacket inPacket() {
+ IPv6 ipv6 = new IPv6();
+ ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
+ ipv6.setSourceAddress(IP2);
+ Ethernet eth = new Ethernet();
+ eth.setEtherType(Ethernet.TYPE_IPV6)
+ .setVlanID(VLAN.toShort())
+ .setSourceMACAddress(MAC2.toBytes())
+ .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
+ .setPayload(ipv6);
+ ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
+ portNumber(INPORT));
+ return new DefaultInboundPacket(receivedFrom, eth,
+ ByteBuffer.wrap(eth.serialize()));
+ }
+
+ @Override
+ public OutboundPacket outPacket() {
+ return null;
+ }
+
+ @Override
+ public TrafficTreatment.Builder treatmentBuilder() {
+ return null;
+ }
+
+ @Override
+ public void send() {
+
+ }
+
+ @Override
+ public boolean block() {
+ return false;
+ }
+
+ @Override
+ public boolean isHandled() {
+ return false;
+ }
+ }
+
+ /**
+ * Generates IPv6 Unicast packet.
+ */
+ private class TestIpv6PacketContext implements PacketContext {
+ private final String deviceId;
+
+ public TestIpv6PacketContext(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ @Override
+ public long time() {
+ return 0;
+ }
+
+ @Override
+ public InboundPacket inPacket() {
+ IPv6 ipv6 = new IPv6();
+ ipv6.setDestinationAddress(Ip6Address.valueOf("1000::1").toOctets());
+ ipv6.setSourceAddress(IP2);
+ Ethernet eth = new Ethernet();
+ eth.setEtherType(Ethernet.TYPE_IPV6)
+ .setVlanID(VLAN.toShort())
+ .setSourceMACAddress(MAC2)
+ .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
+ .setPayload(ipv6);
+ ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
+ portNumber(INPORT));
+ return new DefaultInboundPacket(receivedFrom, eth,
+ ByteBuffer.wrap(eth.serialize()));
+ }
+
+ @Override
+ public OutboundPacket outPacket() {
+ return null;
+ }
+
+ @Override
+ public TrafficTreatment.Builder treatmentBuilder() {
+ return null;
+ }
+
+ @Override
+ public void send() {
+
+ }
+
+ @Override
+ public boolean block() {
+ return false;
+ }
+
+ @Override
+ public boolean isHandled() {
+ return false;
+ }
+ }
+
private class TestDeviceService extends DeviceServiceAdapter {
private DeviceListener listener;
@@ -361,12 +1015,26 @@
private class TestHostService extends HostServiceAdapter {
@Override
public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
- return ImmutableSet.of(HOST);
+ ConnectPoint cp1 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT));
+ ConnectPoint cp2 = new ConnectPoint(deviceId(DEV4), portNumber(INPORT));
+ if (connectPoint.equals(cp1)) {
+ return ImmutableSet.of(HOST);
+ } else if (connectPoint.equals(cp2)) {
+ return ImmutableSet.of(HOST2);
+ } else {
+ return ImmutableSet.of();
+ }
}
@Override
public Set<Host> getConnectedHosts(DeviceId deviceId) {
- return ImmutableSet.of(HOST);
+ if (deviceId.equals(deviceId(DEV1))) {
+ return ImmutableSet.of(HOST);
+ } else if (deviceId.equals(deviceId(DEV4))) {
+ return ImmutableSet.of(HOST2);
+ } else {
+ return ImmutableSet.of();
+ }
}
}