Snap for 11947545 from 63331ec31bfe733b134ed882d353874e9721ae6d to mainline-art-release

Change-Id: Ibb0eec52a088951e9b2810d8643a1e2d9f43d487
diff --git a/src/android/net/apf/AndroidPacketFilter.java b/src/android/net/apf/AndroidPacketFilter.java
index 3862048..2a7165b 100644
--- a/src/android/net/apf/AndroidPacketFilter.java
+++ b/src/android/net/apf/AndroidPacketFilter.java
@@ -105,6 +105,6 @@
      * opcodes LDDW (LoaD Data Word) and STDW (STore Data Word).
      */
     default boolean hasDataAccess(@NonNull ApfCapabilities capabilities) {
-        return capabilities.hasDataAccess();
+        return capabilities.apfVersionSupported > 2;
     }
 }
diff --git a/src/android/net/apf/ApfFilter.java b/src/android/net/apf/ApfFilter.java
index 9e6ba2f..c705928 100644
--- a/src/android/net/apf/ApfFilter.java
+++ b/src/android/net/apf/ApfFilter.java
@@ -1799,13 +1799,24 @@
     }
 
     @GuardedBy("this")
-    private List<byte[]> getUnicastIpv6Addresses() {
+    private List<byte[]> getIpv6Addresses(
+            boolean includeNonTentative, boolean includeTentative, boolean includeAnycast) {
         final List<byte[]> addresses = new ArrayList<>();
-        for (Inet6Address addr : mIPv6NonTentativeAddresses) {
-            addresses.add(addr.getAddress());
+        if (includeNonTentative) {
+            for (Inet6Address addr : mIPv6NonTentativeAddresses) {
+                addresses.add(addr.getAddress());
+            }
         }
 
-        addresses.addAll(mDependencies.getAnycast6Addresses(mInterfaceParams.name));
+        if (includeTentative) {
+            for (Inet6Address addr : mIPv6TentativeAddresses) {
+                addresses.add(addr.getAddress());
+            }
+        }
+
+        if (includeAnycast) {
+            addresses.addAll(mDependencies.getAnycast6Addresses(mInterfaceParams.name));
+        }
         return addresses;
     }
 
@@ -1821,7 +1832,10 @@
     @GuardedBy("this")
     private void generateNsFilterLocked(ApfV6Generator v6Gen)
             throws IllegalInstructionException {
-        final List<byte[]> allIPv6Addrs = getUnicastIpv6Addresses();
+        final List<byte[]> allIPv6Addrs = getIpv6Addresses(
+                true /* includeNonTentative */,
+                true /* includeTentative */,
+                true /* includeAnycast */);
         if (allIPv6Addrs.isEmpty()) {
             // There is no IPv6 link local address.
             v6Gen.addCountAndDrop(DROPPED_IPV6_NS_NO_ADDRESS);
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 20b7800..304b038 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -2523,11 +2523,19 @@
     }
 
     @Nullable
-    private AndroidPacketFilter maybeCreateApfFilter(final ApfCapabilities apfCapabilities) {
+    private AndroidPacketFilter maybeCreateApfFilter(final ApfCapabilities apfCaps) {
         ApfFilter.ApfConfiguration apfConfig = new ApfFilter.ApfConfiguration();
-        apfConfig.apfCapabilities = apfCapabilities;
-        if (apfCapabilities != null && !SdkLevel.isAtLeastV()
-                && apfCapabilities.apfVersionSupported <= 4) {
+        apfConfig.apfCapabilities = apfCaps;
+        if (apfCaps != null && !SdkLevel.isAtLeastS()) {
+            // Due to potential OEM modifications in Android R, reconfigure
+            // apfVersionSupported using apfCapabilities.hasDataAccess() to ensure safe data
+            // region access within ApfFilter.
+            int apfVersionSupported = apfCaps.hasDataAccess() ? 3 : 2;
+            apfConfig.apfCapabilities = new ApfCapabilities(apfVersionSupported,
+                    apfCaps.maximumApfProgramSize, apfCaps.apfPacketFormat);
+        }
+        if (apfConfig.apfCapabilities != null && !SdkLevel.isAtLeastV()
+                && apfConfig.apfCapabilities.apfVersionSupported <= 4) {
             apfConfig.installableProgramSizeClamp = 1024;
         }
         apfConfig.multicastFilter = mMulticastFiltering;
diff --git a/src/android/net/ip/IpReachabilityMonitor.java b/src/android/net/ip/IpReachabilityMonitor.java
index 58cd051..4e8185e 100644
--- a/src/android/net/ip/IpReachabilityMonitor.java
+++ b/src/android/net/ip/IpReachabilityMonitor.java
@@ -47,6 +47,7 @@
 import android.stats.connectivity.NudEventType;
 import android.stats.connectivity.NudNeighborType;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -69,7 +70,6 @@
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -248,7 +248,7 @@
     private final boolean mIgnoreOrganicNudFailure;
     private final boolean mIgnoreNeverReachableNeighbor;
     // A set to track whether a neighbor has ever entered NUD_REACHABLE state before.
-    private final Set<InetAddress> mEverReachableNeighbors = new HashSet<>();
+    private final Set<InetAddress> mEverReachableNeighbors = new ArraySet<>();
 
     public IpReachabilityMonitor(
             Context context, InterfaceParams ifParams, Handler h, SharedLog log, Callback callback,
diff --git a/tests/unit/src/android/net/apf/LegacyApfTest.java b/tests/unit/src/android/net/apf/LegacyApfTest.java
index f51ecdd..cb3fbca 100644
--- a/tests/unit/src/android/net/apf/LegacyApfTest.java
+++ b/tests/unit/src/android/net/apf/LegacyApfTest.java
@@ -1766,267 +1766,6 @@
         }
     }
 
-    // Test for go/apf-ra-filter Case 1a.
-    // Old lifetime is 0
-    @Test
-    public void testAcceptRaMinLftCase1a() throws Exception {
-        final MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        // configure accept_ra_min_lft
-        final ApfConfiguration config = getDefaultConfig();
-        config.acceptRaMinLft = 180;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback,
-                mNetworkQuirkMetrics, mDependencies);
-
-        // Create an initial RA and build an APF program
-        byte[] ra = new RaPacketBuilder(1800 /* router lifetime */)
-                .addPioOption(1800 /*valid*/, 0 /*preferred*/, "2001:db8::/64")
-                .build();
-
-        apfFilter.pretendPacketReceived(ra);
-        byte[] program = ipClientCallback.assertProgramUpdateAndGet();
-
-        // repeated RA is dropped
-        assertDrop(program, ra);
-
-        // PIO preferred lifetime increases
-        ra = new RaPacketBuilder(1800 /* router lifetime */)
-                .addPioOption(1800 /*valid*/, 1 /*preferred*/, "2001:db8::/64")
-                .build();
-        assertPass(program, ra);
-    }
-
-    // Test for go/apf-ra-filter Case 2a.
-    // Old lifetime is > 0
-    @Test
-    public void testAcceptRaMinLftCase2a() throws Exception {
-        final MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        // configure accept_ra_min_lft
-        final ApfConfiguration config = getDefaultConfig();
-        config.acceptRaMinLft = 180;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback,
-                mNetworkQuirkMetrics, mDependencies);
-
-        // Create an initial RA and build an APF program
-        byte[] ra = new RaPacketBuilder(1800 /* router lifetime */)
-                .addPioOption(1800 /*valid*/, 100 /*preferred*/, "2001:db8::/64")
-                .build();
-
-        apfFilter.pretendPacketReceived(ra);
-        byte[] program = ipClientCallback.assertProgramUpdateAndGet();
-
-        // repeated RA is dropped
-        assertDrop(program, ra);
-
-        // PIO preferred lifetime increases
-        ra = new RaPacketBuilder(1800 /* router lifetime */)
-                .addPioOption(1800 /*valid*/, 101 /*preferred*/, "2001:db8::/64")
-                .build();
-        assertPass(program, ra);
-
-        // PIO preferred lifetime decreases significantly
-        ra = new RaPacketBuilder(1800 /* router lifetime */)
-                .addPioOption(1800 /*valid*/, 33 /*preferred*/, "2001:db8::/64")
-                .build();
-        assertPass(program, ra);
-    }
-
-
-    // Test for go/apf-ra-filter Case 1b.
-    // Old lifetime is 0
-    @Test
-    public void testAcceptRaMinLftCase1b() throws Exception {
-        final MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        // configure accept_ra_min_lft
-        final ApfConfiguration config = getDefaultConfig();
-        config.acceptRaMinLft = 180;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback,
-                mNetworkQuirkMetrics, mDependencies);
-
-        // Create an initial RA and build an APF program
-        byte[] ra = new RaPacketBuilder(0 /* router lifetime */).build();
-
-        apfFilter.pretendPacketReceived(ra);
-        byte[] program = ipClientCallback.assertProgramUpdateAndGet();
-
-        // repeated RA is dropped
-        assertDrop(program, ra);
-
-        // lifetime increases below accept_ra_min_lft
-        ra = new RaPacketBuilder(179 /* router lifetime */).build();
-        assertDrop(program, ra);
-
-        // lifetime increases to accept_ra_min_lft
-        ra = new RaPacketBuilder(180 /* router lifetime */).build();
-        assertPass(program, ra);
-    }
-
-
-    // Test for go/apf-ra-filter Case 2b.
-    // Old lifetime is < accept_ra_min_lft (but not 0).
-    @Test
-    public void testAcceptRaMinLftCase2b() throws Exception {
-        final MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        // configure accept_ra_min_lft
-        final ApfConfiguration config = getDefaultConfig();
-        config.acceptRaMinLft = 180;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback,
-                mNetworkQuirkMetrics, mDependencies);
-
-        // Create an initial RA and build an APF program
-        byte[] ra = new RaPacketBuilder(100 /* router lifetime */).build();
-
-        apfFilter.pretendPacketReceived(ra);
-        byte[] program = ipClientCallback.assertProgramUpdateAndGet();
-
-        // repeated RA is dropped
-        assertDrop(program, ra);
-
-        // lifetime increases
-        ra = new RaPacketBuilder(101 /* router lifetime */).build();
-        assertDrop(program, ra);
-
-        // lifetime decreases significantly
-        ra = new RaPacketBuilder(1 /* router lifetime */).build();
-        assertDrop(program, ra);
-
-        // equals accept_ra_min_lft
-        ra = new RaPacketBuilder(180 /* router lifetime */).build();
-        assertPass(program, ra);
-
-        // lifetime is 0
-        ra = new RaPacketBuilder(0 /* router lifetime */).build();
-        assertPass(program, ra);
-    }
-
-    // Test for go/apf-ra-filter Case 3b.
-    // Old lifetime is >= accept_ra_min_lft and <= 3 * accept_ra_min_lft
-    @Test
-    public void testAcceptRaMinLftCase3b() throws Exception {
-        final MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        // configure accept_ra_min_lft
-        final ApfConfiguration config = getDefaultConfig();
-        config.acceptRaMinLft = 180;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback,
-                mNetworkQuirkMetrics, mDependencies);
-
-        // Create an initial RA and build an APF program
-        byte[] ra = new RaPacketBuilder(200 /* router lifetime */).build();
-
-        apfFilter.pretendPacketReceived(ra);
-        byte[] program = ipClientCallback.assertProgramUpdateAndGet();
-
-        // repeated RA is dropped
-        assertDrop(program, ra);
-
-        // lifetime increases
-        ra = new RaPacketBuilder(201 /* router lifetime */).build();
-        assertPass(program, ra);
-
-        // lifetime is below accept_ra_min_lft (but not 0)
-        ra = new RaPacketBuilder(1 /* router lifetime */).build();
-        assertDrop(program, ra);
-
-        // lifetime is 0
-        ra = new RaPacketBuilder(0 /* router lifetime */).build();
-        assertPass(program, ra);
-    }
-
-    // Test for go/apf-ra-filter Case 4b.
-    // Old lifetime is > 3 * accept_ra_min_lft
-    @Test
-    public void testAcceptRaMinLftCase4b() throws Exception {
-        final MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        // configure accept_ra_min_lft
-        final ApfConfiguration config = getDefaultConfig();
-        config.acceptRaMinLft = 180;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback,
-                mNetworkQuirkMetrics, mDependencies);
-
-        // Create an initial RA and build an APF program
-        byte[] ra = new RaPacketBuilder(1800 /* router lifetime */).build();
-
-        apfFilter.pretendPacketReceived(ra);
-        byte[] program = ipClientCallback.assertProgramUpdateAndGet();
-
-        // repeated RA is dropped
-        assertDrop(program, ra);
-
-        // lifetime increases
-        ra = new RaPacketBuilder(1801 /* router lifetime */).build();
-        assertPass(program, ra);
-
-        // lifetime is 1/3 of old lft
-        ra = new RaPacketBuilder(600 /* router lifetime */).build();
-        assertDrop(program, ra);
-
-        // lifetime is below 1/3 of old lft
-        ra = new RaPacketBuilder(599 /* router lifetime */).build();
-        assertPass(program, ra);
-
-        // lifetime is below accept_ra_min_lft (but not 0)
-        ra = new RaPacketBuilder(1 /* router lifetime */).build();
-        assertDrop(program, ra);
-
-        // lifetime is 0
-        ra = new RaPacketBuilder(0 /* router lifetime */).build();
-        assertPass(program, ra);
-    }
-
-    @Test
-    public void testRaFilterIsUpdated() throws Exception {
-        final MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        // configure accept_ra_min_lft
-        final ApfConfiguration config = getDefaultConfig();
-        config.acceptRaMinLft = 180;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback,
-                mNetworkQuirkMetrics, mDependencies);
-
-        // Create an initial RA and build an APF program
-        byte[] ra = new RaPacketBuilder(1800 /* router lifetime */).build();
-        apfFilter.pretendPacketReceived(ra);
-        byte[] program = ipClientCallback.assertProgramUpdateAndGet();
-
-        // repeated RA is dropped.
-        assertDrop(program, ra);
-
-        // updated RA is passed, repeated RA is dropped after program update.
-        ra = new RaPacketBuilder(599 /* router lifetime */).build();
-        assertPass(program, ra);
-        apfFilter.pretendPacketReceived(ra);
-        program = ipClientCallback.assertProgramUpdateAndGet();
-        assertDrop(program, ra);
-
-        ra = new RaPacketBuilder(180 /* router lifetime */).build();
-        assertPass(program, ra);
-        apfFilter.pretendPacketReceived(ra);
-        program = ipClientCallback.assertProgramUpdateAndGet();
-        assertDrop(program, ra);
-
-        ra = new RaPacketBuilder(0 /* router lifetime */).build();
-        assertPass(program, ra);
-        apfFilter.pretendPacketReceived(ra);
-        program = ipClientCallback.assertProgramUpdateAndGet();
-        assertDrop(program, ra);
-
-        ra = new RaPacketBuilder(180 /* router lifetime */).build();
-        assertPass(program, ra);
-        apfFilter.pretendPacketReceived(ra);
-        program = ipClientCallback.assertProgramUpdateAndGet();
-        assertDrop(program, ra);
-
-        ra = new RaPacketBuilder(599 /* router lifetime */).build();
-        assertPass(program, ra);
-        apfFilter.pretendPacketReceived(ra);
-        program = ipClientCallback.assertProgramUpdateAndGet();
-        assertDrop(program, ra);
-
-        ra = new RaPacketBuilder(1800 /* router lifetime */).build();
-        assertPass(program, ra);
-        apfFilter.pretendPacketReceived(ra);
-        program = ipClientCallback.assertProgramUpdateAndGet();
-        assertDrop(program, ra);
-    }
-
     private TestAndroidPacketFilter makeTestApfFilter(ApfConfiguration config,
             MockIpClientCallback ipClientCallback) throws Exception {
         return new TestLegacyApfFilter(mContext, config, ipClientCallback, mIpConnectivityLog,
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java
index 8d99b11..00982c7 100644
--- a/tests/unit/src/android/net/ip/IpClientTest.java
+++ b/tests/unit/src/android/net/ip/IpClientTest.java
@@ -83,6 +83,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.modules.utils.build.SdkLevel;
 import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.netlink.NduseroptMessage;
 import com.android.net.module.util.netlink.RtNetlinkAddressMessage;
@@ -884,7 +885,8 @@
                 any(), configCaptor.capture(), any(), any(), any(), anyBoolean());
         final ApfConfiguration actual = configCaptor.getValue();
         assertNotNull(actual);
-        assertEquals(4, actual.apfCapabilities.apfVersionSupported);
+        int expectedApfVersion = SdkLevel.isAtLeastS() ? 4 : 3;
+        assertEquals(expectedApfVersion, actual.apfCapabilities.apfVersionSupported);
         assertEquals(4096, actual.apfCapabilities.maximumApfProgramSize);
         assertEquals(4, actual.apfCapabilities.apfPacketFormat);