[ONOS-7983] Use IPv6 RA and RS to discover hosts
Change-Id: I5ee3dcb93536ab8f0cc760b38bf0bf73d63e3547
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 2e4b412..874bf38 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
@@ -115,6 +115,7 @@
HOST_REMOVAL_ENABLED + ":Boolean=" + HOST_REMOVAL_ENABLED_DEFAULT,
REQUEST_ARP + ":Boolean=" + REQUEST_ARP_DEFAULT,
REQUEST_NDP + ":Boolean=" + REQUEST_NDP_DEFAULT,
+ REQUEST_NDP_RS_RA + ":Boolean=" + REQUEST_NDP_RS_RA_DEFAULT,
USE_DHCP + ":Boolean=" + USE_DHCP_DEFAULT,
USE_DHCP6 + ":Boolean=" + USE_DHCP6_DEFAULT,
REQUEST_INTERCEPTS_ENABLED + ":Boolean=" + REQUEST_INTERCEPTS_ENABLED_DEFAULT,
@@ -162,9 +163,12 @@
/** Request ARP packets for neighbor discovery by the Host Location Provider; default is true. */
private boolean requestArp = true;
- /** Requests IPv6 Neighbor Discovery by the Host Location Provider; default is false. */
+ /** Requests IPv6 NDP Neighbor Solicitation and Advertisement by the Host Location Provider; default is false. */
private boolean requestIpv6ND = false;
+ /** Requests IPv6 NDP Router Solicitation and Advertisement by the Host Location Provider; default is false. */
+ private boolean requestIpv6NdpRsRa = false;
+
/** Use DHCP to update IP address of the host; default is false. */
private boolean useDhcp = false;
@@ -257,32 +261,40 @@
*/
private void requestIntercepts() {
// Use ARP
- TrafficSelector arpSelector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_ARP)
- .build();
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_ARP);
if (requestArp) {
- packetService.requestPackets(arpSelector, PacketPriority.CONTROL, appId);
+ packetService.requestPackets(selector.build(), PacketPriority.CONTROL, appId);
} else {
- packetService.cancelPackets(arpSelector, PacketPriority.CONTROL, appId);
+ packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId);
}
- // Use IPv6 Neighbor Discovery
- TrafficSelector ipv6NsSelector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV6)
- .matchIPProtocol(IPv6.PROTOCOL_ICMP6)
- .matchIcmpv6Type(ICMP6.NEIGHBOR_SOLICITATION)
- .build();
- TrafficSelector ipv6NaSelector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV6)
- .matchIPProtocol(IPv6.PROTOCOL_ICMP6)
- .matchIcmpv6Type(ICMP6.NEIGHBOR_ADVERTISEMENT)
- .build();
+ // Use IPv6 NDP Neighbor Solicitation and Advertisement
+ selector.matchEthType(Ethernet.TYPE_IPV6)
+ .matchIPProtocol(IPv6.PROTOCOL_ICMP6);
if (requestIpv6ND) {
- packetService.requestPackets(ipv6NsSelector, PacketPriority.CONTROL, appId);
- packetService.requestPackets(ipv6NaSelector, PacketPriority.CONTROL, appId);
+ selector.matchIcmpv6Type(ICMP6.NEIGHBOR_SOLICITATION);
+ packetService.requestPackets(selector.build(), PacketPriority.CONTROL, appId);
+ selector.matchIcmpv6Type(ICMP6.NEIGHBOR_ADVERTISEMENT);
+ packetService.requestPackets(selector.build(), PacketPriority.CONTROL, appId);
} else {
- packetService.cancelPackets(ipv6NsSelector, PacketPriority.CONTROL, appId);
- packetService.cancelPackets(ipv6NaSelector, PacketPriority.CONTROL, appId);
+ selector.matchIcmpv6Type(ICMP6.NEIGHBOR_SOLICITATION);
+ packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId);
+ selector.matchIcmpv6Type(ICMP6.NEIGHBOR_ADVERTISEMENT);
+ packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId);
+ }
+
+ // Use IPv6 NDP Router Solicitation and Advertisement
+ if (requestIpv6NdpRsRa) {
+ selector.matchIcmpv6Type(ICMP6.ROUTER_SOLICITATION);
+ packetService.requestPackets(selector.build(), PacketPriority.CONTROL, appId);
+ selector.matchIcmpv6Type(ICMP6.ROUTER_ADVERTISEMENT);
+ packetService.requestPackets(selector.build(), PacketPriority.CONTROL, appId);
+ } else {
+ selector.matchIcmpv6Type(ICMP6.ROUTER_SOLICITATION);
+ packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId);
+ selector.matchIcmpv6Type(ICMP6.ROUTER_ADVERTISEMENT);
+ packetService.cancelPackets(selector.build(), PacketPriority.CONTROL, appId);
}
}
@@ -340,10 +352,20 @@
"using current value of {}", requestIpv6ND);
} else {
requestIpv6ND = flag;
- log.info("Configured. Using IPv6 Neighbor Discovery is {}",
+ log.info("Configured. Using IPv6 NDP Neighbor Solicitation and Advertisement is {}",
requestIpv6ND ? "enabled" : "disabled");
}
+ flag = Tools.isPropertyEnabled(properties, REQUEST_NDP_RS_RA);
+ if (flag == null) {
+ log.info("Using IPv6 Neighbor Discovery is not configured, " +
+ "using current value of {}", requestIpv6NdpRsRa);
+ } else {
+ requestIpv6NdpRsRa = flag;
+ log.info("Configured. Using IPv6 NDP Router Solicitation and Advertisement is {}",
+ requestIpv6NdpRsRa ? "enabled" : "disabled");
+ }
+
flag = Tools.isPropertyEnabled(properties, USE_DHCP);
if (flag == null) {
log.info("Using DHCP is not configured, " +
@@ -610,8 +632,12 @@
// Neighbor Discovery Protocol
pkt = pkt.getPayload();
if (pkt != null) {
- // RouterSolicitation, RouterAdvertisement
- if (pkt instanceof RouterAdvertisement || pkt instanceof RouterSolicitation) {
+ if ((pkt instanceof RouterAdvertisement || pkt instanceof RouterSolicitation)) {
+ if (ip.isZero()) {
+ return;
+ }
+ // RouterSolicitation, RouterAdvertisement
+ createOrUpdateHost(hid, srcMac, vlan, innerVlan, outerTpid, hloc, ip);
return;
}
if (pkt instanceof NeighborSolicitation || pkt instanceof NeighborAdvertisement) {
diff --git a/providers/host/src/main/java/org/onosproject/provider/host/impl/OsgiPropertyConstants.java b/providers/host/src/main/java/org/onosproject/provider/host/impl/OsgiPropertyConstants.java
index eb8dafe..ac7035b 100644
--- a/providers/host/src/main/java/org/onosproject/provider/host/impl/OsgiPropertyConstants.java
+++ b/providers/host/src/main/java/org/onosproject/provider/host/impl/OsgiPropertyConstants.java
@@ -34,6 +34,9 @@
public static final String REQUEST_NDP = "requestIpv6ND";
public static final boolean REQUEST_NDP_DEFAULT = false;
+ public static final String REQUEST_NDP_RS_RA = "requestIpv6NdpRsRa";
+ public static final boolean REQUEST_NDP_RS_RA_DEFAULT = false;
+
public static final String USE_DHCP = "useDhcp";
public static final boolean USE_DHCP_DEFAULT = false;
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 9971921..0fab86e 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
@@ -506,23 +506,35 @@
}
/**
- * When receiving RouterAdvertisement, ignores it.
+ * When receiving RouterAdvertisement, update location and IP.
*/
@Test
public void receivesRa() {
testProcessor.process(new TestRAPacketContext(DEV4));
TestTools.assertAfter(ASSERTION_DELAY, () -> assertThat("receivesRa. No host description expected",
- providerService.descriptions.size(), is(0)));
+ providerService.descriptions.size(), is(1)));
+
+ final HostDescription desc = providerService.descriptions.get(0);
+ TestTools.assertAfter(ASSERTION_DELAY, () -> assertThat(desc.location(), is(LOCATION2)));
+ TestTools.assertAfter(ASSERTION_DELAY, () -> assertThat(desc.hwAddress(), is(MAC2)));
+ TestTools.assertAfter(ASSERTION_DELAY, () -> assertThat(desc.ipAddress().toArray()[0], is(IP_ADDRESS2)));
+ TestTools.assertAfter(ASSERTION_DELAY, () -> assertThat(desc.vlan(), is(VLAN)));
}
/**
- * When receiving RouterSolicitation, ignores it.
+ * When receiving RouterSolicitation, update location and IP.
*/
@Test
public void receiveRs() {
testProcessor.process(new TestRSPacketContext(DEV4));
TestTools.assertAfter(ASSERTION_DELAY, () -> assertThat("receiveRs. No host description expected",
- providerService.descriptions.size(), is(0)));
+ providerService.descriptions.size(), is(1)));
+
+ final HostDescription desc = providerService.descriptions.get(0);
+ TestTools.assertAfter(ASSERTION_DELAY, () -> assertThat(desc.location(), is(LOCATION2)));
+ TestTools.assertAfter(ASSERTION_DELAY, () -> assertThat(desc.hwAddress(), is(MAC2)));
+ TestTools.assertAfter(ASSERTION_DELAY, () -> assertThat(desc.ipAddress().toArray()[0], is(IP_ADDRESS2)));
+ TestTools.assertAfter(ASSERTION_DELAY, () -> assertThat(desc.vlan(), is(VLAN)));
}
/**
@@ -1034,7 +1046,7 @@
IPv6 ipv6 = new IPv6();
ipv6.setPayload(icmp6);
ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::2").toOctets());
- ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
+ ipv6.setSourceAddress(IP2);
Ethernet eth = new Ethernet();
eth.setEtherType(Ethernet.TYPE_IPV6)
.setVlanID(VLAN.toShort())