Trace IPv6 hosts
ONOS-511: Implement NeighborSolicitation
Change-Id: I9aaf35d499cfc7885c74f9c4bf281210ef9f3969
ONOS-507: Trace NeighborSolicitation/NeighborAdvertisement/IPv6 packets in HostLocationProvider
* Complete Javadoc of IPv6, ICMP6, NeighborAdvertisement and NeighborSolicitation
- The Javadoc for serialize() is removed since the one in its superclass just works fine.
* Change 'diffServ' in IPv6 to 'trafficClass' to meet the field name in RFC.
- The setter method, getter method and unit test are also updated accordingly.
* Add IpAddress.isZero() to determine if this address is zero.
- The unit test is also updated accordingly.
* Fix misuse of IpAddress.valueOf(int) in HostLocationProvider
Change-Id: Id0d873aeb1bc61bf26d4964e7aab4bb06ccd0a38
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 f2a5b6c..b8a93bb 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
@@ -46,6 +46,10 @@
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
+import org.onlab.packet.IPacket;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.NeighborAdvertisement;
+import org.onlab.packet.NeighborSolicitation;
import org.onlab.packet.VlanId;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
@@ -155,22 +159,43 @@
HostId hid = HostId.hostId(eth.getSourceMAC(), vlan);
- // Potentially a new or moved host
+ // ARP: possible new hosts, update both location and IP
if (eth.getEtherType() == Ethernet.TYPE_ARP) {
ARP arp = (ARP) eth.getPayload();
- IpAddress ip =
- IpAddress.valueOf(IpAddress.Version.INET,
- arp.getSenderProtocolAddress());
+ IpAddress ip = IpAddress.valueOf(IpAddress.Version.INET, arp.getSenderProtocolAddress());
HostDescription hdescr =
new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
providerService.hostDetected(hid, hdescr);
+ // IPv4: update location only
} else if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
- //Do not learn new ip from ip packet.
HostDescription hdescr =
new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc);
providerService.hostDetected(hid, hdescr);
+ // NeighborAdvertisement and NeighborSolicitation: possible new hosts, update both location and IP
+ // IPv6: update location only
+ } else if (eth.getEtherType() == Ethernet.TYPE_IPV6) {
+ IpAddress ip = null;
+ IPv6 ipv6 = (IPv6) eth.getPayload();
+
+ IPacket iPkt = ipv6;
+ while (iPkt != null) {
+ if (iPkt instanceof NeighborAdvertisement || iPkt instanceof NeighborSolicitation) {
+ IpAddress sourceAddress =
+ IpAddress.valueOf(IpAddress.Version.INET6, ipv6.getSourceAddress());
+ // Ignore DAD packets, in which source address is all zeros.
+ if (!sourceAddress.isZero()) {
+ ip = sourceAddress;
+ break;
+ }
+ }
+ iPkt = iPkt.getPayload();
+ }
+ HostDescription hdescr = (ip == null) ?
+ new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc) :
+ new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
+ providerService.hostDetected(hid, hdescr);
}
}
}