diff --git a/common/netlinkclient/src/android/net/netlink/NdOption.java b/common/netlinkclient/src/android/net/netlink/NdOption.java
new file mode 100644
index 0000000..db262b9
--- /dev/null
+++ b/common/netlinkclient/src/android/net/netlink/NdOption.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Base class for IPv6 neighbour discovery options.
+ */
+public class NdOption {
+    public static final int STRUCT_SIZE = 2;
+
+    /** The option type. */
+    public final byte type;
+    /** The length of the option in 8-byte units. Actually an unsigned 8-bit integer */
+    public final int length;
+
+    /** Constructs a new NdOption. */
+    public NdOption(byte type, int length) {
+        this.type = type;
+        this.length = length;
+    }
+
+    /**
+     * Parses a neighbour discovery option.
+     *
+     * Parses (and consumes) the option if it is of a known type. If the option is of an unknown
+     * type, advances the buffer (so the caller can continue parsing if desired) and returns
+     * {@link #UNKNOWN}. If the option claims a length of 0, returns null because parsing cannot
+     * continue.
+     *
+     * No checks are performed on the length other than ensuring it is not 0, so if a caller wants
+     * to deal with options that might overflow the structure that contains them, it must explicitly
+     * set the buffer's limit to the position at which that structure ends.
+     *
+     * @param buf the buffer to parse.
+     * @return a subclass of {@link NdOption}, or {@code null} for an unknown or malformed option.
+     */
+    public static NdOption parse(ByteBuffer buf) {
+        if (buf == null || buf.remaining() < STRUCT_SIZE) return null;
+
+        // Peek the type without advancing the buffer.
+        byte type = buf.get(buf.position());
+        int length = Byte.toUnsignedInt(buf.get(buf.position() + 1));
+        if (length == 0) return null;
+
+        switch (type) {
+            case StructNdOptPref64.TYPE:
+                return StructNdOptPref64.parse(buf);
+
+            default:
+                int newPosition = Math.min(buf.limit(), buf.position() + length * 8);
+                buf.position(newPosition);
+                return UNKNOWN;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return String.format("NdOption(%d, %d)", Byte.toUnsignedInt(type), length);
+    }
+
+    public static final NdOption UNKNOWN = new NdOption((byte) 0, 0);
+}
diff --git a/common/netlinkclient/src/android/net/netlink/NduseroptMessage.java b/common/netlinkclient/src/android/net/netlink/NduseroptMessage.java
new file mode 100644
index 0000000..4940f6e
--- /dev/null
+++ b/common/netlinkclient/src/android/net/netlink/NduseroptMessage.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import static android.system.OsConstants.AF_INET6;
+
+import androidx.annotation.NonNull;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * A NetlinkMessage subclass for RTM_NEWNDUSEROPT messages.
+ */
+public class NduseroptMessage extends NetlinkMessage {
+    public static final int STRUCT_SIZE = 16;
+
+    static final int NDUSEROPT_SRCADDR = 1;
+
+    /** The address family. Presumably always AF_INET6. */
+    public final byte family;
+    /**
+     * The total length in bytes of the options that follow this structure.
+     * Actually a 16-bit unsigned integer.
+     */
+    public final int opts_len;
+    /** The interface index on which the options were received. */
+    public final int ifindex;
+    /** The ICMP type of the packet that contained the options. */
+    public final byte icmp_type;
+    /** The ICMP code of the packet that contained the options. */
+    public final byte icmp_code;
+
+    /**
+     * ND option that was in this message.
+     * Even though the length field is called "opts_len", the kernel only ever sends one option per
+     * message. It is unlikely that this will ever change as it would break existing userspace code.
+     * But if it does, we can simply update this code, since userspace is typically newer than the
+     * kernel.
+     */
+    public final NdOption option;
+
+    /** The IP address that sent the packet containing the option. */
+    public final InetAddress srcaddr;
+
+    NduseroptMessage(@NonNull StructNlMsgHdr header, @NonNull ByteBuffer buf)
+            throws UnknownHostException {
+        super(header);
+
+        // The structure itself.
+        buf.order(ByteOrder.nativeOrder());
+        family = buf.get();
+        buf.get();  // Skip 1 byte of padding.
+        opts_len = Short.toUnsignedInt(buf.getShort());
+        ifindex = buf.getInt();
+        icmp_type = buf.get();
+        icmp_code = buf.get();
+        buf.order(ByteOrder.BIG_ENDIAN);
+        buf.position(buf.position() + 6);  // Skip 6 bytes of padding.
+
+        // The ND option.
+        // Ensure we don't read past opts_len even if the option length is invalid.
+        // Note that this check is not really necessary since if the option length is not valid,
+        // this struct won't be very useful to the caller.
+        int oldLimit = buf.limit();
+        buf.limit(STRUCT_SIZE + opts_len);
+        try {
+            option = NdOption.parse(buf);
+        } finally {
+            buf.limit(oldLimit);
+        }
+
+        // The source address.
+        int newPosition = STRUCT_SIZE + opts_len;
+        if (newPosition >= buf.limit()) {
+            throw new IllegalArgumentException("ND options extend past end of buffer");
+        }
+        buf.position(newPosition);
+
+        StructNlAttr nla = StructNlAttr.parse(buf);
+        if (nla == null || nla.nla_type != NDUSEROPT_SRCADDR || nla.nla_value == null) {
+            throw new IllegalArgumentException("Invalid source address in ND useropt");
+        }
+        if (family == AF_INET6) {
+            // InetAddress.getByAddress only looks at the ifindex if the address type needs one.
+            srcaddr = Inet6Address.getByAddress(null /* hostname */, nla.nla_value, ifindex);
+        } else {
+            srcaddr = InetAddress.getByAddress(nla.nla_value);
+        }
+    }
+
+    /**
+     * Parses a StructNduseroptmsg from a {@link ByteBuffer}.
+     *
+     * @param header the netlink message header.
+     * @param buf The buffer from which to parse the option. The buffer's byte order must be
+     *            {@link java.nio.ByteOrder#BIG_ENDIAN}.
+     * @return the parsed option, or {@code null} if the option could not be parsed successfully
+     *         (for example, if it was truncated, or if the prefix length code was wrong).
+     */
+    public static NduseroptMessage parse(@NonNull StructNlMsgHdr header, @NonNull ByteBuffer buf) {
+        if (buf == null || buf.remaining() < STRUCT_SIZE) return null;
+        try {
+            return new NduseroptMessage(header, buf);
+        } catch (IllegalArgumentException | UnknownHostException | BufferUnderflowException e) {
+            // Not great, but better than throwing an exception that might crash the caller.
+            // Convention in this package is that null indicates that the option was truncated, so
+            // callers must already handle it.
+            return null;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return String.format("Nduseroptmsg(%d, %d, %d, %d, %d, %s)",
+                family, opts_len, ifindex, Byte.toUnsignedInt(icmp_type),
+                Byte.toUnsignedInt(icmp_code), srcaddr.getHostAddress());
+    }
+}
diff --git a/common/netlinkclient/src/android/net/netlink/NetlinkMessage.java b/common/netlinkclient/src/android/net/netlink/NetlinkMessage.java
index b730032..dafa66b 100644
--- a/common/netlinkclient/src/android/net/netlink/NetlinkMessage.java
+++ b/common/netlinkclient/src/android/net/netlink/NetlinkMessage.java
@@ -64,6 +64,8 @@
                 return (NetlinkMessage) RtNetlinkNeighborMessage.parse(nlmsghdr, byteBuffer);
             case NetlinkConstants.SOCK_DIAG_BY_FAMILY:
                 return (NetlinkMessage) InetDiagMessage.parse(nlmsghdr, byteBuffer);
+            case NetlinkConstants.RTM_NEWNDUSEROPT:
+                return (NetlinkMessage) NduseroptMessage.parse(nlmsghdr, byteBuffer);
             default:
                 if (nlmsghdr.nlmsg_type <= NetlinkConstants.NLMSG_MAX_RESERVED) {
                     // Netlink control message.  Just parse the header for now,
diff --git a/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java b/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java
index 6a68df8..5cce3da 100644
--- a/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java
+++ b/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java
@@ -41,16 +41,12 @@
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *
  */
-public class StructNdOptPref64 {
+public class StructNdOptPref64 extends NdOption {
     public static final int STRUCT_SIZE = 16;
     public static final int TYPE = 38;
 
     private static final String TAG = StructNdOptPref64.class.getSimpleName();
 
-    /** The option type. Always ICMPV6_ND_OPTION_PREF64. */
-    public final byte type;
-    /** The length of the option in 8-byte units. Actually an unsigned 8-bit integer. */
-    public final int length;
     /**
      * How many seconds the prefix is expected to remain valid.
      * Valid values are from 0 to 65528 in multiples of 8.
@@ -72,9 +68,8 @@
         }
     }
 
-    StructNdOptPref64(@NonNull ByteBuffer buf) {
-        type = buf.get();
-        length = buf.get();
+    public StructNdOptPref64(@NonNull ByteBuffer buf) {
+        super(buf.get(), Byte.toUnsignedInt(buf.get()));
         if (type != TYPE) throw new IllegalArgumentException("Invalid type " + type);
         if (length != 2) throw new IllegalArgumentException("Invalid length " + length);
 
diff --git a/tests/unit/src/android/net/netlink/NduseroptMessageTest.java b/tests/unit/src/android/net/netlink/NduseroptMessageTest.java
new file mode 100644
index 0000000..0c27b97
--- /dev/null
+++ b/tests/unit/src/android/net/netlink/NduseroptMessageTest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.IpPrefix;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import libcore.util.HexEncoding;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NduseroptMessageTest {
+
+    // Pick ifindices that are high enough that they will "never" be an existing interface index,
+    // and always be represented numerically in the address. That way, the test will never need to
+    // determine the interface names corresponding to these indices. That simplifies the code and
+    // makes the test more useful because determining interface names might require permissions.
+    private static final int IFINDEX1 = 15715755;
+    private static final int IFINDEX2 = 1431655765;
+
+    // IPv6, 0 bytes of options, interface index 15715755, type 134 (RA), code 0, padding.
+    private static final String HDR_EMPTY = "0a00" + "0000" + "abcdef00" + "8600000000000000";
+
+    // IPv6, 16 bytes of options, interface index 1431655765, type 134 (RA), code 0, padding.
+    private static final String HDR_16BYTE = "0a00" + "1000" + "55555555" + "8600000000000000";
+
+    // IPv6, 32 bytes of options, interface index 1431655765, type 134 (RA), code 0, padding.
+    private static final String HDR_32BYTE = "0a00" + "2000" + "55555555" + "8600000000000000";
+
+    // PREF64 option, 2001:db8:3:4:5:6::/96, lifetime=10064
+    private static final String OPT_PREF64 = "2602" + "2750" + "20010db80003000400050006";
+
+    // Length 20, NDUSEROPT_SRCADDR, fe80:2:3:4:5:6:7:8
+    private static final String NLA_SRCADDR = "1400" + "0100" + "fe800002000300040005000600070008";
+
+    private static final String SRCADDR1 = "fe80:2:3:4:5:6:7:8%" + IFINDEX1;
+    private static final String SRCADDR2 = "fe80:2:3:4:5:6:7:8%" + IFINDEX2;
+
+    private static final String MSG_EMPTY = HDR_EMPTY + NLA_SRCADDR;
+    private static final String MSG_PREF64 = HDR_16BYTE + OPT_PREF64 + NLA_SRCADDR;
+
+    @Test
+    public void testParsing() {
+        NduseroptMessage msg = parseNduseroptMessage(toBuffer(MSG_EMPTY));
+        assertMatches((byte) 10, 0, IFINDEX1, (byte) 134, (byte) 0, SRCADDR1, msg);
+        assertNull(msg.option);
+
+        msg = parseNduseroptMessage(toBuffer(MSG_PREF64));
+        assertMatches((byte) 10, 16, IFINDEX2, (byte) 134, (byte) 0, SRCADDR2, msg);
+        assertPref64Option("2001:db8:3:4:5:6::/96", msg.option);
+    }
+
+    @Test
+    public void testUnknownOption() {
+        ByteBuffer buf = toBuffer(MSG_PREF64);
+        // Replace the PREF64 option type (38) with an unknown option number.
+        final int optionStart = NduseroptMessage.STRUCT_SIZE;
+        assertEquals(38, buf.get(optionStart));
+        buf.put(optionStart, (byte) 42);
+
+        NduseroptMessage msg = parseNduseroptMessage(buf);
+        assertMatches((byte) 10, 16, IFINDEX2, (byte) 134, (byte) 0, SRCADDR2, msg);
+        assertEquals(NdOption.UNKNOWN, msg.option);
+
+        buf.flip();
+        assertEquals(42, buf.get(optionStart));
+        buf.put(optionStart, (byte) 38);
+
+        msg = parseNduseroptMessage(buf);
+        assertMatches((byte) 10, 16, IFINDEX2, (byte) 134, (byte) 0, SRCADDR2, msg);
+        assertPref64Option("2001:db8:3:4:5:6::/96", msg.option);
+    }
+
+    @Test
+    public void testZeroLengthOption() {
+        // Make sure an unknown option with a 0-byte length is ignored and parsing continues with
+        // the address, which comes after it.
+        final String hexString = HDR_16BYTE + "00000000000000000000000000000000" + NLA_SRCADDR;
+        ByteBuffer buf = toBuffer(hexString);
+        assertEquals(52, buf.limit());
+        NduseroptMessage msg = parseNduseroptMessage(buf);
+        assertMatches((byte) 10, 16, IFINDEX2, (byte) 134, (byte) 0, SRCADDR2, msg);
+        assertNull(msg.option);
+    }
+
+    @Test
+    public void testTooLongOption() {
+        // Make sure that if an option's length is too long, it's ignored and parsing continues with
+        // the address, which comes after it.
+        final String hexString = HDR_16BYTE + "26030000000000000000000000000000" + NLA_SRCADDR;
+        ByteBuffer buf = toBuffer(hexString);
+        assertEquals(52, buf.limit());
+        NduseroptMessage msg = parseNduseroptMessage(buf);
+        assertMatches((byte) 10, 16, IFINDEX2, (byte) 134, (byte) 0, SRCADDR2, msg);
+        assertNull(msg.option);
+    }
+
+    @Test
+    public void testOptionsTooLong() {
+        // Header claims 32 bytes of options. Buffer ends before options end.
+        String hexString = HDR_32BYTE + OPT_PREF64;
+        ByteBuffer buf = toBuffer(hexString);
+        assertEquals(32, buf.limit());
+        assertNull(NduseroptMessage.parse(toBuffer(hexString)));
+
+        // Header claims 32 bytes of options. Buffer ends at end of options with no source address.
+        hexString = HDR_32BYTE + OPT_PREF64 + OPT_PREF64;
+        buf = toBuffer(hexString);
+        assertEquals(48, buf.limit());
+        assertNull(NduseroptMessage.parse(toBuffer(hexString)));
+    }
+
+    @Test
+    public void testTruncation() {
+        final int optLen = MSG_PREF64.length() / 2;  // 1 byte = 2 hex chars
+        for (int len = 0; len < optLen; len++) {
+            ByteBuffer buf = toBuffer(MSG_PREF64.substring(0, len * 2));
+            NduseroptMessage msg = parseNduseroptMessage(buf);
+            if (len < optLen) {
+                assertNull(msg);
+            } else {
+                assertNotNull(msg);
+                assertPref64Option("2001:db8:3:4:5:6::/96", msg.option);
+            }
+        }
+    }
+
+    @Test
+    public void testToString() {
+        NduseroptMessage msg = parseNduseroptMessage(toBuffer(MSG_PREF64));
+        assertNotNull(msg);
+        assertEquals("Nduseroptmsg(10, 16, 1431655765, 134, 0, fe80:2:3:4:5:6:7:8%1431655765)",
+                msg.toString());
+    }
+
+    // Convenience method to parse a NduseroptMessage that's not part of a netlink message.
+    private NduseroptMessage parseNduseroptMessage(ByteBuffer buf) {
+        return NduseroptMessage.parse(null, buf);
+    }
+
+    private ByteBuffer toBuffer(String hexString) {
+        return ByteBuffer.wrap(HexEncoding.decode(hexString));
+    }
+
+    private void assertMatches(byte family, int optsLen, int ifindex, byte icmpType,
+            byte icmpCode, String srcaddr, NduseroptMessage msg) {
+        assertNotNull(msg);
+        assertEquals(family, msg.family);
+        assertEquals(ifindex, msg.ifindex);
+        assertEquals(optsLen, msg.opts_len);
+        assertEquals(icmpType, msg.icmp_type);
+        assertEquals(icmpCode, msg.icmp_code);
+        assertEquals(srcaddr, msg.srcaddr.getHostAddress());
+    }
+
+    private void assertPref64Option(String prefix, NdOption opt) {
+        assertNotNull(opt);
+        assertTrue(opt instanceof StructNdOptPref64);
+        StructNdOptPref64 pref64Opt = (StructNdOptPref64) opt;
+        assertEquals(new IpPrefix(prefix), pref64Opt.prefix);
+    }
+}
