Reapply "Set accept_ra_min_lft systctl when starting IPv6 stack."

This reverts commit 64364be83550315d0d30238832473ce04f8dd1db and
reintroduces aosp/2743254.

Reason for revert: This CL should apply cleanly to the November module.

Test: atest NetworkStackIntegrationTests
Change-Id: Ib29663bb2b8efad83eecd724f698ded5031572aa
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index b798a83..29cb526 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -42,6 +42,7 @@
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_DHCPV6_PREFIX_DELEGATION_VERSION;
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_GARP_NA_ROAMING_VERSION;
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_GRATUITOUS_NA_VERSION;
+import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_IGNORE_LOW_RA_LIFETIME_FORCE_DISABLE;
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_MULTICAST_NS_VERSION;
 import static com.android.server.util.PermissionUtil.enforceNetworkStackCallingPermission;
 
@@ -130,6 +131,7 @@
 import com.android.server.NetworkObserverRegistry;
 import com.android.server.NetworkStackService.NetworkStackServiceManager;
 
+import java.io.File;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.net.Inet4Address;
@@ -475,6 +477,8 @@
     // Sysctl parameter strings.
     private static final String ACCEPT_RA = "accept_ra";
     private static final String ACCEPT_RA_DEFRTR = "accept_ra_defrtr";
+    @VisibleForTesting
+    static final String ACCEPT_RA_MIN_LFT = "accept_ra_min_lft";
     private static final String DAD_TRANSMITS = "dad_transmits";
 
     // Below constants are picked up by MessageUtils and exempt from ProGuard optimization.
@@ -525,6 +529,11 @@
     private static final int DEFAULT_MIN_RDNSS_LIFETIME =
             ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q) ? 120 : 0;
 
+    @VisibleForTesting
+    static final String CONFIG_ACCEPT_RA_MIN_LFT = "ipclient_accept_ra_min_lft";
+    @VisibleForTesting
+    static final int DEFAULT_ACCEPT_RA_MIN_LFT = 180;
+
     // Used to wait for the provisioning to complete eventually and then decide the target
     // network type, which gives the accurate hint to set DTIM multiplier. Per current IPv6
     // provisioning connection latency metrics, the latency of 95% can go up to 16s, so pick
@@ -644,6 +653,9 @@
     // Ignore nonzero RDNSS option lifetimes below this value. 0 = disabled.
     private final int mMinRdnssLifetimeSec;
 
+    // Ignore any nonzero RA section with lifetime below this value.
+    private final int mAcceptRaMinLft;
+
     // Experiment flag read from device config.
     private final boolean mDhcp6PrefixDelegationEnabled;
 
@@ -804,6 +816,15 @@
         public boolean isNetworkStackFeatureNotChickenedOut(final String name) {
             return DeviceConfigUtils.isNetworkStackFeatureNotChickenedOut(name);
         }
+
+        /**
+         * Check if a specific IPv6 sysctl file exists or not.
+         */
+        public boolean hasIpv6Sysctl(final String ifname, final String name) {
+            final String path = "/proc/sys/net/ipv6/conf/" + ifname + "/" + name;
+            final File sysctl = new File(path);
+            return sysctl.exists();
+        }
     }
 
     public IpClient(Context context, String ifName, IIpClientCallbacks callback,
@@ -848,6 +869,8 @@
 
         mMinRdnssLifetimeSec = mDependencies.getDeviceConfigPropertyInt(
                 CONFIG_MIN_RDNSS_LIFETIME, DEFAULT_MIN_RDNSS_LIFETIME);
+        mAcceptRaMinLft = mDependencies.getDeviceConfigPropertyInt(CONFIG_ACCEPT_RA_MIN_LFT,
+                DEFAULT_ACCEPT_RA_MIN_LFT);
 
         IpClientLinkObserver.Configuration config = new IpClientLinkObserver.Configuration(
                 mMinRdnssLifetimeSec);
@@ -2127,6 +2150,13 @@
                 setIpv6Sysctl(DAD_TRANSMITS, 0 /* dad_transmits */);
             }
         }
+        // Check chickened out flag first before reading IPv6 sysctl, which can prevent from
+        // triggering a potential kernel bug about the sysctl.
+        if (mDependencies.isNetworkStackFeatureNotChickenedOut(
+                IPCLIENT_IGNORE_LOW_RA_LIFETIME_FORCE_DISABLE)
+                && mDependencies.hasIpv6Sysctl(mInterfaceName, ACCEPT_RA_MIN_LFT)) {
+            setIpv6Sysctl(ACCEPT_RA_MIN_LFT, mAcceptRaMinLft);
+        }
         return mInterfaceCtrl.setIPv6PrivacyExtensions(true)
                 && mInterfaceCtrl.setIPv6AddrGenModeIfSupported(mConfiguration.mIPv6AddrGenMode)
                 && mInterfaceCtrl.enableIPv6();
@@ -2204,6 +2234,11 @@
         setIpv6Sysctl(ACCEPT_RA, 2);
         setIpv6Sysctl(ACCEPT_RA_DEFRTR, 1);
         maybeRestoreDadTransmits();
+        if (mDependencies.isNetworkStackFeatureNotChickenedOut(
+                IPCLIENT_IGNORE_LOW_RA_LIFETIME_FORCE_DISABLE)
+                && mDependencies.hasIpv6Sysctl(mInterfaceName, ACCEPT_RA_MIN_LFT)) {
+            setIpv6Sysctl(ACCEPT_RA_MIN_LFT, 0 /* sysctl default */);
+        }
     }
 
     private void maybeSaveNetworkToIpMemoryStore() {
diff --git a/src/com/android/networkstack/util/NetworkStackUtils.java b/src/com/android/networkstack/util/NetworkStackUtils.java
index 05f4a52..b3bd2ef 100755
--- a/src/com/android/networkstack/util/NetworkStackUtils.java
+++ b/src/com/android/networkstack/util/NetworkStackUtils.java
@@ -276,6 +276,13 @@
     public static final String IPCLIENT_PARSE_NETLINK_EVENTS_FORCE_DISABLE =
             "ipclient_parse_netlink_events_force_disable";
 
+    /**
+     * Kill switch flag to disable the feature of ignoring any individual RA section with lifetime
+     * below accept_ra_min_lft sysctl.
+     */
+    public static final String IPCLIENT_IGNORE_LOW_RA_LIFETIME_FORCE_DISABLE =
+            "ipclient_ignore_low_ra_lifetime_force_disable";
+
     static {
         System.loadLibrary("networkstackutilsjni");
     }
diff --git a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
index f8dce2e..585b3a0 100644
--- a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -40,6 +40,8 @@
 import static android.net.dhcp.DhcpPacket.MIN_V6ONLY_WAIT_MS;
 import static android.net.ip.IIpClientCallbacks.DTIM_MULTIPLIER_RESET;
 import static android.net.ip.IpClient.CONFIG_IPV6_AUTOCONF_TIMEOUT;
+import static android.net.ip.IpClient.CONFIG_ACCEPT_RA_MIN_LFT;
+import static android.net.ip.IpClient.DEFAULT_ACCEPT_RA_MIN_LFT;
 import static android.net.ip.IpClientLinkObserver.CLAT_PREFIX;
 import static android.net.ip.IpClientLinkObserver.CONFIG_SOCKET_RECV_BUFSIZE;
 import static android.net.ip.IpReachabilityMonitor.NUD_MCAST_RESOLICIT_NUM;
@@ -802,6 +804,10 @@
 
         // Set the timeout to wait IPv6 autoconf to complete.
         mDependencies.setDeviceConfigProperty(CONFIG_IPV6_AUTOCONF_TIMEOUT, 500);
+
+        // Set the minimal RA lifetime value, any RA section with liftime below this value will be
+        // ignored.
+        mDependencies.setDeviceConfigProperty(CONFIG_ACCEPT_RA_MIN_LFT, DEFAULT_ACCEPT_RA_MIN_LFT);
     }
 
     private void awaitIpClientShutdown() throws Exception {