Merge "Cleanup IpReachabilityMonitor" into tm-dev
diff --git a/Android.bp b/Android.bp
index ec7f8b0..7fcd206 100644
--- a/Android.bp
+++ b/Android.bp
@@ -45,6 +45,10 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+// In some branches, this may be module_current instead of module_33 if the SDK prebuilts are not
+// yet dropped there, meaning module_33 cannot be used yet.
+module_33_version = "module_33"
+
 // TODO: remove this default and replace with ConnectivityNextEnableDefaults. This will need to be
 // done separately in each branch due to merge conflicts.
 // Defaults to enable/disable java targets that depend on
@@ -72,11 +76,12 @@
 
 java_defaults {
     name: "NetworkStackReleaseApiLevel",
-    sdk_version: "module_31",
+    sdk_version: module_33_version,
     min_sdk_version: "29",
-    target_sdk_version: "31",
+    target_sdk_version: "33",
     libs: [
         "framework-connectivity",
+        "framework-connectivity-t",
         "framework-statsd",
         "framework-wifi",
     ]
@@ -142,9 +147,6 @@
     },
 }
 
-// Shims for APIs being added to the current development version of Android. These APIs are not
-// stable and have no defined version number. These could be called 10000, but they use the next
-// integer so if the next SDK release happens to use that integer, we don't need to rename them.
 java_library {
     name: "NetworkStackApi31Shims",
     defaults: ["NetworkStackShimsDefaults"],
@@ -161,10 +163,6 @@
     visibility: ["//visibility:private"],
 }
 
-
-// Shims for APIs being added to the current development version of Android. These APIs are not
-// stable and have no defined version number. These could be called 10000, but they use the next
-// integer so if the next SDK release happens to use that integer, we don't need to rename them.
 java_library {
     name: "NetworkStackApi33Shims",
     defaults: ["NetworkStackShimsDefaults", "ConnectivityNextEnableDefaults"],
@@ -185,6 +183,34 @@
         "framework-tethering",
         "android.net.ipsec.ike.stubs.module_lib",
     ],
+    sdk_version: module_33_version,
+    visibility: ["//visibility:private"],
+}
+
+// Shims for APIs being added to the current development version of Android. These APIs are not
+// stable and have no defined version number. These could be called 10000, but they use the next
+// integer so if the next SDK release happens to use that integer, we don't need to rename them.
+java_library {
+    name: "NetworkStackApi34Shims",
+    defaults: ["NetworkStackShimsDefaults", "ConnectivityNextEnableDefaults"],
+    srcs: [
+        "apishim/34/**/*.java",
+    ],
+    static_libs: [
+        "net-utils-framework-common",
+    ],
+    libs: [
+        "NetworkStackShimsCommon",
+        "NetworkStackApi29Shims",
+        "NetworkStackApi30Shims",
+        "NetworkStackApi31Shims",
+        "NetworkStackApi33Shims",
+        "framework-bluetooth",
+        "framework-connectivity",
+        "framework-connectivity-t.stubs.module_lib",
+        "framework-tethering",
+        "android.net.ipsec.ike.stubs.module_lib",
+    ],
     sdk_version: "module_current",
     visibility: ["//visibility:private"],
 }
@@ -194,15 +220,19 @@
 // called directly by the networkstack code.
 java_library {
     name: "NetworkStackApiCurrentShims",
-    defaults: ["NetworkStackShimsDefaults", "ConnectivityNextEnableDefaults"],
+    defaults: [
+        "NetworkStackShimsDefaults",
+        "NetworkStackDevApiLevel",
+        "ConnectivityNextEnableDefaults",
+    ],
     static_libs: [
         "NetworkStackShimsCommon",
         "NetworkStackApi29Shims",
         "NetworkStackApi30Shims",
         "NetworkStackApi31Shims",
         "NetworkStackApi33Shims",
+        "NetworkStackApi34Shims",
     ],
-    sdk_version: "module_current",
     visibility: [
         "//packages/modules/Connectivity/Tethering",
         "//packages/modules/Connectivity/service",
@@ -217,15 +247,15 @@
 // the networkstack code.
 java_library {
     name: "NetworkStackApiStableShims",
-    defaults: ["NetworkStackShimsDefaults"],
+    defaults: ["NetworkStackShimsDefaults", "NetworkStackReleaseApiLevel"],
     static_libs: [
         "NetworkStackShimsCommon",
         "NetworkStackApi29Shims",
         "NetworkStackApi30Shims",
         "NetworkStackApi31Shims",
+        "NetworkStackApi33Shims",
     ],
     jarjar_rules: "apishim/jarjar-rules-compat.txt",
-    sdk_version: "module_31",
     visibility: [
         "//packages/modules/Connectivity/Tethering",
         "//packages/modules/Connectivity/service",
@@ -347,11 +377,9 @@
     manifest: "AndroidManifest_InProcess.xml",
     // InProcessNetworkStack is a replacement for NetworkStack
     overrides: ["NetworkStack", "NetworkStackNext"],
-    // The permission configuration *must* be included to ensure security of the device
     // The InProcessNetworkStack goes together with the PlatformCaptivePortalLogin, which replaces
     // the default CaptivePortalLogin.
     required: [
-        "PlatformNetworkPermissionConfig",
         "PlatformCaptivePortalLogin",
     ],
 }
@@ -379,9 +407,7 @@
     static_libs: ["NetworkStackNextManifestBase"],
     certificate: "networkstack",
     manifest: "AndroidManifest_Next.xml",
-    // The permission configuration *must* be included to ensure security of the device
     required: [
-        "NetworkPermissionConfig",
         "privapp_whitelist_com.android.networkstack",
     ],
     lint: { strict_updatability_linting: true },
@@ -394,9 +420,7 @@
     static_libs: ["NetworkStackApiStableLib"],
     certificate: "networkstack",
     manifest: "AndroidManifest.xml",
-    // The permission configuration *must* be included to ensure security of the device
     required: [
-        "NetworkPermissionConfig",
         "privapp_whitelist_com.android.networkstack",
     ],
     updatable: true,
@@ -475,9 +499,7 @@
     static_libs: ["NetworkStackApiStableLib"],
     certificate: "networkstack",
     manifest: ":NetworkStackTestAndroidManifest",
-    // The permission configuration *must* be included to ensure security of the device
     required: [
-        "NetworkPermissionConfig",
         "privapp_whitelist_com.android.networkstack",
     ],
 }
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8750795..ad6c2b5 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -23,6 +23,9 @@
   android:versionName="s_aml_319999900"
   coreApp="true"
 >
+    <!--- Defines the MAINLINE_NETWORK_STACK permission used by the networkstack process. -->
+    <permission android:name="android.permission.MAINLINE_NETWORK_STACK"
+                android:protectionLevel="signature"/>
     <!-- Permissions must be defined here, and not in the base manifest, as the network stack
          running in the system server process does not need any permission, and having privileged
          permissions added would cause crashes on startup unless they are also added to the
diff --git a/AndroidManifest_InProcess.xml b/AndroidManifest_InProcess.xml
index 6c64d87..7934826 100644
--- a/AndroidManifest_InProcess.xml
+++ b/AndroidManifest_InProcess.xml
@@ -21,6 +21,9 @@
           android:sharedUserId="android.uid.system"
           android:process="system"
           coreApp="true">
+    <!--- Defines the MAINLINE_NETWORK_STACK permission used by the networkstack process. -->
+    <permission android:name="android.permission.MAINLINE_NETWORK_STACK"
+                android:protectionLevel="signature"/>
     <application>
         <service android:name="com.android.server.NetworkStackService"
                  android:process="system"
diff --git a/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java b/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java
index 7159cea..0dcd0db 100644
--- a/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java
+++ b/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java
@@ -40,6 +40,8 @@
     public static final int VPN_PROFILE_STATE_CONNECTING = 1;
     public static final int VPN_PROFILE_STATE_CONNECTED = 2;
 
+    public static final String ACTION_VPN_MANAGER_EVENT = "android.net.action.VPN_MANAGER_EVENT";
+
     // Constants defined in android.net.ConnectivityDiagnosticsManager.
     public static final int DETECTION_METHOD_DNS_EVENTS = 1;
     public static final int DETECTION_METHOD_TCP_METRICS = 2;
diff --git a/apishim/33/com/android/networkstack/apishim/BluetoothPanShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/BluetoothPanShimImpl.java
similarity index 97%
rename from apishim/33/com/android/networkstack/apishim/BluetoothPanShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/BluetoothPanShimImpl.java
index 990a312..09a3573 100644
--- a/apishim/33/com/android/networkstack/apishim/BluetoothPanShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/BluetoothPanShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
 
diff --git a/apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/CaptivePortalDataShimImpl.java
similarity index 96%
rename from apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/CaptivePortalDataShimImpl.java
index 63fa021..7a4dbba 100644
--- a/apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/CaptivePortalDataShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.net.CaptivePortalData;
 import android.os.Build;
diff --git a/apishim/33/com/android/networkstack/apishim/ConnectivityFrameworkInitShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/ConnectivityFrameworkInitShimImpl.java
similarity index 96%
rename from apishim/33/com/android/networkstack/apishim/ConnectivityFrameworkInitShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/ConnectivityFrameworkInitShimImpl.java
index 2fc4ca1..a97e717 100644
--- a/apishim/33/com/android/networkstack/apishim/ConnectivityFrameworkInitShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/ConnectivityFrameworkInitShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.net.ConnectivityFrameworkInitializerTiramisu;
 import android.os.Build;
diff --git a/apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/ConnectivityManagerShimImpl.java
similarity index 95%
rename from apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/ConnectivityManagerShimImpl.java
index 7675960..1cb36ae 100644
--- a/apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/ConnectivityManagerShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.content.Context;
 import android.os.Build;
diff --git a/apishim/33/com/android/networkstack/apishim/ConstantsShim.java b/apishim/33/com/android/networkstack/apishim/api33/ConstantsShim.java
similarity index 95%
rename from apishim/33/com/android/networkstack/apishim/ConstantsShim.java
rename to apishim/33/com/android/networkstack/apishim/api33/ConstantsShim.java
index 6d146f5..227b60c 100644
--- a/apishim/33/com/android/networkstack/apishim/ConstantsShim.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/ConstantsShim.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import androidx.annotation.VisibleForTesting;
 
diff --git a/apishim/33/com/android/networkstack/apishim/EthernetManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/EthernetManagerShimImpl.java
similarity index 98%
rename from apishim/33/com/android/networkstack/apishim/EthernetManagerShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/EthernetManagerShimImpl.java
index 82a8f35..5bd6487 100644
--- a/apishim/33/com/android/networkstack/apishim/EthernetManagerShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/EthernetManagerShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
 
diff --git a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/Ikev2VpnProfileBuilderShimImpl.java
similarity index 96%
rename from apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/Ikev2VpnProfileBuilderShimImpl.java
index 634b6b5..f8c92ee 100644
--- a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/Ikev2VpnProfileBuilderShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.net.Ikev2VpnProfile;
 import android.net.ipsec.ike.IkeTunnelConnectionParams;
@@ -32,7 +32,7 @@
 @RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class Ikev2VpnProfileBuilderShimImpl
         extends com.android.networkstack.apishim.api31.Ikev2VpnProfileBuilderShimImpl {
-    private Ikev2VpnProfileBuilderShimImpl(@Nullable String serverAddr,
+    protected Ikev2VpnProfileBuilderShimImpl(@Nullable String serverAddr,
             @Nullable String identity, @Nullable Object params) {
         super(serverAddr, identity, params);
 
diff --git a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/Ikev2VpnProfileShimImpl.java
similarity index 96%
rename from apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/Ikev2VpnProfileShimImpl.java
index c3e35d3..e846a64 100644
--- a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/Ikev2VpnProfileShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.net.Ikev2VpnProfile;
 import android.os.Build;
diff --git a/apishim/33/com/android/networkstack/apishim/NetworkAgentConfigShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/NetworkAgentConfigShimImpl.java
similarity index 97%
rename from apishim/33/com/android/networkstack/apishim/NetworkAgentConfigShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/NetworkAgentConfigShimImpl.java
index 912b721..ee7f026 100644
--- a/apishim/33/com/android/networkstack/apishim/NetworkAgentConfigShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/NetworkAgentConfigShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
 
diff --git a/apishim/33/com/android/networkstack/apishim/NetworkInformationShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/NetworkInformationShimImpl.java
similarity index 97%
rename from apishim/33/com/android/networkstack/apishim/NetworkInformationShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/NetworkInformationShimImpl.java
index 46ba098..5d6ada1 100644
--- a/apishim/33/com/android/networkstack/apishim/NetworkInformationShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/NetworkInformationShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
 
diff --git a/apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/NetworkRequestShimImpl.java
similarity index 95%
rename from apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/NetworkRequestShimImpl.java
index 72dfef2..a73d6a1 100644
--- a/apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/NetworkRequestShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.os.Build;
 
diff --git a/apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/NetworkShimImpl.java
similarity index 95%
rename from apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/NetworkShimImpl.java
index 0968c4c..d084c01 100644
--- a/apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/NetworkShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.net.Network;
 import android.os.Build;
diff --git a/apishim/33/com/android/networkstack/apishim/NsdShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/NsdShimImpl.java
similarity index 98%
rename from apishim/33/com/android/networkstack/apishim/NsdShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/NsdShimImpl.java
index 2f13397..1f0907f 100644
--- a/apishim/33/com/android/networkstack/apishim/NsdShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/NsdShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.net.Network;
 import android.net.NetworkRequest;
diff --git a/apishim/33/com/android/networkstack/apishim/ProcessShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/ProcessShimImpl.java
similarity index 96%
rename from apishim/33/com/android/networkstack/apishim/ProcessShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/ProcessShimImpl.java
index 882dfbf..a6c282e 100644
--- a/apishim/33/com/android/networkstack/apishim/ProcessShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/ProcessShimImpl.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.os.Build;
 import android.os.Process;
diff --git a/apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/SettingsShimImpl.java
similarity index 95%
rename from apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/SettingsShimImpl.java
index cd3a463..113b013 100644
--- a/apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/SettingsShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.os.Build;
 
diff --git a/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/SocketUtilsShimImpl.java
similarity index 95%
rename from apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/SocketUtilsShimImpl.java
index d4ab534..1da7ea2 100644
--- a/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/SocketUtilsShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.os.Build;
 
diff --git a/apishim/33/com/android/networkstack/apishim/TelephonyManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/TelephonyManagerShimImpl.java
similarity index 98%
rename from apishim/33/com/android/networkstack/apishim/TelephonyManagerShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/TelephonyManagerShimImpl.java
index af481b6..473db91 100644
--- a/apishim/33/com/android/networkstack/apishim/TelephonyManagerShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/TelephonyManagerShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
 import static com.android.net.module.util.CollectionUtils.toIntArray;
diff --git a/apishim/33/com/android/networkstack/apishim/VpnManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/VpnManagerShimImpl.java
similarity index 97%
rename from apishim/33/com/android/networkstack/apishim/VpnManagerShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/VpnManagerShimImpl.java
index ffd3da3..37a58df 100644
--- a/apishim/33/com/android/networkstack/apishim/VpnManagerShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/VpnManagerShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
 
diff --git a/apishim/33/com/android/networkstack/apishim/VpnProfileStateShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/VpnProfileStateShimImpl.java
similarity index 97%
rename from apishim/33/com/android/networkstack/apishim/VpnProfileStateShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/VpnProfileStateShimImpl.java
index 7c61b02..4521364 100644
--- a/apishim/33/com/android/networkstack/apishim/VpnProfileStateShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/VpnProfileStateShimImpl.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.net.VpnProfileState;
 import android.os.Build;
diff --git a/apishim/33/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/VpnServiceBuilderShimImpl.java
similarity index 97%
rename from apishim/33/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/api33/VpnServiceBuilderShimImpl.java
index da8f774..464da3c 100644
--- a/apishim/33/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/api33/VpnServiceBuilderShimImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+package com.android.networkstack.apishim.api33;
 
 import android.net.IpPrefix;
 import android.net.VpnService;
diff --git a/apishim/34/com/android/networkstack/apishim/BluetoothPanShimImpl.java b/apishim/34/com/android/networkstack/apishim/BluetoothPanShimImpl.java
new file mode 100644
index 0000000..94c3d38
--- /dev/null
+++ b/apishim/34/com/android/networkstack/apishim/BluetoothPanShimImpl.java
@@ -0,0 +1,35 @@
+/*
+ * 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.bluetooth.BluetoothPan;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+/**
+ * Implementation of {@link BluetoothPanShimImpl} 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 BluetoothPanShimImpl extends
+        com.android.networkstack.apishim.api33.BluetoothPanShimImpl {
+    // Currently identical to the API 33 shim, so inherit everything
+    protected BluetoothPanShimImpl(BluetoothPan pan) {
+        super(pan);
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java b/apishim/34/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
similarity index 76%
copy from apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
copy to apishim/34/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
index 63fa021..94814aa 100644
--- a/apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
+++ b/apishim/34/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -27,10 +27,11 @@
 /**
  * Compatibility implementation of {@link CaptivePortalDataShim}.
  */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
 public class CaptivePortalDataShimImpl
-        extends com.android.networkstack.apishim.api31.CaptivePortalDataShimImpl {
-    // Currently identical to the API 31 shim, so inherit everything
+        extends com.android.networkstack.apishim.api33.CaptivePortalDataShimImpl {
+    // Currently identical to the API 33 shim, so inherit everything
     public CaptivePortalDataShimImpl(@NonNull CaptivePortalData data) {
         super(data);
     }
diff --git a/apishim/34/com/android/networkstack/apishim/ConnectivityFrameworkInitShimImpl.java b/apishim/34/com/android/networkstack/apishim/ConnectivityFrameworkInitShimImpl.java
new file mode 100644
index 0000000..a343b67
--- /dev/null
+++ b/apishim/34/com/android/networkstack/apishim/ConnectivityFrameworkInitShimImpl.java
@@ -0,0 +1,34 @@
+/*
+ * 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.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.ConnectivityFrameworkInitShim;
+
+/**
+ * Implementation of {@link ConnectivityFrameworkInitShim}.
+ */
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
+public class ConnectivityFrameworkInitShimImpl extends
+        com.android.networkstack.apishim.api33.ConnectivityFrameworkInitShimImpl {
+    // Currently identical to the API 33 shim, so inherit everything
+    protected ConnectivityFrameworkInitShimImpl() {}
+}
diff --git a/apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java b/apishim/34/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
similarity index 75%
copy from apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
copy to apishim/34/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
index 7675960..7f6ad39 100644
--- a/apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
+++ b/apishim/34/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -26,10 +26,11 @@
 /**
  * Compatibility implementation of {@link ConnectivityManagerShim}.
  */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
 public class ConnectivityManagerShimImpl
-        extends com.android.networkstack.apishim.api31.ConnectivityManagerShimImpl  {
-    // Currently identical to the API 31 shim, so inherit everything
+        extends com.android.networkstack.apishim.api33.ConnectivityManagerShimImpl  {
+    // Currently identical to the API 33 shim, so inherit everything
     protected ConnectivityManagerShimImpl(Context context) {
         super(context);
     }
diff --git a/apishim/33/com/android/networkstack/apishim/ConstantsShim.java b/apishim/34/com/android/networkstack/apishim/ConstantsShim.java
similarity index 77%
copy from apishim/33/com/android/networkstack/apishim/ConstantsShim.java
copy to apishim/34/com/android/networkstack/apishim/ConstantsShim.java
index 6d146f5..9df84d5 100644
--- a/apishim/33/com/android/networkstack/apishim/ConstantsShim.java
+++ b/apishim/34/com/android/networkstack/apishim/ConstantsShim.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -16,12 +16,17 @@
 
 package com.android.networkstack.apishim;
 
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
 import androidx.annotation.VisibleForTesting;
 
 /**
  * Utility class for defining and importing constants from the Android platform.
  */
-public class ConstantsShim extends com.android.networkstack.apishim.api31.ConstantsShim {
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
+public class ConstantsShim extends com.android.networkstack.apishim.api33.ConstantsShim {
     /**
      * Constant that callers can use to determine what version of the shim they are using.
      * Must be the same as the version of the shims.
@@ -29,5 +34,5 @@
      * the shimmed objects and methods themselves.
      */
     @VisibleForTesting
-    public static final int VERSION = 33;
+    public static final int VERSION = 34;
 }
diff --git a/apishim/34/com/android/networkstack/apishim/EthernetManagerShimImpl.java b/apishim/34/com/android/networkstack/apishim/EthernetManagerShimImpl.java
new file mode 100644
index 0000000..e9a33a1
--- /dev/null
+++ b/apishim/34/com/android/networkstack/apishim/EthernetManagerShimImpl.java
@@ -0,0 +1,36 @@
+/*
+ * 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/34/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java b/apishim/34/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java
new file mode 100644
index 0000000..305f469
--- /dev/null
+++ b/apishim/34/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java
@@ -0,0 +1,35 @@
+/*
+ * 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.os.Build;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
+/**
+ * A shim for Ikev2VpnProfile.Builder
+ */
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
+public class Ikev2VpnProfileBuilderShimImpl
+        extends com.android.networkstack.apishim.api33.Ikev2VpnProfileBuilderShimImpl {
+    protected Ikev2VpnProfileBuilderShimImpl(@Nullable String serverAddr,
+            @Nullable String identity, @Nullable Object params) {
+        super(serverAddr, identity, params);
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java b/apishim/34/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
similarity index 65%
copy from apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
copy to apishim/34/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
index c3e35d3..c6c3ac9 100644
--- a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
+++ b/apishim/34/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
@@ -24,26 +24,11 @@
 /**
  * A shim for Ikev2VpnProfile
  */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
 public class Ikev2VpnProfileShimImpl
-        extends com.android.networkstack.apishim.api31.Ikev2VpnProfileShimImpl {
+        extends com.android.networkstack.apishim.api33.Ikev2VpnProfileShimImpl {
     public Ikev2VpnProfileShimImpl(Ikev2VpnProfile profile) {
        super(profile);
     }
-
-    /**
-     * @see Ikev2VpnProfile#isInternetValidationRequired()
-     */
-    @Override
-    public boolean isInternetValidationRequired() {
-        return mProfile.isInternetValidationRequired();
-    }
-
-    /**
-     * @see Ikev2VpnProfile#getIkeTunnelConnectionParams()
-     */
-    @Override
-    public Object getIkeTunnelConnectionParams() {
-        return mProfile.getIkeTunnelConnectionParams();
-    }
 }
diff --git a/apishim/34/com/android/networkstack/apishim/NetworkAgentConfigShimImpl.java b/apishim/34/com/android/networkstack/apishim/NetworkAgentConfigShimImpl.java
new file mode 100644
index 0000000..4d8ede2
--- /dev/null
+++ b/apishim/34/com/android/networkstack/apishim/NetworkAgentConfigShimImpl.java
@@ -0,0 +1,35 @@
+/*
+ * 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.net.NetworkAgentConfig;
+import android.os.Build;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
+/**
+ * A shim for NetworkAgentConfig
+ */
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
+public class NetworkAgentConfigShimImpl
+        extends com.android.networkstack.apishim.api33.NetworkAgentConfigShimImpl {
+    protected NetworkAgentConfigShimImpl(@Nullable final NetworkAgentConfig config) {
+        super(config);
+    }
+}
diff --git a/apishim/34/com/android/networkstack/apishim/NetworkInformationShimImpl.java b/apishim/34/com/android/networkstack/apishim/NetworkInformationShimImpl.java
new file mode 100644
index 0000000..b8905e8
--- /dev/null
+++ b/apishim/34/com/android/networkstack/apishim/NetworkInformationShimImpl.java
@@ -0,0 +1,33 @@
+/*
+ * 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.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.NetworkInformationShim;
+
+/**
+ * Compatibility implementation of {@link NetworkInformationShim}.
+ */
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
+public class NetworkInformationShimImpl
+        extends com.android.networkstack.apishim.api33.NetworkInformationShimImpl {
+    protected NetworkInformationShimImpl() {}
+}
diff --git a/apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java b/apishim/34/com/android/networkstack/apishim/NetworkRequestShimImpl.java
similarity index 69%
copy from apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java
copy to apishim/34/com/android/networkstack/apishim/NetworkRequestShimImpl.java
index 72dfef2..61c9d09 100644
--- a/apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java
+++ b/apishim/34/com/android/networkstack/apishim/NetworkRequestShimImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -23,12 +23,13 @@
 import com.android.networkstack.apishim.common.NetworkRequestShim;
 
 /**
- * Implementation of {@link NetworkRequestShim} for API 33.
+ * Implementation of {@link NetworkRequestShim} for API 34.
  */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
 public class NetworkRequestShimImpl
-        extends com.android.networkstack.apishim.api31.NetworkRequestShimImpl {
-    // Currently identical to the API 31 shim, so inherit everything
+        extends com.android.networkstack.apishim.api33.NetworkRequestShimImpl {
+    // Currently identical to the API 33 shim, so inherit everything
     protected NetworkRequestShimImpl() {
         super();
     }
diff --git a/apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java b/apishim/34/com/android/networkstack/apishim/NetworkShimImpl.java
similarity index 77%
copy from apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java
copy to apishim/34/com/android/networkstack/apishim/NetworkShimImpl.java
index 0968c4c..683d1eb 100644
--- a/apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java
+++ b/apishim/34/com/android/networkstack/apishim/NetworkShimImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -25,9 +25,10 @@
 /**
  * Compatibility implementation of {@link com.android.networkstack.apishim.common.NetworkShim}.
  */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
-public class NetworkShimImpl extends com.android.networkstack.apishim.api30.NetworkShimImpl {
-    // Currently, this is the same as the API 31 shim, so inherit everything from that.
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
+public class NetworkShimImpl extends com.android.networkstack.apishim.api33.NetworkShimImpl {
+    // Currently, this is the same as the API 33 shim, so inherit everything from that.
     protected NetworkShimImpl(@NonNull Network network) {
         super(network);
     }
diff --git a/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java b/apishim/34/com/android/networkstack/apishim/NsdShimImpl.java
similarity index 61%
copy from apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
copy to apishim/34/com/android/networkstack/apishim/NsdShimImpl.java
index d4ab534..c7b2b7a 100644
--- a/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
+++ b/apishim/34/com/android/networkstack/apishim/NsdShimImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -20,12 +20,13 @@
 
 import androidx.annotation.RequiresApi;
 
+import com.android.networkstack.apishim.common.NsdShim;
+
 /**
- * Implementation of {@link com.android.networkstack.apishim.common.SocketUtilsShim}.
+ * Implementation of {@link NsdShim}.
  */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
-public class SocketUtilsShimImpl
-        extends com.android.networkstack.apishim.api30.SocketUtilsShimImpl {
-    // Currently, this is the same as the API 31 shim, so inherit everything from that.
-    protected SocketUtilsShimImpl() {}
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
+public class NsdShimImpl extends com.android.networkstack.apishim.api33.NsdShimImpl {
+    protected NsdShimImpl() {}
 }
diff --git a/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java b/apishim/34/com/android/networkstack/apishim/ProcessShimImpl.java
similarity index 60%
copy from apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
copy to apishim/34/com/android/networkstack/apishim/ProcessShimImpl.java
index d4ab534..460ed46 100644
--- a/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
+++ b/apishim/34/com/android/networkstack/apishim/ProcessShimImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -13,19 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.android.networkstack.apishim;
 
 import android.os.Build;
 
 import androidx.annotation.RequiresApi;
 
-/**
- * Implementation of {@link com.android.networkstack.apishim.common.SocketUtilsShim}.
- */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
-public class SocketUtilsShimImpl
-        extends com.android.networkstack.apishim.api30.SocketUtilsShimImpl {
-    // Currently, this is the same as the API 31 shim, so inherit everything from that.
-    protected SocketUtilsShimImpl() {}
+import com.android.networkstack.apishim.common.ProcessShim;
+
+/** Implementation of {@link ProcessShim} 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 ProcessShimImpl extends com.android.networkstack.apishim.api33.ProcessShimImpl {
+    protected ProcessShimImpl() {}
 }
diff --git a/apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java b/apishim/34/com/android/networkstack/apishim/SettingsShimImpl.java
similarity index 72%
copy from apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java
copy to apishim/34/com/android/networkstack/apishim/SettingsShimImpl.java
index cd3a463..aa12005 100644
--- a/apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java
+++ b/apishim/34/com/android/networkstack/apishim/SettingsShimImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -23,11 +23,12 @@
 import com.android.networkstack.apishim.common.SettingsShim;
 
 /**
- * Compatibility implementation of {@link SettingsShim} for API 33.
+ * Compatibility implementation of {@link SettingsShim} for API 34.
  */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
 public class SettingsShimImpl
-        extends com.android.networkstack.apishim.api30.SettingsShimImpl {
-    // Currently identical to the API 31 shim, so inherit everything
+        extends com.android.networkstack.apishim.api33.SettingsShimImpl {
+    // Currently identical to the API 33 shim, so inherit everything
     protected SettingsShimImpl() { }
 }
diff --git a/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java b/apishim/34/com/android/networkstack/apishim/SocketUtilsShimImpl.java
similarity index 72%
copy from apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
copy to apishim/34/com/android/networkstack/apishim/SocketUtilsShimImpl.java
index d4ab534..ca7b64c 100644
--- a/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
+++ b/apishim/34/com/android/networkstack/apishim/SocketUtilsShimImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -23,9 +23,10 @@
 /**
  * Implementation of {@link com.android.networkstack.apishim.common.SocketUtilsShim}.
  */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
 public class SocketUtilsShimImpl
-        extends com.android.networkstack.apishim.api30.SocketUtilsShimImpl {
-    // Currently, this is the same as the API 31 shim, so inherit everything from that.
+        extends com.android.networkstack.apishim.api33.SocketUtilsShimImpl {
+    // Currently, this is the same as the API 33 shim, so inherit everything from that.
     protected SocketUtilsShimImpl() {}
 }
diff --git a/apishim/34/com/android/networkstack/apishim/TelephonyManagerShimImpl.java b/apishim/34/com/android/networkstack/apishim/TelephonyManagerShimImpl.java
new file mode 100644
index 0000000..ed81f52
--- /dev/null
+++ b/apishim/34/com/android/networkstack/apishim/TelephonyManagerShimImpl.java
@@ -0,0 +1,36 @@
+/*
+ * 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.os.Build;
+import android.telephony.TelephonyManager;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.TelephonyManagerShim;
+
+/**
+ * Implementation of {@link TelephonyManagerShim} 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 TelephonyManagerShimImpl extends
+        com.android.networkstack.apishim.api33.TelephonyManagerShimImpl {
+    protected TelephonyManagerShimImpl(TelephonyManager telephonyManager) {
+        super(telephonyManager);
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java b/apishim/34/com/android/networkstack/apishim/VpnManagerShimImpl.java
similarity index 60%
copy from apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
copy to apishim/34/com/android/networkstack/apishim/VpnManagerShimImpl.java
index 7675960..d7f6280 100644
--- a/apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
+++ b/apishim/34/com/android/networkstack/apishim/VpnManagerShimImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -21,16 +21,15 @@
 
 import androidx.annotation.RequiresApi;
 
-import com.android.networkstack.apishim.common.ConnectivityManagerShim;
+import com.android.networkstack.apishim.common.VpnManagerShim;
 
 /**
- * Compatibility implementation of {@link ConnectivityManagerShim}.
+ * Compatibility implementation of {@link VpnManagerShim}.
  */
-@RequiresApi(Build.VERSION_CODES.TIRAMISU)
-public class ConnectivityManagerShimImpl
-        extends com.android.networkstack.apishim.api31.ConnectivityManagerShimImpl  {
-    // Currently identical to the API 31 shim, so inherit everything
-    protected ConnectivityManagerShimImpl(Context context) {
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
+public class VpnManagerShimImpl extends com.android.networkstack.apishim.api33.VpnManagerShimImpl {
+    protected VpnManagerShimImpl(Context context) {
         super(context);
     }
 }
diff --git a/apishim/34/com/android/networkstack/apishim/VpnProfileStateShimImpl.java b/apishim/34/com/android/networkstack/apishim/VpnProfileStateShimImpl.java
new file mode 100644
index 0000000..23f346d
--- /dev/null
+++ b/apishim/34/com/android/networkstack/apishim/VpnProfileStateShimImpl.java
@@ -0,0 +1,34 @@
+/*
+ * 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.net.VpnProfileState;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.VpnProfileStateShim;
+
+/** Implementation of {@link VpnProfileStateShim} 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 VpnProfileStateShimImpl
+        extends com.android.networkstack.apishim.api33.VpnProfileStateShimImpl {
+    protected VpnProfileStateShimImpl(@NonNull VpnProfileState profileState) {
+        super(profileState);
+    }
+}
diff --git a/apishim/34/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java b/apishim/34/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java
new file mode 100644
index 0000000..b78a77b
--- /dev/null
+++ b/apishim/34/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java
@@ -0,0 +1,33 @@
+/*
+ * 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.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.VpnServiceBuilderShim;
+
+/**
+ * Implementation of {@link VpnServiceBuilderShim}.
+ */
+// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
+public class VpnServiceBuilderShimImpl extends
+        com.android.networkstack.apishim.api33.VpnServiceBuilderShimImpl {
+    protected VpnServiceBuilderShimImpl() {}
+}
diff --git a/apishim/jarjar-rules-compat.txt b/apishim/jarjar-rules-compat.txt
index 4f34ccb..09fa04d 100644
--- a/apishim/jarjar-rules-compat.txt
+++ b/apishim/jarjar-rules-compat.txt
@@ -1,7 +1,7 @@
 # jarjar rules to use on API stable builds.
 # Use the latest stable apishim package as the main apishim package, to replace and avoid building
 # the unstable, non-compatibility shims.
-# Once API 32 is stable, apishim/32/com.android.networkstack.apishim should be moved to the
-# com.android.networkstack.apishim.api32 package, a new apishim/33/com.android.networkstack.apishim
-# package should be created, and this rule should reference api32.
-rule com.android.networkstack.apishim.api31.** com.android.networkstack.apishim.@1
\ No newline at end of file
+# Once API 34 is stable, apishim/34/com.android.networkstack.apishim should be moved to the
+# com.android.networkstack.apishim.api34 package, a new apishim/34/com.android.networkstack.apishim
+# package should be created, and this rule should reference api34.
+rule com.android.networkstack.apishim.api33.** com.android.networkstack.apishim.@1
\ No newline at end of file
diff --git a/res/values-mcc460/config.xml b/res/values-mcc460/config.xml
index 2863edd..3c4b493 100644
--- a/res/values-mcc460/config.xml
+++ b/res/values-mcc460/config.xml
@@ -5,13 +5,20 @@
          general case as this could degrade the user experience (portals not detected properly).
          However in China the default URLs are not accessible in general. The below alternatives
          should allow users to connect to local networks normally. -->
+    <!-- default_captive_portal_http_url is not configured as overlayable so
+         OEMs that wish to change captive_portal_http_url configuration must
+         do so via configuring runtime resource overlay to
+         config_captive_portal_http_url and *NOT* by changing or overlaying
+         this resource. It will break if the enforcement of overlayable starts.
+         -->
+    <string name="default_captive_portal_http_url" translatable="false">http://connectivitycheck.gstatic.cn/generate_204</string>
     <!-- default_captive_portal_https_url is not configured as overlayable so
          OEMs that wish to change captive_portal_https_url configuration must
          do so via configuring runtime resource overlay to
          config_captive_portal_https_url and *NOT* by changing or overlaying
          this resource. It will break if the enforcement of overlayable starts.
          -->
-    <string name="default_captive_portal_https_url" translatable="false">https://connectivitycheck.gstatic.com/generate_204</string>
+    <string name="default_captive_portal_https_url" translatable="false">https://connectivitycheck.gstatic.cn/generate_204</string>
     <!-- default_captive_portal_fallback_urls is not configured as overlayable
          so OEMs that wish to change captive_portal_fallback_urls configuration
          must do so via configuring runtime resource overlay to
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 3ed6c0c..4ada67f 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -493,10 +493,6 @@
     private static final boolean NO_CALLBACKS = false;
     private static final boolean SEND_CALLBACKS = true;
 
-    // This must match the interface prefix in clatd.c.
-    // TODO: Revert this hack once IpClient and Nat464Xlat work in concert.
-    private static final String CLAT_PREFIX = "v4-";
-
     private static final int IMMEDIATE_FAILURE_DURATION = 0;
 
     private static final int PROV_CHANGE_STILL_NOT_PROVISIONED = 1;
@@ -544,7 +540,6 @@
     private final String mTag;
     private final Context mContext;
     private final String mInterfaceName;
-    private final String mClatInterfaceName;
     @VisibleForTesting
     protected final IpClientCallbacksWrapper mCallback;
     private final Dependencies mDependencies;
@@ -712,7 +707,6 @@
 
         mContext = context;
         mInterfaceName = ifName;
-        mClatInterfaceName = CLAT_PREFIX + ifName;
         mDependencies = deps;
         mMetricsLog = deps.getIpConnectivityLog();
         mNetworkQuirkMetrics = deps.getNetworkQuirkMetrics();
@@ -762,44 +756,19 @@
                             updateGratuitousNaTargetSet(targetIp, false /* remove address */);
                         });
                     }
+
+                    @Override
+                    public void onClatInterfaceStateUpdate(boolean add) {
+                        // TODO: when clat interface was removed, consider sending a message to
+                        // the IpClient main StateMachine thread, in case "NDO enabled" state
+                        // becomes tied to more things that 464xlat operation.
+                        getHandler().post(() -> {
+                            mCallback.setNeighborDiscoveryOffload(add ? false : true);
+                        });
+                    }
                 },
-                config, mLog, mDependencies) {
-            @Override
-            public void onInterfaceAdded(String iface) {
-                super.onInterfaceAdded(iface);
-                if (mClatInterfaceName.equals(iface)) {
-                    mCallback.setNeighborDiscoveryOffload(false);
-                } else if (!mInterfaceName.equals(iface)) {
-                    return;
-                }
-
-                final String msg = "interfaceAdded(" + iface + ")";
-                logMsg(msg);
-            }
-
-            @Override
-            public void onInterfaceRemoved(String iface) {
-                super.onInterfaceRemoved(iface);
-                // TODO: Also observe mInterfaceName going down and take some
-                // kind of appropriate action.
-                if (mClatInterfaceName.equals(iface)) {
-                    // TODO: consider sending a message to the IpClient main
-                    // StateMachine thread, in case "NDO enabled" state becomes
-                    // tied to more things that 464xlat operation.
-                    mCallback.setNeighborDiscoveryOffload(true);
-                } else if (!mInterfaceName.equals(iface)) {
-                    return;
-                }
-
-                final String msg = "interfaceRemoved(" + iface + ")";
-                logMsg(msg);
-            }
-
-            private void logMsg(String msg) {
-                Log.d(mTag, msg);
-                getHandler().post(() -> mLog.log("OBSERVED " + msg));
-            }
-        };
+                config, mLog, mDependencies
+        );
 
         mLinkProperties = new LinkProperties();
         mLinkProperties.setInterfaceName(mInterfaceName);
diff --git a/src/android/net/ip/IpClientLinkObserver.java b/src/android/net/ip/IpClientLinkObserver.java
index 8a5ed2e..f0126e6 100644
--- a/src/android/net/ip/IpClientLinkObserver.java
+++ b/src/android/net/ip/IpClientLinkObserver.java
@@ -21,6 +21,7 @@
 import static android.system.OsConstants.AF_UNSPEC;
 import static android.system.OsConstants.IFF_LOOPBACK;
 
+import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
 import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
 import static com.android.net.module.util.netlink.NetlinkConstants.IFF_LOWER_UP;
 import static com.android.net.module.util.netlink.NetlinkConstants.RTM_F_CLONED;
@@ -42,6 +43,7 @@
 import android.util.Log;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.netlink.NduseroptMessage;
@@ -121,6 +123,14 @@
          * @param addr The removed IPv6 address.
          */
         void onIpv6AddressRemoved(Inet6Address addr);
+
+        /**
+         * Called when the clat interface was added/removed.
+         *
+         * @param add True: clat interface was added.
+         *            False: clat interface was removed.
+         */
+        void onClatInterfaceStateUpdate(boolean add);
     }
 
     /** Configuration parameters for IpClientLinkObserver. */
@@ -142,15 +152,21 @@
     private final Configuration mConfig;
     private final Handler mHandler;
     private final IpClient.Dependencies mDependencies;
-
+    private final String mClatInterfaceName;
     private final MyNetlinkMonitor mNetlinkMonitor;
 
+    private boolean mClatInterfaceExists;
+
+    // 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;
 
     public IpClientLinkObserver(Context context, Handler h, String iface, Callback callback,
             Configuration config, SharedLog log, IpClient.Dependencies deps) {
         mContext = context;
         mInterfaceName = iface;
+        mClatInterfaceName = CLAT_PREFIX + iface;
         mTag = "NetlinkTracker/" + mInterfaceName;
         mCallback = callback;
         mLinkProperties = new LinkProperties();
@@ -188,23 +204,26 @@
 
     private boolean isNetlinkEventParsingEnabled() {
         return mDependencies.isFeatureEnabled(mContext, IPCLIENT_PARSE_NETLINK_EVENTS_VERSION,
-                false /* default value */);
+                isAtLeastT() /* default value */);
+    }
+
+    @Override
+    public void onInterfaceAdded(String iface) {
+        if (isNetlinkEventParsingEnabled()) return;
+        maybeLog("interfaceAdded", iface);
+        if (mClatInterfaceName.equals(iface)) {
+            mCallback.onClatInterfaceStateUpdate(true /* add interface */);
+        }
     }
 
     @Override
     public void onInterfaceRemoved(String iface) {
+        if (isNetlinkEventParsingEnabled()) return;
         maybeLog("interfaceRemoved", iface);
-        if (mInterfaceName.equals(iface)) {
-            // Our interface was removed. Clear our LinkProperties and tell our owner that they are
-            // now empty. Note that from the moment that the interface is removed, any further
-            // interface-specific messages (e.g., RTM_DELADDR) will not reach us, because the netd
-            // code that parses them will not be able to resolve the ifindex to an interface name.
-            final boolean linkState;
-            synchronized (this) {
-                clearLinkProperties();
-                linkState = getInterfaceLinkStateLocked();
-            }
-            mCallback.update(linkState);
+        if (mClatInterfaceName.equals(iface)) {
+            mCallback.onClatInterfaceStateUpdate(false /* remove interface */);
+        } else if (mInterfaceName.equals(iface)) {
+            updateInterfaceRemoved();
         }
     }
 
@@ -308,6 +327,19 @@
         }
     }
 
+    private void updateInterfaceRemoved() {
+        // Our interface was removed. Clear our LinkProperties and tell our owner that they are
+        // now empty. Note that from the moment that the interface is removed, any further
+        // interface-specific messages (e.g., RTM_DELADDR) will not reach us, because the netd
+        // code that parses them will not be able to resolve the ifindex to an interface name.
+        final boolean linkState;
+        synchronized (this) {
+            clearLinkProperties();
+            linkState = getInterfaceLinkStateLocked();
+        }
+        mCallback.update(linkState);
+    }
+
     /**
      * Returns a copy of this object's LinkProperties.
      */
@@ -503,14 +535,45 @@
             }
         }
 
+        private void updateClatInterfaceLinkState(@NonNull final StructIfinfoMsg ifinfoMsg,
+                @Nullable final String ifname, short nlMsgType) {
+            switch (nlMsgType) {
+                case NetlinkConstants.RTM_NEWLINK:
+                    if (mClatInterfaceExists) break;
+                    maybeLog("clatInterfaceAdded", ifname);
+                    mCallback.onClatInterfaceStateUpdate(true /* add interface */);
+                    mClatInterfaceExists = true;
+                    break;
+
+                case NetlinkConstants.RTM_DELLINK:
+                    if (!mClatInterfaceExists) break;
+                    maybeLog("clatInterfaceRemoved", ifname);
+                    mCallback.onClatInterfaceStateUpdate(false /* remove interface */);
+                    mClatInterfaceExists = false;
+                    break;
+
+                default:
+                    Log.e(mTag, "unsupported rtnetlink link msg type " + nlMsgType);
+                    break;
+            }
+        }
+
         private void processRtNetlinkLinkMessage(RtNetlinkLinkMessage msg) {
             if (!isNetlinkEventParsingEnabled()) return;
 
+            // Check if receiving netlink link state update for clat interface.
+            final String ifname = msg.getInterfaceName();
+            final short nlMsgType = msg.getHeader().nlmsg_type;
             final StructIfinfoMsg ifinfoMsg = msg.getIfinfoHeader();
+            if (mClatInterfaceName.equals(ifname)) {
+                updateClatInterfaceLinkState(ifinfoMsg, ifname, nlMsgType);
+                return;
+            }
+
             if (ifinfoMsg.family != AF_UNSPEC || ifinfoMsg.index != mIfindex) return;
             if ((ifinfoMsg.flags & IFF_LOOPBACK) != 0) return;
 
-            switch (msg.getHeader().nlmsg_type) {
+            switch (nlMsgType) {
                 case NetlinkConstants.RTM_NEWLINK:
                     final boolean state = (ifinfoMsg.flags & IFF_LOWER_UP) != 0;
                     maybeLog("interfaceLinkStateChanged", "ifindex " + mIfindex
@@ -519,10 +582,12 @@
                     break;
 
                 case NetlinkConstants.RTM_DELLINK:
+                    maybeLog("interfaceRemoved", ifname);
+                    updateInterfaceRemoved();
                     break;
 
                 default:
-                    Log.e(mTag, "Unknown rtnetlink link msg type " + msg.getHeader().nlmsg_type);
+                    Log.e(mTag, "Unknown rtnetlink link msg type " + nlMsgType);
                     break;
             }
         }
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
index 36c6162..9984a54 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -34,6 +34,7 @@
 
 java_defaults {
     name: "NetworkStackIntegrationTestsDefaults",
+    defaults: ["framework-connectivity-test-defaults"],
     srcs: [
         "src/**/*.java",
         "src/**/*.kt",
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
index f423862..78d0bca 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
@@ -28,6 +28,7 @@
 import static android.net.dhcp.DhcpPacket.INFINITE_LEASE;
 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.IpReachabilityMonitor.MIN_NUD_SOLICIT_NUM;
 import static android.net.ip.IpReachabilityMonitor.NUD_MCAST_RESOLICIT_NUM;
 import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt;
@@ -670,6 +671,16 @@
         mHandler.post(() -> mPacketReader.start());
     }
 
+    private TestNetworkInterface setUpClatInterface(@NonNull String baseIface) throws Exception {
+        final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+        final TestNetworkInterface iface = runAsShell(MANAGE_TEST_NETWORKS, () -> {
+            final TestNetworkManager tnm =
+                    inst.getContext().getSystemService(TestNetworkManager.class);
+            return tnm.createTapInterface(false /* bringUp */, CLAT_PREFIX + baseIface);
+        });
+        return iface;
+    }
+
     private void teardownTapInterface() {
         if (mPacketReader != null) {
             mHandler.post(() -> mPacketReader.stop());  // Also closes the socket
@@ -1077,7 +1088,7 @@
         return getNextDhcpPacket();
     }
 
-    private void removeTapInterface(final FileDescriptor fd) {
+    private void removeTestInterface(final FileDescriptor fd) {
         try {
             Os.close(fd);
         } catch (ErrnoException e) {
@@ -1109,7 +1120,7 @@
     }
 
     private void doRestoreInitialMtuTest(final boolean shouldChangeMtu,
-            final boolean shouldRemoveTapInterface) throws Exception {
+            final boolean shouldRemoveTestInterface) throws Exception {
         final long currentTime = System.currentTimeMillis();
         int mtu = TEST_DEFAULT_MTU;
 
@@ -1132,11 +1143,11 @@
         // empty LinkProperties changes instead of one.
         reset(mCb);
 
-        if (shouldRemoveTapInterface) removeTapInterface(mTapFd);
+        if (shouldRemoveTestInterface) removeTestInterface(mTapFd);
         try {
             mIpc.shutdown();
             awaitIpClientShutdown();
-            if (shouldRemoveTapInterface) {
+            if (shouldRemoveTestInterface) {
                 verify(mNetd, never()).interfaceSetMtu(mIfaceName, TEST_DEFAULT_MTU);
             } else {
                 // Verify that MTU indeed has been restored or not.
@@ -1504,12 +1515,12 @@
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
     public void testRestoreInitialInterfaceMtu() throws Exception {
-        doRestoreInitialMtuTest(true /* shouldChangeMtu */, false /* shouldRemoveTapInterface */);
+        doRestoreInitialMtuTest(true /* shouldChangeMtu */, false /* shouldRemoveTestInterface */);
     }
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
     public void testRestoreInitialInterfaceMtu_WithoutMtuChange() throws Exception {
-        doRestoreInitialMtuTest(false /* shouldChangeMtu */, false /* shouldRemoveTapInterface */);
+        doRestoreInitialMtuTest(false /* shouldChangeMtu */, false /* shouldRemoveTestInterface */);
     }
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
@@ -1517,19 +1528,19 @@
         doThrow(new RemoteException("NetdNativeService::interfaceSetMtu")).when(mNetd)
                 .interfaceSetMtu(mIfaceName, TEST_DEFAULT_MTU);
 
-        doRestoreInitialMtuTest(true /* shouldChangeMtu */, false /* shouldRemoveTapInterface */);
+        doRestoreInitialMtuTest(true /* shouldChangeMtu */, false /* shouldRemoveTestInterface */);
         assertEquals(NetworkInterface.getByName(mIfaceName).getMTU(), TEST_MIN_MTU);
     }
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
     public void testRestoreInitialInterfaceMtu_NotFoundInterfaceWhenStopping() throws Exception {
-        doRestoreInitialMtuTest(true /* shouldChangeMtu */, true /* shouldRemoveTapInterface */);
+        doRestoreInitialMtuTest(true /* shouldChangeMtu */, true /* shouldRemoveTestInterface */);
     }
 
     @Test
     public void testRestoreInitialInterfaceMtu_NotFoundInterfaceWhenStartingProvisioning()
             throws Exception {
-        removeTapInterface(mTapFd);
+        removeTestInterface(mTapFd);
         ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
                 .withoutIpReachabilityMonitor()
                 .withoutIPv6()
@@ -1588,7 +1599,7 @@
 
         // Intend to remove the tap interface and force IpClient throw provisioning failure
         // due to that interface is not found.
-        removeTapInterface(mTapFd);
+        removeTestInterface(mTapFd);
         assertNull(InterfaceParams.getByName(mIfaceName));
 
         startIpClientProvisioning(config);
@@ -3752,4 +3763,25 @@
                         .build()
         );
     }
+
+    @Test
+    public void testIpClientLinkObserver_onClatInterfaceStateUpdate() throws Exception {
+        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
+                .withoutIPv4()
+                .build();
+        startIpClientProvisioning(config);
+        doIpv6OnlyProvisioning();
+
+        reset(mCb);
+
+        // Add the clat interface and check the callback.
+        final TestNetworkInterface clatIface = setUpClatInterface(mIfaceName);
+        assertNotNull(clatIface);
+        assertTrue(clatIface.getInterfaceName().equals(CLAT_PREFIX + mIfaceName));
+        verify(mCb, timeout(TEST_TIMEOUT_MS)).setNeighborDiscoveryOffload(false);
+
+        // Remove the clat interface and check the callback.
+        removeTestInterface(clatIface.getFileDescriptor().getFileDescriptor());
+        verify(mCb, timeout(TEST_TIMEOUT_MS)).setNeighborDiscoveryOffload(true);
+    }
 }
diff --git a/tests/unit/src/android/net/testutils/DeviceInfoUtilsTest.java b/tests/unit/src/android/net/testutils/DeviceInfoUtilsTest.java
new file mode 100644
index 0000000..f99700a
--- /dev/null
+++ b/tests/unit/src/android/net/testutils/DeviceInfoUtilsTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.testutils;
+
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+@SmallTest
+public final class DeviceInfoUtilsTest {
+    /**
+     * Verifies that version string compare logic returns expected result for various cases.
+     * Note that only major and minor number are compared.
+     */
+    @Test
+    public void testMajorMinorVersionCompare() {
+        assertEquals(0, DeviceInfoUtils.compareMajorMinorVersion("4.8.1", "4.8"));
+        assertEquals(1, DeviceInfoUtils.compareMajorMinorVersion("4.9", "4.8.1"));
+        assertEquals(1, DeviceInfoUtils.compareMajorMinorVersion("5.0", "4.8"));
+        assertEquals(1, DeviceInfoUtils.compareMajorMinorVersion("5", "4.8"));
+        assertEquals(0, DeviceInfoUtils.compareMajorMinorVersion("5", "5.0"));
+        assertEquals(1, DeviceInfoUtils.compareMajorMinorVersion("5-beta1", "4.8"));
+        assertEquals(0, DeviceInfoUtils.compareMajorMinorVersion("4.8.0.0", "4.8"));
+        assertEquals(0, DeviceInfoUtils.compareMajorMinorVersion("4.8-RC1", "4.8"));
+        assertEquals(0, DeviceInfoUtils.compareMajorMinorVersion("4.8", "4.8"));
+        assertEquals(-1, DeviceInfoUtils.compareMajorMinorVersion("3.10", "4.8.0"));
+        assertEquals(-1, DeviceInfoUtils.compareMajorMinorVersion("4.7.10.10", "4.8"));
+    }
+}