Snap for 8746144 from 19e420b2000ce979db0b6dbd9c4326f9ed8878bf to mainline-conscrypt-release

Change-Id: Ie9ca2a4b1d29f75c9f76f1f75cad735dba812e08
diff --git a/Android.bp b/Android.bp
index 7fcd206..4b3d558 100644
--- a/Android.bp
+++ b/Android.bp
@@ -181,7 +181,6 @@
         "framework-connectivity",
         "framework-connectivity-t.stubs.module_lib",
         "framework-tethering",
-        "android.net.ipsec.ike.stubs.module_lib",
     ],
     sdk_version: module_33_version,
     visibility: ["//visibility:private"],
@@ -209,7 +208,6 @@
         "framework-connectivity",
         "framework-connectivity-t.stubs.module_lib",
         "framework-tethering",
-        "android.net.ipsec.ike.stubs.module_lib",
     ],
     sdk_version: "module_current",
     visibility: ["//visibility:private"],
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ad6c2b5..d616750 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -19,8 +19,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.android.networkstack"
   android:sharedUserId="android.uid.networkstack"
-  android:versionCode="319999900"
-  android:versionName="s_aml_319999900"
+  android:versionCode="339990000"
+  android:versionName="339990000"
   coreApp="true"
 >
     <!--- Defines the MAINLINE_NETWORK_STACK permission used by the networkstack process. -->
diff --git a/AndroidManifest_Next.xml b/AndroidManifest_Next.xml
index 244d465..200a921 100644
--- a/AndroidManifest_Next.xml
+++ b/AndroidManifest_Next.xml
@@ -17,7 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.networkstack"
           android:sharedUserId="android.uid.networkstack"
-          android:versionCode="320000000"
+          android:versionCode="339990000"
           android:versionName="T-next"
           coreApp="true">
 </manifest>
diff --git a/apishim/29/com/android/networkstack/apishim/api29/EthernetManagerShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/EthernetManagerShimImpl.java
deleted file mode 100644
index 2f5fb7d..0000000
--- a/apishim/29/com/android/networkstack/apishim/api29/EthernetManagerShimImpl.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 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 com.android.networkstack.apishim.api29;
-
-import android.content.Context;
-import android.os.Build;
-
-import androidx.annotation.RequiresApi;
-
-import com.android.networkstack.apishim.common.EthernetManagerShim;
-
-/**
- * Implementation of {@link EthernetManagerShim} for API 29.
- *
- * Cannot actually import EthernetManager because that only became @SystemApi in API 30.
- */
-@RequiresApi(Build.VERSION_CODES.Q)
-public class EthernetManagerShimImpl implements EthernetManagerShim {
-    /**
-     * Get a new instance of {@link EthernetManagerShim}.
-     */
-    public static EthernetManagerShim newInstance(Context context) {
-        return new EthernetManagerShimImpl();
-    }
-}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/EthernetManagerShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/EthernetManagerShimImpl.java
deleted file mode 100644
index 2c93d7c..0000000
--- a/apishim/31/com/android/networkstack/apishim/api31/EthernetManagerShimImpl.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2022 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 com.android.networkstack.apishim.api31;
-
-import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
-
-import android.content.Context;
-import android.os.Build;
-
-import androidx.annotation.RequiresApi;
-
-import com.android.networkstack.apishim.common.EthernetManagerShim;
-
-/**
- * Implementation of {@link EthernetManagerShim} for API 31.
- *
- * Doesn't have any methods, but must exist because the stable shim API level is currently 31.
- * TODO: delete when the stable shim API level becomes 33.
- */
-@RequiresApi(Build.VERSION_CODES.S)
-public class EthernetManagerShimImpl
-        extends com.android.networkstack.apishim.api29.EthernetManagerShimImpl {
-    /**
-     * Get a new instance of {@link EthernetManagerShim}.
-     */
-    @RequiresApi(Build.VERSION_CODES.Q)
-    public static EthernetManagerShim newInstance(Context context) {
-        if (!isAtLeastS()) {
-            return com.android.networkstack.apishim.api29.EthernetManagerShimImpl
-                    .newInstance(context);
-        }
-        return new EthernetManagerShimImpl();
-    }
-}
diff --git a/apishim/33/com/android/networkstack/apishim/api33/EthernetManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/EthernetManagerShimImpl.java
deleted file mode 100644
index 5bd6487..0000000
--- a/apishim/33/com/android/networkstack/apishim/api33/EthernetManagerShimImpl.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2022 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 com.android.networkstack.apishim.api33;
-
-import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
-
-import android.content.Context;
-import android.net.EthernetManager;
-import android.os.Build;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-
-import com.android.networkstack.apishim.common.EthernetManagerShim;
-
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-
-/**
- * Implementation of {@link EthernetManagerShim} for API 33.
- */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
-public class EthernetManagerShimImpl
-        extends com.android.networkstack.apishim.api31.EthernetManagerShimImpl {
-
-    protected final EthernetManager mEm;
-
-    // This is needed because callers of the shim cannot use EthernetManager.InterfaceStateListener,
-    // they need to use EthernetManagerShim.InterfaceStateListener instead. But when actually
-    // registering a callback, the callback type passed to EthernetManager must be a real
-    // listener, not a shim. This map keeps track of the mapping between the two objects so that
-    // when a caller calls removeInterfaceStateListener with a shim listener, this class knows what
-    // real listener to pass to EthernetManager.
-    private final ConcurrentHashMap<InterfaceStateListener, EthernetManager.InterfaceStateListener>
-            mListeners = new ConcurrentHashMap<>();
-
-    protected EthernetManagerShimImpl(Context context) {
-        mEm = context.getSystemService(EthernetManager.class);
-    }
-
-    /**
-     * Get a new instance of {@link EthernetManagerShim}.
-     */
-    @RequiresApi(Build.VERSION_CODES.Q)
-    public static EthernetManagerShim newInstance(Context context) {
-        if (!isAtLeastT()) {
-            return com.android.networkstack.apishim.api31.EthernetManagerShimImpl
-                    .newInstance(context);
-        }
-        return new EthernetManagerShimImpl(context);
-    }
-
-    @Override
-    public void addInterfaceStateListener(@NonNull Executor executor,
-            @NonNull InterfaceStateListener listener) {
-        final EthernetManager.InterfaceStateListener wrapper = (a, b, c, d) -> {
-            listener.onInterfaceStateChanged(a, b, c, d);
-        };
-        // EthernetManager#addInterfaceStateListener will allow registering the same listener twice,
-        // but this does not seem very useful and is difficult to support with the wrapper scheme
-        // used by this shim. Don't allow it.
-        final EthernetManager.InterfaceStateListener existing =
-                mListeners.putIfAbsent(listener, wrapper);
-        if (existing != null) {
-            throw new IllegalStateException("Attempt to register duplicate listener");
-        }
-        mEm.addInterfaceStateListener(executor, wrapper);
-    }
-
-    @Override
-    public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) {
-        final EthernetManager.InterfaceStateListener wrapper = mListeners.remove(listener);
-        if (wrapper != null) {
-            mEm.removeInterfaceStateListener(wrapper);
-        }
-    }
-
-    @Override
-    // This method existed in R and S, but as @TestApi, so should not appear in the shims before T
-    // because otherwise it could be used by production code on R and S.
-    public void setIncludeTestInterfaces(boolean include) {
-        mEm.setIncludeTestInterfaces(include);
-    }
-
-    @Override
-    @NonNull
-    public List<String> getInterfaceList() {
-        return mEm.getInterfaceList();
-    }
-}
diff --git a/apishim/34/com/android/networkstack/apishim/EthernetManagerShimImpl.java b/apishim/34/com/android/networkstack/apishim/EthernetManagerShimImpl.java
deleted file mode 100644
index e9a33a1..0000000
--- a/apishim/34/com/android/networkstack/apishim/EthernetManagerShimImpl.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2022 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 com.android.networkstack.apishim;
-
-import android.content.Context;
-import android.os.Build;
-
-import androidx.annotation.RequiresApi;
-
-import com.android.networkstack.apishim.common.EthernetManagerShim;
-
-/**
- * Implementation of {@link EthernetManagerShim} for API 34.
- */
-// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
-public class EthernetManagerShimImpl
-        extends com.android.networkstack.apishim.api33.EthernetManagerShimImpl {
-    protected EthernetManagerShimImpl(Context context) {
-        super(context);
-    }
-}
diff --git a/apishim/common/com/android/networkstack/apishim/common/EthernetManagerShim.java b/apishim/common/com/android/networkstack/apishim/common/EthernetManagerShim.java
deleted file mode 100644
index 02a08de..0000000
--- a/apishim/common/com/android/networkstack/apishim/common/EthernetManagerShim.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2022 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 com.android.networkstack.apishim.common;
-
-import android.net.IpConfiguration;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/** API shim for EthernetManager */
-public interface EthernetManagerShim {
-    int STATE_ABSENT = 0;
-    int STATE_LINK_DOWN = 1;
-    int STATE_LINK_UP = 2;
-    int ROLE_NONE = 0;
-    int ROLE_CLIENT = 1;
-    int ROLE_SERVER = 2;
-
-    /** Shim for EthernetManager#InterfaceStateListener. */
-    interface InterfaceStateListener {
-        void onInterfaceStateChanged(@NonNull String iface, int state, int role,
-                @Nullable IpConfiguration configuration);
-    }
-
-    /** Shim for EthernetManager#addInterfaceStateListener */
-    default void addInterfaceStateListener(@NonNull Executor executor,
-            @NonNull InterfaceStateListener listener) throws UnsupportedApiLevelException {
-        throw new UnsupportedApiLevelException();
-    }
-
-    /** Shim for EthernetManager#removeInterfaceStateListener */
-    default void removeInterfaceStateListener(@NonNull InterfaceStateListener listener)
-            throws UnsupportedApiLevelException {
-        throw new UnsupportedApiLevelException("Not supported until API 33");
-    }
-
-    /** Shim for EthernetManager#setIncludeTestInterfaces */
-    default void setIncludeTestInterfaces(boolean include) throws UnsupportedApiLevelException {
-        throw new UnsupportedApiLevelException("Not supported until API 30");
-    }
-
-    /** Shim for EthernetManager#getInterfaceList */
-    default List<String> getInterfaceList() throws UnsupportedApiLevelException {
-        throw new UnsupportedApiLevelException("Not supported until API 33");
-    }
-}
diff --git a/common/moduleutils/src/android/net/ip/NetlinkMonitor.java b/common/moduleutils/src/android/net/ip/NetlinkMonitor.java
index 17157d8..e58b44e 100644
--- a/common/moduleutils/src/android/net/ip/NetlinkMonitor.java
+++ b/common/moduleutils/src/android/net/ip/NetlinkMonitor.java
@@ -18,6 +18,7 @@
 
 import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
 import static android.system.OsConstants.AF_NETLINK;
+import static android.system.OsConstants.ENOBUFS;
 import static android.system.OsConstants.SOCK_DGRAM;
 import static android.system.OsConstants.SOCK_NONBLOCK;
 import static android.system.OsConstants.SOL_SOCKET;
@@ -101,7 +102,11 @@
         try {
             fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, mFamily);
             if (mSockRcvbufSize != DEFAULT_SOCKET_RECV_BUFSIZE) {
-                Os.setsockoptInt(fd, SOL_SOCKET, SO_RCVBUF, mSockRcvbufSize);
+                try {
+                    Os.setsockoptInt(fd, SOL_SOCKET, SO_RCVBUF, mSockRcvbufSize);
+                } catch (ErrnoException e) {
+                    Log.wtf(mTag, "Failed to set SO_RCVBUF to " + mSockRcvbufSize, e);
+                }
             }
             Os.bind(fd, makeNetlinkSocketAddress(0, mBindGroups));
             NetlinkSocket.connectToKernel(fd);
@@ -147,6 +152,32 @@
         }
     }
 
+    @Override
+    protected void logError(String msg, Exception e) {
+        mLog.e(msg, e);
+    }
+
+    // Ignoring ENOBUFS may miss any important netlink messages, there are some messages which
+    // cannot be recovered by dumping current state once missed since kernel doesn't keep state
+    // for it. In addition, dumping current state will not result in any RTM_DELxxx messages, so
+    // reconstructing current state from a dump will be difficult. However, for those netlink
+    // messages don't cause any state changes, e.g. RTM_NEWLINK with current link state, maybe
+    // it's okay to ignore them, because these netlink messages won't cause any changes on the
+    // LinkProperties. Given the above trade-offs, try to ignore ENOBUFS and that's similar to
+    // what netd does today.
+    //
+    // TODO: log metrics when ENOBUFS occurs, or even force a disconnect, it will help see how
+    // often this error occurs on fields with the associated socket receive buffer size.
+    @Override
+    protected boolean handleReadError(ErrnoException e) {
+        logError("readPacket error: ", e);
+        if (e.errno == ENOBUFS) {
+            Log.wtf(mTag, "Errno: ENOBUFS");
+            return false;
+        }
+        return true;
+    }
+
     // TODO: move NetworkStackUtils to frameworks/libs/net for NetworkStackUtils#closeSocketQuietly.
     private void closeSocketQuietly(FileDescriptor fd) {
         try {
diff --git a/common/networkstackclient/Android.bp b/common/networkstackclient/Android.bp
index 53477ac..c363a2b 100644
--- a/common/networkstackclient/Android.bp
+++ b/common/networkstackclient/Android.bp
@@ -194,7 +194,6 @@
     ],
     static_libs: [
         "networkstack-aidl-latest",
-        "modules-utils-build",
     ],
     visibility: [
         "//frameworks/base/packages/Connectivity/service",
@@ -205,10 +204,12 @@
         "//packages/apps/Bluetooth",
         "//packages/modules/Bluetooth/android/app",
         "//packages/modules/NetworkStack",
+        "//packages/modules/Wifi/service",
     ],
     apex_available: [
         "//apex_available:platform",
         "com.android.bluetooth",
         "com.android.tethering",
+        "com.android.wifi",
     ],
 }
diff --git a/common/networkstackclient/src/android/net/NetworkMonitorManager.java b/common/networkstackclient/src/android/net/NetworkMonitorManager.java
index 98598a1..c39c684 100644
--- a/common/networkstackclient/src/android/net/NetworkMonitorManager.java
+++ b/common/networkstackclient/src/android/net/NetworkMonitorManager.java
@@ -23,8 +23,6 @@
 import android.os.RemoteException;
 import android.util.Log;
 
-import com.android.modules.utils.build.SdkLevel;
-
 /**
  * A convenience wrapper for INetworkMonitor.
  *
@@ -150,15 +148,25 @@
         }
     }
 
+    // This should not be called starting from S
+    @Deprecated
+    public boolean notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.notifyNetworkConnected(lp, nc);
+            return true;
+        } catch (RemoteException e) {
+            log("Error in notifyNetworkConnected", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     public boolean notifyNetworkConnected(NetworkMonitorParameters params) {
         final long token = Binder.clearCallingIdentity();
         try {
-            if (SdkLevel.isAtLeastT()) {
-                mNetworkMonitor.notifyNetworkConnectedParcel(params);
-            } else {
-                mNetworkMonitor.notifyNetworkConnected(params.linkProperties,
-                        params.networkCapabilities);
-            }
+            mNetworkMonitor.notifyNetworkConnectedParcel(params);
             return true;
         } catch (RemoteException e) {
             log("Error in notifyNetworkConnected", e);
diff --git a/src/android/net/dhcp/DhcpInformPacket.java b/src/android/net/dhcp/DhcpInformPacket.java
deleted file mode 100644
index 135b8f6..0000000
--- a/src/android/net/dhcp/DhcpInformPacket.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2010 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.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the (unused) DHCP-INFORM packet.
- */
-public class DhcpInformPacket extends DhcpPacket {
-    /**
-     * Generates an INFORM packet with the specified parameters.
-     */
-    DhcpInformPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                     Inet4Address nextIp, Inet4Address relayIp,
-                     byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, nextIp, relayIp, clientMac, false);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " INFORM";
-    }
-
-    /**
-     * Builds an INFORM packet.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-
-        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
-            DHCP_BOOTREQUEST, false);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds additional parameters to the INFORM packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_INFORM);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        addCommonClientTlvs(buffer);
-        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/src/android/net/dhcp/DhcpPacket.java b/src/android/net/dhcp/DhcpPacket.java
index 63c5b0c..7dc1b99 100644
--- a/src/android/net/dhcp/DhcpPacket.java
+++ b/src/android/net/dhcp/DhcpPacket.java
@@ -1346,11 +1346,6 @@
                 newPacket = new DhcpReleasePacket(
                         transactionId, serverIdentifier, clientIp, relayIp, clientMac);
                 break;
-            case DHCP_MESSAGE_TYPE_INFORM:
-                newPacket = new DhcpInformPacket(
-                    transactionId, secs, clientIp, yourIp, nextIp, relayIp,
-                    clientMac);
-                break;
             default:
                 throw new ParseException(DhcpErrorEvent.DHCP_UNKNOWN_MSG_TYPE,
                         "Unimplemented DHCP type %d", dhcpType);
diff --git a/src/android/net/ip/IpClientLinkObserver.java b/src/android/net/ip/IpClientLinkObserver.java
index f0126e6..bebe7c9 100644
--- a/src/android/net/ip/IpClientLinkObserver.java
+++ b/src/android/net/ip/IpClientLinkObserver.java
@@ -45,6 +45,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.netlink.NduseroptMessage;
 import com.android.net.module.util.netlink.NetlinkConstants;
@@ -160,7 +161,14 @@
     // This must match the interface prefix in clatd.c.
     // TODO: Revert this hack once IpClient and Nat464Xlat work in concert.
     protected static final String CLAT_PREFIX = "v4-";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
+
+    // The default socket receive buffer size in bytes(4MB). If too many netlink messages are
+    // sent too quickly, those messages can overflow the socket receive buffer. Set a large-enough
+    // recv buffer size to avoid the ENOBUFS as much as possible.
+    @VisibleForTesting
+    static final String CONFIG_SOCKET_RECV_BUFSIZE = "ipclient_netlink_sock_recv_buf_size";
+    private static final int SOCKET_RECV_BUFSIZE = 4 * 1024 * 1024;
 
     public IpClientLinkObserver(Context context, Handler h, String iface, Callback callback,
             Configuration config, SharedLog log, IpClient.Dependencies deps) {
@@ -178,7 +186,11 @@
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mDependencies = deps;
         mNetlinkMonitor = new MyNetlinkMonitor(h, log, mTag);
-        mHandler.post(mNetlinkMonitor::start);
+        mHandler.post(() -> {
+            if (!mNetlinkMonitor.start()) {
+                Log.wtf(mTag, "Fail to start NetlinkMonitor.");
+            }
+        });
     }
 
     public void shutdown() {
@@ -207,6 +219,15 @@
                 isAtLeastT() /* default value */);
     }
 
+    private int getSocketReceiveBufferSize() {
+        final int size = mDependencies.getDeviceConfigPropertyInt(CONFIG_SOCKET_RECV_BUFSIZE,
+                SOCKET_RECV_BUFSIZE /* default value */);
+        if (size < 0) {
+            throw new IllegalArgumentException("Invalid SO_RCVBUF " + size);
+        }
+        return size;
+    }
+
     @Override
     public void onInterfaceAdded(String iface) {
         if (isNetlinkEventParsingEnabled()) return;
@@ -279,10 +300,10 @@
     }
 
     private void updateInterfaceDnsServerInfo(long lifetime, final String[] addresses) {
-        maybeLog("interfaceDnsServerInfo", Arrays.toString(addresses));
         final boolean changed = mDnsServerRepository.addServers(lifetime, addresses);
         final boolean linkState;
         if (changed) {
+            maybeLog("interfaceDnsServerInfo", Arrays.toString(addresses));
             synchronized (this) {
                 mDnsServerRepository.setDnsServersOn(mLinkProperties);
                 linkState = getInterfaceLinkStateLocked();
@@ -291,7 +312,7 @@
         }
     }
 
-    private void updateInterfaceAddress(@NonNull final LinkAddress address, boolean add) {
+    private boolean updateInterfaceAddress(@NonNull final LinkAddress address, boolean add) {
         final boolean changed;
         final boolean linkState;
         synchronized (this) {
@@ -309,9 +330,10 @@
                 mCallback.onIpv6AddressRemoved(addr);
             }
         }
+        return changed;
     }
 
-    private void updateInterfaceRoute(final RouteInfo route, boolean add) {
+    private boolean updateInterfaceRoute(final RouteInfo route, boolean add) {
         final boolean changed;
         final boolean linkState;
         synchronized (this) {
@@ -325,6 +347,7 @@
         if (changed) {
             mCallback.update(linkState);
         }
+        return changed;
     }
 
     private void updateInterfaceRemoved() {
@@ -400,11 +423,12 @@
         MyNetlinkMonitor(Handler h, SharedLog log, String tag) {
             super(h, log, tag, OsConstants.NETLINK_ROUTE,
                     !isNetlinkEventParsingEnabled()
-                    ? NetlinkConstants.RTMGRP_ND_USEROPT
-                    : (NetlinkConstants.RTMGRP_ND_USEROPT | NetlinkConstants.RTMGRP_LINK
-                            | NetlinkConstants.RTMGRP_IPV4_IFADDR
-                            | NetlinkConstants.RTMGRP_IPV6_IFADDR
-                            | NetlinkConstants.RTMGRP_IPV6_ROUTE));
+                        ? NetlinkConstants.RTMGRP_ND_USEROPT
+                        : (NetlinkConstants.RTMGRP_ND_USEROPT | NetlinkConstants.RTMGRP_LINK
+                                | NetlinkConstants.RTMGRP_IPV4_IFADDR
+                                | NetlinkConstants.RTMGRP_IPV6_IFADDR
+                                | NetlinkConstants.RTMGRP_IPV6_ROUTE),
+                    getSocketReceiveBufferSize());
 
             mHandler = h;
         }
@@ -423,6 +447,9 @@
         private int mIfindex;
 
         void setIfindex(int ifindex) {
+            if (!isRunning()) {
+                Log.wtf(mTag, "NetlinkMonitor is not running when setting interface parameter!");
+            }
             mIfindex = ifindex;
         }
 
@@ -602,12 +629,14 @@
 
             switch (msg.getHeader().nlmsg_type) {
                 case NetlinkConstants.RTM_NEWADDR:
-                    maybeLog("addressUpdated", mIfindex, la);
-                    updateInterfaceAddress(la, true /* add address */);
+                    if (updateInterfaceAddress(la, true /* add address */)) {
+                        maybeLog("addressUpdated", mIfindex, la);
+                    }
                     break;
                 case NetlinkConstants.RTM_DELADDR:
-                    maybeLog("addressRemoved", mIfindex, la);
-                    updateInterfaceAddress(la, false /* remove address */);
+                    if (updateInterfaceAddress(la, false /* remove address */)) {
+                        maybeLog("addressRemoved", mIfindex, la);
+                    }
                     break;
                 default:
                     Log.e(mTag, "Unknown rtnetlink address msg type " + msg.getHeader().nlmsg_type);
@@ -632,12 +661,14 @@
                     mInterfaceName, msg.getRtMsgHeader().type);
             switch (msg.getHeader().nlmsg_type) {
                 case NetlinkConstants.RTM_NEWROUTE:
-                    maybeLog("routeUpdated", route);
-                    updateInterfaceRoute(route, true /* add route */);
+                    if (updateInterfaceRoute(route, true /* add route */)) {
+                        maybeLog("routeUpdated", route);
+                    }
                     break;
                 case NetlinkConstants.RTM_DELROUTE:
-                    maybeLog("routeRemoved", route);
-                    updateInterfaceRoute(route, false /* remove route */);
+                    if (updateInterfaceRoute(route, false /* remove route */)) {
+                        maybeLog("routeRemoved", route);
+                    }
                     break;
                 default:
                     Log.e(mTag, "Unknown rtnetlink route msg type " + msg.getHeader().nlmsg_type);
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
index 9984a54..2bf0529 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -36,8 +36,8 @@
     name: "NetworkStackIntegrationTestsDefaults",
     defaults: ["framework-connectivity-test-defaults"],
     srcs: [
-        "src/**/*.java",
-        "src/**/*.kt",
+        "common/**/*.java",
+        "common/**/*.kt",
     ],
     static_libs: [
         "androidx.annotation_annotation",
@@ -57,6 +57,10 @@
 android_library {
     name: "NetworkStackIntegrationTestsLib",
     defaults: ["NetworkStackIntegrationTestsDefaults"],
+    srcs: [
+        "signature/**/*.java",
+        "signature/**/*.kt",
+    ],
     min_sdk_version: "29",
     static_libs: [
         "NetworkStackApiStableLib",
@@ -84,6 +88,10 @@
         "NetworkStackIntegrationTestsJniDefaults",
         "ConnectivityNextEnableDefaults",
     ],
+    srcs: [
+        "signature/**/*.java",
+        "signature/**/*.kt",
+    ],
     static_libs: [
         "NetworkStackApiCurrentLib",
     ],
@@ -93,6 +101,26 @@
     jarjar_rules: ":NetworkStackJarJarRules",
 }
 
+// Network stack integration root tests.
+android_test {
+    name: "NetworkStackRootTests",
+    defaults: [
+        "NetworkStackIntegrationTestsDefaults",
+        "NetworkStackIntegrationTestsJniDefaults",
+    ],
+    srcs: [
+        "root/**/*.java",
+        "root/**/*.kt",
+    ],
+    static_libs: [
+        "NetworkStackApiCurrentLib",
+    ],
+    platform_apis: true,
+    test_suites: ["general-tests", "mts-networking"],
+    manifest: "AndroidManifest_root.xml",
+    jarjar_rules: ":NetworkStackJarJarRules",
+}
+
 // Special version of the network stack tests that includes all tests necessary for code coverage
 // purposes. This is currently the union of NetworkStackTests and NetworkStackIntegrationTests.
 android_test {
@@ -101,7 +129,7 @@
     platform_apis: true,
     min_sdk_version: "29",
     target_sdk_version: "30",
-    test_suites: ["device-tests", "mts"],
+    test_suites: ["device-tests", "mts-networking"],
     test_config: "AndroidTest_Coverage.xml",
     defaults: ["NetworkStackIntegrationTestsJniDefaults"],
     static_libs: [
diff --git a/tests/integration/AndroidManifest_root.xml b/tests/integration/AndroidManifest_root.xml
new file mode 100644
index 0000000..02b82c5
--- /dev/null
+++ b/tests/integration/AndroidManifest_root.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.server.networkstack.roottests">
+
+    <application android:debuggable="true">
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.server.networkstack.roottests"
+        android:label="Networking stack integration root tests">
+    </instrumentation>
+</manifest>
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
similarity index 97%
rename from tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
rename to tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
index 78d0bca..959b0b7 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -29,6 +29,7 @@
 import static android.net.dhcp.DhcpPacket.MIN_V6ONLY_WAIT_MS;
 import static android.net.dhcp.DhcpResultsParcelableUtil.fromStableParcelable;
 import static android.net.ip.IpClientLinkObserver.CLAT_PREFIX;
+import static android.net.ip.IpClientLinkObserver.CONFIG_SOCKET_RECV_BUFSIZE;
 import static android.net.ip.IpReachabilityMonitor.MIN_NUD_SOLICIT_NUM;
 import static android.net.ip.IpReachabilityMonitor.NUD_MCAST_RESOLICIT_NUM;
 import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt;
@@ -552,10 +553,10 @@
     protected abstract void assertIpMemoryNeverStoreNetworkAttributes(String l2Key, long timeout);
 
     protected final boolean testSkipped() {
-        // TODO: split out a test suite for root tests, and fail hard instead of skipping the test
-        // if it is run on devices where TestNetworkStackServiceClient is not supported
-        return !useNetworkStackSignature()
-                && (mIsSignatureRequiredTest || !TestNetworkStackServiceClient.isSupported());
+        if (!useNetworkStackSignature() && !TestNetworkStackServiceClient.isSupported()) {
+            fail("Device running root tests doesn't support TestNetworkStackServiceClient.");
+        }
+        return !useNetworkStackSignature() && mIsSignatureRequiredTest;
     }
 
     protected void setDhcpFeatures(final boolean isDhcpLeaseCacheEnabled,
@@ -632,6 +633,11 @@
         mDependencies.setDeviceConfigProperty(DhcpClient.ARP_PROBE_MAX_MS, 20);
         mDependencies.setDeviceConfigProperty(DhcpClient.ARP_FIRST_ANNOUNCE_DELAY_MS, 10);
         mDependencies.setDeviceConfigProperty(DhcpClient.ARP_ANNOUNCE_INTERVAL_MS, 10);
+
+        // Set the initial netlink socket receive buffer size to a minimum of 100KB to ensure test
+        // cases are still working, meanwhile in order to easily overflow the receive buffer by
+        // sending as few RAs as possible for test case where it's used to verify ENOBUFS.
+        mDependencies.setDeviceConfigProperty(CONFIG_SOCKET_RECV_BUFSIZE, 100 * 1024);
     }
 
     private void awaitIpClientShutdown() throws Exception {
@@ -1657,13 +1663,16 @@
     private void sendRouterAdvertisement(boolean waitForRs, short lifetime) throws Exception {
         final String dnsServer = "2001:4860:4860::64";
         final ByteBuffer pio = buildPioOption(3600, 1800, "2001:db8:1::/64");
-        ByteBuffer rdnss = buildRdnssOption(3600, dnsServer);
-        ByteBuffer ra = buildRaPacket(lifetime, pio, rdnss);
+        final ByteBuffer rdnss = buildRdnssOption(3600, dnsServer);
+        sendRouterAdvertisement(waitForRs, lifetime, pio, rdnss);
+    }
 
+    private void sendRouterAdvertisement(boolean waitForRs, short lifetime,
+            ByteBuffer... options) throws Exception {
+        final ByteBuffer ra = buildRaPacket(lifetime, options);
         if (waitForRs) {
             waitForRouterSolicitation();
         }
-
         mPacketReader.sendResponse(ra);
     }
 
@@ -3764,7 +3773,10 @@
         );
     }
 
+    // Since createTapInterface(boolean, String) method was introduced since T, this method
+    // cannot be found on Q/R/S platform, ignore this test on T- platform.
     @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
     public void testIpClientLinkObserver_onClatInterfaceStateUpdate() throws Exception {
         ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
                 .withoutIPv4()
@@ -3784,4 +3796,59 @@
         removeTestInterface(clatIface.getFileDescriptor().getFileDescriptor());
         verify(mCb, timeout(TEST_TIMEOUT_MS)).setNeighborDiscoveryOffload(true);
     }
+
+    @Test @SignatureRequiredTest(reason = "requires mock callback object")
+    public void testNetlinkSocketReceiveENOBUFS() throws Exception {
+        // Only run the test when the flag of parsing netlink events is enabled.
+        assumeTrue(mIsNetlinkEventParseEnabled);
+
+        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
+                .withoutIPv4()
+                .build();
+        startIpClientProvisioning(config);
+        doIpv6OnlyProvisioning();
+        HandlerUtils.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS);
+
+        final Handler handler = mIpc.getHandler();
+        // Block IpClient handler.
+        final CountDownLatch latch = new CountDownLatch(1);
+        handler.post(() -> {
+            try {
+                latch.await(10, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                fail("latch wait unexpectedly interrupted");
+            }
+        });
+
+        // Send large amount of RAs to overflow the netlink socket receive buffer.
+        for (int i = 0; i < 100; i++) {
+            sendBasicRouterAdvertisement(false /* waitRs */);
+        }
+
+        // Send another RA with a different IPv6 global prefix. This PIO option should be dropped
+        // due to the ENOBUFS happens, it means IpClient shouldn't see the new IPv6 global prefix.
+        final String dnsServer = "2001:4860:4860::64";
+        final String prefix = "2001:db8:dead:beef::/64";
+        final ByteBuffer pio = buildPioOption(3600, 1800, prefix);
+        ByteBuffer rdnss = buildRdnssOption(3600, dnsServer);
+        sendRouterAdvertisement(false /* waitForRs */, (short) 1800, pio, rdnss);
+
+        // Unblock the IpClient handler and ENOBUFS should happen then.
+        latch.countDown();
+        HandlerUtils.waitForIdle(handler, TEST_TIMEOUT_MS);
+
+        reset(mCb);
+
+        // Send RA with 0 router lifetime to see if IpClient can see the loss of IPv6 default route.
+        // Due to ignoring the ENOBUFS and wait until handler gets idle, IpClient should be still
+        // able to see the RA with 0 router lifetime and the IPv6 default route will be removed.
+        // LinkProperties should not include any route to the new prefix 2001:db8:dead:beef::/64.
+        sendRouterAdvertisementWithZeroLifetime();
+        final ArgumentCaptor<LinkProperties> captor = ArgumentCaptor.forClass(LinkProperties.class);
+        verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningFailure(captor.capture());
+        final LinkProperties lp = captor.getValue();
+        assertNotNull(lp);
+        assertFalse(hasRouteTo(lp, prefix));
+        assertFalse(lp.hasIpv6DefaultRoute());
+    }
 }
diff --git a/tests/integration/src/android/net/networkstack/TestNetworkStackServiceClient.kt b/tests/integration/common/android/net/networkstack/TestNetworkStackServiceClient.kt
similarity index 99%
rename from tests/integration/src/android/net/networkstack/TestNetworkStackServiceClient.kt
rename to tests/integration/common/android/net/networkstack/TestNetworkStackServiceClient.kt
index 47936ac..9f5e5e7 100644
--- a/tests/integration/src/android/net/networkstack/TestNetworkStackServiceClient.kt
+++ b/tests/integration/common/android/net/networkstack/TestNetworkStackServiceClient.kt
@@ -78,4 +78,4 @@
     fun disconnect() {
         InstrumentationRegistry.getInstrumentation().context.unbindService(serviceConnection)
     }
-}
\ No newline at end of file
+}
diff --git a/tests/integration/lint-baseline.xml b/tests/integration/lint-baseline.xml
index eadec6f..1868549 100644
--- a/tests/integration/lint-baseline.xml
+++ b/tests/integration/lint-baseline.xml
@@ -7,8 +7,8 @@
         errorLine1="        assertEquals(SERVER_ADDR, captor.getValue().getDhcpServerAddress());"
         errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="packages/modules/NetworkStack/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java"
-            line="1327"
+            file="packages/modules/NetworkStack/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java"
+            line="1513"
             column="53"/>
     </issue>
 
@@ -18,8 +18,8 @@
         errorLine1="                argThat(lp -> Objects.equals(expected, lp.getNat64Prefix())));"
         errorLine2="                                                          ~~~~~~~~~~~~~~">
         <location
-            file="packages/modules/NetworkStack/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java"
-            line="1623"
+            file="packages/modules/NetworkStack/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java"
+            line="1836"
             column="59"/>
     </issue>
 
@@ -29,8 +29,8 @@
         errorLine1="                lp -> !Objects.equals(unchanged, lp.getNat64Prefix())));"
         errorLine2="                                                    ~~~~~~~~~~~~~~">
         <location
-            file="packages/modules/NetworkStack/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java"
-            line="1629"
+            file="packages/modules/NetworkStack/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java"
+            line="1842"
             column="53"/>
     </issue>
 
@@ -40,8 +40,8 @@
         errorLine1="        if (lp.getNat64Prefix() != null) {"
         errorLine2="               ~~~~~~~~~~~~~~">
         <location
-            file="packages/modules/NetworkStack/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java"
-            line="1660"
+            file="packages/modules/NetworkStack/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java"
+            line="1873"
             column="16"/>
     </issue>
 
@@ -51,8 +51,8 @@
         errorLine1="            assertEquals(prefix, lp.getNat64Prefix());"
         errorLine2="                                    ~~~~~~~~~~~~~~">
         <location
-            file="packages/modules/NetworkStack/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java"
-            line="1661"
+            file="packages/modules/NetworkStack/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java"
+            line="1874"
             column="37"/>
     </issue>
 
diff --git a/tests/integration/src/android/net/ip/IpClientRootTest.kt b/tests/integration/root/android/net/ip/IpClientRootTest.kt
similarity index 100%
rename from tests/integration/src/android/net/ip/IpClientRootTest.kt
rename to tests/integration/root/android/net/ip/IpClientRootTest.kt
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt b/tests/integration/signature/android/net/ip/IpClientSignatureTest.kt
similarity index 96%
rename from tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
rename to tests/integration/signature/android/net/ip/IpClientSignatureTest.kt
index fa379d3..c9e33b5 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
+++ b/tests/integration/signature/android/net/ip/IpClientSignatureTest.kt
@@ -32,7 +32,7 @@
 /**
  * Tests for IpClient, run with signature permissions.
  */
-class IpClientIntegrationTest : IpClientIntegrationTestCommon() {
+class IpClientSignatureTest : IpClientIntegrationTestCommon() {
     private val mEnabledFeatures = ArrayMap<String, Boolean>()
 
     override fun makeIIpClient(ifaceName: String, cb: IIpClientCallbacks): IIpClient {
diff --git a/tests/integration/src/android/net/netlink/InetDiagSocketIntegrationTest.java b/tests/integration/signature/android/net/netlink/InetDiagSocketIntegrationTest.java
similarity index 100%
rename from tests/integration/src/android/net/netlink/InetDiagSocketIntegrationTest.java
rename to tests/integration/signature/android/net/netlink/InetDiagSocketIntegrationTest.java
diff --git a/tests/integration/src/android/net/util/NetworkStackUtilsIntegrationTest.kt b/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt
similarity index 100%
rename from tests/integration/src/android/net/util/NetworkStackUtilsIntegrationTest.kt
rename to tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt