Treat optimistic addresses as global preferred.

If the kernel sends notification of an optimistic address then
treat is a useable address (isGlobalPreferred()).

Note that addresses flagged as IFA_F_OPTIMISTIC are
simultaneously flagged as IFA_F_TENTATIVE (when the tentative
state has cleared either DAD has succeeded or failed, and both
flags are cleared regardless).

Additionally: do not consider RFC 4193 ULA addresses sufficient
for "global preffered".  They are, by definition, of global scope
but not sufficient for global reachability.

Bug: 17769720
Change-Id: I759623b28fd52758f2d4d76d167f3cafd9319d6a
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index c387055..384ab1c 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -21,12 +21,14 @@
 import android.util.Pair;
 
 import java.net.Inet4Address;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InterfaceAddress;
 import java.net.UnknownHostException;
 
 import static android.system.OsConstants.IFA_F_DADFAILED;
 import static android.system.OsConstants.IFA_F_DEPRECATED;
+import static android.system.OsConstants.IFA_F_OPTIMISTIC;
 import static android.system.OsConstants.IFA_F_TENTATIVE;
 import static android.system.OsConstants.RT_SCOPE_HOST;
 import static android.system.OsConstants.RT_SCOPE_LINK;
@@ -93,6 +95,20 @@
     }
 
     /**
+     * Utility function to check if |address| is a Unique Local IPv6 Unicast Address
+     * (a.k.a. "ULA"; RFC 4193).
+     *
+     * Per RFC 4193 section 8, fc00::/7 identifies these addresses.
+     */
+    private boolean isIPv6ULA() {
+        if (address != null && address instanceof Inet6Address) {
+            byte[] bytes = address.getAddress();
+            return ((bytes[0] & (byte)0xfc) == (byte)0xfc);
+        }
+        return false;
+    }
+
+    /**
      * Utility function for the constructors.
      */
     private void init(InetAddress address, int prefixLength, int flags, int scope) {
@@ -268,8 +284,16 @@
      * @hide
      */
     public boolean isGlobalPreferred() {
+        /**
+         * Note that addresses flagged as IFA_F_OPTIMISTIC are
+         * simultaneously flagged as IFA_F_TENTATIVE (when the tentative
+         * state has cleared either DAD has succeeded or failed, and both
+         * flags are cleared regardless).
+         */
         return (scope == RT_SCOPE_UNIVERSE &&
-                (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED | IFA_F_TENTATIVE)) == 0L);
+                !isIPv6ULA() &&
+                (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED)) == 0L &&
+                ((flags & IFA_F_TENTATIVE) == 0L || (flags & IFA_F_OPTIMISTIC) != 0L));
     }
 
     /**