DAD NS should not contain SRC_LL_ADDR option
Change-Id: I2022786d7d0d6673220ca6118e9b9d42d6484c74
diff --git a/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java b/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java
index 0df878e..82071da 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java
@@ -230,36 +230,29 @@
return null;
}
- /*
- * Here we craft the Ethernet packet.
- */
+ // Here we craft the Ethernet packet.
Ethernet ethernet = new Ethernet();
ethernet.setEtherType(Ethernet.TYPE_IPV6)
.setDestinationMACAddress(destinationMac)
.setSourceMACAddress(sourceMac);
ethernet.setVlanID(vlan.id());
- /*
- * IPv6 packet is created.
- */
+ // IPv6 packet is created.
IPv6 ipv6 = new IPv6();
ipv6.setSourceAddress(sourceIp);
ipv6.setDestinationAddress(destinationIp);
ipv6.setHopLimit((byte) 255);
- /*
- * Create the ICMPv6 packet.
- */
+ // Create the ICMPv6 packet.
ICMP6 icmp6 = new ICMP6();
icmp6.setIcmpType(ICMP6.NEIGHBOR_SOLICITATION);
icmp6.setIcmpCode((byte) 0);
- /*
- * Create the Neighbor Solicitation packet.
- */
+ // Create the Neighbor Solicitation packet.
NeighborSolicitation ns = new NeighborSolicitation();
ns.setTargetAddress(targetIp);
- ns.addOption(NeighborDiscoveryOptions.TYPE_SOURCE_LL_ADDRESS, sourceMac);
- /*
- * Set the payloads
- */
+ // DAD packets should not contain SRC_LL_ADDR option
+ if (!Arrays.equals(sourceIp, Ip6Address.ZERO.toOctets())) {
+ ns.addOption(NeighborDiscoveryOptions.TYPE_SOURCE_LL_ADDRESS, sourceMac);
+ }
+ // Set the payloads
icmp6.setPayload(ns);
ipv6.setPayload(icmp6);
ethernet.setPayload(ipv6);
diff --git a/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborSolicitationTest.java b/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborSolicitationTest.java
index cc514f9..e01db27 100644
--- a/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborSolicitationTest.java
+++ b/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborSolicitationTest.java
@@ -19,18 +19,31 @@
import org.junit.Test;
import org.onlab.packet.DeserializationException;
import org.onlab.packet.Deserializer;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.Ip6Address;
import org.onlab.packet.MacAddress;
import org.onlab.packet.PacketTestUtils;
+import org.onlab.packet.VlanId;
import java.nio.ByteBuffer;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
+import static org.onlab.packet.ndp.NeighborDiscoveryOptions.TYPE_SOURCE_LL_ADDRESS;
/**
* Tests for class {@link NeighborSolicitation}.
*/
public class NeighborSolicitationTest {
+ private static final Ip6Address TARGET_IP = Ip6Address.valueOf("2000::1");
+ private static final Ip6Address SRC_IP = Ip6Address.valueOf("2000::f");
+ private static final Ip6Address DST_IP = Ip6Address.valueOf("2000::1");
+ private static final MacAddress SRC_MAC = MacAddress.valueOf("00:00:00:00:00:0f");
+ private static final MacAddress DST_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+ private static final VlanId VLAN_ID = VlanId.NONE;
+
private static final byte[] TARGET_ADDRESS = {
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
@@ -139,4 +152,37 @@
// TODO: need to handle TARGET_ADDRESS and Options
}
+
+ /**
+ * Tests regular non-DAD neighbor solicitation.
+ */
+ @Test
+ public void testBuildNdpSolicit() throws Exception {
+ Ethernet ethPacket = NeighborSolicitation.buildNdpSolicit(TARGET_IP.toOctets(),
+ SRC_IP.toOctets(), DST_IP.toOctets(),
+ SRC_MAC.toBytes(), DST_MAC.toBytes(), VLAN_ID);
+ IPv6 ipPacket = (IPv6) ethPacket.getPayload();
+ ICMP6 icmp6Packet = (ICMP6) ipPacket.getPayload();
+ NeighborSolicitation nsPacket = (NeighborSolicitation) icmp6Packet.getPayload();
+
+ assertEquals("Non-DAD NS should have 1 option", 1, nsPacket.getOptions().size());
+ assertEquals("The option should be SRC_LL_ADDR type", TYPE_SOURCE_LL_ADDRESS,
+ nsPacket.getOptions().stream().findFirst().get().type());
+ }
+
+ /**
+ * Tests DAD neighbor solicitation.
+ * Source IP should be all-zero.
+ */
+ @Test
+ public void testBuildNdpSolicitDad() throws Exception {
+ Ethernet ethPacket = NeighborSolicitation.buildNdpSolicit(TARGET_IP.toOctets(),
+ Ip6Address.ZERO.toOctets(), DST_IP.toOctets(),
+ SRC_MAC.toBytes(), DST_MAC.toBytes(), VLAN_ID);
+ IPv6 ipPacket = (IPv6) ethPacket.getPayload();
+ ICMP6 icmp6Packet = (ICMP6) ipPacket.getPayload();
+ NeighborSolicitation nsPacket = (NeighborSolicitation) icmp6Packet.getPayload();
+
+ assertEquals("DAD NS should have no option", 0, nsPacket.getOptions().size());
+ }
}