Learn target ip from IPv6 neighbor advertisement message
Change-Id: I3d27f4cd937548e9880bb242033358e57559656c
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 227415e..16a8f24 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
@@ -585,20 +585,27 @@
if (pkt != null && pkt instanceof ICMP6) {
// Neighbor Discovery Protocol
pkt = pkt.getPayload();
- // RouterSolicitation, RouterAdvertisement
- if (pkt != null && (pkt instanceof RouterAdvertisement ||
- pkt instanceof RouterSolicitation)) {
- return;
- }
- if (pkt != null && (pkt instanceof NeighborSolicitation ||
- pkt instanceof NeighborAdvertisement)) {
- // Duplicate Address Detection
- if (ip.isZero()) {
+ if (pkt != null) {
+ // RouterSolicitation, RouterAdvertisement
+ if (pkt instanceof RouterAdvertisement || pkt instanceof RouterSolicitation) {
return;
}
- // NeighborSolicitation, NeighborAdvertisement
- createOrUpdateHost(hid, srcMac, vlan, hloc, ip);
- return;
+ if (pkt instanceof NeighborSolicitation || pkt instanceof NeighborAdvertisement) {
+ // Duplicate Address Detection
+ if (ip.isZero()) {
+ return;
+ }
+ // NeighborSolicitation, NeighborAdvertisement
+ createOrUpdateHost(hid, srcMac, vlan, hloc, ip);
+
+ // Also learn from the target address of NeighborAdvertisement
+ if (pkt instanceof NeighborAdvertisement) {
+ NeighborAdvertisement na = (NeighborAdvertisement) pkt;
+ Ip6Address targetAddr = Ip6Address.valueOf(na.getTargetAddress());
+ createOrUpdateHost(hid, srcMac, vlan, hloc, targetAddr);
+ }
+ return;
+ }
}
}
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 77e2caa..a1d3d4d 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
@@ -97,6 +97,7 @@
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
import static org.onlab.packet.VlanId.vlanId;
import static org.onosproject.net.Device.Type.SWITCH;
import static org.onosproject.net.DeviceId.deviceId;
@@ -143,8 +144,11 @@
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 byte[] LLIP2 = IPv6.getLinkLocalAddress(MAC2.toBytes());
private static final IpAddress IP_ADDRESS2 =
IpAddress.valueOf(IpAddress.Version.INET6, IP2);
+ private static final IpAddress LLIP_ADDRESS2 =
+ IpAddress.valueOf(IpAddress.Version.INET6, LLIP2);
private static final HostLocation LOCATION2 =
new HostLocation(deviceId(DEV4), portNumber(INPORT), 0L);
private static final DefaultHost HOST2 =
@@ -258,21 +262,25 @@
providerService.clear();
- // New host. Expect one additional host description.
+ // New host. Expect two additional host descriptions. One for target IP. One for dest IP.
testProcessor.process(new TestNaPacketContext(DEV4));
- assertThat("New host expected", providerService.descriptions.size(), is(1));
+ assertThat("New host expected", providerService.descriptions.size(), is(2));
- // The host moved to new switch. Expect one additional host description.
- // The second host description should have a different location.
+ // The host moved to new switch. Expect two additional host descriptions.
+ // The 3rd and 4th host description should have a different location.
testProcessor.process(new TestNaPacketContext(DEV5));
- assertThat("Host motion expected", providerService.descriptions.size(), is(2));
+ assertThat("Host motion expected", providerService.descriptions.size(), is(4));
loc1 = providerService.descriptions.get(0).location();
loc2 = providerService.descriptions.get(1).location();
- assertNotEquals("Host location should be different", loc1, loc2);
+ HostLocation loc3 = providerService.descriptions.get(2).location();
+ HostLocation loc4 = providerService.descriptions.get(3).location();
+ assertEquals("1st and 2nd location should be equal", loc1, loc2);
+ assertEquals("3rd and 4th location should be equal", loc3, loc4);
+ assertNotEquals("1st and 3rd location should be different", loc1, loc3);
// The host was misheard on a spine. Expect no additional host description.
testProcessor.process(new TestNaPacketContext(DEV6));
- assertThat("Host misheard on spine switch", providerService.descriptions.size(), is(2));
+ assertThat("Host misheard on spine switch", providerService.descriptions.size(), is(4));
}
@Test
@@ -440,16 +448,23 @@
/**
* When receiving NeighborAdvertisement, updates location and IP.
+ * We should also expect that target IP is learnt.
*/
@Test
public void receiveNa() {
testProcessor.process(new TestNaPacketContext(DEV4));
assertThat("receiveNa. One host description expected",
- providerService.descriptions.size(), is(1));
+ providerService.descriptions.size(), is(2));
HostDescription descr = providerService.descriptions.get(0);
assertThat(descr.location(), is(LOCATION2));
assertThat(descr.hwAddress(), is(MAC2));
- assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
+ assertTrue(descr.ipAddress().contains(LLIP_ADDRESS2));
+ assertThat(descr.vlan(), is(VLAN));
+
+ descr = providerService.descriptions.get(1);
+ assertThat(descr.location(), is(LOCATION2));
+ assertThat(descr.hwAddress(), is(MAC2));
+ assertTrue(descr.ipAddress().contains(IP_ADDRESS2));
assertThat(descr.vlan(), is(VLAN));
}
@@ -892,12 +907,13 @@
@Override
public InboundPacket inPacket() {
NeighborAdvertisement na = new NeighborAdvertisement();
+ na.setTargetAddress(IP2);
ICMP6 icmp6 = new ICMP6();
icmp6.setPayload(na);
IPv6 ipv6 = new IPv6();
ipv6.setPayload(icmp6);
ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
- ipv6.setSourceAddress(IP2);
+ ipv6.setSourceAddress(LLIP2);
Ethernet eth = new Ethernet();
eth.setEtherType(Ethernet.TYPE_IPV6)
.setVlanID(VLAN.toShort())