diff --git a/TEST_MAPPING b/TEST_MAPPING
index 6996ad9..ffbd1fc 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -23,6 +23,9 @@
     },
     {
       "name": "TetheringIntegrationTests"
+    },
+    {
+      "name": "traffic_controller_unit_test"
     }
   ],
   "postsubmit": [
@@ -32,6 +35,13 @@
     // TODO: move to presubmit when known green.
     {
       "name": "bpf_existence_test"
+    },
+    {
+      "name": "libclat_test"
+    },
+    {
+      "name": "traffic_controller_unit_test",
+      "keywords": ["netd-device-kernel-4.9", "netd-device-kernel-4.14"]
     }
   ],
   "mainline-presubmit": [
@@ -48,6 +58,9 @@
     },
     {
       "name": "ConnectivityCoverageTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
+    },
+    {
+      "name": "traffic_controller_unit_test[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
     }
   ],
   "mainline-postsubmit": [
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 66efb8b..611f100 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -51,7 +51,8 @@
         first: {
             jni_libs: [
                 "libservice-connectivity",
-                "libcom_android_connectivity_com_android_net_module_util_jni"
+                "libcom_android_connectivity_com_android_net_module_util_jni",
+                "libtraffic_controller_jni",
             ],
         },
         both: {
@@ -63,6 +64,8 @@
     ],
     canned_fs_config: "canned_fs_config",
     bpfs: [
+        "clatd.o_mainline",
+        "netd.o_mainline",
         "offload.o",
         "test.o",
     ],
diff --git a/Tethering/apex/canned_fs_config b/Tethering/apex/canned_fs_config
index 44c57ab..06e9617 100644
--- a/Tethering/apex/canned_fs_config
+++ b/Tethering/apex/canned_fs_config
@@ -1,2 +1,2 @@
 /bin/for-system 0 1000 0550
-/bin/for-system/clatd 1029 1029 06555
+/bin/for-system/clatd 1029 1029 06755
diff --git a/Tethering/proguard.flags b/Tethering/proguard.flags
index f62df7f..6735317 100644
--- a/Tethering/proguard.flags
+++ b/Tethering/proguard.flags
@@ -8,6 +8,10 @@
     native <methods>;
 }
 
+-keep class com.android.networkstack.tethering.util.TcUtils {
+    native <methods>;
+}
+
 -keepclassmembers public class * extends com.android.networkstack.tethering.util.Struct {
     *;
 }
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index b4228da..2bb19db 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -614,10 +614,8 @@
             return false;
         }
 
-        if (mInterfaceType == TetheringManager.TETHERING_BLUETOOTH) {
-            // BT configures the interface elsewhere: only start DHCP.
-            // TODO: make all tethering types behave the same way, and delete the bluetooth
-            // code that calls into NetworkManagementService directly.
+        if (shouldNotConfigureBluetoothInterface()) {
+            // Interface was already configured elsewhere, only start DHCP.
             return configureDhcp(enabled, mIpv4Address, null /* clientAddress */);
         }
 
@@ -651,12 +649,15 @@
         return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr);
     }
 
+    private boolean shouldNotConfigureBluetoothInterface() {
+        // Before T, bluetooth tethering configures the interface elsewhere.
+        return (mInterfaceType == TetheringManager.TETHERING_BLUETOOTH) && !SdkLevel.isAtLeastT();
+    }
+
     private LinkAddress requestIpv4Address(final boolean useLastAddress) {
         if (mStaticIpv4ServerAddr != null) return mStaticIpv4ServerAddr;
 
-        if (mInterfaceType == TetheringManager.TETHERING_BLUETOOTH) {
-            return new LinkAddress(BLUETOOTH_IFACE_ADDR);
-        }
+        if (shouldNotConfigureBluetoothInterface()) return new LinkAddress(BLUETOOTH_IFACE_ADDR);
 
         return mPrivateAddressCoordinator.requestDownstreamAddress(this, useLastAddress);
     }
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfUtils.java b/Tethering/src/com/android/networkstack/tethering/BpfUtils.java
index ad410eb..77efb51 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfUtils.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfUtils.java
@@ -55,11 +55,11 @@
     static final boolean DOWNSTREAM = true;
     static final boolean UPSTREAM = false;
 
-    // The priority of clat/tether hooks - smaller is higher priority.
+    // The priority of tether hooks - smaller is higher priority.
     // TC tether is higher priority then TC clat to match XDP winning over TC.
-    // Sync from system/netd/server/OffloadUtils.h.
-    static final short PRIO_TETHER6 = 1;
-    static final short PRIO_TETHER4 = 2;
+    // Sync from system/netd/server/TcUtils.h.
+    static final short PRIO_TETHER6 = 2;
+    static final short PRIO_TETHER4 = 3;
     // note that the above must be lower than PRIO_CLAT from netd's OffloadUtils.cpp
 
     private static String makeProgPath(boolean downstream, int ipVersion, boolean ether) {
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 55c24d3..db9a64f 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -134,7 +134,12 @@
 import com.android.internal.util.MessageUtils;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.modules.utils.build.SdkLevel;
 import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
+import com.android.networkstack.apishim.common.BluetoothPanShim;
+import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim;
+import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim;
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
 import com.android.networkstack.tethering.util.InterfaceSet;
 import com.android.networkstack.tethering.util.PrefixUtils;
 import com.android.networkstack.tethering.util.TetheringUtils;
@@ -265,8 +270,11 @@
     private int mOffloadStatus = TETHER_HARDWARE_OFFLOAD_STOPPED;
 
     private EthernetManager.TetheredInterfaceRequest mEthernetIfaceRequest;
+    private TetheredInterfaceRequestShim mBluetoothIfaceRequest;
     private String mConfiguredEthernetIface;
+    private String mConfiguredBluetoothIface;
     private EthernetCallback mEthernetCallback;
+    private TetheredInterfaceCallbackShim mBluetoothCallback;
     private SettingsObserver mSettingsObserver;
     private BluetoothPan mBluetoothPan;
     private PanServiceListener mBluetoothPanListener;
@@ -533,14 +541,16 @@
         }
     }
 
-    // This method needs to exist because TETHERING_BLUETOOTH and TETHERING_WIGIG can't use
-    // enableIpServing.
+    // This method needs to exist because TETHERING_BLUETOOTH before Android T and TETHERING_WIGIG
+    // can't use enableIpServing.
     private void processInterfaceStateChange(final String iface, boolean enabled) {
         // Do not listen to USB interface state changes or USB interface add/removes. USB tethering
         // is driven only by USB_ACTION broadcasts.
         final int type = ifaceNameToType(iface);
         if (type == TETHERING_USB || type == TETHERING_NCM) return;
 
+        if (type == TETHERING_BLUETOOTH && SdkLevel.isAtLeastT()) return;
+
         if (enabled) {
             ensureIpServerStarted(iface);
         } else {
@@ -769,6 +779,9 @@
                             TETHERING_BLUETOOTH);
                 }
                 mPendingPanRequests.clear();
+                mBluetoothIfaceRequest = null;
+                mBluetoothCallback = null;
+                maybeDisableBluetoothIpServing();
             });
         }
 
@@ -779,7 +792,11 @@
 
     private void setBluetoothTetheringSettings(@NonNull final BluetoothPan bluetoothPan,
             final boolean enable, final IIntResultListener listener) {
-        bluetoothPan.setBluetoothTethering(enable);
+        if (SdkLevel.isAtLeastT()) {
+            changeBluetoothTetheringSettings(bluetoothPan, enable);
+        } else {
+            changeBluetoothTetheringSettingsPreT(bluetoothPan, enable);
+        }
 
         // Enabling bluetooth tethering settings can silently fail. Send internal error if the
         // result is not expected.
@@ -788,6 +805,68 @@
         sendTetherResult(listener, result, TETHERING_BLUETOOTH);
     }
 
+    private void changeBluetoothTetheringSettingsPreT(@NonNull final BluetoothPan bluetoothPan,
+            final boolean enable) {
+        bluetoothPan.setBluetoothTethering(enable);
+    }
+
+    private void changeBluetoothTetheringSettings(@NonNull final BluetoothPan bluetoothPan,
+            final boolean enable) {
+        final BluetoothPanShim panShim = mDeps.getBluetoothPanShim(bluetoothPan);
+        if (enable) {
+            if (mBluetoothIfaceRequest != null) {
+                Log.d(TAG, "Bluetooth tethering settings already enabled");
+                return;
+            }
+
+            mBluetoothCallback = new BluetoothCallback();
+            try {
+                mBluetoothIfaceRequest = panShim.requestTetheredInterface(mExecutor,
+                        mBluetoothCallback);
+            } catch (UnsupportedApiLevelException e) {
+                Log.wtf(TAG, "Use unsupported API, " + e);
+            }
+        } else {
+            if (mBluetoothIfaceRequest == null) {
+                Log.d(TAG, "Bluetooth tethering settings already disabled");
+                return;
+            }
+
+            mBluetoothIfaceRequest.release();
+            mBluetoothIfaceRequest = null;
+            mBluetoothCallback = null;
+            // If bluetooth request is released, tethering won't able to receive
+            // onUnavailable callback, explicitly disable bluetooth IpServer manually.
+            maybeDisableBluetoothIpServing();
+        }
+    }
+
+    // BluetoothCallback is only called after T. Before T, PanService would call tether/untether to
+    // notify bluetooth interface status.
+    private class BluetoothCallback implements TetheredInterfaceCallbackShim {
+        @Override
+        public void onAvailable(String iface) {
+            if (this != mBluetoothCallback) return;
+
+            enableIpServing(TETHERING_BLUETOOTH, iface, getRequestedState(TETHERING_BLUETOOTH));
+            mConfiguredBluetoothIface = iface;
+        }
+
+        @Override
+        public void onUnavailable() {
+            if (this != mBluetoothCallback) return;
+
+            maybeDisableBluetoothIpServing();
+        }
+    }
+
+    private void maybeDisableBluetoothIpServing() {
+        if (mConfiguredBluetoothIface == null) return;
+
+        ensureIpServerStopped(mConfiguredBluetoothIface);
+        mConfiguredBluetoothIface = null;
+    }
+
     private int setEthernetTethering(final boolean enable) {
         final EthernetManager em = (EthernetManager) mContext.getSystemService(
                 Context.ETHERNET_SERVICE);
diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java b/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
index 7df9475..c1a747e 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
@@ -18,6 +18,7 @@
 
 import android.app.usage.NetworkStatsManager;
 import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothPan;
 import android.content.Context;
 import android.net.INetd;
 import android.net.ip.IpServer;
@@ -31,6 +32,8 @@
 import androidx.annotation.NonNull;
 
 import com.android.internal.util.StateMachine;
+import com.android.networkstack.apishim.BluetoothPanShimImpl;
+import com.android.networkstack.apishim.common.BluetoothPanShim;
 
 import java.util.ArrayList;
 
@@ -158,4 +161,13 @@
             TetheringConfiguration cfg) {
         return new PrivateAddressCoordinator(ctx, cfg);
     }
+
+    /**
+     * Get BluetoothPanShim object to enable/disable bluetooth tethering.
+     *
+     * TODO: use BluetoothPan directly when mainline module is built with API 32.
+     */
+    public BluetoothPanShim getBluetoothPanShim(BluetoothPan pan) {
+        return BluetoothPanShimImpl.newInstance(pan);
+    }
 }
diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 2f2cde0..267c376 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -16,6 +16,7 @@
 
 package android.net.ip;
 
+import static android.net.INetd.IF_STATE_DOWN;
 import static android.net.INetd.IF_STATE_UP;
 import static android.net.RouteInfo.RTN_UNICAST;
 import static android.net.TetheringManager.TETHERING_BLUETOOTH;
@@ -33,6 +34,7 @@
 import static android.net.ip.IpServer.STATE_UNAVAILABLE;
 import static android.system.OsConstants.ETH_P_IPV6;
 
+import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
 import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
 import static com.android.net.module.util.netlink.NetlinkConstants.RTM_DELNEIGH;
 import static com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWNEIGH;
@@ -400,11 +402,16 @@
     }
 
     @Test
-    public void canBeTethered() throws Exception {
+    public void canBeTetheredAsBluetooth() throws Exception {
         initStateMachine(TETHERING_BLUETOOTH);
 
         dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
-        InOrder inOrder = inOrder(mCallback, mNetd);
+        InOrder inOrder = inOrder(mCallback, mNetd, mAddressCoordinator);
+        if (isAtLeastT()) {
+            inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(true));
+            inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
+                    IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
+        }
         inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
         inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
         // One for ipv4 route, one for ipv6 link local route.
@@ -426,7 +433,13 @@
         inOrder.verify(mNetd).tetherApplyDnsInterfaces();
         inOrder.verify(mNetd).tetherInterfaceRemove(IFACE_NAME);
         inOrder.verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
-        inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
+        // One is ipv4 address clear (set to 0.0.0.0), another is set interface down which only
+        // happen after T. Before T, the interface configuration control in bluetooth side.
+        if (isAtLeastT()) {
+            inOrder.verify(mNetd).interfaceSetCfg(
+                    argThat(cfg -> assertContainsFlag(cfg.flags, IF_STATE_DOWN)));
+        }
+        inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> cfg.flags.length == 0));
         inOrder.verify(mAddressCoordinator).releaseDownstream(any());
         inOrder.verify(mCallback).updateInterfaceState(
                 mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
@@ -443,7 +456,7 @@
         InOrder inOrder = inOrder(mCallback, mNetd, mAddressCoordinator);
         inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(true));
         inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
-                  IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
+                IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
         inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
         inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
         inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
@@ -587,7 +600,8 @@
         inOrder.verify(mNetd).tetherApplyDnsInterfaces();
         inOrder.verify(mNetd).tetherInterfaceRemove(IFACE_NAME);
         inOrder.verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
-        inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
+        inOrder.verify(mNetd, times(isAtLeastT() ? 2 : 1)).interfaceSetCfg(
+                argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
         inOrder.verify(mAddressCoordinator).releaseDownstream(any());
         inOrder.verify(mBpfCoordinator).tetherOffloadClientClear(mIpServer);
         inOrder.verify(mBpfCoordinator).stopMonitoring(mIpServer);
@@ -683,7 +697,11 @@
         initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
         dispatchTetherConnectionChanged(UPSTREAM_IFACE);
 
-        assertDhcpStarted(mBluetoothPrefix);
+        if (isAtLeastT()) {
+            assertDhcpStarted(PrefixUtils.asIpPrefix(mTestAddress));
+        } else {
+            assertDhcpStarted(mBluetoothPrefix);
+        }
     }
 
     @Test
@@ -1371,7 +1389,6 @@
         for (String flag : flags) {
             if (flag.equals(match)) return true;
         }
-        fail("Missing flag: " + match);
         return false;
     }
 
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 40d133a..e4dbc7d 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -62,6 +62,7 @@
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
+import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
 import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
 import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0;
@@ -81,6 +82,8 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.notNull;
 import static org.mockito.Matchers.anyInt;
@@ -182,6 +185,10 @@
 import com.android.internal.util.test.BroadcastInterceptingContext;
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.net.module.util.CollectionUtils;
+import com.android.networkstack.apishim.common.BluetoothPanShim;
+import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim;
+import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim;
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
 import com.android.networkstack.tethering.TestConnectivityManager.TestNetworkAgent;
 import com.android.testutils.MiscAsserts;
 
@@ -261,6 +268,8 @@
     @Mock private PackageManager mPackageManager;
     @Mock private BluetoothAdapter mBluetoothAdapter;
     @Mock private BluetoothPan mBluetoothPan;
+    @Mock private BluetoothPanShim mBluetoothPanShim;
+    @Mock private TetheredInterfaceRequestShim mTetheredInterfaceRequestShim;
 
     private final MockIpServerDependencies mIpServerDependencies =
             spy(new MockIpServerDependencies());
@@ -285,6 +294,7 @@
     private PrivateAddressCoordinator mPrivateAddressCoordinator;
     private SoftApCallback mSoftApCallback;
     private UpstreamNetworkMonitor mUpstreamNetworkMonitor;
+    private TetheredInterfaceCallbackShim mTetheredInterfaceCallbackShim;
 
     private TestConnectivityManager mCm;
 
@@ -483,13 +493,23 @@
             return false;
         }
 
-
         @Override
         public PrivateAddressCoordinator getPrivateAddressCoordinator(Context ctx,
                 TetheringConfiguration cfg) {
             mPrivateAddressCoordinator = super.getPrivateAddressCoordinator(ctx, cfg);
             return mPrivateAddressCoordinator;
         }
+
+        @Override
+        public BluetoothPanShim getBluetoothPanShim(BluetoothPan pan) {
+            try {
+                when(mBluetoothPanShim.requestTetheredInterface(
+                        any(), any())).thenReturn(mTetheredInterfaceRequestShim);
+            } catch (UnsupportedApiLevelException e) {
+                fail("BluetoothPan#requestTetheredInterface is not supported");
+            }
+            return mBluetoothPanShim;
+        }
     }
 
     private static LinkProperties buildUpstreamLinkProperties(String interfaceName,
@@ -2557,6 +2577,44 @@
 
     @Test
     public void testBluetoothTethering() throws Exception {
+        // Switch to @IgnoreUpTo(Build.VERSION_CODES.S_V2) when it is available for AOSP.
+        assumeTrue(isAtLeastT());
+
+        final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
+        mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result);
+        mLooper.dispatchAll();
+        verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
+        result.assertHasResult();
+
+        mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME);
+        mLooper.dispatchAll();
+        verifyNetdCommandForBtSetup();
+
+        // If PAN disconnect, tethering should also be stopped.
+        mTetheredInterfaceCallbackShim.onUnavailable();
+        mLooper.dispatchAll();
+        verifyNetdCommandForBtTearDown();
+
+        // Tethering could restart if PAN reconnect.
+        mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME);
+        mLooper.dispatchAll();
+        verifyNetdCommandForBtSetup();
+
+        // Pretend that bluetooth tethering was disabled.
+        mockBluetoothSettings(true /* bluetoothOn */, false /* tetheringOn */);
+        mTethering.stopTethering(TETHERING_BLUETOOTH);
+        mLooper.dispatchAll();
+        verifySetBluetoothTethering(false /* enable */, false /* bindToPanService */);
+
+        verifyNetdCommandForBtTearDown();
+    }
+
+    @Test
+    public void testBluetoothTetheringBeforeT() throws Exception {
+        // Switch to @IgnoreAfter(Build.VERSION_CODES.S_V2) when it is available for AOSP.
+        assumeFalse(isAtLeastT());
+
         final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
         mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result);
@@ -2610,12 +2668,17 @@
         mTethering.interfaceAdded(TEST_BT_IFNAME);
         mLooper.dispatchAll();
 
-        mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false);
-        mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true);
-        final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
-        mTethering.tether(TEST_BT_IFNAME, IpServer.STATE_TETHERED, tetherResult);
-        mLooper.dispatchAll();
-        tetherResult.assertHasResult();
+        if (isAtLeastT()) {
+            mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME);
+            mLooper.dispatchAll();
+        } else {
+            mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false);
+            mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true);
+            final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
+            mTethering.tether(TEST_BT_IFNAME, IpServer.STATE_TETHERED, tetherResult);
+            mLooper.dispatchAll();
+            tetherResult.assertHasResult();
+        }
 
         verifyNetdCommandForBtSetup();
 
@@ -2632,6 +2695,10 @@
     }
 
     private void verifyNetdCommandForBtSetup() throws Exception {
+        if (isAtLeastT()) {
+            verify(mNetd).interfaceSetCfg(argThat(cfg -> TEST_BT_IFNAME.equals(cfg.ifName)
+                    && assertContainsFlag(cfg.flags, INetd.IF_STATE_UP)));
+        }
         verify(mNetd).tetherInterfaceAdd(TEST_BT_IFNAME);
         verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, TEST_BT_IFNAME);
         verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_BT_IFNAME),
@@ -2644,19 +2711,30 @@
         reset(mNetd);
     }
 
+    private boolean assertContainsFlag(String[] flags, String match) {
+        for (String flag : flags) {
+            if (flag.equals(match)) return true;
+        }
+        return false;
+    }
+
     private void verifyNetdCommandForBtTearDown() throws Exception {
         verify(mNetd).tetherApplyDnsInterfaces();
         verify(mNetd).tetherInterfaceRemove(TEST_BT_IFNAME);
         verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_BT_IFNAME);
-        verify(mNetd).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
+        // One is ipv4 address clear (set to 0.0.0.0), another is set interface down which only
+        // happen after T. Before T, the interface configuration control in bluetooth side.
+        verify(mNetd, times(isAtLeastT() ? 2 : 1)).interfaceSetCfg(
+                any(InterfaceConfigurationParcel.class));
         verify(mNetd).tetherStop();
         verify(mNetd).ipfwdDisableForwarding(TETHERING_NAME);
+        reset(mNetd);
     }
 
     // If bindToPanService is true, this function would return ServiceListener which could notify
     // PanService is connected or disconnected.
     private ServiceListener verifySetBluetoothTethering(final boolean enable,
-            final boolean bindToPanService) {
+            final boolean bindToPanService) throws Exception {
         ServiceListener listener = null;
         verify(mBluetoothAdapter).isEnabled();
         if (bindToPanService) {
@@ -2671,7 +2749,19 @@
             verify(mBluetoothAdapter, never()).getProfileProxy(eq(mServiceContext), any(),
                     anyInt());
         }
-        verify(mBluetoothPan).setBluetoothTethering(enable);
+
+        if (isAtLeastT()) {
+            if (enable) {
+                final ArgumentCaptor<TetheredInterfaceCallbackShim> callbackCaptor =
+                        ArgumentCaptor.forClass(TetheredInterfaceCallbackShim.class);
+                verify(mBluetoothPanShim).requestTetheredInterface(any(), callbackCaptor.capture());
+                mTetheredInterfaceCallbackShim = callbackCaptor.getValue();
+            } else {
+                verify(mTetheredInterfaceRequestShim).release();
+            }
+        } else {
+            verify(mBluetoothPan).setBluetoothTethering(enable);
+        }
         verify(mBluetoothPan).isTetheringOn();
         verifyNoMoreInteractions(mBluetoothAdapter, mBluetoothPan);
         reset(mBluetoothAdapter, mBluetoothPan);
diff --git a/bpf_progs/Android.bp b/bpf_progs/Android.bp
index d015ef6..a3ca90c 100644
--- a/bpf_progs/Android.bp
+++ b/bpf_progs/Android.bp
@@ -42,7 +42,9 @@
         // TODO: remove it when NetworkStatsService is moved into the mainline module and no more
         // calls to JNI in libservices.core.
         "//frameworks/base/services/core/jni",
+        "//packages/modules/Connectivity/service/native/libs/libclat",
         "//packages/modules/Connectivity/Tethering",
+        "//packages/modules/Connectivity/service/native",
         "//packages/modules/Connectivity/tests/unit/jni",
         // TODO: remove system/netd/* when all BPF code is moved out of Netd.
         "//system/netd/libnetdbpf",
@@ -71,3 +73,29 @@
         "-Werror",
     ],
 }
+
+bpf {
+    name: "clatd.o_mainline",
+    srcs: ["clatd.c"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    include_dirs: [
+        "frameworks/libs/net/common/netd/libnetdutils/include",
+    ],
+    sub_dir: "net_shared",
+}
+
+bpf {
+    name: "netd.o_mainline",
+    srcs: ["netd.c"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    include_dirs: [
+        "frameworks/libs/net/common/netd/libnetdutils/include",
+    ],
+    sub_dir: "net_shared",
+}
diff --git a/bpf_progs/clatd.c b/bpf_progs/clatd.c
new file mode 100644
index 0000000..dc646c3
--- /dev/null
+++ b/bpf_progs/clatd.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <linux/bpf.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/pkt_cls.h>
+#include <linux/swab.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+// bionic kernel uapi linux/udp.h header is munged...
+#define __kernel_udphdr udphdr
+#include <linux/udp.h>
+
+#include "bpf_helpers.h"
+#include "bpf_net_helpers.h"
+#include "bpf_shared.h"
+
+// From kernel:include/net/ip.h
+#define IP_DF 0x4000  // Flag: "Don't Fragment"
+
+DEFINE_BPF_MAP_GRW(clat_ingress6_map, HASH, ClatIngress6Key, ClatIngress6Value, 16, AID_SYSTEM)
+
+static inline __always_inline int nat64(struct __sk_buff* skb, bool is_ethernet) {
+    const int l2_header_size = is_ethernet ? sizeof(struct ethhdr) : 0;
+    void* data = (void*)(long)skb->data;
+    const void* data_end = (void*)(long)skb->data_end;
+    const struct ethhdr* const eth = is_ethernet ? data : NULL;  // used iff is_ethernet
+    const struct ipv6hdr* const ip6 = is_ethernet ? (void*)(eth + 1) : data;
+
+    // Require ethernet dst mac address to be our unicast address.
+    if (is_ethernet && (skb->pkt_type != PACKET_HOST)) return TC_ACT_PIPE;
+
+    // Must be meta-ethernet IPv6 frame
+    if (skb->protocol != htons(ETH_P_IPV6)) return TC_ACT_PIPE;
+
+    // Must have (ethernet and) ipv6 header
+    if (data + l2_header_size + sizeof(*ip6) > data_end) return TC_ACT_PIPE;
+
+    // Ethertype - if present - must be IPv6
+    if (is_ethernet && (eth->h_proto != htons(ETH_P_IPV6))) return TC_ACT_PIPE;
+
+    // IP version must be 6
+    if (ip6->version != 6) return TC_ACT_PIPE;
+
+    // Maximum IPv6 payload length that can be translated to IPv4
+    if (ntohs(ip6->payload_len) > 0xFFFF - sizeof(struct iphdr)) return TC_ACT_PIPE;
+
+    switch (ip6->nexthdr) {
+        case IPPROTO_TCP:  // For TCP & UDP the checksum neutrality of the chosen IPv6
+        case IPPROTO_UDP:  // address means there is no need to update their checksums.
+        case IPPROTO_GRE:  // We do not need to bother looking at GRE/ESP headers,
+        case IPPROTO_ESP:  // since there is never a checksum to update.
+            break;
+
+        default:  // do not know how to handle anything else
+            return TC_ACT_PIPE;
+    }
+
+    ClatIngress6Key k = {
+            .iif = skb->ifindex,
+            .pfx96.in6_u.u6_addr32 =
+                    {
+                            ip6->saddr.in6_u.u6_addr32[0],
+                            ip6->saddr.in6_u.u6_addr32[1],
+                            ip6->saddr.in6_u.u6_addr32[2],
+                    },
+            .local6 = ip6->daddr,
+    };
+
+    ClatIngress6Value* v = bpf_clat_ingress6_map_lookup_elem(&k);
+
+    if (!v) return TC_ACT_PIPE;
+
+    struct ethhdr eth2;  // used iff is_ethernet
+    if (is_ethernet) {
+        eth2 = *eth;                     // Copy over the ethernet header (src/dst mac)
+        eth2.h_proto = htons(ETH_P_IP);  // But replace the ethertype
+    }
+
+    struct iphdr ip = {
+            .version = 4,                                                      // u4
+            .ihl = sizeof(struct iphdr) / sizeof(__u32),                       // u4
+            .tos = (ip6->priority << 4) + (ip6->flow_lbl[0] >> 4),             // u8
+            .tot_len = htons(ntohs(ip6->payload_len) + sizeof(struct iphdr)),  // u16
+            .id = 0,                                                           // u16
+            .frag_off = htons(IP_DF),                                          // u16
+            .ttl = ip6->hop_limit,                                             // u8
+            .protocol = ip6->nexthdr,                                          // u8
+            .check = 0,                                                        // u16
+            .saddr = ip6->saddr.in6_u.u6_addr32[3],                            // u32
+            .daddr = v->local4.s_addr,                                         // u32
+    };
+
+    // Calculate the IPv4 one's complement checksum of the IPv4 header.
+    __wsum sum4 = 0;
+    for (int i = 0; i < sizeof(ip) / sizeof(__u16); ++i) {
+        sum4 += ((__u16*)&ip)[i];
+    }
+    // Note that sum4 is guaranteed to be non-zero by virtue of ip.version == 4
+    sum4 = (sum4 & 0xFFFF) + (sum4 >> 16);  // collapse u32 into range 1 .. 0x1FFFE
+    sum4 = (sum4 & 0xFFFF) + (sum4 >> 16);  // collapse any potential carry into u16
+    ip.check = (__u16)~sum4;                // sum4 cannot be zero, so this is never 0xFFFF
+
+    // Calculate the *negative* IPv6 16-bit one's complement checksum of the IPv6 header.
+    __wsum sum6 = 0;
+    // We'll end up with a non-zero sum due to ip6->version == 6 (which has '0' bits)
+    for (int i = 0; i < sizeof(*ip6) / sizeof(__u16); ++i) {
+        sum6 += ~((__u16*)ip6)[i];  // note the bitwise negation
+    }
+
+    // Note that there is no L4 checksum update: we are relying on the checksum neutrality
+    // of the ipv6 address chosen by netd's ClatdController.
+
+    // Packet mutations begin - point of no return, but if this first modification fails
+    // the packet is probably still pristine, so let clatd handle it.
+    if (bpf_skb_change_proto(skb, htons(ETH_P_IP), 0)) return TC_ACT_PIPE;
+
+    // This takes care of updating the skb->csum field for a CHECKSUM_COMPLETE packet.
+    //
+    // In such a case, skb->csum is a 16-bit one's complement sum of the entire payload,
+    // thus we need to subtract out the ipv6 header's sum, and add in the ipv4 header's sum.
+    // However, by construction of ip.check above the checksum of an ipv4 header is zero.
+    // Thus we only need to subtract the ipv6 header's sum, which is the same as adding
+    // in the sum of the bitwise negation of the ipv6 header.
+    //
+    // bpf_csum_update() always succeeds if the skb is CHECKSUM_COMPLETE and returns an error
+    // (-ENOTSUPP) if it isn't.  So we just ignore the return code.
+    //
+    // if (skb->ip_summed == CHECKSUM_COMPLETE)
+    //   return (skb->csum = csum_add(skb->csum, csum));
+    // else
+    //   return -ENOTSUPP;
+    bpf_csum_update(skb, sum6);
+
+    // bpf_skb_change_proto() invalidates all pointers - reload them.
+    data = (void*)(long)skb->data;
+    data_end = (void*)(long)skb->data_end;
+
+    // I cannot think of any valid way for this error condition to trigger, however I do
+    // believe the explicit check is required to keep the in kernel ebpf verifier happy.
+    if (data + l2_header_size + sizeof(struct iphdr) > data_end) return TC_ACT_SHOT;
+
+    if (is_ethernet) {
+        struct ethhdr* new_eth = data;
+
+        // Copy over the updated ethernet header
+        *new_eth = eth2;
+
+        // Copy over the new ipv4 header.
+        *(struct iphdr*)(new_eth + 1) = ip;
+    } else {
+        // Copy over the new ipv4 header without an ethernet header.
+        *(struct iphdr*)data = ip;
+    }
+
+    // Redirect, possibly back to same interface, so tcpdump sees packet twice.
+    if (v->oif) return bpf_redirect(v->oif, BPF_F_INGRESS);
+
+    // Just let it through, tcpdump will not see IPv4 packet.
+    return TC_ACT_PIPE;
+}
+
+DEFINE_BPF_PROG("schedcls/ingress6/clat_ether", AID_ROOT, AID_SYSTEM, sched_cls_ingress6_clat_ether)
+(struct __sk_buff* skb) {
+    return nat64(skb, true);
+}
+
+DEFINE_BPF_PROG("schedcls/ingress6/clat_rawip", AID_ROOT, AID_SYSTEM, sched_cls_ingress6_clat_rawip)
+(struct __sk_buff* skb) {
+    return nat64(skb, false);
+}
+
+DEFINE_BPF_MAP_GRW(clat_egress4_map, HASH, ClatEgress4Key, ClatEgress4Value, 16, AID_SYSTEM)
+
+DEFINE_BPF_PROG("schedcls/egress4/clat_ether", AID_ROOT, AID_SYSTEM, sched_cls_egress4_clat_ether)
+(struct __sk_buff* skb) {
+    return TC_ACT_PIPE;
+}
+
+DEFINE_BPF_PROG("schedcls/egress4/clat_rawip", AID_ROOT, AID_SYSTEM, sched_cls_egress4_clat_rawip)
+(struct __sk_buff* skb) {
+    void* data = (void*)(long)skb->data;
+    const void* data_end = (void*)(long)skb->data_end;
+    const struct iphdr* const ip4 = data;
+
+    // Must be meta-ethernet IPv4 frame
+    if (skb->protocol != htons(ETH_P_IP)) return TC_ACT_PIPE;
+
+    // Must have ipv4 header
+    if (data + sizeof(*ip4) > data_end) return TC_ACT_PIPE;
+
+    // IP version must be 4
+    if (ip4->version != 4) return TC_ACT_PIPE;
+
+    // We cannot handle IP options, just standard 20 byte == 5 dword minimal IPv4 header
+    if (ip4->ihl != 5) return TC_ACT_PIPE;
+
+    // Calculate the IPv4 one's complement checksum of the IPv4 header.
+    __wsum sum4 = 0;
+    for (int i = 0; i < sizeof(*ip4) / sizeof(__u16); ++i) {
+        sum4 += ((__u16*)ip4)[i];
+    }
+    // Note that sum4 is guaranteed to be non-zero by virtue of ip4->version == 4
+    sum4 = (sum4 & 0xFFFF) + (sum4 >> 16);  // collapse u32 into range 1 .. 0x1FFFE
+    sum4 = (sum4 & 0xFFFF) + (sum4 >> 16);  // collapse any potential carry into u16
+    // for a correct checksum we should get *a* zero, but sum4 must be positive, ie 0xFFFF
+    if (sum4 != 0xFFFF) return TC_ACT_PIPE;
+
+    // Minimum IPv4 total length is the size of the header
+    if (ntohs(ip4->tot_len) < sizeof(*ip4)) return TC_ACT_PIPE;
+
+    // We are incapable of dealing with IPv4 fragments
+    if (ip4->frag_off & ~htons(IP_DF)) return TC_ACT_PIPE;
+
+    switch (ip4->protocol) {
+        case IPPROTO_TCP:  // For TCP & UDP the checksum neutrality of the chosen IPv6
+        case IPPROTO_GRE:  // address means there is no need to update their checksums.
+        case IPPROTO_ESP:  // We do not need to bother looking at GRE/ESP headers,
+            break;         // since there is never a checksum to update.
+
+        case IPPROTO_UDP:  // See above comment, but must also have UDP header...
+            if (data + sizeof(*ip4) + sizeof(struct udphdr) > data_end) return TC_ACT_PIPE;
+            const struct udphdr* uh = (const struct udphdr*)(ip4 + 1);
+            // If IPv4/UDP checksum is 0 then fallback to clatd so it can calculate the
+            // checksum.  Otherwise the network or more likely the NAT64 gateway might
+            // drop the packet because in most cases IPv6/UDP packets with a zero checksum
+            // are invalid. See RFC 6935.  TODO: calculate checksum via bpf_csum_diff()
+            if (!uh->check) return TC_ACT_PIPE;
+            break;
+
+        default:  // do not know how to handle anything else
+            return TC_ACT_PIPE;
+    }
+
+    ClatEgress4Key k = {
+            .iif = skb->ifindex,
+            .local4.s_addr = ip4->saddr,
+    };
+
+    ClatEgress4Value* v = bpf_clat_egress4_map_lookup_elem(&k);
+
+    if (!v) return TC_ACT_PIPE;
+
+    // Translating without redirecting doesn't make sense.
+    if (!v->oif) return TC_ACT_PIPE;
+
+    // This implementation is currently limited to rawip.
+    if (v->oifIsEthernet) return TC_ACT_PIPE;
+
+    struct ipv6hdr ip6 = {
+            .version = 6,                                    // __u8:4
+            .priority = ip4->tos >> 4,                       // __u8:4
+            .flow_lbl = {(ip4->tos & 0xF) << 4, 0, 0},       // __u8[3]
+            .payload_len = htons(ntohs(ip4->tot_len) - 20),  // __be16
+            .nexthdr = ip4->protocol,                        // __u8
+            .hop_limit = ip4->ttl,                           // __u8
+            .saddr = v->local6,                              // struct in6_addr
+            .daddr = v->pfx96,                               // struct in6_addr
+    };
+    ip6.daddr.in6_u.u6_addr32[3] = ip4->daddr;
+
+    // Calculate the IPv6 16-bit one's complement checksum of the IPv6 header.
+    __wsum sum6 = 0;
+    // We'll end up with a non-zero sum due to ip6.version == 6
+    for (int i = 0; i < sizeof(ip6) / sizeof(__u16); ++i) {
+        sum6 += ((__u16*)&ip6)[i];
+    }
+
+    // Note that there is no L4 checksum update: we are relying on the checksum neutrality
+    // of the ipv6 address chosen by netd's ClatdController.
+
+    // Packet mutations begin - point of no return, but if this first modification fails
+    // the packet is probably still pristine, so let clatd handle it.
+    if (bpf_skb_change_proto(skb, htons(ETH_P_IPV6), 0)) return TC_ACT_PIPE;
+
+    // This takes care of updating the skb->csum field for a CHECKSUM_COMPLETE packet.
+    //
+    // In such a case, skb->csum is a 16-bit one's complement sum of the entire payload,
+    // thus we need to subtract out the ipv4 header's sum, and add in the ipv6 header's sum.
+    // However, we've already verified the ipv4 checksum is correct and thus 0.
+    // Thus we only need to add the ipv6 header's sum.
+    //
+    // bpf_csum_update() always succeeds if the skb is CHECKSUM_COMPLETE and returns an error
+    // (-ENOTSUPP) if it isn't.  So we just ignore the return code (see above for more details).
+    bpf_csum_update(skb, sum6);
+
+    // bpf_skb_change_proto() invalidates all pointers - reload them.
+    data = (void*)(long)skb->data;
+    data_end = (void*)(long)skb->data_end;
+
+    // I cannot think of any valid way for this error condition to trigger, however I do
+    // believe the explicit check is required to keep the in kernel ebpf verifier happy.
+    if (data + sizeof(ip6) > data_end) return TC_ACT_SHOT;
+
+    // Copy over the new ipv6 header without an ethernet header.
+    *(struct ipv6hdr*)data = ip6;
+
+    // Redirect to non v4-* interface.  Tcpdump only sees packet after this redirect.
+    return bpf_redirect(v->oif, 0 /* this is effectively BPF_F_EGRESS */);
+}
+
+LICENSE("Apache 2.0");
+CRITICAL("netd");
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
new file mode 100644
index 0000000..72ee431
--- /dev/null
+++ b/bpf_progs/netd.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include <bpf_helpers.h>
+#include <linux/bpf.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/if_packet.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/pkt_cls.h>
+#include <linux/tcp.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include "bpf_net_helpers.h"
+#include "bpf_shared.h"
+
+// This is defined for cgroup bpf filter only.
+#define BPF_DROP_UNLESS_DNS 2
+#define BPF_PASS 1
+#define BPF_DROP 0
+
+// This is used for xt_bpf program only.
+#define BPF_NOMATCH 0
+#define BPF_MATCH 1
+
+#define BPF_EGRESS 0
+#define BPF_INGRESS 1
+
+#define IP_PROTO_OFF offsetof(struct iphdr, protocol)
+#define IPV6_PROTO_OFF offsetof(struct ipv6hdr, nexthdr)
+#define IPPROTO_IHL_OFF 0
+#define TCP_FLAG_OFF 13
+#define RST_OFFSET 2
+
+DEFINE_BPF_MAP_GRW(cookie_tag_map, HASH, uint64_t, UidTagValue, COOKIE_UID_MAP_SIZE,
+                   AID_NET_BW_ACCT)
+DEFINE_BPF_MAP_GRW(uid_counterset_map, HASH, uint32_t, uint8_t, UID_COUNTERSET_MAP_SIZE,
+                   AID_NET_BW_ACCT)
+DEFINE_BPF_MAP_GRW(app_uid_stats_map, HASH, uint32_t, StatsValue, APP_STATS_MAP_SIZE,
+                   AID_NET_BW_ACCT)
+DEFINE_BPF_MAP_GRW(stats_map_A, HASH, StatsKey, StatsValue, STATS_MAP_SIZE, AID_NET_BW_ACCT)
+DEFINE_BPF_MAP_GRW(stats_map_B, HASH, StatsKey, StatsValue, STATS_MAP_SIZE, AID_NET_BW_ACCT)
+DEFINE_BPF_MAP_GRW(iface_stats_map, HASH, uint32_t, StatsValue, IFACE_STATS_MAP_SIZE,
+                   AID_NET_BW_ACCT)
+DEFINE_BPF_MAP_GRW(configuration_map, HASH, uint32_t, uint8_t, CONFIGURATION_MAP_SIZE,
+                   AID_NET_BW_ACCT)
+DEFINE_BPF_MAP_GRW(uid_owner_map, HASH, uint32_t, UidOwnerValue, UID_OWNER_MAP_SIZE,
+                   AID_NET_BW_ACCT)
+DEFINE_BPF_MAP_GRW(uid_permission_map, HASH, uint32_t, uint8_t, UID_OWNER_MAP_SIZE, AID_NET_BW_ACCT)
+
+/* never actually used from ebpf */
+DEFINE_BPF_MAP_GRW(iface_index_name_map, HASH, uint32_t, IfaceValue, IFACE_INDEX_NAME_MAP_SIZE,
+                   AID_NET_BW_ACCT)
+
+static __always_inline int is_system_uid(uint32_t uid) {
+    return (uid <= MAX_SYSTEM_UID) && (uid >= MIN_SYSTEM_UID);
+}
+
+/*
+ * Note: this blindly assumes an MTU of 1500, and that packets > MTU are always TCP,
+ * and that TCP is using the Linux default settings with TCP timestamp option enabled
+ * which uses 12 TCP option bytes per frame.
+ *
+ * These are not unreasonable assumptions:
+ *
+ * The internet does not really support MTUs greater than 1500, so most TCP traffic will
+ * be at that MTU, or slightly below it (worst case our upwards adjustment is too small).
+ *
+ * The chance our traffic isn't IP at all is basically zero, so the IP overhead correction
+ * is bound to be needed.
+ *
+ * Furthermore, the likelyhood that we're having to deal with GSO (ie. > MTU) packets that
+ * are not IP/TCP is pretty small (few other things are supported by Linux) and worse case
+ * our extra overhead will be slightly off, but probably still better than assuming none.
+ *
+ * Most servers are also Linux and thus support/default to using TCP timestamp option
+ * (and indeed TCP timestamp option comes from RFC 1323 titled "TCP Extensions for High
+ * Performance" which also defined TCP window scaling and are thus absolutely ancient...).
+ *
+ * All together this should be more correct than if we simply ignored GSO frames
+ * (ie. counted them as single packets with no extra overhead)
+ *
+ * Especially since the number of packets is important for any future clat offload correction.
+ * (which adjusts upward by 20 bytes per packet to account for ipv4 -> ipv6 header conversion)
+ */
+#define DEFINE_UPDATE_STATS(the_stats_map, TypeOfKey)                                          \
+    static __always_inline inline void update_##the_stats_map(struct __sk_buff* skb,           \
+                                                              int direction, TypeOfKey* key) { \
+        StatsValue* value = bpf_##the_stats_map##_lookup_elem(key);                            \
+        if (!value) {                                                                          \
+            StatsValue newValue = {};                                                          \
+            bpf_##the_stats_map##_update_elem(key, &newValue, BPF_NOEXIST);                    \
+            value = bpf_##the_stats_map##_lookup_elem(key);                                    \
+        }                                                                                      \
+        if (value) {                                                                           \
+            const int mtu = 1500;                                                              \
+            uint64_t packets = 1;                                                              \
+            uint64_t bytes = skb->len;                                                         \
+            if (bytes > mtu) {                                                                 \
+                bool is_ipv6 = (skb->protocol == htons(ETH_P_IPV6));                           \
+                int ip_overhead = (is_ipv6 ? sizeof(struct ipv6hdr) : sizeof(struct iphdr));   \
+                int tcp_overhead = ip_overhead + sizeof(struct tcphdr) + 12;                   \
+                int mss = mtu - tcp_overhead;                                                  \
+                uint64_t payload = bytes - tcp_overhead;                                       \
+                packets = (payload + mss - 1) / mss;                                           \
+                bytes = tcp_overhead * packets + payload;                                      \
+            }                                                                                  \
+            if (direction == BPF_EGRESS) {                                                     \
+                __sync_fetch_and_add(&value->txPackets, packets);                              \
+                __sync_fetch_and_add(&value->txBytes, bytes);                                  \
+            } else if (direction == BPF_INGRESS) {                                             \
+                __sync_fetch_and_add(&value->rxPackets, packets);                              \
+                __sync_fetch_and_add(&value->rxBytes, bytes);                                  \
+            }                                                                                  \
+        }                                                                                      \
+    }
+
+DEFINE_UPDATE_STATS(app_uid_stats_map, uint32_t)
+DEFINE_UPDATE_STATS(iface_stats_map, uint32_t)
+DEFINE_UPDATE_STATS(stats_map_A, StatsKey)
+DEFINE_UPDATE_STATS(stats_map_B, StatsKey)
+
+static inline bool skip_owner_match(struct __sk_buff* skb) {
+    int offset = -1;
+    int ret = 0;
+    if (skb->protocol == htons(ETH_P_IP)) {
+        offset = IP_PROTO_OFF;
+        uint8_t proto, ihl;
+        uint8_t flag;
+        ret = bpf_skb_load_bytes(skb, offset, &proto, 1);
+        if (!ret) {
+            if (proto == IPPROTO_ESP) {
+                return true;
+            } else if (proto == IPPROTO_TCP) {
+                ret = bpf_skb_load_bytes(skb, IPPROTO_IHL_OFF, &ihl, 1);
+                ihl = ihl & 0x0F;
+                ret = bpf_skb_load_bytes(skb, ihl * 4 + TCP_FLAG_OFF, &flag, 1);
+                if (ret == 0 && (flag >> RST_OFFSET & 1)) {
+                    return true;
+                }
+            }
+        }
+    } else if (skb->protocol == htons(ETH_P_IPV6)) {
+        offset = IPV6_PROTO_OFF;
+        uint8_t proto;
+        ret = bpf_skb_load_bytes(skb, offset, &proto, 1);
+        if (!ret) {
+            if (proto == IPPROTO_ESP) {
+                return true;
+            } else if (proto == IPPROTO_TCP) {
+                uint8_t flag;
+                ret = bpf_skb_load_bytes(skb, sizeof(struct ipv6hdr) + TCP_FLAG_OFF, &flag, 1);
+                if (ret == 0 && (flag >> RST_OFFSET & 1)) {
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+static __always_inline BpfConfig getConfig(uint32_t configKey) {
+    uint32_t mapSettingKey = configKey;
+    BpfConfig* config = bpf_configuration_map_lookup_elem(&mapSettingKey);
+    if (!config) {
+        // Couldn't read configuration entry. Assume everything is disabled.
+        return DEFAULT_CONFIG;
+    }
+    return *config;
+}
+
+static inline int bpf_owner_match(struct __sk_buff* skb, uint32_t uid, int direction) {
+    if (skip_owner_match(skb)) return BPF_PASS;
+
+    if (is_system_uid(uid)) return BPF_PASS;
+
+    BpfConfig enabledRules = getConfig(UID_RULES_CONFIGURATION_KEY);
+
+    UidOwnerValue* uidEntry = bpf_uid_owner_map_lookup_elem(&uid);
+    uint8_t uidRules = uidEntry ? uidEntry->rule : 0;
+    uint32_t allowed_iif = uidEntry ? uidEntry->iif : 0;
+
+    if (enabledRules) {
+        if ((enabledRules & DOZABLE_MATCH) && !(uidRules & DOZABLE_MATCH)) {
+            return BPF_DROP;
+        }
+        if ((enabledRules & STANDBY_MATCH) && (uidRules & STANDBY_MATCH)) {
+            return BPF_DROP;
+        }
+        if ((enabledRules & POWERSAVE_MATCH) && !(uidRules & POWERSAVE_MATCH)) {
+            return BPF_DROP;
+        }
+        if ((enabledRules & RESTRICTED_MATCH) && !(uidRules & RESTRICTED_MATCH)) {
+            return BPF_DROP;
+        }
+    }
+    if (direction == BPF_INGRESS && (uidRules & IIF_MATCH)) {
+        // Drops packets not coming from lo nor the allowlisted interface
+        if (allowed_iif && skb->ifindex != 1 && skb->ifindex != allowed_iif) {
+            return BPF_DROP_UNLESS_DNS;
+        }
+    }
+    return BPF_PASS;
+}
+
+static __always_inline inline void update_stats_with_config(struct __sk_buff* skb, int direction,
+                                                            StatsKey* key, uint8_t selectedMap) {
+    if (selectedMap == SELECT_MAP_A) {
+        update_stats_map_A(skb, direction, key);
+    } else if (selectedMap == SELECT_MAP_B) {
+        update_stats_map_B(skb, direction, key);
+    }
+}
+
+static __always_inline inline int bpf_traffic_account(struct __sk_buff* skb, int direction) {
+    uint32_t sock_uid = bpf_get_socket_uid(skb);
+    uint64_t cookie = bpf_get_socket_cookie(skb);
+    UidTagValue* utag = bpf_cookie_tag_map_lookup_elem(&cookie);
+    uint32_t uid, tag;
+    if (utag) {
+        uid = utag->uid;
+        tag = utag->tag;
+    } else {
+        uid = sock_uid;
+        tag = 0;
+    }
+
+    // Always allow and never count clat traffic. Only the IPv4 traffic on the stacked
+    // interface is accounted for and subject to usage restrictions.
+    // TODO: remove sock_uid check once Nat464Xlat javaland adds the socket tag AID_CLAT for clat.
+    if (sock_uid == AID_CLAT || uid == AID_CLAT) {
+        return BPF_PASS;
+    }
+
+    int match = bpf_owner_match(skb, sock_uid, direction);
+    if ((direction == BPF_EGRESS) && (match == BPF_DROP)) {
+        // If an outbound packet is going to be dropped, we do not count that
+        // traffic.
+        return match;
+    }
+
+// Workaround for secureVPN with VpnIsolation enabled, refer to b/159994981 for details.
+// Keep TAG_SYSTEM_DNS in sync with DnsResolver/include/netd_resolv/resolv.h
+// and TrafficStatsConstants.java
+#define TAG_SYSTEM_DNS 0xFFFFFF82
+    if (tag == TAG_SYSTEM_DNS && uid == AID_DNS) {
+        uid = sock_uid;
+        if (match == BPF_DROP_UNLESS_DNS) match = BPF_PASS;
+    } else {
+        if (match == BPF_DROP_UNLESS_DNS) match = BPF_DROP;
+    }
+
+    StatsKey key = {.uid = uid, .tag = tag, .counterSet = 0, .ifaceIndex = skb->ifindex};
+
+    uint8_t* counterSet = bpf_uid_counterset_map_lookup_elem(&uid);
+    if (counterSet) key.counterSet = (uint32_t)*counterSet;
+
+    uint32_t mapSettingKey = CURRENT_STATS_MAP_CONFIGURATION_KEY;
+    uint8_t* selectedMap = bpf_configuration_map_lookup_elem(&mapSettingKey);
+
+    // Use asm("%0 &= 1" : "+r"(match)) before return match,
+    // to help kernel's bpf verifier, so that it can be 100% certain
+    // that the returned value is always BPF_NOMATCH(0) or BPF_MATCH(1).
+    if (!selectedMap) {
+        asm("%0 &= 1" : "+r"(match));
+        return match;
+    }
+
+    if (key.tag) {
+        update_stats_with_config(skb, direction, &key, *selectedMap);
+        key.tag = 0;
+    }
+
+    update_stats_with_config(skb, direction, &key, *selectedMap);
+    update_app_uid_stats_map(skb, direction, &uid);
+    asm("%0 &= 1" : "+r"(match));
+    return match;
+}
+
+DEFINE_BPF_PROG("cgroupskb/ingress/stats", AID_ROOT, AID_ROOT, bpf_cgroup_ingress)
+(struct __sk_buff* skb) {
+    return bpf_traffic_account(skb, BPF_INGRESS);
+}
+
+DEFINE_BPF_PROG("cgroupskb/egress/stats", AID_ROOT, AID_ROOT, bpf_cgroup_egress)
+(struct __sk_buff* skb) {
+    return bpf_traffic_account(skb, BPF_EGRESS);
+}
+
+DEFINE_BPF_PROG("skfilter/egress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_egress_prog)
+(struct __sk_buff* skb) {
+    // Clat daemon does not generate new traffic, all its traffic is accounted for already
+    // on the v4-* interfaces (except for the 20 (or 28) extra bytes of IPv6 vs IPv4 overhead,
+    // but that can be corrected for later when merging v4-foo stats into interface foo's).
+    // TODO: remove sock_uid check once Nat464Xlat javaland adds the socket tag AID_CLAT for clat.
+    uint32_t sock_uid = bpf_get_socket_uid(skb);
+    if (sock_uid == AID_CLAT) return BPF_NOMATCH;
+    if (sock_uid == AID_SYSTEM) {
+        uint64_t cookie = bpf_get_socket_cookie(skb);
+        UidTagValue* utag = bpf_cookie_tag_map_lookup_elem(&cookie);
+        if (utag && utag->uid == AID_CLAT) return BPF_NOMATCH;
+    }
+
+    uint32_t key = skb->ifindex;
+    update_iface_stats_map(skb, BPF_EGRESS, &key);
+    return BPF_MATCH;
+}
+
+DEFINE_BPF_PROG("skfilter/ingress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_ingress_prog)
+(struct __sk_buff* skb) {
+    // Clat daemon traffic is not accounted by virtue of iptables raw prerouting drop rule
+    // (in clat_raw_PREROUTING chain), which triggers before this (in bw_raw_PREROUTING chain).
+    // It will be accounted for on the v4-* clat interface instead.
+    // Keep that in mind when moving this out of iptables xt_bpf and into tc ingress (or xdp).
+
+    uint32_t key = skb->ifindex;
+    update_iface_stats_map(skb, BPF_INGRESS, &key);
+    return BPF_MATCH;
+}
+
+DEFINE_BPF_PROG("schedact/ingress/account", AID_ROOT, AID_NET_ADMIN, tc_bpf_ingress_account_prog)
+(struct __sk_buff* skb) {
+    // Account for ingress traffic before tc drops it.
+    uint32_t key = skb->ifindex;
+    update_iface_stats_map(skb, BPF_INGRESS, &key);
+    return TC_ACT_UNSPEC;
+}
+
+DEFINE_BPF_PROG("skfilter/allowlist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_allowlist_prog)
+(struct __sk_buff* skb) {
+    uint32_t sock_uid = bpf_get_socket_uid(skb);
+    if (is_system_uid(sock_uid)) return BPF_MATCH;
+
+    // 65534 is the overflow 'nobody' uid, usually this being returned means
+    // that skb->sk is NULL during RX (early decap socket lookup failure),
+    // which commonly happens for incoming packets to an unconnected udp socket.
+    // Additionally bpf_get_socket_cookie() returns 0 if skb->sk is NULL
+    if ((sock_uid == 65534) && !bpf_get_socket_cookie(skb) && is_received_skb(skb))
+        return BPF_MATCH;
+
+    UidOwnerValue* allowlistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
+    if (allowlistMatch) return allowlistMatch->rule & HAPPY_BOX_MATCH ? BPF_MATCH : BPF_NOMATCH;
+    return BPF_NOMATCH;
+}
+
+DEFINE_BPF_PROG("skfilter/denylist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_denylist_prog)
+(struct __sk_buff* skb) {
+    uint32_t sock_uid = bpf_get_socket_uid(skb);
+    UidOwnerValue* denylistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
+    if (denylistMatch) return denylistMatch->rule & PENALTY_BOX_MATCH ? BPF_MATCH : BPF_NOMATCH;
+    return BPF_NOMATCH;
+}
+
+DEFINE_BPF_PROG_KVER("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_create,
+                     KVER(4, 14, 0))
+(struct bpf_sock* sk) {
+    uint64_t gid_uid = bpf_get_current_uid_gid();
+    /*
+     * A given app is guaranteed to have the same app ID in all the profiles in
+     * which it is installed, and install permission is granted to app for all
+     * user at install time so we only check the appId part of a request uid at
+     * run time. See UserHandle#isSameApp for detail.
+     */
+    uint32_t appId = (gid_uid & 0xffffffff) % PER_USER_RANGE;
+    uint8_t* permissions = bpf_uid_permission_map_lookup_elem(&appId);
+    if (!permissions) {
+        // UID not in map. Default to just INTERNET permission.
+        return 1;
+    }
+
+    // A return value of 1 means allow, everything else means deny.
+    return (*permissions & BPF_PERMISSION_INTERNET) == BPF_PERMISSION_INTERNET;
+}
+
+LICENSE("Apache 2.0");
+CRITICAL("netd");
diff --git a/framework/api/current.txt b/framework/api/current.txt
index 827da6d..ce0c868 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -294,7 +294,7 @@
     ctor public NetworkCapabilities(android.net.NetworkCapabilities);
     method public int describeContents();
     method @NonNull public int[] getCapabilities();
-    method @NonNull public int[] getEnterpriseCapabilitySubLevels();
+    method @NonNull public int[] getEnterpriseIds();
     method public int getLinkDownstreamBandwidthKbps();
     method public int getLinkUpstreamBandwidthKbps();
     method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
@@ -302,6 +302,7 @@
     method public int getSignalStrength();
     method @Nullable public android.net.TransportInfo getTransportInfo();
     method public boolean hasCapability(int);
+    method public boolean hasEnterpriseId(int);
     method public boolean hasTransport(int);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
@@ -332,6 +333,11 @@
     field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10
     field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6
     field public static final int NET_CAPABILITY_XCAP = 9; // 0x9
+    field public static final int NET_ENTERPRISE_ID_1 = 1; // 0x1
+    field public static final int NET_ENTERPRISE_ID_2 = 2; // 0x2
+    field public static final int NET_ENTERPRISE_ID_3 = 3; // 0x3
+    field public static final int NET_ENTERPRISE_ID_4 = 4; // 0x4
+    field public static final int NET_ENTERPRISE_ID_5 = 5; // 0x5
     field public static final int SIGNAL_STRENGTH_UNSPECIFIED = -2147483648; // 0x80000000
     field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2
     field public static final int TRANSPORT_CELLULAR = 0; // 0x0
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index 415b3e5..db08c48 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -133,11 +133,6 @@
   public final class NetworkCapabilities implements android.os.Parcelable {
     method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids();
     method public boolean hasForbiddenCapability(int);
-    field public static final int NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1 = 1; // 0x1
-    field public static final int NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2 = 2; // 0x2
-    field public static final int NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_3 = 3; // 0x3
-    field public static final int NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_4 = 4; // 0x4
-    field public static final int NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_5 = 5; // 0x5
     field public static final long REDACT_ALL = -1L; // 0xffffffffffffffffL
     field public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1L; // 0x1L
     field public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 2L; // 0x2L
@@ -163,7 +158,10 @@
 
   public final class ProfileNetworkPreference implements android.os.Parcelable {
     method public int describeContents();
+    method @NonNull public java.util.List<java.lang.Integer> getExcludedUids();
+    method @NonNull public java.util.List<java.lang.Integer> getIncludedUids();
     method public int getPreference();
+    method public int getPreferenceEnterpriseId();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.ProfileNetworkPreference> CREATOR;
   }
@@ -171,7 +169,10 @@
   public static final class ProfileNetworkPreference.Builder {
     ctor public ProfileNetworkPreference.Builder();
     method @NonNull public android.net.ProfileNetworkPreference build();
+    method @NonNull public android.net.ProfileNetworkPreference.Builder setExcludedUids(@Nullable java.util.List<java.lang.Integer>);
+    method @NonNull public android.net.ProfileNetworkPreference.Builder setIncludedUids(@Nullable java.util.List<java.lang.Integer>);
     method @NonNull public android.net.ProfileNetworkPreference.Builder setPreference(int);
+    method @NonNull public android.net.ProfileNetworkPreference.Builder setPreferenceEnterpriseId(int);
   }
 
   public final class TestNetworkInterface implements android.os.Parcelable {
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 8d084e6..b4b3588 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -294,11 +294,11 @@
     ctor public NetworkCapabilities.Builder();
     ctor public NetworkCapabilities.Builder(@NonNull android.net.NetworkCapabilities);
     method @NonNull public android.net.NetworkCapabilities.Builder addCapability(int);
-    method @NonNull public android.net.NetworkCapabilities.Builder addEnterpriseCapabilitySubLevel(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder addEnterpriseId(int);
     method @NonNull public android.net.NetworkCapabilities.Builder addTransportType(int);
     method @NonNull public android.net.NetworkCapabilities build();
     method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int);
-    method @NonNull public android.net.NetworkCapabilities.Builder removeEnterpriseCapabilitySubLevel(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder removeEnterpriseId(int);
     method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int);
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]);
     method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int);
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 7d65f8c..7593482 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -16,6 +16,7 @@
 package android.net;
 
 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
 import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
 import static android.net.NetworkRequest.Type.LISTEN;
 import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
@@ -5537,6 +5538,9 @@
         ProfileNetworkPreference.Builder preferenceBuilder =
                 new ProfileNetworkPreference.Builder();
         preferenceBuilder.setPreference(preference);
+        if (preference != PROFILE_NETWORK_PREFERENCE_DEFAULT) {
+            preferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        }
         setProfileNetworkPreferences(profile,
                 List.of(preferenceBuilder.build()), executor, listener);
     }
@@ -5612,7 +5616,7 @@
      * background data is restricted.
      *
      * @param uid uid of target app
-     * @throws IllegalStateException if update allow list failed.
+     * @throws IllegalStateException if updating allow list failed.
      * @hide
      */
     @SystemApi(client = MODULE_LIBRARIES)
@@ -5634,7 +5638,7 @@
      * Takes precedence over {@link #updateMeteredNetworkAllowList}.
      *
      * @param uid uid of target app
-     * @throws IllegalStateException if update deny list failed.
+     * @throws IllegalStateException if updating deny list failed.
      * @hide
      */
     @SystemApi(client = MODULE_LIBRARIES)
@@ -5656,8 +5660,8 @@
      *
      * @param chain target chain.
      * @param uid uid to allow/deny.
-     * @param allow either add or remove rule.
-     * @throws IllegalStateException if update firewall rule failed.
+     * @param allow whether networking is allowed or denied.
+     * @throws IllegalStateException if updating firewall rule failed.
      * @hide
      */
     @SystemApi(client = MODULE_LIBRARIES)
@@ -5680,7 +5684,7 @@
      *
      * @param chain target chain.
      * @param enable whether the chain should be enabled.
-     * @throws IllegalStateException if set firewall chain failed.
+     * @throws IllegalStateException if enabling or disabling the firewall chain failed.
      * @hide
      */
     @SystemApi(client = MODULE_LIBRARIES)
@@ -5702,7 +5706,7 @@
      *
      * @param chain target chain to replace.
      * @param uids The list of UIDs to be placed into chain.
-     * @throws IllegalStateException if replace firewall chain failed.
+     * @throws IllegalStateException if replacing the firewall chain failed.
      * @throws IllegalArgumentException if {@code chain} is not a valid chain.
      * @hide
      */
@@ -5727,7 +5731,7 @@
      * NetworkStatsFactory which is platform code but will be moved into connectivity (tethering)
      * mainline module.
      *
-     * @throws IllegalStateException if swap active stats map failed.
+     * @throws IllegalStateException if swapping active stats map failed.
      * @hide
      */
     @SystemApi(client = MODULE_LIBRARIES)
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index 84f7cbb..c98be47 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -16,8 +16,6 @@
 
 package android.net;
 
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
 
 import android.annotation.IntDef;
@@ -149,67 +147,83 @@
     private String mRequestorPackageName;
 
     /**
-     * enterprise capability sub level 1
-     * @hide
+     * Enterprise capability identifier 1.
      */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static final int NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1 = 1;
+    public static final int NET_ENTERPRISE_ID_1 = 1;
 
     /**
-     * enterprise capability sub level 2
-     * @hide
+     * Enterprise capability identifier 2.
      */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static final int NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2 = 2;
+    public static final int NET_ENTERPRISE_ID_2 = 2;
 
     /**
-     * enterprise capability sub level 3
-     * @hide
+     * Enterprise capability identifier 3.
      */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static final int NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_3 = 3;
+    public static final int NET_ENTERPRISE_ID_3 = 3;
 
     /**
-     * enterprise capability sub level 4
-     * @hide
+     * Enterprise capability identifier 4.
      */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static final int NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_4 = 4;
+    public static final int NET_ENTERPRISE_ID_4 = 4;
 
     /**
-     * enterprise capability sub level 5
-     * @hide
+     * Enterprise capability identifier 5.
      */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static final int NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_5 = 5;
+    public static final int NET_ENTERPRISE_ID_5 = 5;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = { "NET_CAPABILITY_ENTERPRISE_SUB_LEVEL" }, value = {
-            NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1,
-            NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2,
-            NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_3,
-            NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_4,
-            NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_5,
+            NET_ENTERPRISE_ID_1,
+            NET_ENTERPRISE_ID_2,
+            NET_ENTERPRISE_ID_3,
+            NET_ENTERPRISE_ID_4,
+            NET_ENTERPRISE_ID_5,
     })
 
-    public @interface EnterpriseCapabilitySubLevel {
+    public @interface EnterpriseId {
     }
 
     /**
-     * Bitfield representing the network's enterprise capability sublevel.  If any are specified
+     * Bitfield representing the network's enterprise capability identifier.  If any are specified
      * they will be satisfied by any Network that matches all of them.
-     * {@see addEnterpriseCapabilitySubLevel} for details on how masks are added
+     * {@see addEnterpriseId} for details on how masks are added
      */
-    private int mEnterpriseCapabilitySubLevel;
+    private int mEnterpriseId;
 
     /**
-     * @return all the enteprise capabilities sub level set on this {@code NetworkCapability}
-     * instance.
+     * Get enteprise identifiers set.
+     *
+     * Get all the enterprise capabilities identifier set on this {@code NetworkCapability}
+     * If NET_CAPABILITY_ENTERPRISE is set and no enterprise ID is set, it is
+     * considered to have NET_CAPABILITY_ENTERPRISE by default.
+     * @return all the enterprise capabilities identifier set.
      *
      */
-    public @NonNull @EnterpriseCapabilitySubLevel int[] getEnterpriseCapabilitySubLevels() {
-        return NetworkCapabilitiesUtils.unpackBits(mEnterpriseCapabilitySubLevel);
+    public @NonNull @EnterpriseId int[] getEnterpriseIds() {
+        if (hasCapability(NET_CAPABILITY_ENTERPRISE) && mEnterpriseId == 0) {
+            return new int[]{NET_ENTERPRISE_ID_1};
+        }
+        return NetworkCapabilitiesUtils.unpackBits(mEnterpriseId);
+    }
+
+    /**
+     * Tests for the presence of an enterprise capability identifier on this instance.
+     *
+     * If NET_CAPABILITY_ENTERPRISE is set and no enterprise ID is set, it is
+     * considered to have NET_CAPABILITY_ENTERPRISE by default.
+     * @param enterpriseId the enterprise capability identifier to be tested for.
+     * @return {@code true} if set on this instance.
+     */
+    public boolean hasEnterpriseId(
+            @EnterpriseId int enterpriseId) {
+        if (enterpriseId == NET_ENTERPRISE_ID_1) {
+            if (hasCapability(NET_CAPABILITY_ENTERPRISE) && mEnterpriseId == 0) {
+                return true;
+            }
+        }
+        return isValidEnterpriseId(enterpriseId)
+                && ((mEnterpriseId & (1L << enterpriseId)) != 0);
     }
 
     public NetworkCapabilities() {
@@ -258,7 +272,7 @@
         mRequestorPackageName = null;
         mSubIds = new ArraySet<>();
         mUnderlyingNetworks = null;
-        mEnterpriseCapabilitySubLevel = 0;
+        mEnterpriseId = 0;
     }
 
     /**
@@ -291,7 +305,7 @@
         // mUnderlyingNetworks is an unmodifiable list if non-null, so a defensive copy is not
         // necessary.
         mUnderlyingNetworks = nc.mUnderlyingNetworks;
-        mEnterpriseCapabilitySubLevel = nc.mEnterpriseCapabilitySubLevel;
+        mEnterpriseId = nc.mEnterpriseId;
     }
 
     /**
@@ -784,34 +798,34 @@
     }
 
     /**
-     * Adds the given enterprise capability sub level to this {@code NetworkCapability} instance.
-     * Note that when searching for a network to satisfy a request, all capabilities sub level
+     * Adds the given enterprise capability identifier to this {@code NetworkCapability} instance.
+     * Note that when searching for a network to satisfy a request, all capabilities identifier
      * requested must be satisfied.
      *
-     * @param enterpriseCapabilitySubLevel the enterprise capability sub level to be added.
+     * @param enterpriseId the enterprise capability identifier to be added.
      * @return This NetworkCapabilities instance, to facilitate chaining.
      * @hide
      */
-    private @NonNull NetworkCapabilities addEnterpriseCapabilitySubLevel(
-            @EnterpriseCapabilitySubLevel int enterpriseCapabilitySubLevel) {
-        checkValidEnterpriseCapabilitySublevel(enterpriseCapabilitySubLevel);
-        mEnterpriseCapabilitySubLevel |= 1 << enterpriseCapabilitySubLevel;
+    public @NonNull NetworkCapabilities addEnterpriseId(
+            @EnterpriseId int enterpriseId) {
+        checkValidEnterpriseId(enterpriseId);
+        mEnterpriseId |= 1 << enterpriseId;
         return this;
     }
 
     /**
-     * Removes (if found) the given enterprise capability sublevel from this
-     * {@code NetworkCapability} instance that were added via addEnterpriseCapabilitySubLevel(int)
+     * Removes (if found) the given enterprise capability identifier from this
+     * {@code NetworkCapability} instance that were added via addEnterpriseId(int)
      *
-     * @param enterpriseCapabilitySubLevel the enterprise capability sublevel to be removed.
+     * @param enterpriseId the enterprise capability identifier to be removed.
      * @return This NetworkCapabilities instance, to facilitate chaining.
      * @hide
      */
-    private @NonNull NetworkCapabilities removeEnterpriseCapabilitySubLevel(
-            @EnterpriseCapabilitySubLevel  int enterpriseCapabilitySubLevel) {
-        checkValidEnterpriseCapabilitySublevel(enterpriseCapabilitySubLevel);
-        final int mask = ~(1 << enterpriseCapabilitySubLevel);
-        mEnterpriseCapabilitySubLevel &= mask;
+    private @NonNull NetworkCapabilities removeEnterpriseId(
+            @EnterpriseId  int enterpriseId) {
+        checkValidEnterpriseId(enterpriseId);
+        final int mask = ~(1 << enterpriseId);
+        mEnterpriseId &= mask;
         return this;
     }
 
@@ -915,16 +929,19 @@
         return null;
     }
 
-    private boolean equalsEnterpriseCapabilitiesSubLevel(@NonNull NetworkCapabilities nc) {
-        return nc.mEnterpriseCapabilitySubLevel == this.mEnterpriseCapabilitySubLevel;
+    private boolean equalsEnterpriseCapabilitiesId(@NonNull NetworkCapabilities nc) {
+        return nc.mEnterpriseId == this.mEnterpriseId;
     }
 
-    private boolean satisfiedByEnterpriseCapabilitiesSubLevel(@NonNull NetworkCapabilities nc) {
-        final int requestedEnterpriseCapabilitiesSubLevel = mEnterpriseCapabilitySubLevel;
-        final int providedEnterpriseCapabailitiesSubLevel = nc.mEnterpriseCapabilitySubLevel;
+    private boolean satisfiedByEnterpriseCapabilitiesId(@NonNull NetworkCapabilities nc) {
+        final int requestedEnterpriseCapabilitiesId = mEnterpriseId;
+        final int providedEnterpriseCapabailitiesId = nc.mEnterpriseId;
 
-        if ((providedEnterpriseCapabailitiesSubLevel & requestedEnterpriseCapabilitiesSubLevel)
-                == requestedEnterpriseCapabilitiesSubLevel) {
+        if ((providedEnterpriseCapabailitiesId & requestedEnterpriseCapabilitiesId)
+                == requestedEnterpriseCapabilitiesId) {
+            return true;
+        } else if (providedEnterpriseCapabailitiesId == 0
+                && (requestedEnterpriseCapabilitiesId == (1L << NET_ENTERPRISE_ID_1))) {
             return true;
         } else {
             return false;
@@ -1836,7 +1853,7 @@
                 && satisfiedByTransportTypes(nc)
                 && (onlyImmutable || satisfiedByLinkBandwidths(nc))
                 && satisfiedBySpecifier(nc)
-                && satisfiedByEnterpriseCapabilitiesSubLevel(nc)
+                && satisfiedByEnterpriseCapabilitiesId(nc)
                 && (onlyImmutable || satisfiedBySignalStrength(nc))
                 && (onlyImmutable || satisfiedByUids(nc))
                 && (onlyImmutable || satisfiedBySSID(nc))
@@ -1940,7 +1957,7 @@
                 && equalsAdministratorUids(that)
                 && equalsSubscriptionIds(that)
                 && equalsUnderlyingNetworks(that)
-                && equalsEnterpriseCapabilitiesSubLevel(that);
+                && equalsEnterpriseCapabilitiesId(that);
     }
 
     @Override
@@ -1965,7 +1982,7 @@
                 + Arrays.hashCode(mAdministratorUids) * 61
                 + Objects.hashCode(mSubIds) * 67
                 + Objects.hashCode(mUnderlyingNetworks) * 71
-                + mEnterpriseCapabilitySubLevel * 73;
+                + mEnterpriseId * 73;
     }
 
     @Override
@@ -2001,7 +2018,7 @@
         dest.writeString(mRequestorPackageName);
         dest.writeIntArray(CollectionUtils.toIntArray(mSubIds));
         dest.writeTypedList(mUnderlyingNetworks);
-        dest.writeInt(mEnterpriseCapabilitySubLevel);
+        dest.writeInt(mEnterpriseId);
     }
 
     public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
@@ -2031,7 +2048,7 @@
                     netCap.mSubIds.add(subIdInts[i]);
                 }
                 netCap.setUnderlyingNetworks(in.createTypedArrayList(Network.CREATOR));
-                netCap.mEnterpriseCapabilitySubLevel = in.readInt();
+                netCap.mEnterpriseId = in.readInt();
                 return netCap;
             }
             @Override
@@ -2123,10 +2140,10 @@
             sb.append(" SubscriptionIds: ").append(mSubIds);
         }
 
-        if (0 != mEnterpriseCapabilitySubLevel) {
-            sb.append(" EnterpriseCapabilitySublevel: ");
-            appendStringRepresentationOfBitMaskToStringBuilder(sb, mEnterpriseCapabilitySubLevel,
-                    NetworkCapabilities::enterpriseCapabilitySublevelNameOf, "&");
+        if (0 != mEnterpriseId) {
+            sb.append(" EnterpriseId: ");
+            appendStringRepresentationOfBitMaskToStringBuilder(sb, mEnterpriseId,
+                    NetworkCapabilities::enterpriseIdNameOf, "&");
         }
 
         sb.append(" UnderlyingNetworks: ");
@@ -2228,7 +2245,7 @@
         }
     }
 
-    private static @NonNull String enterpriseCapabilitySublevelNameOf(
+    private static @NonNull String enterpriseIdNameOf(
             @NetCapability int capability) {
         return Integer.toString(capability);
     }
@@ -2273,17 +2290,17 @@
         }
     }
 
-    private static boolean isValidEnterpriseCapabilitySubLevel(
-            @NetworkCapabilities.EnterpriseCapabilitySubLevel int enterpriseCapabilitySubLevel) {
-        return enterpriseCapabilitySubLevel >= NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1
-                && enterpriseCapabilitySubLevel <= NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_5;
+    private static boolean isValidEnterpriseId(
+            @NetworkCapabilities.EnterpriseId int enterpriseId) {
+        return enterpriseId >= NET_ENTERPRISE_ID_1
+                && enterpriseId <= NET_ENTERPRISE_ID_5;
     }
 
-    private static void checkValidEnterpriseCapabilitySublevel(
-            @NetworkCapabilities.EnterpriseCapabilitySubLevel int enterpriseCapabilitySubLevel) {
-        if (!isValidEnterpriseCapabilitySubLevel(enterpriseCapabilitySubLevel)) {
-            throw new IllegalArgumentException("enterprise capability sublevel "
-                    + enterpriseCapabilitySubLevel + " is out of range");
+    private static void checkValidEnterpriseId(
+            @NetworkCapabilities.EnterpriseId int enterpriseId) {
+        if (!isValidEnterpriseId(enterpriseId)) {
+            throw new IllegalArgumentException("enterprise capability identifier "
+                    + enterpriseId + " is out of range");
         }
     }
 
@@ -2613,33 +2630,33 @@
         }
 
         /**
-         * Adds the given enterprise capability sub level.
-         * Note that when searching for a network to satisfy a request, all capabilities sub level
-         * requested must be satisfied. Enterprise capability sub-level is applicable only
+         * Adds the given enterprise capability identifier.
+         * Note that when searching for a network to satisfy a request, all capabilities identifier
+         * requested must be satisfied. Enterprise capability identifier is applicable only
          * for NET_CAPABILITY_ENTERPRISE capability
          *
-         * @param enterpriseCapabilitySubLevel enterprise capability sub-level.
+         * @param enterpriseId enterprise capability identifier.
          *
          * @return this builder
          */
         @NonNull
-        public Builder addEnterpriseCapabilitySubLevel(
-                @EnterpriseCapabilitySubLevel  int enterpriseCapabilitySubLevel) {
-            mCaps.addEnterpriseCapabilitySubLevel(enterpriseCapabilitySubLevel);
+        public Builder addEnterpriseId(
+                @EnterpriseId  int enterpriseId) {
+            mCaps.addEnterpriseId(enterpriseId);
             return this;
         }
 
         /**
-         * Removes the given enterprise capability sub level. Enterprise capability sub-level is
+         * Removes the given enterprise capability identifier. Enterprise capability identifier is
          * applicable only for NET_CAPABILITY_ENTERPRISE capability
          *
-         * @param enterpriseCapabilitySubLevel the enterprise capability subLevel
+         * @param enterpriseId the enterprise capability identifier
          * @return this builder
          */
         @NonNull
-        public Builder removeEnterpriseCapabilitySubLevel(
-                @EnterpriseCapabilitySubLevel  int enterpriseCapabilitySubLevel) {
-            mCaps.removeEnterpriseCapabilitySubLevel(enterpriseCapabilitySubLevel);
+        public Builder removeEnterpriseId(
+                @EnterpriseId  int enterpriseId) {
+            mCaps.removeEnterpriseId(enterpriseId);
             return this;
         }
 
@@ -2902,10 +2919,10 @@
                 }
             }
 
-            if ((mCaps.getEnterpriseCapabilitySubLevels().length != 0)
+            if ((mCaps.getEnterpriseIds().length != 0)
                     && !mCaps.hasCapability(NET_CAPABILITY_ENTERPRISE)) {
-                throw new IllegalStateException("Enterprise capability sublevel is applicable only"
-                        + " with ENTERPRISE capability.");
+                throw new IllegalStateException("Enterprise capability identifier is applicable"
+                        + " only with ENTERPRISE capability.");
             }
             return new NetworkCapabilities(mCaps);
         }
diff --git a/framework/src/android/net/ProfileNetworkPreference.java b/framework/src/android/net/ProfileNetworkPreference.java
index 2ce1698..f43acce 100644
--- a/framework/src/android/net/ProfileNetworkPreference.java
+++ b/framework/src/android/net/ProfileNetworkPreference.java
@@ -18,13 +18,20 @@
 
 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.net.ConnectivityManager.ProfileNetworkPreferencePolicy;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
 /**
  * Network preferences to be set for the user profile
  * {@link ProfileNetworkPreferencePolicy}.
@@ -33,23 +40,91 @@
 @SystemApi(client = MODULE_LIBRARIES)
 public final class ProfileNetworkPreference implements Parcelable {
     private final @ProfileNetworkPreferencePolicy int mPreference;
+    private final @NetworkCapabilities.EnterpriseId int mPreferenceEnterpriseId;
+    private final List<Integer> mIncludedUids;
+    private final List<Integer> mExcludedUids;
 
-    private ProfileNetworkPreference(int preference) {
+    private ProfileNetworkPreference(int preference, List<Integer> includedUids,
+            List<Integer> excludedUids,
+            @NetworkCapabilities.EnterpriseId int preferenceEnterpriseId) {
         mPreference = preference;
+        mPreferenceEnterpriseId = preferenceEnterpriseId;
+        if (includedUids != null) {
+            mIncludedUids = new ArrayList<>(includedUids);
+        } else {
+            mIncludedUids = new ArrayList<>();
+        }
+
+        if (excludedUids != null) {
+            mExcludedUids = new ArrayList<>(excludedUids);
+        } else {
+            mExcludedUids = new ArrayList<>();
+        }
     }
 
     private ProfileNetworkPreference(Parcel in) {
         mPreference = in.readInt();
+        mIncludedUids = in.readArrayList(Integer.class.getClassLoader());
+        mExcludedUids = in.readArrayList(Integer.class.getClassLoader());
+        mPreferenceEnterpriseId = in.readInt();
     }
 
     public int getPreference() {
         return mPreference;
     }
 
+    /**
+     * Get the list of UIDs subject to this preference.
+     *
+     * Included UIDs and Excluded UIDs can't both be non-empty.
+     * if both are empty, it means this request applies to all uids in the user profile.
+     * if included is not empty, then only included UIDs are applied.
+     * if excluded is not empty, then it is all uids in the user profile except these UIDs.
+     * @return List of uids included for the profile preference.
+     * {@see #getExcludedUids()}
+     */
+    public @NonNull List<Integer> getIncludedUids() {
+        return new ArrayList<>(mIncludedUids);
+    }
+
+    /**
+     * Get the list of UIDS excluded from this preference.
+     *
+     * <ul>Included UIDs and Excluded UIDs can't both be non-empty.</ul>
+     * <ul>If both are empty, it means this request applies to all uids in the user profile.</ul>
+     * <ul>If included is not empty, then only included UIDs are applied.</ul>
+     * <ul>If excluded is not empty, then it is all uids in the user profile except these UIDs.</ul>
+     * @return List of uids not included for the profile preference.
+     * {@see #getIncludedUids()}
+     */
+    public @NonNull List<Integer> getExcludedUids() {
+        return new ArrayList<>(mExcludedUids);
+    }
+
+    /**
+     * Get preference enterprise identifier.
+     *
+     * Preference enterprise identifier will be used to create different network preferences
+     * within enterprise preference category.
+     * Valid values starts from PROFILE_NETWORK_PREFERENCE_ENTERPRISE_ID_1 to
+     * NetworkCapabilities.NET_ENTERPRISE_ID_5.
+     * Preference identifier is not applicable if preference is set as
+     * PROFILE_NETWORK_PREFERENCE_DEFAULT. Default value is
+     * NetworkCapabilities.NET_ENTERPRISE_ID_1.
+     * @return Preference enterprise identifier.
+     *
+     */
+    public @NetworkCapabilities.EnterpriseId int getPreferenceEnterpriseId() {
+        return mPreferenceEnterpriseId;
+    }
+
     @Override
     public String toString() {
         return "ProfileNetworkPreference{"
                 + "mPreference=" + getPreference()
+                + "mIncludedUids=" + mIncludedUids.toString()
+                + "mExcludedUids=" + mExcludedUids.toString()
+                + "mPreferenceEnterpriseId=" + mPreferenceEnterpriseId
                 + '}';
     }
 
@@ -58,12 +133,18 @@
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
         final ProfileNetworkPreference that = (ProfileNetworkPreference) o;
-        return mPreference == that.mPreference;
+        return mPreference == that.mPreference
+                && (Objects.equals(mIncludedUids, that.mIncludedUids))
+                && (Objects.equals(mExcludedUids, that.mExcludedUids))
+                && mPreferenceEnterpriseId == that.mPreferenceEnterpriseId;
     }
 
     @Override
     public int hashCode() {
-        return mPreference;
+        return mPreference
+                + mPreferenceEnterpriseId * 2
+                + (Objects.hashCode(mIncludedUids) * 11)
+                + (Objects.hashCode(mExcludedUids) * 13);
     }
 
     /**
@@ -73,6 +154,9 @@
     public static final class Builder {
         private @ProfileNetworkPreferencePolicy int mPreference =
                 PROFILE_NETWORK_PREFERENCE_DEFAULT;
+        private @NonNull List<Integer> mIncludedUids = new ArrayList<>();
+        private @NonNull List<Integer> mExcludedUids = new ArrayList<>();
+        private int mPreferenceEnterpriseId;
 
         /**
          * Constructs an empty Builder with PROFILE_NETWORK_PREFERENCE_DEFAULT profile preference
@@ -93,18 +177,112 @@
         }
 
         /**
+         * This is a list of uids for which profile perefence is set.
+         * Null would mean that this preference applies to all uids in the profile.
+         * {@see #setExcludedUids(List<Integer>)}
+         * Included UIDs and Excluded UIDs can't both be non-empty.
+         * if both are empty, it means this request applies to all uids in the user profile.
+         * if included is not empty, then only included UIDs are applied.
+         * if excluded is not empty, then it is all uids in the user profile except these UIDs.
+         * @param uids  list of uids that are included
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder setIncludedUids(@Nullable List<Integer> uids) {
+            if (uids != null) {
+                mIncludedUids = new ArrayList<Integer>(uids);
+            } else {
+                mIncludedUids = new ArrayList<Integer>();
+            }
+            return this;
+        }
+
+
+        /**
+         * This is a list of uids that are excluded for the profile perefence.
+         * {@see #setIncludedUids(List<Integer>)}
+         * Included UIDs and Excluded UIDs can't both be non-empty.
+         * if both are empty, it means this request applies to all uids in the user profile.
+         * if included is not empty, then only included UIDs are applied.
+         * if excluded is not empty, then it is all uids in the user profile except these UIDs.
+         * @param uids  list of uids that are not included
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder setExcludedUids(@Nullable List<Integer> uids) {
+            if (uids != null) {
+                mExcludedUids = new ArrayList<Integer>(uids);
+            } else {
+                mExcludedUids = new ArrayList<Integer>();
+            }
+            return this;
+        }
+
+        /**
+         * Check if given preference enterprise identifier is valid
+         *
+         * Valid values starts from PROFILE_NETWORK_PREFERENCE_ENTERPRISE_ID_1 to
+         * NetworkCapabilities.NET_ENTERPRISE_ID_5.
+         * @return True if valid else false
+         * @hide
+         */
+        private boolean isEnterpriseIdentifierValid(
+                @NetworkCapabilities.EnterpriseId int identifier) {
+            if ((identifier >= NET_ENTERPRISE_ID_1)
+                    && (identifier <= NET_ENTERPRISE_ID_5)) {
+                return true;
+            }
+            return false;
+        }
+
+        /**
          * Returns an instance of {@link ProfileNetworkPreference} created from the
          * fields set on this builder.
          */
         @NonNull
         public ProfileNetworkPreference  build() {
-            return new ProfileNetworkPreference(mPreference);
+            if (mIncludedUids.size() > 0 && mExcludedUids.size() > 0) {
+                throw new IllegalArgumentException("Both includedUids and excludedUids "
+                        + "cannot be nonempty");
+            }
+
+            if (((mPreference != PROFILE_NETWORK_PREFERENCE_DEFAULT)
+                    && (!isEnterpriseIdentifierValid(mPreferenceEnterpriseId)))
+                    || ((mPreference == PROFILE_NETWORK_PREFERENCE_DEFAULT)
+                    && (mPreferenceEnterpriseId != 0))) {
+                throw new IllegalStateException("Invalid preference enterprise identifier");
+            }
+            return new ProfileNetworkPreference(mPreference, mIncludedUids,
+                    mExcludedUids, mPreferenceEnterpriseId);
+        }
+
+        /**
+         * Set the preference enterprise identifier.
+         *
+         * Preference enterprise identifier will be used to create different network preferences
+         * within enterprise preference category.
+         * Valid values starts from NetworkCapabilities.NET_ENTERPRISE_ID_1 to
+         * NetworkCapabilities.NET_ENTERPRISE_ID_5.
+         * Preference identifier is not applicable if preference is set as
+         * PROFILE_NETWORK_PREFERENCE_DEFAULT. Default value is
+         * NetworkCapabilities.NET_ENTERPRISE_ID_1.
+         * @param preferenceId  preference sub level
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder setPreferenceEnterpriseId(
+                @NetworkCapabilities.EnterpriseId int preferenceId) {
+            mPreferenceEnterpriseId = preferenceId;
+            return this;
         }
     }
 
     @Override
     public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
         dest.writeInt(mPreference);
+        dest.writeList(mIncludedUids);
+        dest.writeList(mExcludedUids);
+        dest.writeInt(mPreferenceEnterpriseId);
     }
 
     @Override
diff --git a/service/Android.bp b/service/Android.bp
index 76f9153..d1a9004 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -57,12 +57,19 @@
     ],
     srcs: [
         "jni/com_android_server_TestNetworkService.cpp",
+        "jni/com_android_server_connectivity_ClatCoordinator.cpp",
         "jni/onload.cpp",
     ],
     stl: "libc++_static",
     header_libs: [
         "libbase_headers",
     ],
+    static_libs: [
+        "libbase",
+        "libclat",
+        "libip_checksum",
+        "libnetjniutils",
+    ],
     shared_libs: [
         "liblog",
         "libnativehelper",
@@ -156,3 +163,11 @@
     srcs: ["jarjar-rules.txt"],
     visibility: ["//packages/modules/Connectivity:__subpackages__"],
 }
+
+// TODO: This filegroup temporary exposes for NetworkStats. It should be
+// removed right after NetworkStats moves into mainline module.
+filegroup {
+    name: "traffic-controller-utils",
+    srcs: ["src/com/android/server/BpfNetMaps.java"],
+    visibility: ["//packages/modules/Connectivity:__subpackages__"],
+}
diff --git a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
new file mode 100644
index 0000000..9603139
--- /dev/null
+++ b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
@@ -0,0 +1,361 @@
+/*
+ * 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.
+ */
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/if_tun.h>
+#include <linux/ioctl.h>
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
+#include <net/if.h>
+#include <string>
+
+#include <netjniutils/netjniutils.h>
+
+#include "libclat/bpfhelper.h"
+#include "libclat/clatutils.h"
+#include "nativehelper/scoped_utf_chars.h"
+
+// Sync from system/netd/include/netid_client.h
+#define MARK_UNSET 0u
+
+#define DEVICEPREFIX "v4-"
+
+namespace android {
+static void throwIOException(JNIEnv* env, const char* msg, int error) {
+    jniThrowExceptionFmt(env, "java/io/IOException", "%s: %s", msg, strerror(error));
+}
+
+jstring com_android_server_connectivity_ClatCoordinator_selectIpv4Address(JNIEnv* env,
+                                                                          jobject clazz,
+                                                                          jstring v4addr,
+                                                                          jint prefixlen) {
+    ScopedUtfChars address(env, v4addr);
+    in_addr ip;
+    if (inet_pton(AF_INET, address.c_str(), &ip) != 1) {
+        throwIOException(env, "invalid address", EINVAL);
+        return nullptr;
+    }
+
+    // Pick an IPv4 address.
+    // TODO: this picks the address based on other addresses that are assigned to interfaces, but
+    // the address is only actually assigned to an interface once clatd starts up. So we could end
+    // up with two clatd instances with the same IPv4 address.
+    // Stop doing this and instead pick a free one from the kV4Addr pool.
+    in_addr v4 = {net::clat::selectIpv4Address(ip, prefixlen)};
+    if (v4.s_addr == INADDR_NONE) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "No free IPv4 address in %s/%d",
+                             address.c_str(), prefixlen);
+        return nullptr;
+    }
+
+    char addrstr[INET_ADDRSTRLEN];
+    if (!inet_ntop(AF_INET, (void*)&v4, addrstr, sizeof(addrstr))) {
+        throwIOException(env, "invalid address", EADDRNOTAVAIL);
+        return nullptr;
+    }
+    return env->NewStringUTF(addrstr);
+}
+
+// Picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix.
+jstring com_android_server_connectivity_ClatCoordinator_generateIpv6Address(
+        JNIEnv* env, jobject clazz, jstring ifaceStr, jstring v4Str, jstring prefix64Str) {
+    ScopedUtfChars iface(env, ifaceStr);
+    ScopedUtfChars addr4(env, v4Str);
+    ScopedUtfChars prefix64(env, prefix64Str);
+
+    if (iface.c_str() == nullptr) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid null interface name");
+        return nullptr;
+    }
+
+    in_addr v4;
+    if (inet_pton(AF_INET, addr4.c_str(), &v4) != 1) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid clat v4 address %s",
+                             addr4.c_str());
+        return nullptr;
+    }
+
+    in6_addr nat64Prefix;
+    if (inet_pton(AF_INET6, prefix64.c_str(), &nat64Prefix) != 1) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid prefix %s", prefix64.c_str());
+        return nullptr;
+    }
+
+    in6_addr v6;
+    if (net::clat::generateIpv6Address(iface.c_str(), v4, nat64Prefix, &v6)) {
+        jniThrowExceptionFmt(env, "java/io/IOException",
+                             "Unable to find global source address on %s for %s", iface.c_str(),
+                             prefix64.c_str());
+        return nullptr;
+    }
+
+    char addrstr[INET6_ADDRSTRLEN];
+    if (!inet_ntop(AF_INET6, (void*)&v6, addrstr, sizeof(addrstr))) {
+        throwIOException(env, "invalid address", EADDRNOTAVAIL);
+        return nullptr;
+    }
+    return env->NewStringUTF(addrstr);
+}
+
+static jint com_android_server_connectivity_ClatCoordinator_createTunInterface(JNIEnv* env,
+                                                                               jobject clazz,
+                                                                               jstring tuniface) {
+    ScopedUtfChars v4interface(env, tuniface);
+
+    // open the tun device in non blocking mode as required by clatd
+    jint fd = open("/dev/net/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
+    if (fd == -1) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "open tun device failed (%s)",
+                             strerror(errno));
+        return -1;
+    }
+
+    struct ifreq ifr = {
+            .ifr_flags = IFF_TUN,
+    };
+    strlcpy(ifr.ifr_name, v4interface.c_str(), sizeof(ifr.ifr_name));
+
+    if (ioctl(fd, TUNSETIFF, &ifr, sizeof(ifr))) {
+        close(fd);
+        jniThrowExceptionFmt(env, "java/io/IOException", "ioctl(TUNSETIFF) failed (%s)",
+                             strerror(errno));
+        return -1;
+    }
+
+    return fd;
+}
+
+static jint com_android_server_connectivity_ClatCoordinator_detectMtu(JNIEnv* env, jobject clazz,
+                                                                      jstring platSubnet,
+                                                                      jint plat_suffix, jint mark) {
+    ScopedUtfChars platSubnetStr(env, platSubnet);
+
+    in6_addr plat_subnet;
+    if (inet_pton(AF_INET6, platSubnetStr.c_str(), &plat_subnet) != 1) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid plat prefix address %s",
+                             platSubnetStr.c_str());
+        return -1;
+    }
+
+    int ret = net::clat::detect_mtu(&plat_subnet, plat_suffix, mark);
+    if (ret < 0) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "detect mtu failed: %s", strerror(-ret));
+        return -1;
+    }
+
+    return ret;
+}
+
+static jint com_android_server_connectivity_ClatCoordinator_openPacketSocket(JNIEnv* env,
+                                                                              jobject clazz) {
+    // Will eventually be bound to htons(ETH_P_IPV6) protocol,
+    // but only after appropriate bpf filter is attached.
+    int sock = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    if (sock < 0) {
+        throwIOException(env, "packet socket failed", errno);
+        return -1;
+    }
+    return sock;
+}
+
+static jint com_android_server_connectivity_ClatCoordinator_openRawSocket6(JNIEnv* env,
+                                                                           jobject clazz,
+                                                                           jint mark) {
+    int sock = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_RAW);
+    if (sock < 0) {
+        throwIOException(env, "raw socket failed", errno);
+        return -1;
+    }
+
+    // TODO: check the mark validation
+    if (mark != MARK_UNSET && setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
+        throwIOException(env, "could not set mark on raw socket", errno);
+        close(sock);
+        return -1;
+    }
+
+    return sock;
+}
+
+static void com_android_server_connectivity_ClatCoordinator_addAnycastSetsockopt(
+        JNIEnv* env, jobject clazz, jobject javaFd, jstring addr6, jint ifindex) {
+    int sock = netjniutils::GetNativeFileDescriptor(env, javaFd);
+    if (sock < 0) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
+        return;
+    }
+
+    ScopedUtfChars addrStr(env, addr6);
+
+    in6_addr addr;
+    if (inet_pton(AF_INET6, addrStr.c_str(), &addr) != 1) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid IPv6 address %s",
+                             addrStr.c_str());
+        return;
+    }
+
+    struct ipv6_mreq mreq = {addr, ifindex};
+    int ret = setsockopt(sock, SOL_IPV6, IPV6_JOIN_ANYCAST, &mreq, sizeof(mreq));
+    if (ret) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "setsockopt IPV6_JOIN_ANYCAST failed: %s",
+                             strerror(errno));
+        return;
+    }
+}
+
+static void com_android_server_connectivity_ClatCoordinator_configurePacketSocket(
+        JNIEnv* env, jobject clazz, jobject javaFd, jstring addr6, jint ifindex) {
+    ScopedUtfChars addrStr(env, addr6);
+
+    int sock = netjniutils::GetNativeFileDescriptor(env, javaFd);
+    if (sock < 0) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
+        return;
+    }
+
+    in6_addr addr;
+    if (inet_pton(AF_INET6, addrStr.c_str(), &addr) != 1) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid IPv6 address %s",
+                             addrStr.c_str());
+        return;
+    }
+
+    int ret = net::clat::configure_packet_socket(sock, &addr, ifindex);
+    if (ret < 0) {
+        throwIOException(env, "configure packet socket failed", -ret);
+        return;
+    }
+}
+
+int initTracker(const std::string& iface, const std::string& pfx96, const std::string& v4,
+        const std::string& v6, net::clat::ClatdTracker* output) {
+    strlcpy(output->iface, iface.c_str(), sizeof(output->iface));
+    output->ifIndex = if_nametoindex(iface.c_str());
+    if (output->ifIndex == 0) {
+        ALOGE("interface %s not found", output->iface);
+        return -1;
+    }
+
+    unsigned len = snprintf(output->v4iface, sizeof(output->v4iface),
+            "%s%s", DEVICEPREFIX, iface.c_str());
+    if (len >= sizeof(output->v4iface)) {
+        ALOGE("interface name too long '%s'", output->v4iface);
+        return -1;
+    }
+
+    output->v4ifIndex = if_nametoindex(output->v4iface);
+    if (output->v4ifIndex == 0) {
+        ALOGE("v4-interface %s not found", output->v4iface);
+        return -1;
+    }
+
+    if (!inet_pton(AF_INET6, pfx96.c_str(), &output->pfx96)) {
+        ALOGE("invalid IPv6 address specified for plat prefix: %s", pfx96.c_str());
+        return -1;
+    }
+
+    if (!inet_pton(AF_INET, v4.c_str(), &output->v4)) {
+        ALOGE("Invalid IPv4 address %s", v4.c_str());
+        return -1;
+    }
+
+    if (!inet_pton(AF_INET6, v6.c_str(), &output->v6)) {
+        ALOGE("Invalid source address %s", v6.c_str());
+        return -1;
+    }
+
+    return 0;
+}
+
+// TODO: fork clatd and rename to .._startClatd.
+static jint com_android_server_connectivity_ClatCoordinator_maybeStartBpf(
+        JNIEnv* env, jobject clazz, jobject tunJavaFd, jobject readSockJavaFd,
+        jobject writeSockJavaFd, jstring iface, jstring pfx96, jstring v4, jstring v6) {
+    ScopedUtfChars ifaceStr(env, iface);
+    ScopedUtfChars pfx96Str(env, pfx96);
+    ScopedUtfChars v4Str(env, v4);
+    ScopedUtfChars v6Str(env, v6);
+
+    // Start BPF if any
+    if (!net::clat::initMaps()) {
+        net::clat::ClatdTracker tracker = {};
+        if (!initTracker(ifaceStr.c_str(), pfx96Str.c_str(), v4Str.c_str(), v6Str.c_str(),
+                &tracker)) {
+            net::clat::maybeStartBpf(tracker);
+        }
+    }
+
+    return 0; // TODO: return forked clatd pid.
+}
+
+// TODO: stop clatd and rename to .._stopClatd.
+static void com_android_server_connectivity_ClatCoordinator_maybeStopBpf(JNIEnv* env, jobject clazz,
+                                                                       jstring iface, jstring pfx96,
+                                                                       jstring v4, jstring v6,
+                                                                       jint pid /* unused */) {
+    ScopedUtfChars ifaceStr(env, iface);
+    ScopedUtfChars pfx96Str(env, pfx96);
+    ScopedUtfChars v4Str(env, v4);
+    ScopedUtfChars v6Str(env, v6);
+
+    if (!net::clat::initMaps()) {
+        net::clat::ClatdTracker tracker = {};
+        if (!initTracker(ifaceStr.c_str(), pfx96Str.c_str(), v4Str.c_str(), v6Str.c_str(),
+                &tracker)) {
+            net::clat::maybeStopBpf(tracker);
+        }
+    }
+}
+
+/*
+ * JNI registration.
+ */
+static const JNINativeMethod gMethods[] = {
+        /* name, signature, funcPtr */
+        {"native_selectIpv4Address", "(Ljava/lang/String;I)Ljava/lang/String;",
+         (void*)com_android_server_connectivity_ClatCoordinator_selectIpv4Address},
+        {"native_generateIpv6Address",
+         "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
+         (void*)com_android_server_connectivity_ClatCoordinator_generateIpv6Address},
+        {"native_createTunInterface", "(Ljava/lang/String;)I",
+         (void*)com_android_server_connectivity_ClatCoordinator_createTunInterface},
+        {"native_detectMtu", "(Ljava/lang/String;II)I",
+         (void*)com_android_server_connectivity_ClatCoordinator_detectMtu},
+        {"native_openPacketSocket", "()I",
+         (void*)com_android_server_connectivity_ClatCoordinator_openPacketSocket},
+        {"native_openRawSocket6", "(I)I",
+         (void*)com_android_server_connectivity_ClatCoordinator_openRawSocket6},
+        {"native_addAnycastSetsockopt", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V",
+         (void*)com_android_server_connectivity_ClatCoordinator_addAnycastSetsockopt},
+        {"native_configurePacketSocket", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V",
+         (void*)com_android_server_connectivity_ClatCoordinator_configurePacketSocket},
+        {"native_maybeStartBpf",
+         "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/lang/"
+         "String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
+         (void*)com_android_server_connectivity_ClatCoordinator_maybeStartBpf},
+        {"native_maybeStopBpf",
+         "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V",
+          (void*)com_android_server_connectivity_ClatCoordinator_maybeStopBpf},
+};
+
+int register_android_server_connectivity_ClatCoordinator(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/android/server/connectivity/ClatCoordinator",
+                                    gMethods, NELEM(gMethods));
+}
+
+};  // namespace android
diff --git a/service/jni/onload.cpp b/service/jni/onload.cpp
index 0012879..04d9671 100644
--- a/service/jni/onload.cpp
+++ b/service/jni/onload.cpp
@@ -20,6 +20,7 @@
 namespace android {
 
 int register_android_server_TestNetworkService(JNIEnv* env);
+int register_android_server_connectivity_ClatCoordinator(JNIEnv* env);
 
 extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
     JNIEnv *env;
@@ -32,6 +33,10 @@
         return JNI_ERR;
     }
 
+    if (register_android_server_connectivity_ClatCoordinator(env) < 0) {
+        return JNI_ERR;
+    }
+
     return JNI_VERSION_1_6;
 }
 
diff --git a/service/native/Android.bp b/service/native/Android.bp
new file mode 100644
index 0000000..5816318
--- /dev/null
+++ b/service/native/Android.bp
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+cc_library {
+    name: "libtraffic_controller",
+    defaults: ["netd_defaults"],
+    srcs: [
+        "TrafficController.cpp",
+    ],
+    header_libs: [
+        "bpf_connectivity_headers",
+        "bpf_headers",
+        "bpf_syscall_wrappers",
+    ],
+    static_libs: [
+        "libnetdutils",
+        // TrafficController would use the constants of INetd so that add
+        // netd_aidl_interface-lateststable-ndk.
+        "netd_aidl_interface-lateststable-ndk",
+    ],
+    shared_libs: [
+        // TODO: Find a good way to remove libbase.
+        "libbase",
+        "libcutils",
+        "libutils",
+        "liblog",
+    ],
+    export_include_dirs: ["include"],
+    sanitize: {
+        cfi: true,
+    },
+    apex_available: [
+        "com.android.tethering",
+    ],
+    min_sdk_version: "30",
+}
+
+cc_library_shared {
+    name: "libtraffic_controller_jni",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-unused-parameter",
+        "-Wthread-safety",
+    ],
+    srcs: [
+        "jni/*.cpp",
+    ],
+    header_libs: [
+        "bpf_connectivity_headers",
+    ],
+    static_libs: [
+        "libnetdutils",
+        "libtraffic_controller",
+        "netd_aidl_interface-lateststable-ndk",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libutils",
+        "libnativehelper",
+    ],
+    apex_available: [
+        "com.android.tethering",
+    ],
+    min_sdk_version: "30",
+}
+
+cc_test {
+    name: "traffic_controller_unit_test",
+    test_suites: ["general-tests"],
+    require_root: true,
+    local_include_dirs: ["include"],
+    header_libs: [
+        "bpf_connectivity_headers",
+    ],
+    srcs: [
+        "TrafficControllerTest.cpp",
+    ],
+    static_libs: [
+        "libbase",
+        "libgmock",
+        "liblog",
+        "libnetdutils",
+        "libtraffic_controller",
+        "libutils",
+        "netd_aidl_interface-lateststable-ndk",
+    ],
+}
diff --git a/service/native/TrafficController.cpp b/service/native/TrafficController.cpp
new file mode 100644
index 0000000..cac545d
--- /dev/null
+++ b/service/native/TrafficController.cpp
@@ -0,0 +1,903 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "TrafficController"
+#include <inttypes.h>
+#include <linux/if_ether.h>
+#include <linux/in.h>
+#include <linux/inet_diag.h>
+#include <linux/netlink.h>
+#include <linux/sock_diag.h>
+#include <linux/unistd.h>
+#include <net/if.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+#include <map>
+#include <mutex>
+#include <unordered_set>
+#include <vector>
+
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+#include <netdutils/StatusOr.h>
+#include <netdutils/Syscalls.h>
+#include <netdutils/Utils.h>
+#include <private/android_filesystem_config.h>
+
+#include "TrafficController.h"
+#include "bpf/BpfMap.h"
+#include "netdutils/DumpWriter.h"
+
+namespace android {
+namespace net {
+
+using base::StringPrintf;
+using base::unique_fd;
+using bpf::BpfMap;
+using bpf::OVERFLOW_COUNTERSET;
+using bpf::synchronizeKernelRCU;
+using netdutils::DumpWriter;
+using netdutils::getIfaceList;
+using netdutils::NetlinkListener;
+using netdutils::NetlinkListenerInterface;
+using netdutils::ScopedIndent;
+using netdutils::Slice;
+using netdutils::sSyscalls;
+using netdutils::Status;
+using netdutils::statusFromErrno;
+using netdutils::StatusOr;
+using netdutils::status::ok;
+
+constexpr int kSockDiagMsgType = SOCK_DIAG_BY_FAMILY;
+constexpr int kSockDiagDoneMsgType = NLMSG_DONE;
+
+const char* TrafficController::LOCAL_DOZABLE = "fw_dozable";
+const char* TrafficController::LOCAL_STANDBY = "fw_standby";
+const char* TrafficController::LOCAL_POWERSAVE = "fw_powersave";
+const char* TrafficController::LOCAL_RESTRICTED = "fw_restricted";
+
+static_assert(BPF_PERMISSION_INTERNET == INetd::PERMISSION_INTERNET,
+              "Mismatch between BPF and AIDL permissions: PERMISSION_INTERNET");
+static_assert(BPF_PERMISSION_UPDATE_DEVICE_STATS == INetd::PERMISSION_UPDATE_DEVICE_STATS,
+              "Mismatch between BPF and AIDL permissions: PERMISSION_UPDATE_DEVICE_STATS");
+
+#define FLAG_MSG_TRANS(result, flag, value) \
+    do {                                    \
+        if ((value) & (flag)) {             \
+            (result).append(" " #flag);     \
+            (value) &= ~(flag);             \
+        }                                   \
+    } while (0)
+
+const std::string uidMatchTypeToString(uint8_t match) {
+    std::string matchType;
+    FLAG_MSG_TRANS(matchType, HAPPY_BOX_MATCH, match);
+    FLAG_MSG_TRANS(matchType, PENALTY_BOX_MATCH, match);
+    FLAG_MSG_TRANS(matchType, DOZABLE_MATCH, match);
+    FLAG_MSG_TRANS(matchType, STANDBY_MATCH, match);
+    FLAG_MSG_TRANS(matchType, POWERSAVE_MATCH, match);
+    FLAG_MSG_TRANS(matchType, RESTRICTED_MATCH, match);
+    FLAG_MSG_TRANS(matchType, IIF_MATCH, match);
+    if (match) {
+        return StringPrintf("Unknown match: %u", match);
+    }
+    return matchType;
+}
+
+bool TrafficController::hasUpdateDeviceStatsPermission(uid_t uid) {
+    // This implementation is the same logic as method ActivityManager#checkComponentPermission.
+    // It implies that the calling uid can never be the same as PER_USER_RANGE.
+    uint32_t appId = uid % PER_USER_RANGE;
+    return ((appId == AID_ROOT) || (appId == AID_SYSTEM) ||
+            mPrivilegedUser.find(appId) != mPrivilegedUser.end());
+}
+
+const std::string UidPermissionTypeToString(int permission) {
+    if (permission == INetd::PERMISSION_NONE) {
+        return "PERMISSION_NONE";
+    }
+    if (permission == INetd::PERMISSION_UNINSTALLED) {
+        // This should never appear in the map, complain loudly if it does.
+        return "PERMISSION_UNINSTALLED error!";
+    }
+    std::string permissionType;
+    FLAG_MSG_TRANS(permissionType, BPF_PERMISSION_INTERNET, permission);
+    FLAG_MSG_TRANS(permissionType, BPF_PERMISSION_UPDATE_DEVICE_STATS, permission);
+    if (permission) {
+        return StringPrintf("Unknown permission: %u", permission);
+    }
+    return permissionType;
+}
+
+StatusOr<std::unique_ptr<NetlinkListenerInterface>> TrafficController::makeSkDestroyListener() {
+    const auto& sys = sSyscalls.get();
+    ASSIGN_OR_RETURN(auto event, sys.eventfd(0, EFD_CLOEXEC));
+    const int domain = AF_NETLINK;
+    const int type = SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK;
+    const int protocol = NETLINK_INET_DIAG;
+    ASSIGN_OR_RETURN(auto sock, sys.socket(domain, type, protocol));
+
+    // TODO: if too many sockets are closed too quickly, we can overflow the socket buffer, and
+    // some entries in mCookieTagMap will not be freed. In order to fix this we would need to
+    // periodically dump all sockets and remove the tag entries for sockets that have been closed.
+    // For now, set a large-enough buffer that we can close hundreds of sockets without getting
+    // ENOBUFS and leaking mCookieTagMap entries.
+    int rcvbuf = 512 * 1024;
+    auto ret = sys.setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
+    if (!ret.ok()) {
+        ALOGW("Failed to set SkDestroyListener buffer size to %d: %s", rcvbuf, ret.msg().c_str());
+    }
+
+    sockaddr_nl addr = {
+        .nl_family = AF_NETLINK,
+        .nl_groups = 1 << (SKNLGRP_INET_TCP_DESTROY - 1) | 1 << (SKNLGRP_INET_UDP_DESTROY - 1) |
+                     1 << (SKNLGRP_INET6_TCP_DESTROY - 1) | 1 << (SKNLGRP_INET6_UDP_DESTROY - 1)};
+    RETURN_IF_NOT_OK(sys.bind(sock, addr));
+
+    const sockaddr_nl kernel = {.nl_family = AF_NETLINK};
+    RETURN_IF_NOT_OK(sys.connect(sock, kernel));
+
+    std::unique_ptr<NetlinkListenerInterface> listener =
+            std::make_unique<NetlinkListener>(std::move(event), std::move(sock), "SkDestroyListen");
+
+    return listener;
+}
+
+Status TrafficController::initMaps() {
+    std::lock_guard guard(mMutex);
+
+    RETURN_IF_NOT_OK(mCookieTagMap.init(COOKIE_TAG_MAP_PATH));
+    RETURN_IF_NOT_OK(mUidCounterSetMap.init(UID_COUNTERSET_MAP_PATH));
+    RETURN_IF_NOT_OK(mAppUidStatsMap.init(APP_UID_STATS_MAP_PATH));
+    RETURN_IF_NOT_OK(mStatsMapA.init(STATS_MAP_A_PATH));
+    RETURN_IF_NOT_OK(mStatsMapB.init(STATS_MAP_B_PATH));
+    RETURN_IF_NOT_OK(mIfaceIndexNameMap.init(IFACE_INDEX_NAME_MAP_PATH));
+    RETURN_IF_NOT_OK(mIfaceStatsMap.init(IFACE_STATS_MAP_PATH));
+
+    RETURN_IF_NOT_OK(mConfigurationMap.init(CONFIGURATION_MAP_PATH));
+    RETURN_IF_NOT_OK(
+            mConfigurationMap.writeValue(UID_RULES_CONFIGURATION_KEY, DEFAULT_CONFIG, BPF_ANY));
+    RETURN_IF_NOT_OK(mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY, SELECT_MAP_A,
+                                                  BPF_ANY));
+
+    RETURN_IF_NOT_OK(mUidOwnerMap.init(UID_OWNER_MAP_PATH));
+    RETURN_IF_NOT_OK(mUidOwnerMap.clear());
+    RETURN_IF_NOT_OK(mUidPermissionMap.init(UID_PERMISSION_MAP_PATH));
+
+    return netdutils::status::ok;
+}
+
+Status TrafficController::start() {
+    RETURN_IF_NOT_OK(initMaps());
+
+    // Fetch the list of currently-existing interfaces. At this point NetlinkHandler is
+    // already running, so it will call addInterface() when any new interface appears.
+    // TODO: Clean-up addInterface() after interface monitoring is in
+    // NetworkStatsService.
+    std::map<std::string, uint32_t> ifacePairs;
+    ASSIGN_OR_RETURN(ifacePairs, getIfaceList());
+    for (const auto& ifacePair:ifacePairs) {
+        addInterface(ifacePair.first.c_str(), ifacePair.second);
+    }
+
+    auto result = makeSkDestroyListener();
+    if (!isOk(result)) {
+        ALOGE("Unable to create SkDestroyListener: %s", toString(result).c_str());
+    } else {
+        mSkDestroyListener = std::move(result.value());
+    }
+    // Rx handler extracts nfgenmsg looks up and invokes registered dispatch function.
+    const auto rxHandler = [this](const nlmsghdr&, const Slice msg) {
+        std::lock_guard guard(mMutex);
+        inet_diag_msg diagmsg = {};
+        if (extract(msg, diagmsg) < sizeof(inet_diag_msg)) {
+            ALOGE("Unrecognized netlink message: %s", toString(msg).c_str());
+            return;
+        }
+        uint64_t sock_cookie = static_cast<uint64_t>(diagmsg.id.idiag_cookie[0]) |
+                               (static_cast<uint64_t>(diagmsg.id.idiag_cookie[1]) << 32);
+
+        Status s = mCookieTagMap.deleteValue(sock_cookie);
+        if (!isOk(s) && s.code() != ENOENT) {
+            ALOGE("Failed to delete cookie %" PRIx64 ": %s", sock_cookie, toString(s).c_str());
+            return;
+        }
+    };
+    expectOk(mSkDestroyListener->subscribe(kSockDiagMsgType, rxHandler));
+
+    // In case multiple netlink message comes in as a stream, we need to handle the rxDone message
+    // properly.
+    const auto rxDoneHandler = [](const nlmsghdr&, const Slice msg) {
+        // Ignore NLMSG_DONE  messages
+        inet_diag_msg diagmsg = {};
+        extract(msg, diagmsg);
+    };
+    expectOk(mSkDestroyListener->subscribe(kSockDiagDoneMsgType, rxDoneHandler));
+
+    return netdutils::status::ok;
+}
+
+int TrafficController::setCounterSet(int counterSetNum, uid_t uid, uid_t callingUid) {
+    if (counterSetNum < 0 || counterSetNum >= OVERFLOW_COUNTERSET) return -EINVAL;
+
+    std::lock_guard guard(mMutex);
+    if (!hasUpdateDeviceStatsPermission(callingUid)) return -EPERM;
+
+    // The default counter set for all uid is 0, so deleting the current counterset for that uid
+    // will automatically set it to 0.
+    if (counterSetNum == 0) {
+        Status res = mUidCounterSetMap.deleteValue(uid);
+        if (isOk(res) || (!isOk(res) && res.code() == ENOENT)) {
+            return 0;
+        } else {
+            ALOGE("Failed to delete the counterSet: %s\n", strerror(res.code()));
+            return -res.code();
+        }
+    }
+    uint8_t tmpCounterSetNum = (uint8_t)counterSetNum;
+    Status res = mUidCounterSetMap.writeValue(uid, tmpCounterSetNum, BPF_ANY);
+    if (!isOk(res)) {
+        ALOGE("Failed to set the counterSet: %s, fd: %d", strerror(res.code()),
+              mUidCounterSetMap.getMap().get());
+        return -res.code();
+    }
+    return 0;
+}
+
+// This method only get called by system_server when an app get uinstalled, it
+// is called inside removeUidsLocked() while holding mStatsLock. So it is safe
+// to iterate and modify the stats maps.
+int TrafficController::deleteTagData(uint32_t tag, uid_t uid, uid_t callingUid) {
+    std::lock_guard guard(mMutex);
+    if (!hasUpdateDeviceStatsPermission(callingUid)) return -EPERM;
+
+    // First we go through the cookieTagMap to delete the target uid tag combination. Or delete all
+    // the tags related to the uid if the tag is 0.
+    const auto deleteMatchedCookieEntries = [uid, tag](const uint64_t& key,
+                                                       const UidTagValue& value,
+                                                       BpfMap<uint64_t, UidTagValue>& map) {
+        if (value.uid == uid && (value.tag == tag || tag == 0)) {
+            auto res = map.deleteValue(key);
+            if (res.ok() || (res.error().code() == ENOENT)) {
+                return base::Result<void>();
+            }
+            ALOGE("Failed to delete data(cookie = %" PRIu64 "): %s\n", key,
+                  strerror(res.error().code()));
+        }
+        // Move forward to next cookie in the map.
+        return base::Result<void>();
+    };
+    mCookieTagMap.iterateWithValue(deleteMatchedCookieEntries);
+    // Now we go through the Tag stats map and delete the data entry with correct uid and tag
+    // combination. Or all tag stats under that uid if the target tag is 0.
+    const auto deleteMatchedUidTagEntries = [uid, tag](const StatsKey& key,
+                                                       BpfMap<StatsKey, StatsValue>& map) {
+        if (key.uid == uid && (key.tag == tag || tag == 0)) {
+            auto res = map.deleteValue(key);
+            if (res.ok() || (res.error().code() == ENOENT)) {
+                //Entry is deleted, use the current key to get a new nextKey;
+                return base::Result<void>();
+            }
+            ALOGE("Failed to delete data(uid=%u, tag=%u): %s\n", key.uid, key.tag,
+                  strerror(res.error().code()));
+        }
+        return base::Result<void>();
+    };
+    mStatsMapB.iterate(deleteMatchedUidTagEntries);
+    mStatsMapA.iterate(deleteMatchedUidTagEntries);
+    // If the tag is not zero, we already deleted all the data entry required. If tag is 0, we also
+    // need to delete the stats stored in uidStatsMap and counterSet map.
+    if (tag != 0) return 0;
+
+    auto res = mUidCounterSetMap.deleteValue(uid);
+    if (!res.ok() && res.error().code() != ENOENT) {
+        ALOGE("Failed to delete counterSet data(uid=%u, tag=%u): %s\n", uid, tag,
+              strerror(res.error().code()));
+    }
+
+    auto deleteAppUidStatsEntry = [uid](const uint32_t& key,
+                                        BpfMap<uint32_t, StatsValue>& map) -> base::Result<void> {
+        if (key == uid) {
+            auto res = map.deleteValue(key);
+            if (res.ok() || (res.error().code() == ENOENT)) {
+                return {};
+            }
+            ALOGE("Failed to delete data(uid=%u): %s", key, strerror(res.error().code()));
+        }
+        return {};
+    };
+    mAppUidStatsMap.iterate(deleteAppUidStatsEntry);
+    return 0;
+}
+
+int TrafficController::addInterface(const char* name, uint32_t ifaceIndex) {
+    IfaceValue iface;
+    if (ifaceIndex == 0) {
+        ALOGE("Unknown interface %s(%d)", name, ifaceIndex);
+        return -1;
+    }
+
+    strlcpy(iface.name, name, sizeof(IfaceValue));
+    Status res = mIfaceIndexNameMap.writeValue(ifaceIndex, iface, BPF_ANY);
+    if (!isOk(res)) {
+        ALOGE("Failed to add iface %s(%d): %s", name, ifaceIndex, strerror(res.code()));
+        return -res.code();
+    }
+    return 0;
+}
+
+Status TrafficController::updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
+                                              FirewallType type) {
+    std::lock_guard guard(mMutex);
+    if ((rule == ALLOW && type == ALLOWLIST) || (rule == DENY && type == DENYLIST)) {
+        RETURN_IF_NOT_OK(addRule(uid, match));
+    } else if ((rule == ALLOW && type == DENYLIST) || (rule == DENY && type == ALLOWLIST)) {
+        RETURN_IF_NOT_OK(removeRule(uid, match));
+    } else {
+        //Cannot happen.
+        return statusFromErrno(EINVAL, "");
+    }
+    return netdutils::status::ok;
+}
+
+Status TrafficController::removeRule(uint32_t uid, UidOwnerMatchType match) {
+    auto oldMatch = mUidOwnerMap.readValue(uid);
+    if (oldMatch.ok()) {
+        UidOwnerValue newMatch = {
+                .iif = (match == IIF_MATCH) ? 0 : oldMatch.value().iif,
+                .rule = static_cast<uint8_t>(oldMatch.value().rule & ~match),
+        };
+        if (newMatch.rule == 0) {
+            RETURN_IF_NOT_OK(mUidOwnerMap.deleteValue(uid));
+        } else {
+            RETURN_IF_NOT_OK(mUidOwnerMap.writeValue(uid, newMatch, BPF_ANY));
+        }
+    } else {
+        return statusFromErrno(ENOENT, StringPrintf("uid: %u does not exist in map", uid));
+    }
+    return netdutils::status::ok;
+}
+
+Status TrafficController::addRule(uint32_t uid, UidOwnerMatchType match, uint32_t iif) {
+    // iif should be non-zero if and only if match == MATCH_IIF
+    if (match == IIF_MATCH && iif == 0) {
+        return statusFromErrno(EINVAL, "Interface match must have nonzero interface index");
+    } else if (match != IIF_MATCH && iif != 0) {
+        return statusFromErrno(EINVAL, "Non-interface match must have zero interface index");
+    }
+    auto oldMatch = mUidOwnerMap.readValue(uid);
+    if (oldMatch.ok()) {
+        UidOwnerValue newMatch = {
+                .iif = iif ? iif : oldMatch.value().iif,
+                .rule = static_cast<uint8_t>(oldMatch.value().rule | match),
+        };
+        RETURN_IF_NOT_OK(mUidOwnerMap.writeValue(uid, newMatch, BPF_ANY));
+    } else {
+        UidOwnerValue newMatch = {
+                .iif = iif,
+                .rule = static_cast<uint8_t>(match),
+        };
+        RETURN_IF_NOT_OK(mUidOwnerMap.writeValue(uid, newMatch, BPF_ANY));
+    }
+    return netdutils::status::ok;
+}
+
+Status TrafficController::updateUidOwnerMap(const uint32_t uid,
+                                            UidOwnerMatchType matchType, IptOp op) {
+    std::lock_guard guard(mMutex);
+    if (op == IptOpDelete) {
+        RETURN_IF_NOT_OK(removeRule(uid, matchType));
+    } else if (op == IptOpInsert) {
+        RETURN_IF_NOT_OK(addRule(uid, matchType));
+    } else {
+        // Cannot happen.
+        return statusFromErrno(EINVAL, StringPrintf("invalid IptOp: %d, %d", op, matchType));
+    }
+    return netdutils::status::ok;
+}
+
+FirewallType TrafficController::getFirewallType(ChildChain chain) {
+    switch (chain) {
+        case DOZABLE:
+            return ALLOWLIST;
+        case STANDBY:
+            return DENYLIST;
+        case POWERSAVE:
+            return ALLOWLIST;
+        case RESTRICTED:
+            return ALLOWLIST;
+        case NONE:
+        default:
+            return DENYLIST;
+    }
+}
+
+int TrafficController::changeUidOwnerRule(ChildChain chain, uid_t uid, FirewallRule rule,
+                                          FirewallType type) {
+    Status res;
+    switch (chain) {
+        case DOZABLE:
+            res = updateOwnerMapEntry(DOZABLE_MATCH, uid, rule, type);
+            break;
+        case STANDBY:
+            res = updateOwnerMapEntry(STANDBY_MATCH, uid, rule, type);
+            break;
+        case POWERSAVE:
+            res = updateOwnerMapEntry(POWERSAVE_MATCH, uid, rule, type);
+            break;
+        case RESTRICTED:
+            res = updateOwnerMapEntry(RESTRICTED_MATCH, uid, rule, type);
+            break;
+        case NONE:
+        default:
+            ALOGW("Unknown child chain: %d", chain);
+            return -EINVAL;
+    }
+    if (!isOk(res)) {
+        ALOGE("change uid(%u) rule of %d failed: %s, rule: %d, type: %d", uid, chain,
+              res.msg().c_str(), rule, type);
+        return -res.code();
+    }
+    return 0;
+}
+
+Status TrafficController::replaceRulesInMap(const UidOwnerMatchType match,
+                                            const std::vector<int32_t>& uids) {
+    std::lock_guard guard(mMutex);
+    std::set<int32_t> uidSet(uids.begin(), uids.end());
+    std::vector<uint32_t> uidsToDelete;
+    auto getUidsToDelete = [&uidsToDelete, &uidSet](const uint32_t& key,
+                                                    const BpfMap<uint32_t, UidOwnerValue>&) {
+        if (uidSet.find((int32_t) key) == uidSet.end()) {
+            uidsToDelete.push_back(key);
+        }
+        return base::Result<void>();
+    };
+    RETURN_IF_NOT_OK(mUidOwnerMap.iterate(getUidsToDelete));
+
+    for(auto uid : uidsToDelete) {
+        RETURN_IF_NOT_OK(removeRule(uid, match));
+    }
+
+    for (auto uid : uids) {
+        RETURN_IF_NOT_OK(addRule(uid, match));
+    }
+    return netdutils::status::ok;
+}
+
+Status TrafficController::addUidInterfaceRules(const int iif,
+                                               const std::vector<int32_t>& uidsToAdd) {
+    if (!iif) {
+        return statusFromErrno(EINVAL, "Interface rule must specify interface");
+    }
+    std::lock_guard guard(mMutex);
+
+    for (auto uid : uidsToAdd) {
+        netdutils::Status result = addRule(uid, IIF_MATCH, iif);
+        if (!isOk(result)) {
+            ALOGW("addRule failed(%d): uid=%d iif=%d", result.code(), uid, iif);
+        }
+    }
+    return netdutils::status::ok;
+}
+
+Status TrafficController::removeUidInterfaceRules(const std::vector<int32_t>& uidsToDelete) {
+    std::lock_guard guard(mMutex);
+
+    for (auto uid : uidsToDelete) {
+        netdutils::Status result = removeRule(uid, IIF_MATCH);
+        if (!isOk(result)) {
+            ALOGW("removeRule failed(%d): uid=%d", result.code(), uid);
+        }
+    }
+    return netdutils::status::ok;
+}
+
+int TrafficController::replaceUidOwnerMap(const std::string& name, bool isAllowlist __unused,
+                                          const std::vector<int32_t>& uids) {
+    // FirewallRule rule = isAllowlist ? ALLOW : DENY;
+    // FirewallType type = isAllowlist ? ALLOWLIST : DENYLIST;
+    Status res;
+    if (!name.compare(LOCAL_DOZABLE)) {
+        res = replaceRulesInMap(DOZABLE_MATCH, uids);
+    } else if (!name.compare(LOCAL_STANDBY)) {
+        res = replaceRulesInMap(STANDBY_MATCH, uids);
+    } else if (!name.compare(LOCAL_POWERSAVE)) {
+        res = replaceRulesInMap(POWERSAVE_MATCH, uids);
+    } else if (!name.compare(LOCAL_RESTRICTED)) {
+        res = replaceRulesInMap(RESTRICTED_MATCH, uids);
+    } else {
+        ALOGE("unknown chain name: %s", name.c_str());
+        return -EINVAL;
+    }
+    if (!isOk(res)) {
+        ALOGE("Failed to clean up chain: %s: %s", name.c_str(), res.msg().c_str());
+        return -res.code();
+    }
+    return 0;
+}
+
+int TrafficController::toggleUidOwnerMap(ChildChain chain, bool enable) {
+    std::lock_guard guard(mMutex);
+    uint32_t key = UID_RULES_CONFIGURATION_KEY;
+    auto oldConfiguration = mConfigurationMap.readValue(key);
+    if (!oldConfiguration.ok()) {
+        ALOGE("Cannot read the old configuration from map: %s",
+              oldConfiguration.error().message().c_str());
+        return -oldConfiguration.error().code();
+    }
+    Status res;
+    BpfConfig newConfiguration;
+    uint8_t match;
+    switch (chain) {
+        case DOZABLE:
+            match = DOZABLE_MATCH;
+            break;
+        case STANDBY:
+            match = STANDBY_MATCH;
+            break;
+        case POWERSAVE:
+            match = POWERSAVE_MATCH;
+            break;
+        case RESTRICTED:
+            match = RESTRICTED_MATCH;
+            break;
+        default:
+            return -EINVAL;
+    }
+    newConfiguration =
+            enable ? (oldConfiguration.value() | match) : (oldConfiguration.value() & (~match));
+    res = mConfigurationMap.writeValue(key, newConfiguration, BPF_EXIST);
+    if (!isOk(res)) {
+        ALOGE("Failed to toggleUidOwnerMap(%d): %s", chain, res.msg().c_str());
+    }
+    return -res.code();
+}
+
+Status TrafficController::swapActiveStatsMap() {
+    std::lock_guard guard(mMutex);
+
+    uint32_t key = CURRENT_STATS_MAP_CONFIGURATION_KEY;
+    auto oldConfiguration = mConfigurationMap.readValue(key);
+    if (!oldConfiguration.ok()) {
+        ALOGE("Cannot read the old configuration from map: %s",
+              oldConfiguration.error().message().c_str());
+        return Status(oldConfiguration.error().code(), oldConfiguration.error().message());
+    }
+
+    // Write to the configuration map to inform the kernel eBPF program to switch
+    // from using one map to the other. Use flag BPF_EXIST here since the map should
+    // be already populated in initMaps.
+    uint8_t newConfigure = (oldConfiguration.value() == SELECT_MAP_A) ? SELECT_MAP_B : SELECT_MAP_A;
+    auto res = mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY, newConfigure,
+                                            BPF_EXIST);
+    if (!res.ok()) {
+        ALOGE("Failed to toggle the stats map: %s", strerror(res.error().code()));
+        return res;
+    }
+    // After changing the config, we need to make sure all the current running
+    // eBPF programs are finished and all the CPUs are aware of this config change
+    // before we modify the old map. So we do a special hack here to wait for
+    // the kernel to do a synchronize_rcu(). Once the kernel called
+    // synchronize_rcu(), the config we just updated will be available to all cores
+    // and the next eBPF programs triggered inside the kernel will use the new
+    // map configuration. So once this function returns we can safely modify the
+    // old stats map without concerning about race between the kernel and
+    // userspace.
+    int ret = synchronizeKernelRCU();
+    if (ret) {
+        ALOGE("map swap synchronize_rcu() ended with failure: %s", strerror(-ret));
+        return statusFromErrno(-ret, "map swap synchronize_rcu() failed");
+    }
+    return netdutils::status::ok;
+}
+
+void TrafficController::setPermissionForUids(int permission, const std::vector<uid_t>& uids) {
+    std::lock_guard guard(mMutex);
+    if (permission == INetd::PERMISSION_UNINSTALLED) {
+        for (uid_t uid : uids) {
+            // Clean up all permission information for the related uid if all the
+            // packages related to it are uninstalled.
+            mPrivilegedUser.erase(uid);
+            Status ret = mUidPermissionMap.deleteValue(uid);
+            if (!isOk(ret) && ret.code() != ENOENT) {
+                ALOGE("Failed to clean up the permission for %u: %s", uid, strerror(ret.code()));
+            }
+        }
+        return;
+    }
+
+    bool privileged = (permission & INetd::PERMISSION_UPDATE_DEVICE_STATS);
+
+    for (uid_t uid : uids) {
+        if (privileged) {
+            mPrivilegedUser.insert(uid);
+        } else {
+            mPrivilegedUser.erase(uid);
+        }
+
+        // The map stores all the permissions that the UID has, except if the only permission
+        // the UID has is the INTERNET permission, then the UID should not appear in the map.
+        if (permission != INetd::PERMISSION_INTERNET) {
+            Status ret = mUidPermissionMap.writeValue(uid, permission, BPF_ANY);
+            if (!isOk(ret)) {
+                ALOGE("Failed to set permission: %s of uid(%u) to permission map: %s",
+                      UidPermissionTypeToString(permission).c_str(), uid, strerror(ret.code()));
+            }
+        } else {
+            Status ret = mUidPermissionMap.deleteValue(uid);
+            if (!isOk(ret) && ret.code() != ENOENT) {
+                ALOGE("Failed to remove uid %u from permission map: %s", uid, strerror(ret.code()));
+            }
+        }
+    }
+}
+
+std::string getProgramStatus(const char *path) {
+    int ret = access(path, R_OK);
+    if (ret == 0) {
+        return StringPrintf("OK");
+    }
+    if (ret != 0 && errno == ENOENT) {
+        return StringPrintf("program is missing at: %s", path);
+    }
+    return StringPrintf("check Program %s error: %s", path, strerror(errno));
+}
+
+std::string getMapStatus(const base::unique_fd& map_fd, const char* path) {
+    if (map_fd.get() < 0) {
+        return StringPrintf("map fd lost");
+    }
+    if (access(path, F_OK) != 0) {
+        return StringPrintf("map not pinned to location: %s", path);
+    }
+    return StringPrintf("OK");
+}
+
+// NOLINTNEXTLINE(google-runtime-references): grandfathered pass by non-const reference
+void dumpBpfMap(const std::string& mapName, DumpWriter& dw, const std::string& header) {
+    dw.blankline();
+    dw.println("%s:", mapName.c_str());
+    if (!header.empty()) {
+        dw.println(header);
+    }
+}
+
+const String16 TrafficController::DUMP_KEYWORD = String16("trafficcontroller");
+
+void TrafficController::dump(DumpWriter& dw, bool verbose) {
+    std::lock_guard guard(mMutex);
+    ScopedIndent indentTop(dw);
+    dw.println("TrafficController");
+
+    ScopedIndent indentPreBpfModule(dw);
+
+    dw.blankline();
+    dw.println("mCookieTagMap status: %s",
+               getMapStatus(mCookieTagMap.getMap(), COOKIE_TAG_MAP_PATH).c_str());
+    dw.println("mUidCounterSetMap status: %s",
+               getMapStatus(mUidCounterSetMap.getMap(), UID_COUNTERSET_MAP_PATH).c_str());
+    dw.println("mAppUidStatsMap status: %s",
+               getMapStatus(mAppUidStatsMap.getMap(), APP_UID_STATS_MAP_PATH).c_str());
+    dw.println("mStatsMapA status: %s",
+               getMapStatus(mStatsMapA.getMap(), STATS_MAP_A_PATH).c_str());
+    dw.println("mStatsMapB status: %s",
+               getMapStatus(mStatsMapB.getMap(), STATS_MAP_B_PATH).c_str());
+    dw.println("mIfaceIndexNameMap status: %s",
+               getMapStatus(mIfaceIndexNameMap.getMap(), IFACE_INDEX_NAME_MAP_PATH).c_str());
+    dw.println("mIfaceStatsMap status: %s",
+               getMapStatus(mIfaceStatsMap.getMap(), IFACE_STATS_MAP_PATH).c_str());
+    dw.println("mConfigurationMap status: %s",
+               getMapStatus(mConfigurationMap.getMap(), CONFIGURATION_MAP_PATH).c_str());
+    dw.println("mUidOwnerMap status: %s",
+               getMapStatus(mUidOwnerMap.getMap(), UID_OWNER_MAP_PATH).c_str());
+
+    dw.blankline();
+    dw.println("Cgroup ingress program status: %s",
+               getProgramStatus(BPF_INGRESS_PROG_PATH).c_str());
+    dw.println("Cgroup egress program status: %s", getProgramStatus(BPF_EGRESS_PROG_PATH).c_str());
+    dw.println("xt_bpf ingress program status: %s",
+               getProgramStatus(XT_BPF_INGRESS_PROG_PATH).c_str());
+    dw.println("xt_bpf egress program status: %s",
+               getProgramStatus(XT_BPF_EGRESS_PROG_PATH).c_str());
+    dw.println("xt_bpf bandwidth allowlist program status: %s",
+               getProgramStatus(XT_BPF_ALLOWLIST_PROG_PATH).c_str());
+    dw.println("xt_bpf bandwidth denylist program status: %s",
+               getProgramStatus(XT_BPF_DENYLIST_PROG_PATH).c_str());
+
+    if (!verbose) {
+        return;
+    }
+
+    dw.blankline();
+    dw.println("BPF map content:");
+
+    ScopedIndent indentForMapContent(dw);
+
+    // Print CookieTagMap content.
+    dumpBpfMap("mCookieTagMap", dw, "");
+    const auto printCookieTagInfo = [&dw](const uint64_t& key, const UidTagValue& value,
+                                          const BpfMap<uint64_t, UidTagValue>&) {
+        dw.println("cookie=%" PRIu64 " tag=0x%x uid=%u", key, value.tag, value.uid);
+        return base::Result<void>();
+    };
+    base::Result<void> res = mCookieTagMap.iterateWithValue(printCookieTagInfo);
+    if (!res.ok()) {
+        dw.println("mCookieTagMap print end with error: %s", res.error().message().c_str());
+    }
+
+    // Print UidCounterSetMap content.
+    dumpBpfMap("mUidCounterSetMap", dw, "");
+    const auto printUidInfo = [&dw](const uint32_t& key, const uint8_t& value,
+                                    const BpfMap<uint32_t, uint8_t>&) {
+        dw.println("%u %u", key, value);
+        return base::Result<void>();
+    };
+    res = mUidCounterSetMap.iterateWithValue(printUidInfo);
+    if (!res.ok()) {
+        dw.println("mUidCounterSetMap print end with error: %s", res.error().message().c_str());
+    }
+
+    // Print AppUidStatsMap content.
+    std::string appUidStatsHeader = StringPrintf("uid rxBytes rxPackets txBytes txPackets");
+    dumpBpfMap("mAppUidStatsMap:", dw, appUidStatsHeader);
+    auto printAppUidStatsInfo = [&dw](const uint32_t& key, const StatsValue& value,
+                                      const BpfMap<uint32_t, StatsValue>&) {
+        dw.println("%u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, key, value.rxBytes,
+                   value.rxPackets, value.txBytes, value.txPackets);
+        return base::Result<void>();
+    };
+    res = mAppUidStatsMap.iterateWithValue(printAppUidStatsInfo);
+    if (!res.ok()) {
+        dw.println("mAppUidStatsMap print end with error: %s", res.error().message().c_str());
+    }
+
+    // Print uidStatsMap content.
+    std::string statsHeader = StringPrintf("ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes"
+                                           " rxPackets txBytes txPackets");
+    dumpBpfMap("mStatsMapA", dw, statsHeader);
+    const auto printStatsInfo = [&dw, this](const StatsKey& key, const StatsValue& value,
+                                            const BpfMap<StatsKey, StatsValue>&) {
+        uint32_t ifIndex = key.ifaceIndex;
+        auto ifname = mIfaceIndexNameMap.readValue(ifIndex);
+        if (!ifname.ok()) {
+            ifname = IfaceValue{"unknown"};
+        }
+        dw.println("%u %s 0x%x %u %u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, ifIndex,
+                   ifname.value().name, key.tag, key.uid, key.counterSet, value.rxBytes,
+                   value.rxPackets, value.txBytes, value.txPackets);
+        return base::Result<void>();
+    };
+    res = mStatsMapA.iterateWithValue(printStatsInfo);
+    if (!res.ok()) {
+        dw.println("mStatsMapA print end with error: %s", res.error().message().c_str());
+    }
+
+    // Print TagStatsMap content.
+    dumpBpfMap("mStatsMapB", dw, statsHeader);
+    res = mStatsMapB.iterateWithValue(printStatsInfo);
+    if (!res.ok()) {
+        dw.println("mStatsMapB print end with error: %s", res.error().message().c_str());
+    }
+
+    // Print ifaceIndexToNameMap content.
+    dumpBpfMap("mIfaceIndexNameMap", dw, "");
+    const auto printIfaceNameInfo = [&dw](const uint32_t& key, const IfaceValue& value,
+                                          const BpfMap<uint32_t, IfaceValue>&) {
+        const char* ifname = value.name;
+        dw.println("ifaceIndex=%u ifaceName=%s", key, ifname);
+        return base::Result<void>();
+    };
+    res = mIfaceIndexNameMap.iterateWithValue(printIfaceNameInfo);
+    if (!res.ok()) {
+        dw.println("mIfaceIndexNameMap print end with error: %s", res.error().message().c_str());
+    }
+
+    // Print ifaceStatsMap content
+    std::string ifaceStatsHeader = StringPrintf("ifaceIndex ifaceName rxBytes rxPackets txBytes"
+                                                " txPackets");
+    dumpBpfMap("mIfaceStatsMap:", dw, ifaceStatsHeader);
+    const auto printIfaceStatsInfo = [&dw, this](const uint32_t& key, const StatsValue& value,
+                                                 const BpfMap<uint32_t, StatsValue>&) {
+        auto ifname = mIfaceIndexNameMap.readValue(key);
+        if (!ifname.ok()) {
+            ifname = IfaceValue{"unknown"};
+        }
+        dw.println("%u %s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, key, ifname.value().name,
+                   value.rxBytes, value.rxPackets, value.txBytes, value.txPackets);
+        return base::Result<void>();
+    };
+    res = mIfaceStatsMap.iterateWithValue(printIfaceStatsInfo);
+    if (!res.ok()) {
+        dw.println("mIfaceStatsMap print end with error: %s", res.error().message().c_str());
+    }
+
+    dw.blankline();
+
+    uint32_t key = UID_RULES_CONFIGURATION_KEY;
+    auto configuration = mConfigurationMap.readValue(key);
+    if (configuration.ok()) {
+        dw.println("current ownerMatch configuration: %d%s", configuration.value(),
+                   uidMatchTypeToString(configuration.value()).c_str());
+    } else {
+        dw.println("mConfigurationMap read ownerMatch configure failed with error: %s",
+                   configuration.error().message().c_str());
+    }
+
+    key = CURRENT_STATS_MAP_CONFIGURATION_KEY;
+    configuration = mConfigurationMap.readValue(key);
+    if (configuration.ok()) {
+        const char* statsMapDescription = "???";
+        switch (configuration.value()) {
+            case SELECT_MAP_A:
+                statsMapDescription = "SELECT_MAP_A";
+                break;
+            case SELECT_MAP_B:
+                statsMapDescription = "SELECT_MAP_B";
+                break;
+                // No default clause, so if we ever add a third map, this code will fail to build.
+        }
+        dw.println("current statsMap configuration: %d %s", configuration.value(),
+                   statsMapDescription);
+    } else {
+        dw.println("mConfigurationMap read stats map configure failed with error: %s",
+                   configuration.error().message().c_str());
+    }
+    dumpBpfMap("mUidOwnerMap", dw, "");
+    const auto printUidMatchInfo = [&dw, this](const uint32_t& key, const UidOwnerValue& value,
+                                               const BpfMap<uint32_t, UidOwnerValue>&) {
+        if (value.rule & IIF_MATCH) {
+            auto ifname = mIfaceIndexNameMap.readValue(value.iif);
+            if (ifname.ok()) {
+                dw.println("%u %s %s", key, uidMatchTypeToString(value.rule).c_str(),
+                           ifname.value().name);
+            } else {
+                dw.println("%u %s %u", key, uidMatchTypeToString(value.rule).c_str(), value.iif);
+            }
+        } else {
+            dw.println("%u %s", key, uidMatchTypeToString(value.rule).c_str());
+        }
+        return base::Result<void>();
+    };
+    res = mUidOwnerMap.iterateWithValue(printUidMatchInfo);
+    if (!res.ok()) {
+        dw.println("mUidOwnerMap print end with error: %s", res.error().message().c_str());
+    }
+    dumpBpfMap("mUidPermissionMap", dw, "");
+    const auto printUidPermissionInfo = [&dw](const uint32_t& key, const int& value,
+                                              const BpfMap<uint32_t, uint8_t>&) {
+        dw.println("%u %s", key, UidPermissionTypeToString(value).c_str());
+        return base::Result<void>();
+    };
+    res = mUidPermissionMap.iterateWithValue(printUidPermissionInfo);
+    if (!res.ok()) {
+        dw.println("mUidPermissionMap print end with error: %s", res.error().message().c_str());
+    }
+
+    dumpBpfMap("mPrivilegedUser", dw, "");
+    for (uid_t uid : mPrivilegedUser) {
+        dw.println("%u ALLOW_UPDATE_DEVICE_STATS", (uint32_t)uid);
+    }
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/service/native/TrafficControllerTest.cpp b/service/native/TrafficControllerTest.cpp
new file mode 100644
index 0000000..f401636
--- /dev/null
+++ b/service/native/TrafficControllerTest.cpp
@@ -0,0 +1,750 @@
+/*
+ * Copyright 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.
+ *
+ * TrafficControllerTest.cpp - unit tests for TrafficController.cpp
+ */
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <linux/inet_diag.h>
+#include <linux/sock_diag.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <gtest/gtest.h>
+
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <binder/Status.h>
+
+#include <netdutils/MockSyscalls.h>
+
+#include "TrafficController.h"
+#include "bpf/BpfUtils.h"
+
+using namespace android::bpf;  // NOLINT(google-build-using-namespace): grandfathered
+
+namespace android {
+namespace net {
+
+using android::netdutils::Status;
+using base::Result;
+using netdutils::isOk;
+
+constexpr int TEST_MAP_SIZE = 10;
+constexpr uid_t TEST_UID = 10086;
+constexpr uid_t TEST_UID2 = 54321;
+constexpr uid_t TEST_UID3 = 98765;
+constexpr uint32_t TEST_TAG = 42;
+constexpr uint32_t TEST_COUNTERSET = 1;
+constexpr uint32_t DEFAULT_COUNTERSET = 0;
+
+#define ASSERT_VALID(x) ASSERT_TRUE((x).isValid())
+
+class TrafficControllerTest : public ::testing::Test {
+  protected:
+    TrafficControllerTest() {}
+    TrafficController mTc;
+    BpfMap<uint64_t, UidTagValue> mFakeCookieTagMap;
+    BpfMap<uint32_t, uint8_t> mFakeUidCounterSetMap;
+    BpfMap<uint32_t, StatsValue> mFakeAppUidStatsMap;
+    BpfMap<StatsKey, StatsValue> mFakeStatsMapA;
+    BpfMap<uint32_t, uint8_t> mFakeConfigurationMap;
+    BpfMap<uint32_t, UidOwnerValue> mFakeUidOwnerMap;
+    BpfMap<uint32_t, uint8_t> mFakeUidPermissionMap;
+
+    void SetUp() {
+        std::lock_guard guard(mTc.mMutex);
+        ASSERT_EQ(0, setrlimitForTest());
+
+        mFakeCookieTagMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint64_t), sizeof(UidTagValue),
+                                          TEST_MAP_SIZE, 0));
+        ASSERT_VALID(mFakeCookieTagMap);
+
+        mFakeUidCounterSetMap.reset(
+            createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
+        ASSERT_VALID(mFakeUidCounterSetMap);
+
+        mFakeAppUidStatsMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(StatsValue),
+                                            TEST_MAP_SIZE, 0));
+        ASSERT_VALID(mFakeAppUidStatsMap);
+
+        mFakeStatsMapA.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(StatsKey), sizeof(StatsValue),
+                                       TEST_MAP_SIZE, 0));
+        ASSERT_VALID(mFakeStatsMapA);
+
+        mFakeConfigurationMap.reset(
+                createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), 1, 0));
+        ASSERT_VALID(mFakeConfigurationMap);
+
+        mFakeUidOwnerMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(UidOwnerValue),
+                                         TEST_MAP_SIZE, 0));
+        ASSERT_VALID(mFakeUidOwnerMap);
+        mFakeUidPermissionMap.reset(
+                createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
+        ASSERT_VALID(mFakeUidPermissionMap);
+
+        mTc.mCookieTagMap.reset(dupFd(mFakeCookieTagMap.getMap()));
+        ASSERT_VALID(mTc.mCookieTagMap);
+        mTc.mUidCounterSetMap.reset(dupFd(mFakeUidCounterSetMap.getMap()));
+        ASSERT_VALID(mTc.mUidCounterSetMap);
+        mTc.mAppUidStatsMap.reset(dupFd(mFakeAppUidStatsMap.getMap()));
+        ASSERT_VALID(mTc.mAppUidStatsMap);
+        mTc.mStatsMapA.reset(dupFd(mFakeStatsMapA.getMap()));
+        ASSERT_VALID(mTc.mStatsMapA);
+        mTc.mConfigurationMap.reset(dupFd(mFakeConfigurationMap.getMap()));
+        ASSERT_VALID(mTc.mConfigurationMap);
+
+        // Always write to stats map A by default.
+        ASSERT_RESULT_OK(mTc.mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY,
+                                                          SELECT_MAP_A, BPF_ANY));
+        mTc.mUidOwnerMap.reset(dupFd(mFakeUidOwnerMap.getMap()));
+        ASSERT_VALID(mTc.mUidOwnerMap);
+        mTc.mUidPermissionMap.reset(dupFd(mFakeUidPermissionMap.getMap()));
+        ASSERT_VALID(mTc.mUidPermissionMap);
+        mTc.mPrivilegedUser.clear();
+    }
+
+    int dupFd(const android::base::unique_fd& mapFd) {
+        return fcntl(mapFd.get(), F_DUPFD_CLOEXEC, 0);
+    }
+
+    void populateFakeStats(uint64_t cookie, uint32_t uid, uint32_t tag, StatsKey* key) {
+        UidTagValue cookieMapkey = {.uid = (uint32_t)uid, .tag = tag};
+        EXPECT_RESULT_OK(mFakeCookieTagMap.writeValue(cookie, cookieMapkey, BPF_ANY));
+        *key = {.uid = uid, .tag = tag, .counterSet = TEST_COUNTERSET, .ifaceIndex = 1};
+        StatsValue statsMapValue = {.rxPackets = 1, .rxBytes = 100};
+        uint8_t counterSet = TEST_COUNTERSET;
+        EXPECT_RESULT_OK(mFakeUidCounterSetMap.writeValue(uid, counterSet, BPF_ANY));
+        EXPECT_RESULT_OK(mFakeStatsMapA.writeValue(*key, statsMapValue, BPF_ANY));
+        key->tag = 0;
+        EXPECT_RESULT_OK(mFakeStatsMapA.writeValue(*key, statsMapValue, BPF_ANY));
+        EXPECT_RESULT_OK(mFakeAppUidStatsMap.writeValue(uid, statsMapValue, BPF_ANY));
+        // put tag information back to statsKey
+        key->tag = tag;
+    }
+
+    void checkUidOwnerRuleForChain(ChildChain chain, UidOwnerMatchType match) {
+        uint32_t uid = TEST_UID;
+        EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, DENYLIST));
+        Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
+        EXPECT_RESULT_OK(value);
+        EXPECT_TRUE(value.value().rule & match);
+
+        uid = TEST_UID2;
+        EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, ALLOWLIST));
+        value = mFakeUidOwnerMap.readValue(uid);
+        EXPECT_RESULT_OK(value);
+        EXPECT_TRUE(value.value().rule & match);
+
+        EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, ALLOWLIST));
+        value = mFakeUidOwnerMap.readValue(uid);
+        EXPECT_FALSE(value.ok());
+        EXPECT_EQ(ENOENT, value.error().code());
+
+        uid = TEST_UID;
+        EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, DENYLIST));
+        value = mFakeUidOwnerMap.readValue(uid);
+        EXPECT_FALSE(value.ok());
+        EXPECT_EQ(ENOENT, value.error().code());
+
+        uid = TEST_UID3;
+        EXPECT_EQ(-ENOENT, mTc.changeUidOwnerRule(chain, uid, ALLOW, DENYLIST));
+        value = mFakeUidOwnerMap.readValue(uid);
+        EXPECT_FALSE(value.ok());
+        EXPECT_EQ(ENOENT, value.error().code());
+    }
+
+    void checkEachUidValue(const std::vector<int32_t>& uids, UidOwnerMatchType match) {
+        for (uint32_t uid : uids) {
+            Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
+            EXPECT_RESULT_OK(value);
+            EXPECT_TRUE(value.value().rule & match);
+        }
+        std::set<uint32_t> uidSet(uids.begin(), uids.end());
+        const auto checkNoOtherUid = [&uidSet](const int32_t& key,
+                                               const BpfMap<uint32_t, UidOwnerValue>&) {
+            EXPECT_NE(uidSet.end(), uidSet.find(key));
+            return Result<void>();
+        };
+        EXPECT_RESULT_OK(mFakeUidOwnerMap.iterate(checkNoOtherUid));
+    }
+
+    void checkUidMapReplace(const std::string& name, const std::vector<int32_t>& uids,
+                            UidOwnerMatchType match) {
+        bool isAllowlist = true;
+        EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isAllowlist, uids));
+        checkEachUidValue(uids, match);
+
+        isAllowlist = false;
+        EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isAllowlist, uids));
+        checkEachUidValue(uids, match);
+    }
+
+    void expectUidOwnerMapValues(const std::vector<uint32_t>& appUids, uint8_t expectedRule,
+                                 uint32_t expectedIif) {
+        for (uint32_t uid : appUids) {
+            Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
+            EXPECT_RESULT_OK(value);
+            EXPECT_EQ(expectedRule, value.value().rule)
+                    << "Expected rule for UID " << uid << " to be " << expectedRule << ", but was "
+                    << value.value().rule;
+            EXPECT_EQ(expectedIif, value.value().iif)
+                    << "Expected iif for UID " << uid << " to be " << expectedIif << ", but was "
+                    << value.value().iif;
+        }
+    }
+
+    template <class Key, class Value>
+    void expectMapEmpty(BpfMap<Key, Value>& map) {
+        auto isEmpty = map.isEmpty();
+        EXPECT_RESULT_OK(isEmpty);
+        EXPECT_TRUE(isEmpty.value());
+    }
+
+    void expectUidPermissionMapValues(const std::vector<uid_t>& appUids, uint8_t expectedValue) {
+        for (uid_t uid : appUids) {
+            Result<uint8_t> value = mFakeUidPermissionMap.readValue(uid);
+            EXPECT_RESULT_OK(value);
+            EXPECT_EQ(expectedValue, value.value())
+                    << "Expected value for UID " << uid << " to be " << expectedValue
+                    << ", but was " << value.value();
+        }
+    }
+
+    void expectPrivilegedUserSet(const std::vector<uid_t>& appUids) {
+        std::lock_guard guard(mTc.mMutex);
+        EXPECT_EQ(appUids.size(), mTc.mPrivilegedUser.size());
+        for (uid_t uid : appUids) {
+            EXPECT_NE(mTc.mPrivilegedUser.end(), mTc.mPrivilegedUser.find(uid));
+        }
+    }
+
+    void expectPrivilegedUserSetEmpty() {
+        std::lock_guard guard(mTc.mMutex);
+        EXPECT_TRUE(mTc.mPrivilegedUser.empty());
+    }
+
+    void addPrivilegedUid(uid_t uid) {
+        std::vector privilegedUid = {uid};
+        mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, privilegedUid);
+    }
+
+    void removePrivilegedUid(uid_t uid) {
+        std::vector privilegedUid = {uid};
+        mTc.setPermissionForUids(INetd::PERMISSION_NONE, privilegedUid);
+    }
+
+    void expectFakeStatsUnchanged(uint64_t cookie, uint32_t tag, uint32_t uid,
+                                  StatsKey tagStatsMapKey) {
+        Result<UidTagValue> cookieMapResult = mFakeCookieTagMap.readValue(cookie);
+        EXPECT_RESULT_OK(cookieMapResult);
+        EXPECT_EQ(uid, cookieMapResult.value().uid);
+        EXPECT_EQ(tag, cookieMapResult.value().tag);
+        Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
+        EXPECT_RESULT_OK(counterSetResult);
+        EXPECT_EQ(TEST_COUNTERSET, counterSetResult.value());
+        Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
+        EXPECT_RESULT_OK(statsMapResult);
+        EXPECT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
+        EXPECT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
+        tagStatsMapKey.tag = 0;
+        statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
+        EXPECT_RESULT_OK(statsMapResult);
+        EXPECT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
+        EXPECT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
+        auto appStatsResult = mFakeAppUidStatsMap.readValue(uid);
+        EXPECT_RESULT_OK(appStatsResult);
+        EXPECT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
+        EXPECT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
+    }
+
+    Status updateUidOwnerMaps(const std::vector<uint32_t>& appUids,
+                              UidOwnerMatchType matchType, TrafficController::IptOp op) {
+        Status ret(0);
+        for (auto uid : appUids) {
+        ret = mTc.updateUidOwnerMap(uid, matchType, op);
+           if(!isOk(ret)) break;
+        }
+        return ret;
+    }
+
+};
+
+TEST_F(TrafficControllerTest, TestSetCounterSet) {
+    uid_t callingUid = TEST_UID2;
+    addPrivilegedUid(callingUid);
+    ASSERT_EQ(0, mTc.setCounterSet(TEST_COUNTERSET, TEST_UID, callingUid));
+    uid_t uid = TEST_UID;
+    Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
+    ASSERT_RESULT_OK(counterSetResult);
+    ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
+    ASSERT_EQ(0, mTc.setCounterSet(DEFAULT_COUNTERSET, TEST_UID, callingUid));
+    ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
+    expectMapEmpty(mFakeUidCounterSetMap);
+}
+
+TEST_F(TrafficControllerTest, TestSetCounterSetWithoutPermission) {
+    ASSERT_EQ(-EPERM, mTc.setCounterSet(TEST_COUNTERSET, TEST_UID, TEST_UID2));
+    uid_t uid = TEST_UID;
+    ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
+    expectMapEmpty(mFakeUidCounterSetMap);
+}
+
+TEST_F(TrafficControllerTest, TestSetInvalidCounterSet) {
+    uid_t callingUid = TEST_UID2;
+    addPrivilegedUid(callingUid);
+    ASSERT_GT(0, mTc.setCounterSet(OVERFLOW_COUNTERSET, TEST_UID, callingUid));
+    uid_t uid = TEST_UID;
+    ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
+    expectMapEmpty(mFakeUidCounterSetMap);
+}
+
+TEST_F(TrafficControllerTest, TestDeleteTagDataWithoutPermission) {
+    uint64_t cookie = 1;
+    uid_t uid = TEST_UID;
+    uint32_t tag = TEST_TAG;
+    StatsKey tagStatsMapKey;
+    populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
+    ASSERT_EQ(-EPERM, mTc.deleteTagData(0, TEST_UID, TEST_UID2));
+
+    expectFakeStatsUnchanged(cookie, tag, uid, tagStatsMapKey);
+}
+
+TEST_F(TrafficControllerTest, TestDeleteTagData) {
+    uid_t callingUid = TEST_UID2;
+    addPrivilegedUid(callingUid);
+    uint64_t cookie = 1;
+    uid_t uid = TEST_UID;
+    uint32_t tag = TEST_TAG;
+    StatsKey tagStatsMapKey;
+    populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
+    ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID, callingUid));
+    ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie).ok());
+    Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
+    ASSERT_RESULT_OK(counterSetResult);
+    ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
+    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey).ok());
+    tagStatsMapKey.tag = 0;
+    Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
+    ASSERT_RESULT_OK(statsMapResult);
+    ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
+    ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
+    auto appStatsResult = mFakeAppUidStatsMap.readValue(TEST_UID);
+    ASSERT_RESULT_OK(appStatsResult);
+    ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
+    ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
+}
+
+TEST_F(TrafficControllerTest, TestDeleteAllUidData) {
+    uid_t callingUid = TEST_UID2;
+    addPrivilegedUid(callingUid);
+    uint64_t cookie = 1;
+    uid_t uid = TEST_UID;
+    uint32_t tag = TEST_TAG;
+    StatsKey tagStatsMapKey;
+    populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
+    ASSERT_EQ(0, mTc.deleteTagData(0, TEST_UID, callingUid));
+    ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie).ok());
+    ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
+    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey).ok());
+    tagStatsMapKey.tag = 0;
+    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey).ok());
+    ASSERT_FALSE(mFakeAppUidStatsMap.readValue(TEST_UID).ok());
+}
+
+TEST_F(TrafficControllerTest, TestDeleteDataWithTwoTags) {
+    uid_t callingUid = TEST_UID2;
+    addPrivilegedUid(callingUid);
+    uint64_t cookie1 = 1;
+    uint64_t cookie2 = 2;
+    uid_t uid = TEST_UID;
+    uint32_t tag1 = TEST_TAG;
+    uint32_t tag2 = TEST_TAG + 1;
+    StatsKey tagStatsMapKey1;
+    StatsKey tagStatsMapKey2;
+    populateFakeStats(cookie1, uid, tag1, &tagStatsMapKey1);
+    populateFakeStats(cookie2, uid, tag2, &tagStatsMapKey2);
+    ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID, callingUid));
+    ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie1).ok());
+    Result<UidTagValue> cookieMapResult = mFakeCookieTagMap.readValue(cookie2);
+    ASSERT_RESULT_OK(cookieMapResult);
+    ASSERT_EQ(TEST_UID, cookieMapResult.value().uid);
+    ASSERT_EQ(TEST_TAG + 1, cookieMapResult.value().tag);
+    Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
+    ASSERT_RESULT_OK(counterSetResult);
+    ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
+    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey1).ok());
+    Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey2);
+    ASSERT_RESULT_OK(statsMapResult);
+    ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
+    ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
+}
+
+TEST_F(TrafficControllerTest, TestDeleteDataWithTwoUids) {
+    uid_t callingUid = TEST_UID2;
+    addPrivilegedUid(callingUid);
+    uint64_t cookie1 = 1;
+    uint64_t cookie2 = 2;
+    uid_t uid1 = TEST_UID;
+    uid_t uid2 = TEST_UID + 1;
+    uint32_t tag = TEST_TAG;
+    StatsKey tagStatsMapKey1;
+    StatsKey tagStatsMapKey2;
+    populateFakeStats(cookie1, uid1, tag, &tagStatsMapKey1);
+    populateFakeStats(cookie2, uid2, tag, &tagStatsMapKey2);
+
+    // Delete the stats of one of the uid. Check if it is properly collected by
+    // removedStats.
+    ASSERT_EQ(0, mTc.deleteTagData(0, uid2, callingUid));
+    ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie2).ok());
+    Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid1);
+    ASSERT_RESULT_OK(counterSetResult);
+    ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
+    ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid2).ok());
+    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey2).ok());
+    tagStatsMapKey2.tag = 0;
+    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey2).ok());
+    ASSERT_FALSE(mFakeAppUidStatsMap.readValue(uid2).ok());
+    tagStatsMapKey1.tag = 0;
+    Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey1);
+    ASSERT_RESULT_OK(statsMapResult);
+    ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
+    ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
+    auto appStatsResult = mFakeAppUidStatsMap.readValue(uid1);
+    ASSERT_RESULT_OK(appStatsResult);
+    ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
+    ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
+
+    // Delete the stats of the other uid.
+    ASSERT_EQ(0, mTc.deleteTagData(0, uid1, callingUid));
+    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey1).ok());
+    ASSERT_FALSE(mFakeAppUidStatsMap.readValue(uid1).ok());
+}
+
+TEST_F(TrafficControllerTest, TestUpdateOwnerMapEntry) {
+    uint32_t uid = TEST_UID;
+    ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, DENY, DENYLIST)));
+    Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
+    ASSERT_RESULT_OK(value);
+    ASSERT_TRUE(value.value().rule & STANDBY_MATCH);
+
+    ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, ALLOW, ALLOWLIST)));
+    value = mFakeUidOwnerMap.readValue(uid);
+    ASSERT_RESULT_OK(value);
+    ASSERT_TRUE(value.value().rule & DOZABLE_MATCH);
+
+    ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, DENY, ALLOWLIST)));
+    value = mFakeUidOwnerMap.readValue(uid);
+    ASSERT_RESULT_OK(value);
+    ASSERT_FALSE(value.value().rule & DOZABLE_MATCH);
+
+    ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, DENYLIST)));
+    ASSERT_FALSE(mFakeUidOwnerMap.readValue(uid).ok());
+
+    uid = TEST_UID2;
+    ASSERT_FALSE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, DENYLIST)));
+    ASSERT_FALSE(mFakeUidOwnerMap.readValue(uid).ok());
+}
+
+TEST_F(TrafficControllerTest, TestChangeUidOwnerRule) {
+    checkUidOwnerRuleForChain(DOZABLE, DOZABLE_MATCH);
+    checkUidOwnerRuleForChain(STANDBY, STANDBY_MATCH);
+    checkUidOwnerRuleForChain(POWERSAVE, POWERSAVE_MATCH);
+    checkUidOwnerRuleForChain(RESTRICTED, RESTRICTED_MATCH);
+    ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(NONE, TEST_UID, ALLOW, ALLOWLIST));
+    ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(INVALID_CHAIN, TEST_UID, ALLOW, ALLOWLIST));
+}
+
+TEST_F(TrafficControllerTest, TestReplaceUidOwnerMap) {
+    std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
+    checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
+    checkUidMapReplace("fw_standby", uids, STANDBY_MATCH);
+    checkUidMapReplace("fw_powersave", uids, POWERSAVE_MATCH);
+    checkUidMapReplace("fw_restricted", uids, RESTRICTED_MATCH);
+    ASSERT_EQ(-EINVAL, mTc.replaceUidOwnerMap("unknow", true, uids));
+}
+
+TEST_F(TrafficControllerTest, TestReplaceSameChain) {
+    std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
+    checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
+    std::vector<int32_t> newUids = {TEST_UID2, TEST_UID3};
+    checkUidMapReplace("fw_dozable", newUids, DOZABLE_MATCH);
+}
+
+TEST_F(TrafficControllerTest, TestDenylistUidMatch) {
+    std::vector<uint32_t> appUids = {1000, 1001, 10012};
+    ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, PENALTY_BOX_MATCH,
+                                        TrafficController::IptOpInsert)));
+    expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);
+    ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, PENALTY_BOX_MATCH,
+                                        TrafficController::IptOpDelete)));
+    expectMapEmpty(mFakeUidOwnerMap);
+}
+
+TEST_F(TrafficControllerTest, TestAllowlistUidMatch) {
+    std::vector<uint32_t> appUids = {1000, 1001, 10012};
+    ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpInsert)));
+    expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
+    ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpDelete)));
+    expectMapEmpty(mFakeUidOwnerMap);
+}
+
+TEST_F(TrafficControllerTest, TestReplaceMatchUid) {
+    std::vector<uint32_t> appUids = {1000, 1001, 10012};
+    // Add appUids to the denylist and expect that their values are all PENALTY_BOX_MATCH.
+    ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, PENALTY_BOX_MATCH,
+                                        TrafficController::IptOpInsert)));
+    expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);
+
+    // Add the same UIDs to the allowlist and expect that we get PENALTY_BOX_MATCH |
+    // HAPPY_BOX_MATCH.
+    ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpInsert)));
+    expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH | PENALTY_BOX_MATCH, 0);
+
+    // Remove the same UIDs from the allowlist and check the PENALTY_BOX_MATCH is still there.
+    ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpDelete)));
+    expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);
+
+    // Remove the same UIDs from the denylist and check the map is empty.
+    ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, PENALTY_BOX_MATCH,
+                                        TrafficController::IptOpDelete)));
+    ASSERT_FALSE(mFakeUidOwnerMap.getFirstKey().ok());
+}
+
+TEST_F(TrafficControllerTest, TestDeleteWrongMatchSilentlyFails) {
+    std::vector<uint32_t> appUids = {1000, 1001, 10012};
+    // If the uid does not exist in the map, trying to delete a rule about it will fail.
+    ASSERT_FALSE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH,
+                                         TrafficController::IptOpDelete)));
+    expectMapEmpty(mFakeUidOwnerMap);
+
+    // Add denylist rules for appUids.
+    ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH,
+                                        TrafficController::IptOpInsert)));
+    expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
+
+    // Delete (non-existent) denylist rules for appUids, and check that this silently does
+    // nothing if the uid is in the map but does not have denylist match. This is required because
+    // NetworkManagementService will try to remove a uid from denylist after adding it to the
+    // allowlist and if the remove fails it will not update the uid status.
+    ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, PENALTY_BOX_MATCH,
+                                        TrafficController::IptOpDelete)));
+    expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
+}
+
+TEST_F(TrafficControllerTest, TestAddUidInterfaceFilteringRules) {
+    int iif0 = 15;
+    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif0, {1000, 1001})));
+    expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
+
+    // Add some non-overlapping new uids. They should coexist with existing rules
+    int iif1 = 16;
+    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {2000, 2001})));
+    expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
+    expectUidOwnerMapValues({2000, 2001}, IIF_MATCH, iif1);
+
+    // Overwrite some existing uids
+    int iif2 = 17;
+    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif2, {1000, 2000})));
+    expectUidOwnerMapValues({1001}, IIF_MATCH, iif0);
+    expectUidOwnerMapValues({2001}, IIF_MATCH, iif1);
+    expectUidOwnerMapValues({1000, 2000}, IIF_MATCH, iif2);
+}
+
+TEST_F(TrafficControllerTest, TestRemoveUidInterfaceFilteringRules) {
+    int iif0 = 15;
+    int iif1 = 16;
+    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif0, {1000, 1001})));
+    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {2000, 2001})));
+    expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
+    expectUidOwnerMapValues({2000, 2001}, IIF_MATCH, iif1);
+
+    // Rmove some uids
+    ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1001, 2001})));
+    expectUidOwnerMapValues({1000}, IIF_MATCH, iif0);
+    expectUidOwnerMapValues({2000}, IIF_MATCH, iif1);
+    checkEachUidValue({1000, 2000}, IIF_MATCH);  // Make sure there are only two uids remaining
+
+    // Remove non-existent uids shouldn't fail
+    ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({2000, 3000})));
+    expectUidOwnerMapValues({1000}, IIF_MATCH, iif0);
+    checkEachUidValue({1000}, IIF_MATCH);  // Make sure there are only one uid remaining
+
+    // Remove everything
+    ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1000})));
+    expectMapEmpty(mFakeUidOwnerMap);
+}
+
+TEST_F(TrafficControllerTest, TestUidInterfaceFilteringRulesCoexistWithExistingMatches) {
+    // Set up existing PENALTY_BOX_MATCH rules
+    ASSERT_TRUE(isOk(updateUidOwnerMaps({1000, 1001, 10012}, PENALTY_BOX_MATCH,
+                                        TrafficController::IptOpInsert)));
+    expectUidOwnerMapValues({1000, 1001, 10012}, PENALTY_BOX_MATCH, 0);
+
+    // Add some partially-overlapping uid owner rules and check result
+    int iif1 = 32;
+    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {10012, 10013, 10014})));
+    expectUidOwnerMapValues({1000, 1001}, PENALTY_BOX_MATCH, 0);
+    expectUidOwnerMapValues({10012}, PENALTY_BOX_MATCH | IIF_MATCH, iif1);
+    expectUidOwnerMapValues({10013, 10014}, IIF_MATCH, iif1);
+
+    // Removing some PENALTY_BOX_MATCH rules should not change uid interface rule
+    ASSERT_TRUE(isOk(updateUidOwnerMaps({1001, 10012}, PENALTY_BOX_MATCH,
+                                        TrafficController::IptOpDelete)));
+    expectUidOwnerMapValues({1000}, PENALTY_BOX_MATCH, 0);
+    expectUidOwnerMapValues({10012, 10013, 10014}, IIF_MATCH, iif1);
+
+    // Remove all uid interface rules
+    ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({10012, 10013, 10014})));
+    expectUidOwnerMapValues({1000}, PENALTY_BOX_MATCH, 0);
+    // Make sure these are the only uids left
+    checkEachUidValue({1000}, PENALTY_BOX_MATCH);
+}
+
+TEST_F(TrafficControllerTest, TestUidInterfaceFilteringRulesCoexistWithNewMatches) {
+    int iif1 = 56;
+    // Set up existing uid interface rules
+    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {10001, 10002})));
+    expectUidOwnerMapValues({10001, 10002}, IIF_MATCH, iif1);
+
+    // Add some partially-overlapping doze rules
+    EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_dozable", true, {10002, 10003}));
+    expectUidOwnerMapValues({10001}, IIF_MATCH, iif1);
+    expectUidOwnerMapValues({10002}, DOZABLE_MATCH | IIF_MATCH, iif1);
+    expectUidOwnerMapValues({10003}, DOZABLE_MATCH, 0);
+
+    // Introduce a third rule type (powersave) on various existing UIDs
+    EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_powersave", true, {10000, 10001, 10002, 10003}));
+    expectUidOwnerMapValues({10000}, POWERSAVE_MATCH, 0);
+    expectUidOwnerMapValues({10001}, POWERSAVE_MATCH | IIF_MATCH, iif1);
+    expectUidOwnerMapValues({10002}, POWERSAVE_MATCH | DOZABLE_MATCH | IIF_MATCH, iif1);
+    expectUidOwnerMapValues({10003}, POWERSAVE_MATCH | DOZABLE_MATCH, 0);
+
+    // Remove all doze rules
+    EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_dozable", true, {}));
+    expectUidOwnerMapValues({10000}, POWERSAVE_MATCH, 0);
+    expectUidOwnerMapValues({10001}, POWERSAVE_MATCH | IIF_MATCH, iif1);
+    expectUidOwnerMapValues({10002}, POWERSAVE_MATCH | IIF_MATCH, iif1);
+    expectUidOwnerMapValues({10003}, POWERSAVE_MATCH, 0);
+
+    // Remove all powersave rules, expect ownerMap to only have uid interface rules left
+    EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_powersave", true, {}));
+    expectUidOwnerMapValues({10001, 10002}, IIF_MATCH, iif1);
+    // Make sure these are the only uids left
+    checkEachUidValue({10001, 10002}, IIF_MATCH);
+}
+
+TEST_F(TrafficControllerTest, TestGrantInternetPermission) {
+    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
+
+    mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, appUids);
+    expectMapEmpty(mFakeUidPermissionMap);
+    expectPrivilegedUserSetEmpty();
+}
+
+TEST_F(TrafficControllerTest, TestRevokeInternetPermission) {
+    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
+
+    mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
+    expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
+}
+
+TEST_F(TrafficControllerTest, TestPermissionUninstalled) {
+    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
+
+    mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
+    expectUidPermissionMapValues(appUids, INetd::PERMISSION_UPDATE_DEVICE_STATS);
+    expectPrivilegedUserSet(appUids);
+
+    std::vector<uid_t> uidToRemove = {TEST_UID};
+    mTc.setPermissionForUids(INetd::PERMISSION_UNINSTALLED, uidToRemove);
+
+    std::vector<uid_t> uidRemain = {TEST_UID3, TEST_UID2};
+    expectUidPermissionMapValues(uidRemain, INetd::PERMISSION_UPDATE_DEVICE_STATS);
+    expectPrivilegedUserSet(uidRemain);
+
+    mTc.setPermissionForUids(INetd::PERMISSION_UNINSTALLED, uidRemain);
+    expectMapEmpty(mFakeUidPermissionMap);
+    expectPrivilegedUserSetEmpty();
+}
+
+TEST_F(TrafficControllerTest, TestGrantUpdateStatsPermission) {
+    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
+
+    mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
+    expectUidPermissionMapValues(appUids, INetd::PERMISSION_UPDATE_DEVICE_STATS);
+    expectPrivilegedUserSet(appUids);
+
+    mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
+    expectPrivilegedUserSetEmpty();
+    expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
+}
+
+TEST_F(TrafficControllerTest, TestRevokeUpdateStatsPermission) {
+    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
+
+    mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
+    expectPrivilegedUserSet(appUids);
+
+    std::vector<uid_t> uidToRemove = {TEST_UID};
+    mTc.setPermissionForUids(INetd::PERMISSION_NONE, uidToRemove);
+
+    std::vector<uid_t> uidRemain = {TEST_UID3, TEST_UID2};
+    expectPrivilegedUserSet(uidRemain);
+
+    mTc.setPermissionForUids(INetd::PERMISSION_NONE, uidRemain);
+    expectPrivilegedUserSetEmpty();
+}
+
+TEST_F(TrafficControllerTest, TestGrantWrongPermission) {
+    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
+
+    mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
+    expectPrivilegedUserSetEmpty();
+    expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
+}
+
+TEST_F(TrafficControllerTest, TestGrantDuplicatePermissionSlientlyFail) {
+    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
+
+    mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, appUids);
+    expectMapEmpty(mFakeUidPermissionMap);
+
+    std::vector<uid_t> uidToAdd = {TEST_UID};
+    mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, uidToAdd);
+
+    expectPrivilegedUserSetEmpty();
+
+    mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
+    expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
+
+    mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
+    expectPrivilegedUserSet(appUids);
+
+    mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, uidToAdd);
+    expectPrivilegedUserSet(appUids);
+
+    mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
+    expectPrivilegedUserSetEmpty();
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/service/native/include/Common.h b/service/native/include/Common.h
new file mode 100644
index 0000000..7c0b797
--- /dev/null
+++ b/service/native/include/Common.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#pragma once
+// TODO: deduplicate with the constants in NetdConstants.h.
+#include <aidl/android/net/INetd.h>
+
+using aidl::android::net::INetd;
+
+enum FirewallRule { ALLOW = INetd::FIREWALL_RULE_ALLOW, DENY = INetd::FIREWALL_RULE_DENY };
+
+// ALLOWLIST means the firewall denies all by default, uids must be explicitly ALLOWed
+// DENYLIST means the firewall allows all by default, uids must be explicitly DENYed
+
+enum FirewallType { ALLOWLIST = INetd::FIREWALL_ALLOWLIST, DENYLIST = INetd::FIREWALL_DENYLIST };
+
+enum ChildChain {
+    NONE = INetd::FIREWALL_CHAIN_NONE,
+    DOZABLE = INetd::FIREWALL_CHAIN_DOZABLE,
+    STANDBY = INetd::FIREWALL_CHAIN_STANDBY,
+    POWERSAVE = INetd::FIREWALL_CHAIN_POWERSAVE,
+    RESTRICTED = INetd::FIREWALL_CHAIN_RESTRICTED,
+    INVALID_CHAIN
+};
diff --git a/service/native/include/TrafficController.h b/service/native/include/TrafficController.h
new file mode 100644
index 0000000..c050871
--- /dev/null
+++ b/service/native/include/TrafficController.h
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <set>
+#include <Common.h>
+
+#include "android-base/thread_annotations.h"
+#include "bpf/BpfMap.h"
+#include "bpf_shared.h"
+#include "netdutils/DumpWriter.h"
+#include "netdutils/NetlinkListener.h"
+#include "netdutils/StatusOr.h"
+#include "utils/String16.h"
+
+namespace android {
+namespace net {
+
+using netdutils::StatusOr;
+
+class TrafficController {
+  public:
+    /*
+     * Initialize the whole controller
+     */
+    netdutils::Status start();
+
+    int setCounterSet(int counterSetNum, uid_t uid, uid_t callingUid) EXCLUDES(mMutex);
+
+    /*
+     * When deleting a tag data, the qtaguid module will grab the spinlock of each
+     * related rb_tree one by one and delete the tag information, counterSet
+     * information, iface stats information and uid stats information one by one.
+     * The new eBPF implementation is done similiarly by removing the entry on
+     * each map one by one. And deleting processes are also protected by the
+     * spinlock of the map. So no additional lock is required.
+     */
+    int deleteTagData(uint32_t tag, uid_t uid, uid_t callingUid) EXCLUDES(mMutex);
+
+    /*
+     * Swap the stats map config from current active stats map to the idle one.
+     */
+    netdutils::Status swapActiveStatsMap() EXCLUDES(mMutex);
+
+    /*
+     * Add the interface name and index pair into the eBPF map.
+     */
+    int addInterface(const char* name, uint32_t ifaceIndex);
+
+    int changeUidOwnerRule(ChildChain chain, const uid_t uid, FirewallRule rule, FirewallType type);
+
+    int removeUidOwnerRule(const uid_t uid);
+
+    int replaceUidOwnerMap(const std::string& name, bool isAllowlist,
+                           const std::vector<int32_t>& uids);
+
+    enum IptOp { IptOpInsert, IptOpDelete };
+
+    netdutils::Status updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
+                                          FirewallType type) EXCLUDES(mMutex);
+
+    void dump(netdutils::DumpWriter& dw, bool verbose) EXCLUDES(mMutex);
+
+    netdutils::Status replaceRulesInMap(UidOwnerMatchType match, const std::vector<int32_t>& uids)
+            EXCLUDES(mMutex);
+
+    netdutils::Status addUidInterfaceRules(const int ifIndex, const std::vector<int32_t>& uids)
+            EXCLUDES(mMutex);
+    netdutils::Status removeUidInterfaceRules(const std::vector<int32_t>& uids) EXCLUDES(mMutex);
+
+    netdutils::Status updateUidOwnerMap(const uint32_t uid,
+                                        UidOwnerMatchType matchType, IptOp op) EXCLUDES(mMutex);
+    static const String16 DUMP_KEYWORD;
+
+    int toggleUidOwnerMap(ChildChain chain, bool enable) EXCLUDES(mMutex);
+
+    static netdutils::StatusOr<std::unique_ptr<netdutils::NetlinkListenerInterface>>
+    makeSkDestroyListener();
+
+    void setPermissionForUids(int permission, const std::vector<uid_t>& uids) EXCLUDES(mMutex);
+
+    FirewallType getFirewallType(ChildChain);
+
+    static const char* LOCAL_DOZABLE;
+    static const char* LOCAL_STANDBY;
+    static const char* LOCAL_POWERSAVE;
+    static const char* LOCAL_RESTRICTED;
+
+  private:
+    /*
+     * mCookieTagMap: Store the corresponding tag and uid for a specific socket.
+     * DO NOT hold any locks when modifying this map, otherwise when the untag
+     * operation is waiting for a lock hold by other process and there are more
+     * sockets being closed than can fit in the socket buffer of the netlink socket
+     * that receives them, then the kernel will drop some of these sockets and we
+     * won't delete their tags.
+     * Map Key: uint64_t socket cookie
+     * Map Value: UidTagValue, contains a uint32 uid and a uint32 tag.
+     */
+    bpf::BpfMap<uint64_t, UidTagValue> mCookieTagMap GUARDED_BY(mMutex);
+
+    /*
+     * mUidCounterSetMap: Store the counterSet of a specific uid.
+     * Map Key: uint32 uid.
+     * Map Value: uint32 counterSet specifies if the traffic is a background
+     * or foreground traffic.
+     */
+    bpf::BpfMap<uint32_t, uint8_t> mUidCounterSetMap GUARDED_BY(mMutex);
+
+    /*
+     * mAppUidStatsMap: Store the total traffic stats for a uid regardless of
+     * tag, counterSet and iface. The stats is used by TrafficStats.getUidStats
+     * API to return persistent stats for a specific uid since device boot.
+     */
+    bpf::BpfMap<uint32_t, StatsValue> mAppUidStatsMap;
+
+    /*
+     * mStatsMapA/mStatsMapB: Store the traffic statistics for a specific
+     * combination of uid, tag, iface and counterSet. These two maps contain
+     * both tagged and untagged traffic.
+     * Map Key: StatsKey contains the uid, tag, counterSet and ifaceIndex
+     * information.
+     * Map Value: Stats, contains packet count and byte count of each
+     * transport protocol on egress and ingress direction.
+     */
+    bpf::BpfMap<StatsKey, StatsValue> mStatsMapA GUARDED_BY(mMutex);
+
+    bpf::BpfMap<StatsKey, StatsValue> mStatsMapB GUARDED_BY(mMutex);
+
+    /*
+     * mIfaceIndexNameMap: Store the index name pair of each interface show up
+     * on the device since boot. The interface index is used by the eBPF program
+     * to correctly match the iface name when receiving a packet.
+     */
+    bpf::BpfMap<uint32_t, IfaceValue> mIfaceIndexNameMap;
+
+    /*
+     * mIfaceStataMap: Store per iface traffic stats gathered from xt_bpf
+     * filter.
+     */
+    bpf::BpfMap<uint32_t, StatsValue> mIfaceStatsMap;
+
+    /*
+     * mConfigurationMap: Store the current network policy about uid filtering
+     * and the current stats map in use. There are two configuration entries in
+     * the map right now:
+     * - Entry with UID_RULES_CONFIGURATION_KEY:
+     *    Store the configuration for the current uid rules. It indicates the device
+     *    is in doze/powersave/standby/restricted mode.
+     * - Entry with CURRENT_STATS_MAP_CONFIGURATION_KEY:
+     *    Stores the current live stats map that kernel program is writing to.
+     *    Userspace can do scraping and cleaning job on the other one depending on the
+     *    current configs.
+     */
+    bpf::BpfMap<uint32_t, uint8_t> mConfigurationMap GUARDED_BY(mMutex);
+
+    /*
+     * mUidOwnerMap: Store uids that are used for bandwidth control uid match.
+     */
+    bpf::BpfMap<uint32_t, UidOwnerValue> mUidOwnerMap GUARDED_BY(mMutex);
+
+    /*
+     * mUidOwnerMap: Store uids that are used for INTERNET permission check.
+     */
+    bpf::BpfMap<uint32_t, uint8_t> mUidPermissionMap GUARDED_BY(mMutex);
+
+    std::unique_ptr<netdutils::NetlinkListenerInterface> mSkDestroyListener;
+
+    netdutils::Status removeRule(uint32_t uid, UidOwnerMatchType match) REQUIRES(mMutex);
+
+    netdutils::Status addRule(uint32_t uid, UidOwnerMatchType match, uint32_t iif = 0)
+            REQUIRES(mMutex);
+
+    std::mutex mMutex;
+
+    netdutils::Status initMaps() EXCLUDES(mMutex);
+
+    // Keep track of uids that have permission UPDATE_DEVICE_STATS so we don't
+    // need to call back to system server for permission check.
+    std::set<uid_t> mPrivilegedUser GUARDED_BY(mMutex);
+
+    bool hasUpdateDeviceStatsPermission(uid_t uid) REQUIRES(mMutex);
+
+    // For testing
+    friend class TrafficControllerTest;
+};
+
+}  // namespace net
+}  // namespace android
diff --git a/service/native/jni/com_android_server_BpfNetMaps.cpp b/service/native/jni/com_android_server_BpfNetMaps.cpp
new file mode 100644
index 0000000..7ab4d46
--- /dev/null
+++ b/service/native/jni/com_android_server_BpfNetMaps.cpp
@@ -0,0 +1,266 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "TrafficControllerJni"
+
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+#include <net/if.h>
+#include <vector>
+
+#include "TrafficController.h"
+#include "android-base/logging.h"
+#include "bpf_shared.h"
+#include "utils/Log.h"
+
+using android::net::TrafficController;
+using android::netdutils::Status;
+
+using UidOwnerMatchType::PENALTY_BOX_MATCH;
+using UidOwnerMatchType::HAPPY_BOX_MATCH;
+
+static android::net::TrafficController mTc;
+
+namespace android {
+
+static void native_init(JNIEnv* env, jobject clazz) {
+  Status status = mTc.start();
+   if (!isOk(status)) {
+    ALOGE("%s failed", __func__);
+  }
+}
+
+static jint native_addNaughtyApp(JNIEnv* env, jobject clazz, jint uid) {
+  const uint32_t appUids = static_cast<uint32_t>(abs(uid));
+  Status status = mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH,
+      TrafficController::IptOp::IptOpInsert);
+  if (!isOk(status)) {
+    ALOGE("%s failed, errer code = %d", __func__, status.code());
+  }
+  return (jint)status.code();
+}
+
+static jint native_removeNaughtyApp(JNIEnv* env, jobject clazz, jint uid) {
+  const uint32_t appUids = static_cast<uint32_t>(abs(uid));
+  Status status = mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH,
+      TrafficController::IptOp::IptOpDelete);
+  if (!isOk(status)) {
+    ALOGE("%s failed, errer code = %d", __func__, status.code());
+  }
+  return (jint)status.code();
+}
+
+static jint native_addNiceApp(JNIEnv* env, jobject clazz, jint uid) {
+  const uint32_t appUids = static_cast<uint32_t>(abs(uid));
+  Status status = mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH,
+      TrafficController::IptOp::IptOpInsert);
+  if (!isOk(status)) {
+    ALOGE("%s failed, errer code = %d", __func__, status.code());
+  }
+  return (jint)status.code();
+}
+
+static jint native_removeNiceApp(JNIEnv* env, jobject clazz, jint uid) {
+  const uint32_t appUids = static_cast<uint32_t>(abs(uid));
+  Status status = mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH,
+      TrafficController::IptOp::IptOpDelete);
+  if (!isOk(status)) {
+    ALOGD("%s failed, errer code = %d", __func__, status.code());
+  }
+  return (jint)status.code();
+}
+
+static jint native_setChildChain(JNIEnv* env, jobject clazz, jint childChain, jboolean enable) {
+  auto chain = static_cast<ChildChain>(childChain);
+  int res = mTc.toggleUidOwnerMap(chain, enable);
+  if (res) {
+    ALOGE("%s failed, error code = %d", __func__, res);
+  }
+  return (jint)res;
+}
+
+static jint native_replaceUidChain(JNIEnv* env, jobject clazz, jstring name, jboolean isAllowlist,
+                                jintArray jUids) {
+    const ScopedUtfChars chainNameUtf8(env, name);
+    if (chainNameUtf8.c_str() == nullptr) {
+        return -EINVAL;
+    }
+    const std::string chainName(chainNameUtf8.c_str());
+
+    ScopedIntArrayRO uids(env, jUids);
+    if (uids.get() == nullptr) {
+        return -EINVAL;
+    }
+
+    size_t size = uids.size();
+    std::vector<int32_t> data ((int32_t *)&uids[0], (int32_t*)&uids[size]);
+    int res = mTc.replaceUidOwnerMap(chainName, isAllowlist, data);
+    if (res) {
+      ALOGE("%s failed, error code = %d", __func__, res);
+    }
+    return (jint)res;
+}
+
+static FirewallType getFirewallType(ChildChain chain) {
+    switch (chain) {
+        case DOZABLE:
+            return ALLOWLIST;
+        case STANDBY:
+            return DENYLIST;
+        case POWERSAVE:
+            return ALLOWLIST;
+        case RESTRICTED:
+            return ALLOWLIST;
+        case NONE:
+        default:
+            return DENYLIST;
+    }
+}
+
+static jint native_setUidRule(JNIEnv* env, jobject clazz, jint childChain, jint uid,
+                          jint firewallRule) {
+    auto chain = static_cast<ChildChain>(childChain);
+    auto rule = static_cast<FirewallRule>(firewallRule);
+    FirewallType fType = getFirewallType(chain);
+
+    int res = mTc.changeUidOwnerRule(chain, uid, rule, fType);
+    if (res) {
+      ALOGE("%s failed, error code = %d", __func__, res);
+    }
+    return (jint)res;
+}
+
+static jint native_addUidInterfaceRules(JNIEnv* env, jobject clazz, jstring ifName,
+                                    jintArray jUids) {
+    const ScopedUtfChars ifNameUtf8(env, ifName);
+    if (ifNameUtf8.c_str() == nullptr) {
+        return -EINVAL;
+    }
+    const std::string interfaceName(ifNameUtf8.c_str());
+    const int ifIndex = if_nametoindex(interfaceName.c_str());
+
+    ScopedIntArrayRO uids(env, jUids);
+    if (uids.get() == nullptr) {
+        return -EINVAL;
+    }
+
+    size_t size = uids.size();
+    std::vector<int32_t> data ((int32_t *)&uids[0], (int32_t*)&uids[size]);
+    Status status = mTc.addUidInterfaceRules(ifIndex, data);
+    if (!isOk(status)) {
+        ALOGE("%s failed, error code = %d", __func__, status.code());
+    }
+    return (jint)status.code();
+}
+
+static jint native_removeUidInterfaceRules(JNIEnv* env, jobject clazz, jintArray jUids) {
+    ScopedIntArrayRO uids(env, jUids);
+    if (uids.get() == nullptr) {
+        return -EINVAL;
+    }
+
+    size_t size = uids.size();
+    std::vector<int32_t> data ((int32_t *)&uids[0], (int32_t*)&uids[size]);
+    Status status = mTc.removeUidInterfaceRules(data);
+    if (!isOk(status)) {
+        ALOGE("%s failed, error code = %d", __func__, status.code());
+    }
+    return (jint)status.code();
+}
+
+static jint native_swapActiveStatsMap(JNIEnv* env, jobject clazz) {
+    Status status = mTc.swapActiveStatsMap();
+    if (!isOk(status)) {
+        ALOGD("%s failed, error code = %d", __func__, status.code());
+    }
+    return (jint)status.code();
+}
+
+static void native_setPermissionForUids(JNIEnv* env, jobject clazz, jint permission,
+                                      jintArray jUids) {
+    ScopedIntArrayRO uids(env, jUids);
+    if (uids.get() == nullptr) return;
+
+    size_t size = uids.size();
+    static_assert(sizeof(*(uids.get())) == sizeof(uid_t));
+    std::vector<uid_t> data ((uid_t *)&uids[0], (uid_t*)&uids[size]);
+    mTc.setPermissionForUids(permission, data);
+}
+
+static jint native_setCounterSet(JNIEnv* env, jobject clazz, jint setNum, jint uid) {
+    uid_t callingUid = getuid();
+    int res = mTc.setCounterSet(setNum, (uid_t)uid, callingUid);
+    if (res) {
+      ALOGE("%s failed, error code = %d", __func__, res);
+    }
+    return (jint)res;
+}
+
+static jint native_deleteTagData(JNIEnv* env, jobject clazz, jint tagNum, jint uid) {
+    uid_t callingUid = getuid();
+    int res = mTc.deleteTagData(tagNum, (uid_t)uid, callingUid);
+    if (res) {
+      ALOGE("%s failed, error code = %d", __func__, res);
+    }
+    return (jint)res;
+}
+
+/*
+ * JNI registration.
+ */
+// clang-format off
+static const JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    {"native_init", "()V",
+    (void*)native_init},
+    {"native_addNaughtyApp", "(I)I",
+    (void*)native_addNaughtyApp},
+    {"native_removeNaughtyApp", "(I)I",
+    (void*)native_removeNaughtyApp},
+    {"native_addNiceApp", "(I)I",
+    (void*)native_addNiceApp},
+    {"native_removeNiceApp", "(I)I",
+    (void*)native_removeNiceApp},
+    {"native_setChildChain", "(IZ)I",
+    (void*)native_setChildChain},
+    {"native_replaceUidChain", "(Ljava/lang/String;Z[I)I",
+    (void*)native_replaceUidChain},
+    {"native_setUidRule", "(III)I",
+    (void*)native_setUidRule},
+    {"native_addUidInterfaceRules", "(Ljava/lang/String;[I)I",
+    (void*)native_addUidInterfaceRules},
+    {"native_removeUidInterfaceRules", "([I)I",
+    (void*)native_removeUidInterfaceRules},
+    {"native_swapActiveStatsMap", "()I",
+    (void*)native_swapActiveStatsMap},
+    {"native_setPermissionForUids", "(I[I)V",
+    (void*)native_setPermissionForUids},
+    {"native_setCounterSet", "(II)I",
+    (void*)native_setCounterSet},
+    {"native_deleteTagData", "(II)I",
+    (void*)native_deleteTagData},
+};
+// clang-format on
+
+int register_com_android_server_BpfNetMaps(JNIEnv* env) {
+    return jniRegisterNativeMethods(env,
+    "com/android/server/BpfNetMaps",
+    gMethods, NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/service/native/jni/onload.cpp b/service/native/jni/onload.cpp
new file mode 100644
index 0000000..df7c77b
--- /dev/null
+++ b/service/native/jni/onload.cpp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "TrafficControllerJni"
+
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+
+#include "utils/Log.h"
+
+namespace android {
+
+int register_com_android_server_BpfNetMaps(JNIEnv* env);
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv *env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        ALOGE("%s: ERROR: GetEnv failed", __func__);
+        return JNI_ERR;
+    }
+
+    if (register_com_android_server_BpfNetMaps(env) < 0)
+      return JNI_ERR;
+
+    return JNI_VERSION_1_6;
+}
+
+}; // namespace android
diff --git a/service/native/libs/libclat/Android.bp b/service/native/libs/libclat/Android.bp
new file mode 100644
index 0000000..5e208d8
--- /dev/null
+++ b/service/native/libs/libclat/Android.bp
@@ -0,0 +1,70 @@
+// 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_static {
+    name: "libclat",
+    defaults: ["netd_defaults"],
+    header_libs: [
+        "bpf_connectivity_headers",
+        "bpf_headers",
+        "bpf_syscall_wrappers",
+    ],
+    srcs: [
+        "TcUtils.cpp",  // TODO: move to frameworks/libs/net
+        "bpfhelper.cpp",
+        "clatutils.cpp",
+    ],
+    stl: "libc++_static",
+    static_libs: [
+        "libbase",
+        "libip_checksum",
+        "libnetdutils",  // for netdutils/UidConstants.h in bpf_shared.h
+    ],
+    shared_libs: ["liblog"],
+    export_include_dirs: ["include"],
+    min_sdk_version: "30",
+    apex_available: ["com.android.tethering"],
+}
+
+cc_test {
+    name: "libclat_test",
+    defaults: ["netd_defaults"],
+    test_suites: ["device-tests"],
+    header_libs: [
+        "bpf_connectivity_headers",
+        "bpf_headers",
+        "bpf_syscall_wrappers",
+    ],
+    srcs: [
+        "TcUtilsTest.cpp",
+        "clatutils_test.cpp",
+    ],
+    static_libs: [
+        "libbase",
+        "libclat",
+        "libip_checksum",
+        "libnetd_test_tun_interface",
+        "libnetdutils",  // for netdutils/UidConstants.h in bpf_shared.h
+        "libtcutils",
+    ],
+    shared_libs: [
+        "liblog",
+        "libnetutils",
+    ],
+    require_root: true,
+}
diff --git a/service/native/libs/libclat/TcUtils.cpp b/service/native/libs/libclat/TcUtils.cpp
new file mode 100644
index 0000000..cdfb763
--- /dev/null
+++ b/service/native/libs/libclat/TcUtils.cpp
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#define LOG_TAG "TcUtils"
+
+#include "libclat/TcUtils.h"
+
+#include <arpa/inet.h>
+#include <linux/if.h>
+#include <linux/if_arp.h>
+#include <linux/netlink.h>
+#include <linux/pkt_cls.h>
+#include <linux/pkt_sched.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <log/log.h>
+
+#include "android-base/unique_fd.h"
+
+namespace android {
+namespace net {
+
+using std::max;
+
+// Sync from system/netd/server/NetlinkCommands.h
+const sockaddr_nl KERNEL_NLADDR = {AF_NETLINK, 0, 0, 0};
+const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK;
+
+static int doSIOCGIF(const std::string& interface, int opt) {
+    base::unique_fd ufd(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+
+    if (ufd < 0) {
+        const int err = errno;
+        ALOGE("socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0)");
+        return -err;
+    };
+
+    struct ifreq ifr = {};
+    // We use strncpy() instead of strlcpy() since kernel has to be able
+    // to handle non-zero terminated junk passed in by userspace anyway,
+    // and this way too long interface names (more than IFNAMSIZ-1 = 15
+    // characters plus terminating NULL) will not get truncated to 15
+    // characters and zero-terminated and thus potentially erroneously
+    // match a truncated interface if one were to exist.
+    strncpy(ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name));
+
+    if (ioctl(ufd, opt, &ifr, sizeof(ifr))) return -errno;
+
+    if (opt == SIOCGIFHWADDR) return ifr.ifr_hwaddr.sa_family;
+    if (opt == SIOCGIFMTU) return ifr.ifr_mtu;
+    return -EINVAL;
+}
+
+int hardwareAddressType(const std::string& interface) {
+    return doSIOCGIF(interface, SIOCGIFHWADDR);
+}
+
+int deviceMTU(const std::string& interface) {
+    return doSIOCGIF(interface, SIOCGIFMTU);
+}
+
+base::Result<bool> isEthernet(const std::string& interface) {
+    int rv = hardwareAddressType(interface);
+    if (rv < 0) {
+        errno = -rv;
+        return ErrnoErrorf("Get hardware address type of interface {} failed", interface);
+    }
+
+    switch (rv) {
+        case ARPHRD_ETHER:
+            return true;
+        case ARPHRD_NONE:
+        case ARPHRD_RAWIP:  // in Linux 4.14+ rmnet support was upstreamed and this is 519
+        case 530:           // this is ARPHRD_RAWIP on some Android 4.9 kernels with rmnet
+            return false;
+        default:
+            errno = EAFNOSUPPORT;  // Address family not supported
+            return ErrnoErrorf("Unknown hardware address type {} on interface {}", rv, interface);
+    }
+}
+
+// TODO: use //system/netd/server/NetlinkCommands.cpp:openNetlinkSocket(protocol)
+// and //system/netd/server/SockDiag.cpp:checkError(fd)
+static int sendAndProcessNetlinkResponse(const void* req, int len) {
+    base::unique_fd fd(socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE));
+    if (fd == -1) {
+        const int err = errno;
+        ALOGE("socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE)");
+        return -err;
+    }
+
+    static constexpr int on = 1;
+    int rv = setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &on, sizeof(on));
+    if (rv) ALOGE("setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, %d)", on);
+
+    // this is needed to get sane strace netlink parsing, it allocates the pid
+    rv = bind(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR));
+    if (rv) {
+        const int err = errno;
+        ALOGE("bind(fd, {AF_NETLINK, 0, 0})");
+        return -err;
+    }
+
+    // we do not want to receive messages from anyone besides the kernel
+    rv = connect(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR));
+    if (rv) {
+        const int err = errno;
+        ALOGE("connect(fd, {AF_NETLINK, 0, 0})");
+        return -err;
+    }
+
+    rv = send(fd, req, len, 0);
+    if (rv == -1) return -errno;
+    if (rv != len) return -EMSGSIZE;
+
+    struct {
+        nlmsghdr h;
+        nlmsgerr e;
+        char buf[256];
+    } resp = {};
+
+    rv = recv(fd, &resp, sizeof(resp), MSG_TRUNC);
+
+    if (rv == -1) {
+        const int err = errno;
+        ALOGE("recv() failed");
+        return -err;
+    }
+
+    if (rv < (int)NLMSG_SPACE(sizeof(struct nlmsgerr))) {
+        ALOGE("recv() returned short packet: %d", rv);
+        return -EMSGSIZE;
+    }
+
+    if (resp.h.nlmsg_len != (unsigned)rv) {
+        ALOGE("recv() returned invalid header length: %d != %d", resp.h.nlmsg_len, rv);
+        return -EBADMSG;
+    }
+
+    if (resp.h.nlmsg_type != NLMSG_ERROR) {
+        ALOGE("recv() did not return NLMSG_ERROR message: %d", resp.h.nlmsg_type);
+        return -EBADMSG;
+    }
+
+    return resp.e.error;  // returns 0 on success
+}
+
+// ADD:     nlMsgType=RTM_NEWQDISC nlMsgFlags=NLM_F_EXCL|NLM_F_CREATE
+// REPLACE: nlMsgType=RTM_NEWQDISC nlMsgFlags=NLM_F_CREATE|NLM_F_REPLACE
+// DEL:     nlMsgType=RTM_DELQDISC nlMsgFlags=0
+int doTcQdiscClsact(int ifIndex, uint16_t nlMsgType, uint16_t nlMsgFlags) {
+    // This is the name of the qdisc we are attaching.
+    // Some hoop jumping to make this compile time constant with known size,
+    // so that the structure declaration is well defined at compile time.
+#define CLSACT "clsact"
+    // sizeof() includes the terminating NULL
+    static constexpr size_t ASCIIZ_LEN_CLSACT = sizeof(CLSACT);
+
+    const struct {
+        nlmsghdr n;
+        tcmsg t;
+        struct {
+            nlattr attr;
+            char str[NLMSG_ALIGN(ASCIIZ_LEN_CLSACT)];
+        } kind;
+    } req = {
+            .n =
+                    {
+                            .nlmsg_len = sizeof(req),
+                            .nlmsg_type = nlMsgType,
+                            .nlmsg_flags = static_cast<__u16>(NETLINK_REQUEST_FLAGS | nlMsgFlags),
+                    },
+            .t =
+                    {
+                            .tcm_family = AF_UNSPEC,
+                            .tcm_ifindex = ifIndex,
+                            .tcm_handle = TC_H_MAKE(TC_H_CLSACT, 0),
+                            .tcm_parent = TC_H_CLSACT,
+                    },
+            .kind =
+                    {
+                            .attr =
+                                    {
+                                            .nla_len = NLA_HDRLEN + ASCIIZ_LEN_CLSACT,
+                                            .nla_type = TCA_KIND,
+                                    },
+                            .str = CLSACT,
+                    },
+    };
+#undef CLSACT
+
+    return sendAndProcessNetlinkResponse(&req, sizeof(req));
+}
+
+// tc filter add dev .. in/egress prio 4 protocol ipv6/ip bpf object-pinned /sys/fs/bpf/...
+// direct-action
+int tcFilterAddDevBpf(int ifIndex, bool ingress, uint16_t proto, int bpfFd, bool ethernet) {
+    // This is the name of the filter we're attaching (ie. this is the 'bpf'
+    // packet classifier enabled by kernel config option CONFIG_NET_CLS_BPF.
+    //
+    // We go through some hoops in order to make this compile time constants
+    // so that we can define the struct further down the function with the
+    // field for this sized correctly already during the build.
+#define BPF "bpf"
+    // sizeof() includes the terminating NULL
+    static constexpr size_t ASCIIZ_LEN_BPF = sizeof(BPF);
+
+    // This is to replicate program name suffix used by 'tc' Linux cli
+    // when it attaches programs.
+#define FSOBJ_SUFFIX ":[*fsobj]"
+
+    // This macro expands (from header files) to:
+    //   prog_clatd_schedcls_ingress6_clat_rawip:[*fsobj]
+    // and is the name of the pinned ingress ebpf program for ARPHRD_RAWIP interfaces.
+    // (also compatible with anything that has 0 size L2 header)
+    static constexpr char name_clat_rx_rawip[] = CLAT_INGRESS6_PROG_RAWIP_NAME FSOBJ_SUFFIX;
+
+    // This macro expands (from header files) to:
+    //   prog_clatd_schedcls_ingress6_clat_ether:[*fsobj]
+    // and is the name of the pinned ingress ebpf program for ARPHRD_ETHER interfaces.
+    // (also compatible with anything that has standard ethernet header)
+    static constexpr char name_clat_rx_ether[] = CLAT_INGRESS6_PROG_ETHER_NAME FSOBJ_SUFFIX;
+
+    // This macro expands (from header files) to:
+    //   prog_clatd_schedcls_egress4_clat_rawip:[*fsobj]
+    // and is the name of the pinned egress ebpf program for ARPHRD_RAWIP interfaces.
+    // (also compatible with anything that has 0 size L2 header)
+    static constexpr char name_clat_tx_rawip[] = CLAT_EGRESS4_PROG_RAWIP_NAME FSOBJ_SUFFIX;
+
+    // This macro expands (from header files) to:
+    //   prog_clatd_schedcls_egress4_clat_ether:[*fsobj]
+    // and is the name of the pinned egress ebpf program for ARPHRD_ETHER interfaces.
+    // (also compatible with anything that has standard ethernet header)
+    static constexpr char name_clat_tx_ether[] = CLAT_EGRESS4_PROG_ETHER_NAME FSOBJ_SUFFIX;
+
+#undef FSOBJ_SUFFIX
+
+    // The actual name we'll use is determined at run time via 'ethernet' and 'ingress'
+    // booleans.  We need to compile time allocate enough space in the struct
+    // hence this macro magic to make sure we have enough space for either
+    // possibility.  In practice some of these are actually the same size.
+    static constexpr size_t ASCIIZ_MAXLEN_NAME = max({
+            sizeof(name_clat_rx_rawip),
+            sizeof(name_clat_rx_ether),
+            sizeof(name_clat_tx_rawip),
+            sizeof(name_clat_tx_ether),
+    });
+
+    // These are not compile time constants: 'name' is used in strncpy below
+    const char* const name_clat_rx = ethernet ? name_clat_rx_ether : name_clat_rx_rawip;
+    const char* const name_clat_tx = ethernet ? name_clat_tx_ether : name_clat_tx_rawip;
+    const char* const name = ingress ? name_clat_rx : name_clat_tx;
+
+    struct {
+        nlmsghdr n;
+        tcmsg t;
+        struct {
+            nlattr attr;
+            char str[NLMSG_ALIGN(ASCIIZ_LEN_BPF)];
+        } kind;
+        struct {
+            nlattr attr;
+            struct {
+                nlattr attr;
+                __u32 u32;
+            } fd;
+            struct {
+                nlattr attr;
+                char str[NLMSG_ALIGN(ASCIIZ_MAXLEN_NAME)];
+            } name;
+            struct {
+                nlattr attr;
+                __u32 u32;
+            } flags;
+        } options;
+    } req = {
+            .n =
+                    {
+                            .nlmsg_len = sizeof(req),
+                            .nlmsg_type = RTM_NEWTFILTER,
+                            .nlmsg_flags = NETLINK_REQUEST_FLAGS | NLM_F_EXCL | NLM_F_CREATE,
+                    },
+            .t =
+                    {
+                            .tcm_family = AF_UNSPEC,
+                            .tcm_ifindex = ifIndex,
+                            .tcm_handle = TC_H_UNSPEC,
+                            .tcm_parent = TC_H_MAKE(TC_H_CLSACT,
+                                                    ingress ? TC_H_MIN_INGRESS : TC_H_MIN_EGRESS),
+                            .tcm_info = static_cast<__u32>((PRIO_CLAT << 16) | htons(proto)),
+                    },
+            .kind =
+                    {
+                            .attr =
+                                    {
+                                            .nla_len = sizeof(req.kind),
+                                            .nla_type = TCA_KIND,
+                                    },
+                            .str = BPF,
+                    },
+            .options =
+                    {
+                            .attr =
+                                    {
+                                            .nla_len = sizeof(req.options),
+                                            .nla_type = NLA_F_NESTED | TCA_OPTIONS,
+                                    },
+                            .fd =
+                                    {
+                                            .attr =
+                                                    {
+                                                            .nla_len = sizeof(req.options.fd),
+                                                            .nla_type = TCA_BPF_FD,
+                                                    },
+                                            .u32 = static_cast<__u32>(bpfFd),
+                                    },
+                            .name =
+                                    {
+                                            .attr =
+                                                    {
+                                                            .nla_len = sizeof(req.options.name),
+                                                            .nla_type = TCA_BPF_NAME,
+                                                    },
+                                            // Visible via 'tc filter show', but
+                                            // is overwritten by strncpy below
+                                            .str = "placeholder",
+                                    },
+                            .flags =
+                                    {
+                                            .attr =
+                                                    {
+                                                            .nla_len = sizeof(req.options.flags),
+                                                            .nla_type = TCA_BPF_FLAGS,
+                                                    },
+                                            .u32 = TCA_BPF_FLAG_ACT_DIRECT,
+                                    },
+                    },
+    };
+#undef BPF
+
+    strncpy(req.options.name.str, name, sizeof(req.options.name.str));
+
+    return sendAndProcessNetlinkResponse(&req, sizeof(req));
+}
+
+// tc filter del dev .. in/egress prio 4 protocol ..
+int tcFilterDelDev(int ifIndex, bool ingress, uint16_t prio, uint16_t proto) {
+    const struct {
+        nlmsghdr n;
+        tcmsg t;
+    } req = {
+            .n =
+                    {
+                            .nlmsg_len = sizeof(req),
+                            .nlmsg_type = RTM_DELTFILTER,
+                            .nlmsg_flags = NETLINK_REQUEST_FLAGS,
+                    },
+            .t =
+                    {
+                            .tcm_family = AF_UNSPEC,
+                            .tcm_ifindex = ifIndex,
+                            .tcm_handle = TC_H_UNSPEC,
+                            .tcm_parent = TC_H_MAKE(TC_H_CLSACT,
+                                                    ingress ? TC_H_MIN_INGRESS : TC_H_MIN_EGRESS),
+                            .tcm_info = (static_cast<uint32_t>(prio) << 16) |
+                                        static_cast<uint32_t>(htons(proto)),
+                    },
+    };
+
+    return sendAndProcessNetlinkResponse(&req, sizeof(req));
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/service/native/libs/libclat/TcUtilsTest.cpp b/service/native/libs/libclat/TcUtilsTest.cpp
new file mode 100644
index 0000000..08f3042
--- /dev/null
+++ b/service/native/libs/libclat/TcUtilsTest.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2019 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.
+ *
+ * TcUtilsTest.cpp - unit tests for TcUtils.cpp
+ */
+
+#include <gtest/gtest.h>
+
+#include "libclat/TcUtils.h"
+
+#include <linux/if_arp.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+#include "bpf/BpfUtils.h"
+#include "bpf_shared.h"
+
+namespace android {
+namespace net {
+
+class TcUtilsTest : public ::testing::Test {
+  public:
+    void SetUp() {}
+};
+
+TEST_F(TcUtilsTest, HardwareAddressTypeOfNonExistingIf) {
+    ASSERT_EQ(-ENODEV, hardwareAddressType("not_existing_if"));
+}
+
+TEST_F(TcUtilsTest, HardwareAddressTypeOfLoopback) {
+    ASSERT_EQ(ARPHRD_LOOPBACK, hardwareAddressType("lo"));
+}
+
+// If wireless 'wlan0' interface exists it should be Ethernet.
+TEST_F(TcUtilsTest, HardwareAddressTypeOfWireless) {
+    int type = hardwareAddressType("wlan0");
+    if (type == -ENODEV) return;
+
+    ASSERT_EQ(ARPHRD_ETHER, type);
+}
+
+// If cellular 'rmnet_data0' interface exists it should
+// *probably* not be Ethernet and instead be RawIp.
+TEST_F(TcUtilsTest, HardwareAddressTypeOfCellular) {
+    int type = hardwareAddressType("rmnet_data0");
+    if (type == -ENODEV) return;
+
+    ASSERT_NE(ARPHRD_ETHER, type);
+
+    // ARPHRD_RAWIP is 530 on some pre-4.14 Qualcomm devices.
+    if (type == 530) return;
+
+    ASSERT_EQ(ARPHRD_RAWIP, type);
+}
+
+TEST_F(TcUtilsTest, IsEthernetOfNonExistingIf) {
+    auto res = isEthernet("not_existing_if");
+    ASSERT_FALSE(res.ok());
+    ASSERT_EQ(ENODEV, res.error().code());
+}
+
+TEST_F(TcUtilsTest, IsEthernetOfLoopback) {
+    auto res = isEthernet("lo");
+    ASSERT_FALSE(res.ok());
+    ASSERT_EQ(EAFNOSUPPORT, res.error().code());
+}
+
+// If wireless 'wlan0' interface exists it should be Ethernet.
+// See also HardwareAddressTypeOfWireless.
+TEST_F(TcUtilsTest, IsEthernetOfWireless) {
+    auto res = isEthernet("wlan0");
+    if (!res.ok() && res.error().code() == ENODEV) return;
+
+    ASSERT_RESULT_OK(res);
+    ASSERT_TRUE(res.value());
+}
+
+// If cellular 'rmnet_data0' interface exists it should
+// *probably* not be Ethernet and instead be RawIp.
+// See also HardwareAddressTypeOfCellular.
+TEST_F(TcUtilsTest, IsEthernetOfCellular) {
+    auto res = isEthernet("rmnet_data0");
+    if (!res.ok() && res.error().code() == ENODEV) return;
+
+    ASSERT_RESULT_OK(res);
+    ASSERT_FALSE(res.value());
+}
+
+TEST_F(TcUtilsTest, DeviceMTUOfNonExistingIf) {
+    ASSERT_EQ(-ENODEV, deviceMTU("not_existing_if"));
+}
+
+TEST_F(TcUtilsTest, DeviceMTUofLoopback) {
+    ASSERT_EQ(65536, deviceMTU("lo"));
+}
+
+TEST_F(TcUtilsTest, GetClatEgress4MapFd) {
+    int fd = getClatEgress4MapFd();
+    ASSERT_GE(fd, 3);  // 0,1,2 - stdin/out/err, thus fd >= 3
+    EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
+    close(fd);
+}
+
+TEST_F(TcUtilsTest, GetClatEgress4RawIpProgFd) {
+    int fd = getClatEgress4ProgFd(RAWIP);
+    ASSERT_GE(fd, 3);
+    EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
+    close(fd);
+}
+
+TEST_F(TcUtilsTest, GetClatEgress4EtherProgFd) {
+    int fd = getClatEgress4ProgFd(ETHER);
+    ASSERT_GE(fd, 3);
+    EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
+    close(fd);
+}
+
+TEST_F(TcUtilsTest, GetClatIngress6MapFd) {
+    int fd = getClatIngress6MapFd();
+    ASSERT_GE(fd, 3);  // 0,1,2 - stdin/out/err, thus fd >= 3
+    EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
+    close(fd);
+}
+
+TEST_F(TcUtilsTest, GetClatIngress6RawIpProgFd) {
+    int fd = getClatIngress6ProgFd(RAWIP);
+    ASSERT_GE(fd, 3);
+    EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
+    close(fd);
+}
+
+TEST_F(TcUtilsTest, GetClatIngress6EtherProgFd) {
+    int fd = getClatIngress6ProgFd(ETHER);
+    ASSERT_GE(fd, 3);
+    EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
+    close(fd);
+}
+
+// See Linux kernel source in include/net/flow.h
+#define LOOPBACK_IFINDEX 1
+
+TEST_F(TcUtilsTest, AttachReplaceDetachClsactLo) {
+    // This attaches and detaches a configuration-less and thus no-op clsact
+    // qdisc to loopback interface (and it takes fractions of a second)
+    EXPECT_EQ(0, tcQdiscAddDevClsact(LOOPBACK_IFINDEX));
+    EXPECT_EQ(0, tcQdiscReplaceDevClsact(LOOPBACK_IFINDEX));
+    EXPECT_EQ(0, tcQdiscDelDevClsact(LOOPBACK_IFINDEX));
+    EXPECT_EQ(-EINVAL, tcQdiscDelDevClsact(LOOPBACK_IFINDEX));
+}
+
+static void checkAttachDetachBpfFilterClsactLo(const bool ingress, const bool ethernet) {
+    // Older kernels return EINVAL instead of ENOENT due to lacking proper error propagation...
+    const int errNOENT = android::bpf::isAtLeastKernelVersion(4, 19, 0) ? ENOENT : EINVAL;
+
+    int clatBpfFd = ingress ? getClatIngress6ProgFd(ethernet) : getClatEgress4ProgFd(ethernet);
+    ASSERT_GE(clatBpfFd, 3);
+
+    // This attaches and detaches a clsact plus ebpf program to loopback
+    // interface, but it should not affect traffic by virtue of us not
+    // actually populating the ebpf control map.
+    // Furthermore: it only takes fractions of a second.
+    EXPECT_EQ(-EINVAL, tcFilterDelDevIngressClatIpv6(LOOPBACK_IFINDEX));
+    EXPECT_EQ(-EINVAL, tcFilterDelDevEgressClatIpv4(LOOPBACK_IFINDEX));
+    EXPECT_EQ(0, tcQdiscAddDevClsact(LOOPBACK_IFINDEX));
+    EXPECT_EQ(-errNOENT, tcFilterDelDevIngressClatIpv6(LOOPBACK_IFINDEX));
+    EXPECT_EQ(-errNOENT, tcFilterDelDevEgressClatIpv4(LOOPBACK_IFINDEX));
+    if (ingress) {
+        EXPECT_EQ(0, tcFilterAddDevIngressClatIpv6(LOOPBACK_IFINDEX, clatBpfFd, ethernet));
+        EXPECT_EQ(0, tcFilterDelDevIngressClatIpv6(LOOPBACK_IFINDEX));
+    } else {
+        EXPECT_EQ(0, tcFilterAddDevEgressClatIpv4(LOOPBACK_IFINDEX, clatBpfFd, ethernet));
+        EXPECT_EQ(0, tcFilterDelDevEgressClatIpv4(LOOPBACK_IFINDEX));
+    }
+    EXPECT_EQ(-errNOENT, tcFilterDelDevIngressClatIpv6(LOOPBACK_IFINDEX));
+    EXPECT_EQ(-errNOENT, tcFilterDelDevEgressClatIpv4(LOOPBACK_IFINDEX));
+    EXPECT_EQ(0, tcQdiscDelDevClsact(LOOPBACK_IFINDEX));
+    EXPECT_EQ(-EINVAL, tcFilterDelDevIngressClatIpv6(LOOPBACK_IFINDEX));
+    EXPECT_EQ(-EINVAL, tcFilterDelDevEgressClatIpv4(LOOPBACK_IFINDEX));
+
+    close(clatBpfFd);
+}
+
+TEST_F(TcUtilsTest, CheckAttachBpfFilterRawIpClsactEgressLo) {
+    checkAttachDetachBpfFilterClsactLo(EGRESS, RAWIP);
+}
+
+TEST_F(TcUtilsTest, CheckAttachBpfFilterEthernetClsactEgressLo) {
+    checkAttachDetachBpfFilterClsactLo(EGRESS, ETHER);
+}
+
+TEST_F(TcUtilsTest, CheckAttachBpfFilterRawIpClsactIngressLo) {
+    checkAttachDetachBpfFilterClsactLo(INGRESS, RAWIP);
+}
+
+TEST_F(TcUtilsTest, CheckAttachBpfFilterEthernetClsactIngressLo) {
+    checkAttachDetachBpfFilterClsactLo(INGRESS, ETHER);
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/service/native/libs/libclat/bpfhelper.cpp b/service/native/libs/libclat/bpfhelper.cpp
new file mode 100644
index 0000000..6e230d0
--- /dev/null
+++ b/service/native/libs/libclat/bpfhelper.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright 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.
+ *
+ * main.c - main function
+ */
+#define LOG_TAG "bpfhelper"
+
+#include "libclat/bpfhelper.h"
+
+#include <android-base/unique_fd.h>
+#include <log/log.h>
+
+#include "bpf/BpfMap.h"
+#include "libclat/TcUtils.h"
+
+#define DEVICEPREFIX "v4-"
+
+using android::base::unique_fd;
+using android::net::RAWIP;
+using android::net::getClatEgress4MapFd;
+using android::net::getClatIngress6MapFd;
+using android::net::getClatEgress4ProgFd;
+using android::net::getClatIngress6ProgFd;
+using android::net::tcQdiscAddDevClsact;
+using android::net::tcFilterAddDevEgressClatIpv4;
+using android::net::tcFilterAddDevIngressClatIpv6;
+using android::net::tcFilterDelDevEgressClatIpv4;
+using android::net::tcFilterDelDevIngressClatIpv6;
+using android::bpf::BpfMap;
+
+BpfMap<ClatEgress4Key, ClatEgress4Value> mClatEgress4Map;
+BpfMap<ClatIngress6Key, ClatIngress6Value> mClatIngress6Map;
+
+namespace android {
+namespace net {
+namespace clat {
+
+// TODO: have a clearMap function to remove all stubs while system server crash.
+// For long term, move bpf access into java and map initialization should live
+// ClatCoordinator constructor.
+int initMaps(void) {
+    int rv = getClatEgress4MapFd();
+    if (rv < 0) {
+        ALOGE("getClatEgress4MapFd() failure: %s", strerror(-rv));
+        return -rv;
+    }
+    mClatEgress4Map.reset(rv);
+
+    rv = getClatIngress6MapFd();
+    if (rv < 0) {
+        ALOGE("getClatIngress6MapFd() failure: %s", strerror(-rv));
+        mClatEgress4Map.reset(-1);
+        return -rv;
+    }
+    mClatIngress6Map.reset(rv);
+
+    return 0;
+}
+
+void maybeStartBpf(const ClatdTracker& tracker) {
+    auto isEthernet = android::net::isEthernet(tracker.iface);
+    if (!isEthernet.ok()) {
+        ALOGE("isEthernet(%s[%d]) failure: %s", tracker.iface, tracker.ifIndex,
+              isEthernet.error().message().c_str());
+        return;
+    }
+
+    // This program will be attached to the v4-* interface which is a TUN and thus always rawip.
+    int rv = getClatEgress4ProgFd(RAWIP);
+    if (rv < 0) {
+        ALOGE("getClatEgress4ProgFd(RAWIP) failure: %s", strerror(-rv));
+        return;
+    }
+    unique_fd txRawIpProgFd(rv);
+
+    rv = getClatIngress6ProgFd(isEthernet.value());
+    if (rv < 0) {
+        ALOGE("getClatIngress6ProgFd(%d) failure: %s", isEthernet.value(), strerror(-rv));
+        return;
+    }
+    unique_fd rxProgFd(rv);
+
+    ClatEgress4Key txKey = {
+            .iif = tracker.v4ifIndex,
+            .local4 = tracker.v4,
+    };
+    ClatEgress4Value txValue = {
+            .oif = tracker.ifIndex,
+            .local6 = tracker.v6,
+            .pfx96 = tracker.pfx96,
+            .oifIsEthernet = isEthernet.value(),
+    };
+
+    auto ret = mClatEgress4Map.writeValue(txKey, txValue, BPF_ANY);
+    if (!ret.ok()) {
+        ALOGE("mClatEgress4Map.writeValue failure: %s", strerror(ret.error().code()));
+        return;
+    }
+
+    ClatIngress6Key rxKey = {
+            .iif = tracker.ifIndex,
+            .pfx96 = tracker.pfx96,
+            .local6 = tracker.v6,
+    };
+    ClatIngress6Value rxValue = {
+            // TODO: move all the clat code to eBPF and remove the tun interface entirely.
+            .oif = tracker.v4ifIndex,
+            .local4 = tracker.v4,
+    };
+
+    ret = mClatIngress6Map.writeValue(rxKey, rxValue, BPF_ANY);
+    if (!ret.ok()) {
+        ALOGE("mClatIngress6Map.writeValue failure: %s", strerror(ret.error().code()));
+        ret = mClatEgress4Map.deleteValue(txKey);
+        if (!ret.ok())
+            ALOGE("mClatEgress4Map.deleteValue failure: %s", strerror(ret.error().code()));
+        return;
+    }
+
+    // We do tc setup *after* populating the maps, so scanning through them
+    // can always be used to tell us what needs cleanup.
+
+    // Usually the clsact will be added in RouteController::addInterfaceToPhysicalNetwork.
+    // But clat is started before the v4- interface is added to the network. The clat startup have
+    // to add clsact of v4- tun interface first for adding bpf filter in maybeStartBpf.
+    // TODO: move "qdisc add clsact" of v4- tun interface out from ClatdController.
+    rv = tcQdiscAddDevClsact(tracker.v4ifIndex);
+    if (rv) {
+        ALOGE("tcQdiscAddDevClsact(%d[%s]) failure: %s", tracker.v4ifIndex, tracker.v4iface,
+              strerror(-rv));
+        ret = mClatEgress4Map.deleteValue(txKey);
+        if (!ret.ok())
+            ALOGE("mClatEgress4Map.deleteValue failure: %s", strerror(ret.error().code()));
+        ret = mClatIngress6Map.deleteValue(rxKey);
+        if (!ret.ok())
+            ALOGE("mClatIngress6Map.deleteValue failure: %s", strerror(ret.error().code()));
+        return;
+    }
+
+    rv = tcFilterAddDevEgressClatIpv4(tracker.v4ifIndex, txRawIpProgFd, RAWIP);
+    if (rv) {
+        ALOGE("tcFilterAddDevEgressClatIpv4(%d[%s], RAWIP) failure: %s", tracker.v4ifIndex,
+              tracker.v4iface, strerror(-rv));
+
+        // The v4- interface clsact is not deleted for unwinding error because once it is created
+        // with interface addition, the lifetime is till interface deletion. Moreover, the clsact
+        // has no clat filter now. It should not break anything.
+
+        ret = mClatEgress4Map.deleteValue(txKey);
+        if (!ret.ok())
+            ALOGE("mClatEgress4Map.deleteValue failure: %s", strerror(ret.error().code()));
+        ret = mClatIngress6Map.deleteValue(rxKey);
+        if (!ret.ok())
+            ALOGE("mClatIngress6Map.deleteValue failure: %s", strerror(ret.error().code()));
+        return;
+    }
+
+    rv = tcFilterAddDevIngressClatIpv6(tracker.ifIndex, rxProgFd, isEthernet.value());
+    if (rv) {
+        ALOGE("tcFilterAddDevIngressClatIpv6(%d[%s], %d) failure: %s", tracker.ifIndex,
+              tracker.iface, isEthernet.value(), strerror(-rv));
+        rv = tcFilterDelDevEgressClatIpv4(tracker.v4ifIndex);
+        if (rv) {
+            ALOGE("tcFilterDelDevEgressClatIpv4(%d[%s]) failure: %s", tracker.v4ifIndex,
+                  tracker.v4iface, strerror(-rv));
+        }
+
+        // The v4- interface clsact is not deleted. See the reason in the error unwinding code of
+        // the egress filter attaching of v4- tun interface.
+
+        ret = mClatEgress4Map.deleteValue(txKey);
+        if (!ret.ok())
+            ALOGE("mClatEgress4Map.deleteValue failure: %s", strerror(ret.error().code()));
+        ret = mClatIngress6Map.deleteValue(rxKey);
+        if (!ret.ok())
+            ALOGE("mClatIngress6Map.deleteValue failure: %s", strerror(ret.error().code()));
+        return;
+    }
+
+    // success
+}
+
+void maybeStopBpf(const ClatdTracker& tracker) {
+    int rv = tcFilterDelDevIngressClatIpv6(tracker.ifIndex);
+    if (rv < 0) {
+        ALOGE("tcFilterDelDevIngressClatIpv6(%d[%s]) failure: %s", tracker.ifIndex, tracker.iface,
+              strerror(-rv));
+    }
+
+    rv = tcFilterDelDevEgressClatIpv4(tracker.v4ifIndex);
+    if (rv < 0) {
+        ALOGE("tcFilterDelDevEgressClatIpv4(%d[%s]) failure: %s", tracker.v4ifIndex,
+              tracker.v4iface, strerror(-rv));
+    }
+
+    // We cleanup the maps last, so scanning through them can be used to
+    // determine what still needs cleanup.
+
+    ClatEgress4Key txKey = {
+            .iif = tracker.v4ifIndex,
+            .local4 = tracker.v4,
+    };
+
+    auto ret = mClatEgress4Map.deleteValue(txKey);
+    if (!ret.ok()) ALOGE("mClatEgress4Map.deleteValue failure: %s", strerror(ret.error().code()));
+
+    ClatIngress6Key rxKey = {
+            .iif = tracker.ifIndex,
+            .pfx96 = tracker.pfx96,
+            .local6 = tracker.v6,
+    };
+
+    ret = mClatIngress6Map.deleteValue(rxKey);
+    if (!ret.ok()) ALOGE("mClatIngress6Map.deleteValue failure: %s", strerror(ret.error().code()));
+}
+
+}  // namespace clat
+}  // namespace net
+}  // namespace android
diff --git a/service/native/libs/libclat/clatutils.cpp b/service/native/libs/libclat/clatutils.cpp
new file mode 100644
index 0000000..4a125ba
--- /dev/null
+++ b/service/native/libs/libclat/clatutils.cpp
@@ -0,0 +1,268 @@
+// 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.
+
+#define LOG_TAG "clatutils"
+
+#include "libclat/clatutils.h"
+
+#include <errno.h>
+#include <linux/filter.h>
+#include <linux/if_packet.h>
+#include <linux/if_tun.h>
+#include <log/log.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+extern "C" {
+#include "checksum.h"
+}
+
+// Sync from external/android-clat/clatd.h
+#define MAXMTU 65536
+#define PACKETLEN (MAXMTU + sizeof(struct tun_pi))
+
+// Sync from system/netd/include/netid_client.h.
+#define MARK_UNSET 0u
+
+namespace android {
+namespace net {
+namespace clat {
+
+bool isIpv4AddressFree(in_addr_t addr) {
+    int s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    if (s == -1) {
+        return 0;
+    }
+
+    // Attempt to connect to the address. If the connection succeeds and getsockname returns the
+    // same then the address is already assigned to the system and we can't use it.
+    struct sockaddr_in sin = {
+            .sin_family = AF_INET,
+            .sin_port = htons(53),
+            .sin_addr = {addr},
+    };
+    socklen_t len = sizeof(sin);
+    bool inuse = connect(s, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
+                 getsockname(s, (struct sockaddr*)&sin, &len) == 0 && (size_t)len >= sizeof(sin) &&
+                 sin.sin_addr.s_addr == addr;
+
+    close(s);
+    return !inuse;
+}
+
+// Picks a free IPv4 address, starting from ip and trying all addresses in the prefix in order.
+//   ip        - the IP address from the configuration file
+//   prefixlen - the length of the prefix from which addresses may be selected.
+//   returns: the IPv4 address, or INADDR_NONE if no addresses were available
+in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen) {
+    return selectIpv4AddressInternal(ip, prefixlen, isIpv4AddressFree);
+}
+
+// Only allow testing to use this function directly. Otherwise call selectIpv4Address(ip, pfxlen)
+// which has applied valid isIpv4AddressFree function pointer.
+in_addr_t selectIpv4AddressInternal(const in_addr ip, int16_t prefixlen,
+                                    isIpv4AddrFreeFn isIpv4AddressFreeFunc) {
+    // Impossible! Only test allows to apply fn.
+    if (isIpv4AddressFreeFunc == nullptr) {
+        return INADDR_NONE;
+    }
+
+    // Don't accept prefixes that are too large because we scan addresses one by one.
+    if (prefixlen < 16 || prefixlen > 32) {
+        return INADDR_NONE;
+    }
+
+    // All these are in host byte order.
+    in_addr_t mask = 0xffffffff >> (32 - prefixlen) << (32 - prefixlen);
+    in_addr_t ipv4 = ntohl(ip.s_addr);
+    in_addr_t first_ipv4 = ipv4;
+    in_addr_t prefix = ipv4 & mask;
+
+    // Pick the first IPv4 address in the pool, wrapping around if necessary.
+    // So, for example, 192.0.0.4 -> 192.0.0.5 -> 192.0.0.6 -> 192.0.0.7 -> 192.0.0.0.
+    do {
+        if (isIpv4AddressFreeFunc(htonl(ipv4))) {
+            return htonl(ipv4);
+        }
+        ipv4 = prefix | ((ipv4 + 1) & ~mask);
+    } while (ipv4 != first_ipv4);
+
+    return INADDR_NONE;
+}
+
+// Alters the bits in the IPv6 address to make them checksum neutral with v4 and nat64Prefix.
+void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix) {
+    // Fill last 8 bytes of IPv6 address with random bits.
+    arc4random_buf(&v6->s6_addr[8], 8);
+
+    // Make the IID checksum-neutral. That is, make it so that:
+    //   checksum(Local IPv4 | Remote IPv4) = checksum(Local IPv6 | Remote IPv6)
+    // in other words (because remote IPv6 = NAT64 prefix | Remote IPv4):
+    //   checksum(Local IPv4) = checksum(Local IPv6 | NAT64 prefix)
+    // Do this by adjusting the two bytes in the middle of the IID.
+
+    uint16_t middlebytes = (v6->s6_addr[11] << 8) + v6->s6_addr[12];
+
+    uint32_t c1 = ip_checksum_add(0, &v4, sizeof(v4));
+    uint32_t c2 = ip_checksum_add(0, &nat64Prefix, sizeof(nat64Prefix)) +
+                  ip_checksum_add(0, v6, sizeof(*v6));
+
+    uint16_t delta = ip_checksum_adjust(middlebytes, c1, c2);
+    v6->s6_addr[11] = delta >> 8;
+    v6->s6_addr[12] = delta & 0xff;
+}
+
+// Picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix.
+int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
+                        in6_addr* v6) {
+    int s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    if (s == -1) return -errno;
+
+    if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1) == -1) {
+        close(s);
+        return -errno;
+    }
+
+    sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = nat64Prefix};
+    if (connect(s, reinterpret_cast<struct sockaddr*>(&sin6), sizeof(sin6)) == -1) {
+        close(s);
+        return -errno;
+    }
+
+    socklen_t len = sizeof(sin6);
+    if (getsockname(s, reinterpret_cast<struct sockaddr*>(&sin6), &len) == -1) {
+        close(s);
+        return -errno;
+    }
+
+    *v6 = sin6.sin6_addr;
+
+    if (IN6_IS_ADDR_UNSPECIFIED(v6) || IN6_IS_ADDR_LOOPBACK(v6) || IN6_IS_ADDR_LINKLOCAL(v6) ||
+        IN6_IS_ADDR_SITELOCAL(v6) || IN6_IS_ADDR_ULA(v6)) {
+        close(s);
+        return -ENETUNREACH;
+    }
+
+    makeChecksumNeutral(v6, v4, nat64Prefix);
+    close(s);
+
+    return 0;
+}
+
+int detect_mtu(const struct in6_addr* plat_subnet, uint32_t plat_suffix, uint32_t mark) {
+    // Create an IPv6 UDP socket.
+    int s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    if (s < 0) {
+        int ret = errno;
+        ALOGE("socket(AF_INET6, SOCK_DGRAM, 0) failed: %s", strerror(errno));
+        return -ret;
+    }
+
+    // Socket's mark affects routing decisions (network selection)
+    if ((mark != MARK_UNSET) && setsockopt(s, SOL_SOCKET, SO_MARK, &mark, sizeof(mark))) {
+        int ret = errno;
+        ALOGE("setsockopt(SOL_SOCKET, SO_MARK) failed: %s", strerror(errno));
+        close(s);
+        return -ret;
+    }
+
+    // Try to connect udp socket to plat_subnet(96 bits):plat_suffix(32 bits)
+    struct sockaddr_in6 dst = {
+            .sin6_family = AF_INET6,
+            .sin6_addr = *plat_subnet,
+    };
+    dst.sin6_addr.s6_addr32[3] = plat_suffix;
+    if (connect(s, (struct sockaddr*)&dst, sizeof(dst))) {
+        int ret = errno;
+        ALOGE("connect() failed: %s", strerror(errno));
+        close(s);
+        return -ret;
+    }
+
+    // Fetch the socket's IPv6 mtu - this is effectively fetching mtu from routing table
+    int mtu;
+    socklen_t sz_mtu = sizeof(mtu);
+    if (getsockopt(s, SOL_IPV6, IPV6_MTU, &mtu, &sz_mtu)) {
+        int ret = errno;
+        ALOGE("getsockopt(SOL_IPV6, IPV6_MTU) failed: %s", strerror(errno));
+        close(s);
+        return -ret;
+    }
+    if (sz_mtu != sizeof(mtu)) {
+        ALOGE("getsockopt(SOL_IPV6, IPV6_MTU) returned unexpected size: %d", sz_mtu);
+        close(s);
+        return -EFAULT;
+    }
+    close(s);
+
+    return mtu;
+}
+
+/* function: configure_packet_socket
+ * Binds the packet socket and attaches the receive filter to it.
+ *   sock    - the socket to configure
+ *   addr    - the IP address to filter
+ *   ifindex - index of interface to add the filter to
+ * returns: 0 on success, -errno on failure
+ */
+int configure_packet_socket(int sock, in6_addr* addr, int ifindex) {
+    uint32_t* ipv6 = addr->s6_addr32;
+
+    // clang-format off
+    struct sock_filter filter_code[] = {
+    // Load the first four bytes of the IPv6 destination address (starts 24 bytes in).
+    // Compare it against the first four bytes of our IPv6 address, in host byte order (BPF loads
+    // are always in host byte order). If it matches, continue with next instruction (JMP 0). If it
+    // doesn't match, jump ahead to statement that returns 0 (ignore packet). Repeat for the other
+    // three words of the IPv6 address, and if they all match, return PACKETLEN (accept packet).
+        BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  24),
+        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[0]), 0, 7),
+        BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  28),
+        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[1]), 0, 5),
+        BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  32),
+        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[2]), 0, 3),
+        BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  36),
+        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[3]), 0, 1),
+        BPF_STMT(BPF_RET | BPF_K,              PACKETLEN),
+        BPF_STMT(BPF_RET | BPF_K,              0),
+    };
+    // clang-format on
+    struct sock_fprog filter = {sizeof(filter_code) / sizeof(filter_code[0]), filter_code};
+
+    if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter))) {
+        int res = errno;
+        ALOGE("attach packet filter failed: %s", strerror(errno));
+        return -res;
+    }
+
+    struct sockaddr_ll sll = {
+            .sll_family = AF_PACKET,
+            .sll_protocol = htons(ETH_P_IPV6),
+            .sll_ifindex = ifindex,
+            .sll_pkttype =
+                    PACKET_OTHERHOST,  // The 464xlat IPv6 address is not assigned to the kernel.
+    };
+    if (bind(sock, (struct sockaddr*)&sll, sizeof(sll))) {
+        int res = errno;
+        ALOGE("binding packet socket: %s", strerror(errno));
+        return -res;
+    }
+
+    return 0;
+}
+
+}  // namespace clat
+}  // namespace net
+}  // namespace android
diff --git a/service/native/libs/libclat/clatutils_test.cpp b/service/native/libs/libclat/clatutils_test.cpp
new file mode 100644
index 0000000..4153e19
--- /dev/null
+++ b/service/native/libs/libclat/clatutils_test.cpp
@@ -0,0 +1,187 @@
+// 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.
+
+#include "libclat/clatutils.h"
+
+#include <android-base/stringprintf.h>
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+#include <linux/if_packet.h>
+#include <linux/if_tun.h>
+#include "tun_interface.h"
+
+extern "C" {
+#include "checksum.h"
+}
+
+// Default translation parameters.
+static const char kIPv4LocalAddr[] = "192.0.0.4";
+
+namespace android {
+namespace net {
+namespace clat {
+
+using android::net::TunInterface;
+using base::StringPrintf;
+
+class ClatUtils : public ::testing::Test {};
+
+// Mock functions for isIpv4AddressFree.
+bool neverFree(in_addr_t /* addr */) {
+    return 0;
+}
+bool alwaysFree(in_addr_t /* addr */) {
+    return 1;
+}
+bool only2Free(in_addr_t addr) {
+    return (ntohl(addr) & 0xff) == 2;
+}
+bool over6Free(in_addr_t addr) {
+    return (ntohl(addr) & 0xff) >= 6;
+}
+bool only10Free(in_addr_t addr) {
+    return (ntohl(addr) & 0xff) == 10;
+}
+
+// Apply mocked isIpv4AddressFree function for selectIpv4Address test.
+in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen,
+                            isIpv4AddrFreeFn fn /* mocked function */) {
+    // Call internal function to replace isIpv4AddressFreeFn for testing.
+    return selectIpv4AddressInternal(ip, prefixlen, fn);
+}
+
+TEST_F(ClatUtils, SelectIpv4Address) {
+    struct in_addr addr;
+
+    inet_pton(AF_INET, kIPv4LocalAddr, &addr);
+
+    // If no addresses are free, return INADDR_NONE.
+    EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 29, neverFree));
+    EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 16, neverFree));
+
+    // If the configured address is free, pick that. But a prefix that's too big is invalid.
+    EXPECT_EQ(inet_addr(kIPv4LocalAddr), selectIpv4Address(addr, 29, alwaysFree));
+    EXPECT_EQ(inet_addr(kIPv4LocalAddr), selectIpv4Address(addr, 20, alwaysFree));
+    EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 15, alwaysFree));
+
+    // A prefix length of 32 works, but anything above it is invalid.
+    EXPECT_EQ(inet_addr(kIPv4LocalAddr), selectIpv4Address(addr, 32, alwaysFree));
+    EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 33, alwaysFree));
+
+    // If another address is free, pick it.
+    EXPECT_EQ(inet_addr("192.0.0.6"), selectIpv4Address(addr, 29, over6Free));
+
+    // Check that we wrap around to addresses that are lower than the first address.
+    EXPECT_EQ(inet_addr("192.0.0.2"), selectIpv4Address(addr, 29, only2Free));
+    EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 30, only2Free));
+
+    // If a free address exists outside the prefix, we don't pick it.
+    EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 29, only10Free));
+    EXPECT_EQ(inet_addr("192.0.0.10"), selectIpv4Address(addr, 24, only10Free));
+
+    // Now try using the real function which sees if IP addresses are free using bind().
+    // Assume that the machine running the test has the address 127.0.0.1, but not 8.8.8.8.
+    addr.s_addr = inet_addr("8.8.8.8");
+    EXPECT_EQ(inet_addr("8.8.8.8"), selectIpv4Address(addr, 29));
+
+    addr.s_addr = inet_addr("127.0.0.1");
+    EXPECT_EQ(inet_addr("127.0.0.2"), selectIpv4Address(addr, 29));
+}
+
+TEST_F(ClatUtils, MakeChecksumNeutral) {
+    // We can't test generateIPv6Address here since it requires manipulating routing, which we can't
+    // do without talking to the real netd on the system.
+    uint32_t rand = arc4random_uniform(0xffffffff);
+    uint16_t rand1 = rand & 0xffff;
+    uint16_t rand2 = (rand >> 16) & 0xffff;
+    std::string v6PrefixStr = StringPrintf("2001:db8:%x:%x", rand1, rand2);
+    std::string v6InterfaceAddrStr = StringPrintf("%s::%x:%x", v6PrefixStr.c_str(), rand2, rand1);
+    std::string nat64PrefixStr = StringPrintf("2001:db8:%x:%x::", rand2, rand1);
+
+    in_addr v4 = {inet_addr(kIPv4LocalAddr)};
+    in6_addr v6InterfaceAddr;
+    ASSERT_TRUE(inet_pton(AF_INET6, v6InterfaceAddrStr.c_str(), &v6InterfaceAddr));
+    in6_addr nat64Prefix;
+    ASSERT_TRUE(inet_pton(AF_INET6, nat64PrefixStr.c_str(), &nat64Prefix));
+
+    // Generate a boatload of random IIDs.
+    int onebits = 0;
+    uint64_t prev_iid = 0;
+    for (int i = 0; i < 100000; i++) {
+        in6_addr v6 = v6InterfaceAddr;
+        makeChecksumNeutral(&v6, v4, nat64Prefix);
+
+        // Check the generated IP address is in the same prefix as the interface IPv6 address.
+        EXPECT_EQ(0, memcmp(&v6, &v6InterfaceAddr, 8));
+
+        // Check that consecutive IIDs are not the same.
+        uint64_t iid = *(uint64_t*)(&v6.s6_addr[8]);
+        ASSERT_TRUE(iid != prev_iid)
+                << "Two consecutive random IIDs are the same: " << std::showbase << std::hex << iid
+                << "\n";
+        prev_iid = iid;
+
+        // Check that the IID is checksum-neutral with the NAT64 prefix and the
+        // local prefix.
+        uint16_t c1 = ip_checksum_finish(ip_checksum_add(0, &v4, sizeof(v4)));
+        uint16_t c2 = ip_checksum_finish(ip_checksum_add(0, &nat64Prefix, sizeof(nat64Prefix)) +
+                                         ip_checksum_add(0, &v6, sizeof(v6)));
+
+        if (c1 != c2) {
+            char v6Str[INET6_ADDRSTRLEN];
+            inet_ntop(AF_INET6, &v6, v6Str, sizeof(v6Str));
+            FAIL() << "Bad IID: " << v6Str << " not checksum-neutral with " << kIPv4LocalAddr
+                   << " and " << nat64PrefixStr.c_str() << std::showbase << std::hex
+                   << "\n  IPv4 checksum: " << c1 << "\n  IPv6 checksum: " << c2 << "\n";
+        }
+
+        // Check that IIDs are roughly random and use all the bits by counting the
+        // total number of bits set to 1 in a random sample of 100000 generated IIDs.
+        onebits += __builtin_popcountll(*(uint64_t*)&iid);
+    }
+    EXPECT_LE(3190000, onebits);
+    EXPECT_GE(3210000, onebits);
+}
+
+TEST_F(ClatUtils, DetectMtu) {
+    // ::1 with bottom 32 bits set to 1 is still ::1 which routes via lo with mtu of 64KiB
+    ASSERT_EQ(detect_mtu(&in6addr_loopback, htonl(1), 0 /*MARK_UNSET*/), 65536);
+}
+
+TEST_F(ClatUtils, ConfigurePacketSocket) {
+    // Create an interface for configure_packet_socket to attach socket filter to.
+    TunInterface v6Iface;
+    ASSERT_EQ(0, v6Iface.init());
+
+    int s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IPV6));
+    EXPECT_LE(0, s);
+    struct in6_addr addr6;
+    EXPECT_EQ(1, inet_pton(AF_INET6, "2001:db8::f00", &addr6));
+    EXPECT_EQ(0, configure_packet_socket(s, &addr6, v6Iface.ifindex()));
+
+    // Check that the packet socket is bound to the interface. We can't check the socket filter
+    // because there is no way to fetch it from the kernel.
+    sockaddr_ll sll;
+    socklen_t len = sizeof(sll);
+    ASSERT_EQ(0, getsockname(s, reinterpret_cast<sockaddr*>(&sll), &len));
+    EXPECT_EQ(htons(ETH_P_IPV6), sll.sll_protocol);
+    EXPECT_EQ(sll.sll_ifindex, v6Iface.ifindex());
+
+    close(s);
+    v6Iface.destroy();
+}
+
+}  // namespace clat
+}  // namespace net
+}  // namespace android
diff --git a/service/native/libs/libclat/include/libclat/TcUtils.h b/service/native/libs/libclat/include/libclat/TcUtils.h
new file mode 100644
index 0000000..212838e
--- /dev/null
+++ b/service/native/libs/libclat/include/libclat/TcUtils.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <android-base/result.h>
+#include <errno.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/rtnetlink.h>
+
+#include <string>
+
+#include "bpf/BpfUtils.h"
+#include "bpf_shared.h"
+
+namespace android {
+namespace net {
+
+// For better code clarity - do not change values - used for booleans like
+// with_ethernet_header or isEthernet.
+constexpr bool RAWIP = false;
+constexpr bool ETHER = true;
+
+// For better code clarity when used for 'bool ingress' parameter.
+constexpr bool EGRESS = false;
+constexpr bool INGRESS = true;
+
+// The priority of clat hook - must be after tethering.
+constexpr uint16_t PRIO_CLAT = 4;
+
+// this returns an ARPHRD_* constant or a -errno
+int hardwareAddressType(const std::string& interface);
+
+// return MTU or -errno
+int deviceMTU(const std::string& interface);
+
+base::Result<bool> isEthernet(const std::string& interface);
+
+inline int getClatEgress4MapFd(void) {
+    const int fd = bpf::mapRetrieveRW(CLAT_EGRESS4_MAP_PATH);
+    return (fd == -1) ? -errno : fd;
+}
+
+inline int getClatEgress4ProgFd(bool with_ethernet_header) {
+    const int fd = bpf::retrieveProgram(with_ethernet_header ? CLAT_EGRESS4_PROG_ETHER_PATH
+                                                             : CLAT_EGRESS4_PROG_RAWIP_PATH);
+    return (fd == -1) ? -errno : fd;
+}
+
+inline int getClatIngress6MapFd(void) {
+    const int fd = bpf::mapRetrieveRW(CLAT_INGRESS6_MAP_PATH);
+    return (fd == -1) ? -errno : fd;
+}
+
+inline int getClatIngress6ProgFd(bool with_ethernet_header) {
+    const int fd = bpf::retrieveProgram(with_ethernet_header ? CLAT_INGRESS6_PROG_ETHER_PATH
+                                                             : CLAT_INGRESS6_PROG_RAWIP_PATH);
+    return (fd == -1) ? -errno : fd;
+}
+
+int doTcQdiscClsact(int ifIndex, uint16_t nlMsgType, uint16_t nlMsgFlags);
+
+inline int tcQdiscAddDevClsact(int ifIndex) {
+    return doTcQdiscClsact(ifIndex, RTM_NEWQDISC, NLM_F_EXCL | NLM_F_CREATE);
+}
+
+inline int tcQdiscReplaceDevClsact(int ifIndex) {
+    return doTcQdiscClsact(ifIndex, RTM_NEWQDISC, NLM_F_CREATE | NLM_F_REPLACE);
+}
+
+inline int tcQdiscDelDevClsact(int ifIndex) {
+    return doTcQdiscClsact(ifIndex, RTM_DELQDISC, 0);
+}
+
+// tc filter add dev .. in/egress prio 4 protocol ipv6/ip bpf object-pinned /sys/fs/bpf/...
+// direct-action
+int tcFilterAddDevBpf(int ifIndex, bool ingress, uint16_t proto, int bpfFd, bool ethernet);
+
+// tc filter add dev .. ingress prio 4 protocol ipv6 bpf object-pinned /sys/fs/bpf/... direct-action
+inline int tcFilterAddDevIngressClatIpv6(int ifIndex, int bpfFd, bool ethernet) {
+    return tcFilterAddDevBpf(ifIndex, INGRESS, ETH_P_IPV6, bpfFd, ethernet);
+}
+
+// tc filter add dev .. egress prio 4 protocol ip bpf object-pinned /sys/fs/bpf/... direct-action
+inline int tcFilterAddDevEgressClatIpv4(int ifIndex, int bpfFd, bool ethernet) {
+    return tcFilterAddDevBpf(ifIndex, EGRESS, ETH_P_IP, bpfFd, ethernet);
+}
+
+// tc filter del dev .. in/egress prio .. protocol ..
+int tcFilterDelDev(int ifIndex, bool ingress, uint16_t prio, uint16_t proto);
+
+// tc filter del dev .. ingress prio 4 protocol ipv6
+inline int tcFilterDelDevIngressClatIpv6(int ifIndex) {
+    return tcFilterDelDev(ifIndex, INGRESS, PRIO_CLAT, ETH_P_IPV6);
+}
+
+// tc filter del dev .. egress prio 4 protocol ip
+inline int tcFilterDelDevEgressClatIpv4(int ifIndex) {
+    return tcFilterDelDev(ifIndex, EGRESS, PRIO_CLAT, ETH_P_IP);
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/service/native/libs/libclat/include/libclat/bpfhelper.h b/service/native/libs/libclat/include/libclat/bpfhelper.h
new file mode 100644
index 0000000..c0328c0
--- /dev/null
+++ b/service/native/libs/libclat/include/libclat/bpfhelper.h
@@ -0,0 +1,40 @@
+// 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.
+
+#pragma once
+
+#include <arpa/inet.h>
+#include <linux/if.h>
+
+namespace android {
+namespace net {
+namespace clat {
+
+struct ClatdTracker {
+    unsigned ifIndex;
+    char iface[IFNAMSIZ];
+    unsigned v4ifIndex;
+    char v4iface[IFNAMSIZ];
+    in_addr v4;
+    in6_addr v6;
+    in6_addr pfx96;
+};
+
+int initMaps(void);
+void maybeStartBpf(const ClatdTracker& tracker);
+void maybeStopBpf(const ClatdTracker& tracker);
+
+}  // namespace clat
+}  // namespace net
+}  // namespace android
diff --git a/service/native/libs/libclat/include/libclat/clatutils.h b/service/native/libs/libclat/include/libclat/clatutils.h
new file mode 100644
index 0000000..812c86e
--- /dev/null
+++ b/service/native/libs/libclat/include/libclat/clatutils.h
@@ -0,0 +1,37 @@
+// 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.
+
+#pragma once
+#include <netinet/in.h>
+#include <netinet/in6.h>
+
+namespace android {
+namespace net {
+namespace clat {
+
+bool isIpv4AddressFree(in_addr_t addr);
+in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen);
+void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix);
+int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
+                        in6_addr* v6);
+int detect_mtu(const struct in6_addr* plat_subnet, uint32_t plat_suffix, uint32_t mark);
+int configure_packet_socket(int sock, in6_addr* addr, int ifindex);
+
+// For testing
+typedef bool (*isIpv4AddrFreeFn)(in_addr_t);
+in_addr_t selectIpv4AddressInternal(const in_addr ip, int16_t prefixlen, isIpv4AddrFreeFn fn);
+
+}  // namespace clat
+}  // namespace net
+}  // namespace android
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
new file mode 100644
index 0000000..a6909c0
--- /dev/null
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -0,0 +1,261 @@
+/*
+ * 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.server;
+
+import android.os.ServiceSpecificException;
+import android.system.Os;
+import android.util.Log;
+
+/**
+ * BpfNetMaps is responsible for providing traffic controller relevant functionality.
+ *
+ * {@hide}
+ */
+public class BpfNetMaps {
+    private static final String TAG = "BpfNetMaps";
+
+    static {
+        System.loadLibrary("traffic_controller_jni");
+        native_init();
+    }
+
+   /**
+    * Add naughty app bandwidth rule for specific app
+    *
+    * @param uid uid of target app
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the failure.
+    */
+    public void addNaughtyApp(final int uid) {
+        final int err = native_addNaughtyApp(uid);
+        if (err != 0) {
+            throw new ServiceSpecificException(-err, "Unable to add naughty app: "
+                            + Os.strerror(-err));
+        }
+    }
+
+   /**
+    * Remove naughty app bandwidth rule for specific app
+    *
+    * @param uid uid of target app
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the failure.
+    */
+    public void removeNaughtyApp(final int uid) {
+        final int err = native_removeNaughtyApp(uid);
+        if (err != 0) {
+            throw new ServiceSpecificException(-err, "Unable to remove naughty app: "
+                            + Os.strerror(-err));
+        }
+    }
+
+   /**
+    * Add nice app bandwidth rule for specific app
+    *
+    * @param uid uid of target app
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the failure.
+    */
+    public void addNiceApp(final int uid) {
+        final int err = native_addNiceApp(uid);
+        if (err != 0) {
+            throw new ServiceSpecificException(-err, "Unable to add nice app: "
+                            + Os.strerror(-err));
+        }
+    }
+
+   /**
+    * Remove nice app bandwidth rule for specific app
+    *
+    * @param uid uid of target app
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the failure.
+    */
+    public void removeNiceApp(final int uid) {
+        final int err = native_removeNiceApp(uid);
+        if (err != 0) {
+            throw new ServiceSpecificException(-err, "Unable to remove nice app: "
+                            + Os.strerror(-err));
+        }
+    }
+
+   /**
+    * Set target firewall child chain
+    *
+    * @param childChain target chain to enable
+    * @param enable whether to enable or disable child chain.
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the failure.
+    */
+    public void setChildChain(final int childChain, final boolean enable) {
+        final int err = native_setChildChain(childChain, enable);
+        if (err != 0) {
+            throw new ServiceSpecificException(-err, "Unable to set child chain: "
+                            + Os.strerror(-err));
+        }
+    }
+
+    /**
+     * Replaces the contents of the specified UID-based firewall chain.
+     *
+     * The chain may be an allowlist chain or a denylist chain. A denylist chain contains DROP
+     * rules for the specified UIDs and a RETURN rule at the end. An allowlist chain contains RETURN
+     * rules for the system UID range (0 to {@code UID_APP} - 1), RETURN rules for for the specified
+     * UIDs, and a DROP rule at the end. The chain will be created if it does not exist.
+     *
+     * @param chainName The name of the chain to replace.
+     * @param isAllowlist Whether this is an allowlist or denylist chain.
+     * @param uids The list of UIDs to allow/deny.
+     * @return true if the chain was successfully replaced, false otherwise.
+     */
+    public int replaceUidChain(final String chainName, final boolean isAllowlist,
+            final int[] uids) {
+        final int err = native_replaceUidChain(chainName, isAllowlist, uids);
+        if (err != 0) {
+            Log.e(TAG, "replaceUidChain failed: " + Os.strerror(-err));
+        }
+        return -err;
+    }
+
+   /**
+    * Set firewall rule for uid
+    *
+    * @param childChain target chain
+    * @param uid uid to allow/deny
+    * @param firewallRule either FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the failure.
+    */
+    public void setUidRule(final int childChain, final int uid,
+            final int firewallRule) {
+        final int err = native_setUidRule(childChain, uid, firewallRule);
+        if (err != 0) {
+            throw new ServiceSpecificException(-err, "Unable to set uid rule: "
+                            + Os.strerror(-err));
+        }
+    }
+
+    /**
+     * Add ingress interface filtering rules to a list of UIDs
+     *
+     * For a given uid, once a filtering rule is added, the kernel will only allow packets from the
+     * allowed interface and loopback to be sent to the list of UIDs.
+     *
+     * Calling this method on one or more UIDs with an existing filtering rule but a different
+     * interface name will result in the filtering rule being updated to allow the new interface
+     * instead. Otherwise calling this method will not affect existing rules set on other UIDs.
+     *
+     * @param ifName the name of the interface on which the filtering rules will allow packets to
+              be received.
+     * @param uids an array of UIDs which the filtering rules will be set
+     * @throws ServiceSpecificException in case of failure, with an error code indicating the
+     *         cause of the failure.
+     */
+    public void addUidInterfaceRules(final String ifName, final int[] uids) {
+        final int err = native_addUidInterfaceRules(ifName, uids);
+        if (err != 0) {
+            throw new ServiceSpecificException(-err, "Unable to add uid interface rules: "
+                            + Os.strerror(-err));
+        }
+    }
+
+    /**
+     * Remove ingress interface filtering rules from a list of UIDs
+     *
+     * Clear the ingress interface filtering rules from the list of UIDs which were previously set
+     * by addUidInterfaceRules(). Ignore any uid which does not have filtering rule.
+     *
+     * @param uids an array of UIDs from which the filtering rules will be removed
+     * @throws ServiceSpecificException in case of failure, with an error code indicating the
+     *         cause of the failure.
+     */
+    public void removeUidInterfaceRules(final int[] uids) {
+        final int err = native_removeUidInterfaceRules(uids);
+        if (err != 0) {
+            throw new ServiceSpecificException(-err, "Unable to remove uid interface rules: "
+                            + Os.strerror(-err));
+        }
+    }
+
+   /**
+    * Request netd to change the current active network stats map.
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the failure.
+    */
+    public void swapActiveStatsMap() {
+        final int err = native_swapActiveStatsMap();
+        if (err != 0) {
+            throw new ServiceSpecificException(-err, "Unable to swap active stats map: "
+                            + Os.strerror(-err));
+        }
+    }
+
+   /**
+    * Assigns android.permission.INTERNET and/or android.permission.UPDATE_DEVICE_STATS to the uids
+    * specified. Or remove all permissions from the uids.
+    *
+    * @param permission The permission to grant, it could be either PERMISSION_INTERNET and/or
+    *                   PERMISSION_UPDATE_DEVICE_STATS. If the permission is NO_PERMISSIONS, then
+    *                   revoke all permissions for the uids.
+    * @param uids uid of users to grant permission
+    */
+    public void setNetPermForUids(final int permission, final int[] uids) {
+        native_setPermissionForUids(permission, uids);
+    }
+
+    /**
+     * Set counter set for uid
+     *
+     * @param counterSet either SET_DEFAULT or SET_FOREGROUND
+     * @param uid uid to foreground/background
+     */
+    public int setCounterSet(final int counterSet, final int uid) {
+        final int err = native_setCounterSet(counterSet, uid);
+        if (err != 0) {
+            Log.e(TAG, "setCounterSet failed: " + Os.strerror(-err));
+        }
+        return -err;
+    }
+
+    /**
+     * Reset Uid stats
+     * @param tag default 0
+     * @param uid given uid to be clear
+     */
+    public int deleteTagData(final int tag, final int uid) {
+        final int err = native_deleteTagData(tag, uid);
+        if (err != 0) {
+            Log.e(TAG, "deleteTagData failed: " + Os.strerror(-err));
+        }
+        return -err;
+    }
+
+    private static native void native_init();
+    private native int native_addNaughtyApp(int uid);
+    private native int native_removeNaughtyApp(int uid);
+    private native int native_addNiceApp(int uid);
+    private native int native_removeNiceApp(int uid);
+    private native int native_setChildChain(int childChain, boolean enable);
+    private native int native_replaceUidChain(String name, boolean isAllowlist, int[] uids);
+    private native int native_setUidRule(int childChain, int uid, int firewallRule);
+    private native int native_addUidInterfaceRules(String ifName, int[] uids);
+    private native int native_removeUidInterfaceRules(int[] uids);
+    private native int native_swapActiveStatsMap();
+    private native void native_setPermissionForUids(int permission, int[] uids);
+    private native int native_setCounterSet(int counterSet, int uid);
+    private native int native_deleteTagData(int tag, int uid);
+}
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index d625d1b..ae6fe11 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -73,6 +73,8 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5;
 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
@@ -262,6 +264,7 @@
 import com.android.server.connectivity.ProfileNetworkPreferenceList;
 import com.android.server.connectivity.ProxyTracker;
 import com.android.server.connectivity.QosCallbackTracker;
+import com.android.server.connectivity.UidRangeUtils;
 
 import libcore.io.IoUtils;
 
@@ -1489,16 +1492,17 @@
     }
 
     private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
-        return createDefaultNetworkCapabilitiesForUidRange(new UidRange(uid, uid));
+        return createDefaultNetworkCapabilitiesForUidRangeSet(Collections.singleton(
+                new UidRange(uid, uid)));
     }
 
-    private static NetworkCapabilities createDefaultNetworkCapabilitiesForUidRange(
-            @NonNull final UidRange uids) {
+    private static NetworkCapabilities createDefaultNetworkCapabilitiesForUidRangeSet(
+            @NonNull final Set<UidRange> uidRangeSet) {
         final NetworkCapabilities netCap = new NetworkCapabilities();
         netCap.addCapability(NET_CAPABILITY_INTERNET);
         netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
-        netCap.setUids(UidRange.toIntRanges(Collections.singleton(uids)));
+        netCap.setUids(UidRange.toIntRanges(uidRangeSet));
         return netCap;
     }
 
@@ -10145,14 +10149,30 @@
             switch (preference.getPreference()) {
                 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT:
                     nc = null;
+                    if (preference.getPreferenceEnterpriseId() != 0) {
+                        throw new IllegalArgumentException(
+                                "Invalid enterprise identifier in setProfileNetworkPreferences");
+                    }
                     break;
                 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK:
                     allowFallback = false;
                     // continue to process the enterprise preference.
                 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE:
-                    final UidRange uids = UidRange.createForUser(profile);
-                    nc = createDefaultNetworkCapabilitiesForUidRange(uids);
+                    if (!isEnterpriseIdentifierValid(preference.getPreferenceEnterpriseId())) {
+                        throw new IllegalArgumentException(
+                                "Invalid enterprise identifier in setProfileNetworkPreferences");
+                    }
+                    final Set<UidRange> uidRangeSet =
+                            getUidListToBeAppliedForNetworkPreference(profile, preference);
+                    if (!isRangeAlreadyInPreferenceList(preferenceList, uidRangeSet)) {
+                        nc = createDefaultNetworkCapabilitiesForUidRangeSet(uidRangeSet);
+                    } else {
+                        throw new IllegalArgumentException(
+                                "Overlapping uid range in setProfileNetworkPreferences");
+                    }
                     nc.addCapability(NET_CAPABILITY_ENTERPRISE);
+                    nc.addEnterpriseId(
+                            preference.getPreferenceEnterpriseId());
                     nc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
                     break;
                 default:
@@ -10166,6 +10186,44 @@
                 new Pair<>(preferenceList, listener)));
     }
 
+    private Set<UidRange> getUidListToBeAppliedForNetworkPreference(
+            @NonNull final UserHandle profile,
+            @NonNull final ProfileNetworkPreference profileNetworkPreference) {
+        final UidRange profileUids = UidRange.createForUser(profile);
+        Set<UidRange> uidRangeSet = UidRangeUtils.convertListToUidRange(
+                profileNetworkPreference.getIncludedUids());
+        if (uidRangeSet.size() > 0) {
+            if (!UidRangeUtils.isRangeSetInUidRange(profileUids, uidRangeSet)) {
+                throw new IllegalArgumentException(
+                        "Allow uid range is outside the uid range of profile.");
+            }
+        } else {
+            ArraySet<UidRange> disallowUidRangeSet = UidRangeUtils.convertListToUidRange(
+                    profileNetworkPreference.getExcludedUids());
+            if (disallowUidRangeSet.size() > 0) {
+                if (!UidRangeUtils.isRangeSetInUidRange(profileUids, disallowUidRangeSet)) {
+                    throw new IllegalArgumentException(
+                            "disallow uid range is outside the uid range of profile.");
+                }
+                uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange(profileUids,
+                        disallowUidRangeSet);
+            } else {
+                uidRangeSet = new ArraySet<UidRange>();
+                uidRangeSet.add(profileUids);
+            }
+        }
+        return uidRangeSet;
+    }
+
+    private boolean isEnterpriseIdentifierValid(
+            @NetworkCapabilities.EnterpriseId int identifier) {
+        if ((identifier >= NET_ENTERPRISE_ID_1)
+                && (identifier <= NET_ENTERPRISE_ID_5)) {
+            return true;
+        }
+        return false;
+    }
+
     private void validateNetworkCapabilitiesOfProfileNetworkPreference(
             @Nullable final NetworkCapabilities nc) {
         if (null == nc) return; // Null caps are always allowed. It means to remove the setting.
@@ -10187,6 +10245,11 @@
                 nrs.add(createDefaultInternetRequestForTransport(
                         TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
             }
+            if (VDBG) {
+                loge("pref.capabilities.getUids():" + UidRange.fromIntRanges(
+                        pref.capabilities.getUids()));
+            }
+
             setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids()));
             final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs,
                     PREFERENCE_ORDER_PROFILE);
@@ -10195,6 +10258,25 @@
         return result;
     }
 
+    /**
+     * Compare if the given UID range sets have the same UIDs.
+     *
+     */
+    private boolean isRangeAlreadyInPreferenceList(
+            @NonNull List<ProfileNetworkPreferenceList.Preference> preferenceList,
+            @NonNull Set<UidRange> uidRangeSet) {
+        if (uidRangeSet.size() == 0 || preferenceList.size() == 0) {
+            return false;
+        }
+        for (ProfileNetworkPreferenceList.Preference pref : preferenceList) {
+            if (UidRangeUtils.doesRangeSetOverlap(
+                    UidRange.fromIntRanges(pref.capabilities.getUids()), uidRangeSet)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void handleSetProfileNetworkPreference(
             @NonNull final List<ProfileNetworkPreferenceList.Preference> preferenceList,
             @Nullable final IOnCompleteListener listener) {
diff --git a/service/src/com/android/server/connectivity/ClatCoordinator.java b/service/src/com/android/server/connectivity/ClatCoordinator.java
new file mode 100644
index 0000000..5a5e24a
--- /dev/null
+++ b/service/src/com/android/server/connectivity/ClatCoordinator.java
@@ -0,0 +1,380 @@
+/*
+ * 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.server.connectivity;
+
+import static android.net.INetd.IF_STATE_UP;
+import static android.net.INetd.PERMISSION_SYSTEM;
+
+import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.INetd;
+import android.net.InterfaceConfigurationParcel;
+import android.net.IpPrefix;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.InterfaceParams;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+
+/**
+ * This coordinator is responsible for providing clat relevant functionality.
+ *
+ * {@hide}
+ */
+public class ClatCoordinator {
+    private static final String TAG = ClatCoordinator.class.getSimpleName();
+
+    // Sync from external/android-clat/clatd.c
+    // 40 bytes IPv6 header - 20 bytes IPv4 header + 8 bytes fragment header.
+    @VisibleForTesting
+    static final int MTU_DELTA = 28;
+    @VisibleForTesting
+    static final int CLAT_MAX_MTU = 65536;
+
+    // This must match the interface prefix in clatd.c.
+    private static final String CLAT_PREFIX = "v4-";
+
+    // For historical reasons, start with 192.0.0.4, and after that, use all subsequent addresses
+    // in 192.0.0.0/29 (RFC 7335).
+    @VisibleForTesting
+    static final String INIT_V4ADDR_STRING = "192.0.0.4";
+    @VisibleForTesting
+    static final int INIT_V4ADDR_PREFIX_LEN = 29;
+    private static final InetAddress GOOGLE_DNS_4 = InetAddress.parseNumericAddress("8.8.8.8");
+
+    private static final int INVALID_IFINDEX = 0;
+    private static final int INVALID_PID = 0;
+
+    @NonNull
+    private final INetd mNetd;
+    @NonNull
+    private final Dependencies mDeps;
+    @Nullable
+    private String mIface = null;
+    @Nullable
+    private String mNat64Prefix = null;
+    @Nullable
+    private String mXlatLocalAddress4 = null;
+    @Nullable
+    private String mXlatLocalAddress6 = null;
+    private int mPid = INVALID_PID;
+
+    @VisibleForTesting
+    abstract static class Dependencies {
+        /**
+          * Get netd.
+          */
+        @NonNull
+        public abstract INetd getNetd();
+
+        /**
+         * @see ParcelFileDescriptor#adoptFd(int).
+         */
+        @NonNull
+        public ParcelFileDescriptor adoptFd(int fd) {
+            return ParcelFileDescriptor.adoptFd(fd);
+        }
+
+        /**
+         * Get interface index for a given interface.
+         */
+        public int getInterfaceIndex(String ifName) {
+            final InterfaceParams params = InterfaceParams.getByName(ifName);
+            return params != null ? params.index : INVALID_IFINDEX;
+        }
+
+        /**
+         * Create tun interface for a given interface name.
+         */
+        public int createTunInterface(@NonNull String tuniface) throws IOException {
+            return native_createTunInterface(tuniface);
+        }
+
+        /**
+         * Pick an IPv4 address for clat.
+         */
+        @NonNull
+        public String selectIpv4Address(@NonNull String v4addr, int prefixlen)
+                throws IOException {
+            return native_selectIpv4Address(v4addr, prefixlen);
+        }
+
+        /**
+         * Generate a checksum-neutral IID.
+         */
+        @NonNull
+        public String generateIpv6Address(@NonNull String iface, @NonNull String v4,
+                @NonNull String prefix64) throws IOException {
+            return native_generateIpv6Address(iface, v4, prefix64);
+        }
+
+        /**
+         * Detect MTU.
+         */
+        public int detectMtu(@NonNull String platSubnet, int platSuffix, int mark)
+                throws IOException {
+            return native_detectMtu(platSubnet, platSuffix, mark);
+        }
+
+        /**
+         * Open packet socket.
+         */
+        public int openPacketSocket() throws IOException {
+            return native_openPacketSocket();
+        }
+
+        /**
+         * Open IPv6 raw socket and set SO_MARK.
+         */
+        public int openRawSocket6(int mark) throws IOException {
+            return native_openRawSocket6(mark);
+        }
+
+        /**
+         * Add anycast setsockopt.
+         */
+        public void addAnycastSetsockopt(@NonNull FileDescriptor sock, String v6, int ifindex)
+                throws IOException {
+            native_addAnycastSetsockopt(sock, v6, ifindex);
+        }
+
+        /**
+         * Configure packet socket.
+         */
+        public void configurePacketSocket(@NonNull FileDescriptor sock, String v6, int ifindex)
+                throws IOException {
+            native_configurePacketSocket(sock, v6, ifindex);
+        }
+
+        /**
+         * Maybe start bpf.
+         */
+        public int maybeStartBpf(@NonNull FileDescriptor tunfd, @NonNull FileDescriptor readsock6,
+                @NonNull FileDescriptor writesock6, @NonNull String iface, @NonNull String pfx96,
+                @NonNull String v4, @NonNull String v6) throws IOException {
+            return native_maybeStartBpf(tunfd, readsock6, writesock6, iface, pfx96, v4, v6);
+        }
+
+        /**
+         * Maybe stop bpf.
+         */
+        public void maybeStopBpf(String iface, String pfx96, String v4, String v6, int pid)
+                throws IOException {
+            native_maybeStopBpf(iface, pfx96, v4, v6, pid);
+        }
+    }
+
+    @VisibleForTesting
+    static int getFwmark(int netId) {
+        // See union Fwmark in system/netd/include/Fwmark.h
+        return (netId & 0xffff)
+                | 0x1 << 16  // protectedFromVpn: true
+                | 0x1 << 17  // explicitlySelected: true
+                | (PERMISSION_SYSTEM & 0x3) << 18;
+    }
+
+    @VisibleForTesting
+    static int adjustMtu(int mtu) {
+        // clamp to minimum ipv6 mtu - this probably cannot ever trigger
+        if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU;
+        // clamp to buffer size
+        if (mtu > CLAT_MAX_MTU) mtu = CLAT_MAX_MTU;
+        // decrease by ipv6(40) + ipv6 fragmentation header(8) vs ipv4(20) overhead of 28 bytes
+        mtu -= MTU_DELTA;
+
+        return mtu;
+    }
+
+    public ClatCoordinator(@NonNull Dependencies deps) {
+        mDeps = deps;
+        mNetd = mDeps.getNetd();
+    }
+
+    /**
+     * Start clatd for a given interface and NAT64 prefix.
+     */
+    public String clatStart(final String iface, final int netId,
+            @NonNull final IpPrefix nat64Prefix)
+            throws IOException {
+        if (nat64Prefix.getPrefixLength() != 96) {
+            throw new IOException("Prefix must be 96 bits long: " + nat64Prefix);
+        }
+
+        // [1] Pick an IPv4 address from 192.0.0.4, 192.0.0.5, 192.0.0.6 ..
+        final String v4;
+        try {
+            v4 = mDeps.selectIpv4Address(INIT_V4ADDR_STRING, INIT_V4ADDR_PREFIX_LEN);
+        } catch (IOException e) {
+            throw new IOException("no IPv4 addresses were available for clat: " + e);
+        }
+
+        // [2] Generate a checksum-neutral IID.
+        final String pfx96 = nat64Prefix.getAddress().getHostAddress();
+        final String v6;
+        try {
+            v6 = mDeps.generateIpv6Address(iface, v4, pfx96);
+        } catch (IOException e) {
+            throw new IOException("no IPv6 addresses were available for clat: " + e);
+        }
+
+        // [3] Open, configure and bring up the tun interface.
+        // Create the v4-... tun interface.
+        final String tunIface = CLAT_PREFIX + iface;
+        final ParcelFileDescriptor tunFd;
+        try {
+            tunFd = mDeps.adoptFd(mDeps.createTunInterface(tunIface));
+        } catch (IOException e) {
+            throw new IOException("Create tun interface " + tunIface + " failed: " + e);
+        }
+
+        // disable IPv6 on it - failing to do so is not a critical error
+        try {
+            mNetd.interfaceSetEnableIPv6(tunIface, false /* enabled */);
+        } catch (RemoteException | ServiceSpecificException e) {
+            Log.e(TAG, "Disable IPv6 on " + tunIface + " failed: " + e);
+        }
+
+        // Detect ipv4 mtu.
+        final Integer fwmark = getFwmark(netId);
+        final int detectedMtu = mDeps.detectMtu(pfx96,
+                ByteBuffer.wrap(GOOGLE_DNS_4.getAddress()).getInt(), fwmark);
+        final int mtu = adjustMtu(detectedMtu);
+        Log.i(TAG, "ipv4 mtu is " + mtu);
+
+        // TODO: add setIptablesDropRule
+
+        // Config tun interface mtu, address and bring up.
+        try {
+            mNetd.interfaceSetMtu(tunIface, mtu);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IOException("Set MTU " + mtu + " on " + tunIface + " failed: " + e);
+        }
+        final InterfaceConfigurationParcel ifConfig = new InterfaceConfigurationParcel();
+        ifConfig.ifName = tunIface;
+        ifConfig.ipv4Addr = v4;
+        ifConfig.prefixLength = 32;
+        ifConfig.hwAddr = "";
+        ifConfig.flags = new String[] {IF_STATE_UP};
+        try {
+            mNetd.interfaceSetCfg(ifConfig);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IOException("Setting IPv4 address to " + ifConfig.ipv4Addr + "/"
+                    + ifConfig.prefixLength + " failed on " + ifConfig.ifName + ": " + e);
+        }
+
+        // [4] Open and configure local 464xlat read/write sockets.
+        // Opens a packet socket to receive IPv6 packets in clatd.
+        final ParcelFileDescriptor readSock6;
+        try {
+            // Use a JNI call to get native file descriptor instead of Os.socket() because we would
+            // like to use ParcelFileDescriptor to close file descriptor automatically. But ctor
+            // ParcelFileDescriptor(FileDescriptor fd) is a @hide function. Need to use native file
+            // descriptor to initialize ParcelFileDescriptor object instead.
+            readSock6 = mDeps.adoptFd(mDeps.openPacketSocket());
+        } catch (IOException e) {
+            throw new IOException("Open packet socket failed: " + e);
+        }
+
+        // Opens a raw socket with a given fwmark to send IPv6 packets in clatd.
+        final ParcelFileDescriptor writeSock6;
+        try {
+            // Use a JNI call to get native file descriptor instead of Os.socket(). See above
+            // reason why we use jniOpenPacketSocket6().
+            writeSock6 = mDeps.adoptFd(mDeps.openRawSocket6(fwmark));
+        } catch (IOException e) {
+            throw new IOException("Open raw socket failed: " + e);
+        }
+
+        final int ifaceIndex = mDeps.getInterfaceIndex(iface);
+        if (ifaceIndex == INVALID_IFINDEX) {
+            throw new IOException("Fail to get interface index for interface " + iface);
+        }
+
+        // Start translating packets to the new prefix.
+        try {
+            mDeps.addAnycastSetsockopt(writeSock6.getFileDescriptor(), v6, ifaceIndex);
+        } catch (IOException e) {
+            throw new IOException("add anycast sockopt failed: " + e);
+        }
+
+        // Update our packet socket filter to reflect the new 464xlat IP address.
+        try {
+            mDeps.configurePacketSocket(readSock6.getFileDescriptor(), v6, ifaceIndex);
+        } catch (IOException e) {
+            throw new IOException("configure packet socket failed: " + e);
+        }
+
+        // [5] Maybe start bpf.
+        try {
+            mDeps.maybeStartBpf(tunFd.getFileDescriptor(), readSock6.getFileDescriptor(),
+                    writeSock6.getFileDescriptor(), iface, pfx96, v4, v6);
+            mIface = iface;
+            mNat64Prefix = pfx96;
+            mXlatLocalAddress4 = v4;
+            mXlatLocalAddress6 = v6;
+        } catch (IOException e) {
+            throw new IOException("Error start bpf on " + iface + ": " + e);
+        }
+
+        // TODO: start clatd and returns local xlat464 v6 address.
+        return null;
+    }
+
+    /**
+     * Stop clatd
+     */
+    public void clatStop() throws IOException {
+        mDeps.maybeStopBpf(mIface, mNat64Prefix, mXlatLocalAddress4, mXlatLocalAddress6,
+                mPid /* unused */);
+        // TODO: remove setIptablesDropRule
+
+        Log.i(TAG, "clatd on " + mIface + " stopped");
+
+        mIface = null;
+        mNat64Prefix = null;
+        mXlatLocalAddress4 = null;
+        mXlatLocalAddress6 = null;
+    }
+
+    private static native String native_selectIpv4Address(String v4addr, int prefixlen)
+            throws IOException;
+    private static native String native_generateIpv6Address(String iface, String v4,
+            String prefix64) throws IOException;
+    private static native int native_createTunInterface(String tuniface) throws IOException;
+    private static native int native_detectMtu(String platSubnet, int platSuffix, int mark)
+            throws IOException;
+    private static native int native_openPacketSocket() throws IOException;
+    private static native int native_openRawSocket6(int mark) throws IOException;
+    private static native void native_addAnycastSetsockopt(FileDescriptor sock, String v6,
+            int ifindex) throws IOException;
+    private static native void native_configurePacketSocket(FileDescriptor sock, String v6,
+            int ifindex) throws IOException;
+    private static native int native_maybeStartBpf(FileDescriptor tunfd, FileDescriptor readsock6,
+            FileDescriptor writesock6, String iface, String pfx96, String v4, String v6)
+            throws IOException;
+    private static native void native_maybeStopBpf(String iface, String pfx96, String v4,
+            String v6, int pid) throws IOException;
+}
diff --git a/service/src/com/android/server/connectivity/UidRangeUtils.java b/service/src/com/android/server/connectivity/UidRangeUtils.java
new file mode 100644
index 0000000..7318296
--- /dev/null
+++ b/service/src/com/android/server/connectivity/UidRangeUtils.java
@@ -0,0 +1,156 @@
+/*
+ * 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.server.connectivity;
+
+import android.annotation.NonNull;
+import android.net.UidRange;
+import android.util.ArraySet;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Utility class for UidRange
+ *
+ * @hide
+ */
+public final class UidRangeUtils {
+    /**
+     * Check if given uid range set is within the uid range
+     * @param uids uid range in which uidRangeSet is checked to be in range.
+     * @param uidRangeSet uid range set to be be checked if it is in range of uids
+     * @return true uidRangeSet is in the range of uids
+     * @hide
+     */
+    public static boolean isRangeSetInUidRange(@NonNull UidRange uids,
+            @NonNull Set<UidRange> uidRangeSet) {
+        Objects.requireNonNull(uids);
+        Objects.requireNonNull(uidRangeSet);
+        if (uidRangeSet.size() == 0) {
+            return true;
+        }
+        for (UidRange range : uidRangeSet) {
+            if (!uids.contains(range.start) || !uids.contains(range.stop)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Remove given uid ranges set from a uid range
+     * @param uids uid range from which uidRangeSet will be removed
+     * @param uidRangeSet uid range set to be removed from uids.
+     * WARNING : This function requires the UidRanges in uidRangeSet to be disjoint
+     * WARNING : This function requires the arrayset to be iterated in increasing order of the
+     *                    ranges. Today this is provided by the iteration order stability of
+     *                    ArraySet, and the fact that the code creating this ArraySet always
+     *                    creates it in increasing order.
+     * Note : if any of the above is not satisfied this function throws IllegalArgumentException
+     * TODO : remove these limitations
+     * @hide
+     */
+    public static ArraySet<UidRange> removeRangeSetFromUidRange(@NonNull UidRange uids,
+            @NonNull ArraySet<UidRange> uidRangeSet) {
+        Objects.requireNonNull(uids);
+        Objects.requireNonNull(uidRangeSet);
+        final ArraySet<UidRange> filteredRangeSet = new ArraySet<UidRange>();
+        if (uidRangeSet.size() == 0) {
+            filteredRangeSet.add(uids);
+            return filteredRangeSet;
+        }
+
+        int start = uids.start;
+        UidRange previousRange = null;
+        for (UidRange uidRange : uidRangeSet) {
+            if (previousRange != null) {
+                if (previousRange.stop > uidRange.start) {
+                    throw new IllegalArgumentException("UID ranges are not increasing order");
+                }
+            }
+            if (uidRange.start > start) {
+                filteredRangeSet.add(new UidRange(start, uidRange.start - 1));
+                start = uidRange.stop + 1;
+            } else if (uidRange.start == start) {
+                start = uidRange.stop + 1;
+            }
+            previousRange = uidRange;
+        }
+        if (start < uids.stop) {
+            filteredRangeSet.add(new UidRange(start, uids.stop));
+        }
+        return filteredRangeSet;
+    }
+
+    /**
+     * Compare if the given UID range sets have overlapping uids
+     * @param uidRangeSet1 first uid range set to check for overlap
+     * @param uidRangeSet2 second uid range set to check for overlap
+     * @hide
+     */
+    public static boolean doesRangeSetOverlap(@NonNull Set<UidRange> uidRangeSet1,
+            @NonNull Set<UidRange> uidRangeSet2) {
+        Objects.requireNonNull(uidRangeSet1);
+        Objects.requireNonNull(uidRangeSet2);
+
+        if (uidRangeSet1.size() == 0 || uidRangeSet2.size() == 0) {
+            return false;
+        }
+        for (UidRange range1 : uidRangeSet1) {
+            for (UidRange range2 : uidRangeSet2) {
+                if (range1.contains(range2.start) || range1.contains(range2.stop)
+                        || range2.contains(range1.start) || range2.contains(range1.stop)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Convert a list of uid to set of UidRanges.
+     * @param uids list of uids
+     * @return set of UidRanges
+     * @hide
+     */
+    public static ArraySet<UidRange> convertListToUidRange(@NonNull List<Integer> uids) {
+        Objects.requireNonNull(uids);
+        final ArraySet<UidRange> uidRangeSet = new ArraySet<UidRange>();
+        if (uids.size() == 0) {
+            return uidRangeSet;
+        }
+        List<Integer> uidsNew = new ArrayList<>(uids);
+        Collections.sort(uidsNew);
+        int start = uidsNew.get(0);
+        int stop = start;
+
+        for (Integer i : uidsNew) {
+            if (i <= stop + 1) {
+                stop = i;
+            } else {
+                uidRangeSet.add(new UidRange(start, stop));
+                start = i;
+                stop = i;
+            }
+        }
+        uidRangeSet.add(new UidRange(start, stop));
+        return uidRangeSet;
+    }
+}
diff --git a/tests/common/Android.bp b/tests/common/Android.bp
index f1897f5..acf04bf 100644
--- a/tests/common/Android.bp
+++ b/tests/common/Android.bp
@@ -122,3 +122,25 @@
         "framework-res",
     ],
 }
+
+// Defaults for tests that want to run in mainline-presubmit.
+// Not widely used because many of our tests have AndroidTest.xml files and
+// use the mainline-param config-descriptor metadata in AndroidTest.xml.
+
+// test_mainline_modules is an array of strings. Each element in the array is a list of modules
+// separated by "+". The modules in this list must be in alphabetical order.
+// See SuiteModuleLoader.java.
+// TODO: why are the modules separated by + instead of being separate entries in the array?
+mainline_presubmit_modules = [
+        "CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex",
+]
+
+cc_defaults {
+    name: "connectivity-mainline-presubmit-cc-defaults",
+    test_mainline_modules: mainline_presubmit_modules,
+}
+
+java_defaults {
+    name: "connectivity-mainline-presubmit-java-defaults",
+    test_mainline_modules: mainline_presubmit_modules,
+}
diff --git a/tests/common/java/android/net/NetworkCapabilitiesTest.java b/tests/common/java/android/net/NetworkCapabilitiesTest.java
index 9cc001d..d03629d 100644
--- a/tests/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/common/java/android/net/NetworkCapabilitiesTest.java
@@ -23,11 +23,6 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_3;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_4;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_5;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
@@ -42,6 +37,11 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_2;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_3;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_4;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5;
 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
@@ -57,6 +57,7 @@
 import static com.android.modules.utils.build.SdkLevel.isAtLeastR;
 import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
 import static com.android.testutils.MiscAsserts.assertEmpty;
 import static com.android.testutils.MiscAsserts.assertThrows;
 import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
@@ -788,79 +789,80 @@
         } catch (IllegalStateException expected) { }
     }
 
-    @Test @IgnoreUpTo(Build.VERSION_CODES.S)
-    public void testEnterpriseCapabilitySubLevel() {
+    @Test @IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
+    public void testEnterpriseId() {
         final NetworkCapabilities nc1 = new NetworkCapabilities.Builder()
                 .addCapability(NET_CAPABILITY_ENTERPRISE)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1)
+                .addEnterpriseId(NET_ENTERPRISE_ID_1)
                 .build();
-        assertEquals(1, nc1.getEnterpriseCapabilitySubLevels().length);
-        assertEquals(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1,
-                nc1.getEnterpriseCapabilitySubLevels()[0]);
+        assertEquals(1, nc1.getEnterpriseIds().length);
+        assertEquals(NET_ENTERPRISE_ID_1,
+                nc1.getEnterpriseIds()[0]);
         final NetworkCapabilities nc2 = new NetworkCapabilities.Builder()
                 .addCapability(NET_CAPABILITY_ENTERPRISE)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2)
+                .addEnterpriseId(NET_ENTERPRISE_ID_1)
+                .addEnterpriseId(NET_ENTERPRISE_ID_2)
                 .build();
-        assertEquals(2, nc2.getEnterpriseCapabilitySubLevels().length);
-        assertEquals(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1,
-                nc2.getEnterpriseCapabilitySubLevels()[0]);
-        assertEquals(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2,
-                nc2.getEnterpriseCapabilitySubLevels()[1]);
+        assertEquals(2, nc2.getEnterpriseIds().length);
+        assertEquals(NET_ENTERPRISE_ID_1,
+                nc2.getEnterpriseIds()[0]);
+        assertEquals(NET_ENTERPRISE_ID_2,
+                nc2.getEnterpriseIds()[1]);
         final NetworkCapabilities nc3 = new NetworkCapabilities.Builder()
                 .addCapability(NET_CAPABILITY_ENTERPRISE)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_3)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_4)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_5)
+                .addEnterpriseId(NET_ENTERPRISE_ID_1)
+                .addEnterpriseId(NET_ENTERPRISE_ID_2)
+                .addEnterpriseId(NET_ENTERPRISE_ID_3)
+                .addEnterpriseId(NET_ENTERPRISE_ID_4)
+                .addEnterpriseId(NET_ENTERPRISE_ID_5)
                 .build();
-        assertEquals(5, nc3.getEnterpriseCapabilitySubLevels().length);
-        assertEquals(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1,
-                nc3.getEnterpriseCapabilitySubLevels()[0]);
-        assertEquals(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2,
-                nc3.getEnterpriseCapabilitySubLevels()[1]);
-        assertEquals(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_3,
-                nc3.getEnterpriseCapabilitySubLevels()[2]);
-        assertEquals(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_4,
-                nc3.getEnterpriseCapabilitySubLevels()[3]);
-        assertEquals(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_5,
-                nc3.getEnterpriseCapabilitySubLevels()[4]);
+        assertEquals(5, nc3.getEnterpriseIds().length);
+        assertEquals(NET_ENTERPRISE_ID_1,
+                nc3.getEnterpriseIds()[0]);
+        assertEquals(NET_ENTERPRISE_ID_2,
+                nc3.getEnterpriseIds()[1]);
+        assertEquals(NET_ENTERPRISE_ID_3,
+                nc3.getEnterpriseIds()[2]);
+        assertEquals(NET_ENTERPRISE_ID_4,
+                nc3.getEnterpriseIds()[3]);
+        assertEquals(NET_ENTERPRISE_ID_5,
+                nc3.getEnterpriseIds()[4]);
 
         final Class<IllegalArgumentException> illegalArgumentExceptionClass =
                 IllegalArgumentException.class;
         assertThrows(illegalArgumentExceptionClass, () -> new NetworkCapabilities.Builder()
-                .addEnterpriseCapabilitySubLevel(6)
+                .addEnterpriseId(6)
                 .build());
         assertThrows(illegalArgumentExceptionClass, () -> new NetworkCapabilities.Builder()
-                .removeEnterpriseCapabilitySubLevel(6)
+                .removeEnterpriseId(6)
                 .build());
 
         final Class<IllegalStateException> illegalStateException =
                 IllegalStateException.class;
         assertThrows(illegalStateException, () -> new NetworkCapabilities.Builder()
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1)
+                .addEnterpriseId(NET_ENTERPRISE_ID_1)
                 .build());
 
         final NetworkCapabilities nc4 = new NetworkCapabilities.Builder()
                 .addCapability(NET_CAPABILITY_ENTERPRISE)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2)
-                .removeEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1)
-                .removeEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2)
+                .addEnterpriseId(NET_ENTERPRISE_ID_1)
+                .addEnterpriseId(NET_ENTERPRISE_ID_2)
+                .removeEnterpriseId(NET_ENTERPRISE_ID_1)
+                .removeEnterpriseId(NET_ENTERPRISE_ID_2)
                 .build();
-        assertEquals(0, nc4.getEnterpriseCapabilitySubLevels().length);
+        assertEquals(1, nc4.getEnterpriseIds().length);
+        assertTrue(nc4.hasEnterpriseId(NET_ENTERPRISE_ID_1));
 
         final NetworkCapabilities nc5 = new NetworkCapabilities.Builder()
                 .addCapability(NET_CAPABILITY_CBS)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1)
-                .addEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2)
-                .removeEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_1)
-                .removeEnterpriseCapabilitySubLevel(NET_CAPABILITY_ENTERPRISE_SUB_LEVEL_2)
+                .addEnterpriseId(NET_ENTERPRISE_ID_1)
+                .addEnterpriseId(NET_ENTERPRISE_ID_2)
+                .removeEnterpriseId(NET_ENTERPRISE_ID_1)
+                .removeEnterpriseId(NET_ENTERPRISE_ID_2)
                 .build();
 
         assertTrue(nc4.satisfiedByNetworkCapabilities(nc1));
-        assertFalse(nc1.satisfiedByNetworkCapabilities(nc4));
+        assertTrue(nc1.satisfiedByNetworkCapabilities(nc4));
 
         assertFalse(nc3.satisfiedByNetworkCapabilities(nc2));
         assertTrue(nc2.satisfiedByNetworkCapabilities(nc3));
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
index 916b566..5778b0d 100755
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -36,6 +36,7 @@
 
 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
 import static com.android.testutils.Cleanup.testAndCleanup;
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -71,7 +72,6 @@
 import android.net.VpnTransportInfo;
 import android.net.cts.util.CtsNetUtils;
 import android.net.wifi.WifiManager;
-import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
@@ -830,7 +830,7 @@
                                 .getCaps().getUnderlyingNetworks())));
     }
 
-    @Test @IgnoreUpTo(Build.VERSION_CODES.S)
+    @Test @IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
     public void testChangeUnderlyingNetworks() throws Exception {
         assumeTrue(supportedHardware());
         assumeTrue(mPackageManager.hasSystemFeature(FEATURE_WIFI));
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index 81c30b1..f66231d 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -49,6 +49,7 @@
         "FrameworksNetCommonTests",
         "core-tests-support",
         "cts-net-utils",
+        "CtsNetTestsNonUpdatableLib",
         "ctstestrunner-axt",
         "junit",
         "junit-params",
diff --git a/tests/cts/net/src/android/net/cts/DhcpOptionTest.kt b/tests/cts/net/src/android/net/cts/DhcpOptionTest.kt
index 1a62560..555dd87 100644
--- a/tests/cts/net/src/android/net/cts/DhcpOptionTest.kt
+++ b/tests/cts/net/src/android/net/cts/DhcpOptionTest.kt
@@ -16,11 +16,11 @@
 
 package android.net.cts
 
-import android.os.Build
 import android.net.DhcpOption
 import androidx.test.filters.SmallTest
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
 import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.SC_V2
 import org.junit.Assert.assertArrayEquals
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNull
@@ -28,7 +28,7 @@
 import org.junit.Test
 
 @SmallTest
-@IgnoreUpTo(Build.VERSION_CODES.S)
+@IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
 @RunWith(DevSdkIgnoreRunner::class)
 class DhcpOptionTest {
     private val DHCP_OPTION_TYPE: Byte = 2
diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
index 4992795..c6fc38f 100644
--- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
@@ -25,6 +25,8 @@
 import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
 import static android.system.OsConstants.ETIMEDOUT;
 
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -43,7 +45,6 @@
 import android.net.NetworkRequest;
 import android.net.ParseException;
 import android.net.cts.util.CtsNetUtils;
-import android.os.Build;
 import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.Looper;
@@ -814,7 +815,7 @@
     }
 
     /** Verifies that DnsResolver.DnsException can be subclassed and its constructor re-used. */
-    @Test @IgnoreUpTo(Build.VERSION_CODES.S)
+    @Test @IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
     public void testDnsExceptionConstructor() throws InterruptedException {
         class TestDnsException extends DnsResolver.DnsException {
             TestDnsException(int code, @Nullable Throwable cause) {
diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java
deleted file mode 100644
index 6e61705..0000000
--- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * Copyright (C) 2008 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.cts;
-
-import junit.framework.TestCase;
-
-import android.net.Credentials;
-import android.net.LocalServerSocket;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.system.Os;
-import android.system.OsConstants;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-public class LocalSocketTest extends TestCase {
-    private final static String ADDRESS_PREFIX = "com.android.net.LocalSocketTest";
-
-    public void testLocalConnections() throws IOException {
-        String address = ADDRESS_PREFIX + "_testLocalConnections";
-        // create client and server socket
-        LocalServerSocket localServerSocket = new LocalServerSocket(address);
-        LocalSocket clientSocket = new LocalSocket();
-
-        // establish connection between client and server
-        LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
-        assertFalse(clientSocket.isConnected());
-        clientSocket.connect(locSockAddr);
-        assertTrue(clientSocket.isConnected());
-
-        LocalSocket serverSocket = localServerSocket.accept();
-        assertTrue(serverSocket.isConnected());
-        assertTrue(serverSocket.isBound());
-        try {
-            serverSocket.bind(localServerSocket.getLocalSocketAddress());
-            fail("Cannot bind a LocalSocket from accept()");
-        } catch (IOException expected) {
-        }
-        try {
-            serverSocket.connect(locSockAddr);
-            fail("Cannot connect a LocalSocket from accept()");
-        } catch (IOException expected) {
-        }
-
-        Credentials credent = clientSocket.getPeerCredentials();
-        assertTrue(0 != credent.getPid());
-
-        // send data from client to server
-        OutputStream clientOutStream = clientSocket.getOutputStream();
-        clientOutStream.write(12);
-        InputStream serverInStream = serverSocket.getInputStream();
-        assertEquals(12, serverInStream.read());
-
-        //send data from server to client
-        OutputStream serverOutStream = serverSocket.getOutputStream();
-        serverOutStream.write(3);
-        InputStream clientInStream = clientSocket.getInputStream();
-        assertEquals(3, clientInStream.read());
-
-        // Test sending and receiving file descriptors
-        clientSocket.setFileDescriptorsForSend(new FileDescriptor[]{FileDescriptor.in});
-        clientOutStream.write(32);
-        assertEquals(32, serverInStream.read());
-
-        FileDescriptor[] out = serverSocket.getAncillaryFileDescriptors();
-        assertEquals(1, out.length);
-        FileDescriptor fd = clientSocket.getFileDescriptor();
-        assertTrue(fd.valid());
-
-        //shutdown input stream of client
-        clientSocket.shutdownInput();
-        assertEquals(-1, clientInStream.read());
-
-        //shutdown output stream of client
-        clientSocket.shutdownOutput();
-        try {
-            clientOutStream.write(10);
-            fail("testLocalSocket shouldn't come to here");
-        } catch (IOException e) {
-            // expected
-        }
-
-        //shutdown input stream of server
-        serverSocket.shutdownInput();
-        assertEquals(-1, serverInStream.read());
-
-        //shutdown output stream of server
-        serverSocket.shutdownOutput();
-        try {
-            serverOutStream.write(10);
-            fail("testLocalSocket shouldn't come to here");
-        } catch (IOException e) {
-            // expected
-        }
-
-        //close client socket
-        clientSocket.close();
-        try {
-            clientInStream.read();
-            fail("testLocalSocket shouldn't come to here");
-        } catch (IOException e) {
-            // expected
-        }
-
-        //close server socket
-        serverSocket.close();
-        try {
-            serverInStream.read();
-            fail("testLocalSocket shouldn't come to here");
-        } catch (IOException e) {
-            // expected
-        }
-    }
-
-    public void testAccessors() throws IOException {
-        String address = ADDRESS_PREFIX + "_testAccessors";
-        LocalSocket socket = new LocalSocket();
-        LocalSocketAddress addr = new LocalSocketAddress(address);
-
-        assertFalse(socket.isBound());
-        socket.bind(addr);
-        assertTrue(socket.isBound());
-        assertEquals(addr, socket.getLocalSocketAddress());
-
-        String str = socket.toString();
-        assertTrue(str.contains("impl:android.net.LocalSocketImpl"));
-
-        socket.setReceiveBufferSize(1999);
-        assertEquals(1999 << 1, socket.getReceiveBufferSize());
-
-        socket.setSendBufferSize(3998);
-        assertEquals(3998 << 1, socket.getSendBufferSize());
-
-        assertEquals(0, socket.getSoTimeout());
-        socket.setSoTimeout(1996);
-        assertTrue(socket.getSoTimeout() > 0);
-
-        try {
-            socket.getRemoteSocketAddress();
-            fail("testLocalSocketSecondary shouldn't come to here");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
-
-        try {
-            socket.isClosed();
-            fail("testLocalSocketSecondary shouldn't come to here");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
-
-        try {
-            socket.isInputShutdown();
-            fail("testLocalSocketSecondary shouldn't come to here");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
-
-        try {
-            socket.isOutputShutdown();
-            fail("testLocalSocketSecondary shouldn't come to here");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
-
-        try {
-            socket.connect(addr, 2005);
-            fail("testLocalSocketSecondary shouldn't come to here");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
-
-        socket.close();
-    }
-
-    // http://b/31205169
-    public void testSetSoTimeout_readTimeout() throws Exception {
-        String address = ADDRESS_PREFIX + "_testSetSoTimeout_readTimeout";
-
-        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
-            final LocalSocket clientSocket = socketPair.clientSocket;
-
-            // Set the timeout in millis.
-            int timeoutMillis = 1000;
-            clientSocket.setSoTimeout(timeoutMillis);
-
-            // Avoid blocking the test run if timeout doesn't happen by using a separate thread.
-            Callable<Result> reader = () -> {
-                try {
-                    clientSocket.getInputStream().read();
-                    return Result.noException("Did not block");
-                } catch (IOException e) {
-                    return Result.exception(e);
-                }
-            };
-            // Allow the configured timeout, plus some slop.
-            int allowedTime = timeoutMillis + 2000;
-            Result result = runInSeparateThread(allowedTime, reader);
-
-            // Check the message was a timeout, it's all we have to go on.
-            String expectedMessage = Os.strerror(OsConstants.EAGAIN);
-            result.assertThrewIOException(expectedMessage);
-        }
-    }
-
-    // http://b/31205169
-    public void testSetSoTimeout_writeTimeout() throws Exception {
-        String address = ADDRESS_PREFIX + "_testSetSoTimeout_writeTimeout";
-
-        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
-            final LocalSocket clientSocket = socketPair.clientSocket;
-
-            // Set the timeout in millis.
-            int timeoutMillis = 1000;
-            clientSocket.setSoTimeout(timeoutMillis);
-
-            // Set a small buffer size so we know we can flood it.
-            clientSocket.setSendBufferSize(100);
-            final int bufferSize = clientSocket.getSendBufferSize();
-
-            // Avoid blocking the test run if timeout doesn't happen by using a separate thread.
-            Callable<Result> writer = () -> {
-                try {
-                    byte[] toWrite = new byte[bufferSize * 2];
-                    clientSocket.getOutputStream().write(toWrite);
-                    return Result.noException("Did not block");
-                } catch (IOException e) {
-                    return Result.exception(e);
-                }
-            };
-            // Allow the configured timeout, plus some slop.
-            int allowedTime = timeoutMillis + 2000;
-
-            Result result = runInSeparateThread(allowedTime, writer);
-
-            // Check the message was a timeout, it's all we have to go on.
-            String expectedMessage = Os.strerror(OsConstants.EAGAIN);
-            result.assertThrewIOException(expectedMessage);
-        }
-    }
-
-    public void testAvailable() throws Exception {
-        String address = ADDRESS_PREFIX + "_testAvailable";
-
-        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
-            LocalSocket clientSocket = socketPair.clientSocket;
-            LocalSocket serverSocket = socketPair.serverSocket.accept();
-
-            OutputStream clientOutputStream = clientSocket.getOutputStream();
-            InputStream serverInputStream = serverSocket.getInputStream();
-            assertEquals(0, serverInputStream.available());
-
-            byte[] buffer = new byte[50];
-            clientOutputStream.write(buffer);
-            assertEquals(50, serverInputStream.available());
-
-            InputStream clientInputStream = clientSocket.getInputStream();
-            OutputStream serverOutputStream = serverSocket.getOutputStream();
-            assertEquals(0, clientInputStream.available());
-            serverOutputStream.write(buffer);
-            assertEquals(50, serverInputStream.available());
-
-            serverSocket.close();
-        }
-    }
-
-    // http://b/34095140
-    public void testLocalSocketCreatedFromFileDescriptor() throws Exception {
-        String address = ADDRESS_PREFIX + "_testLocalSocketCreatedFromFileDescriptor";
-
-        // Establish connection between a local client and server to get a valid client socket file
-        // descriptor.
-        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
-            // Extract the client FileDescriptor we can use.
-            FileDescriptor fileDescriptor = socketPair.clientSocket.getFileDescriptor();
-            assertTrue(fileDescriptor.valid());
-
-            // Create the LocalSocket we want to test.
-            LocalSocket clientSocketCreatedFromFileDescriptor =
-                    LocalSocket.createConnectedLocalSocket(fileDescriptor);
-            assertTrue(clientSocketCreatedFromFileDescriptor.isConnected());
-            assertTrue(clientSocketCreatedFromFileDescriptor.isBound());
-
-            // Test the LocalSocket can be used for communication.
-            LocalSocket serverSocket = socketPair.serverSocket.accept();
-            OutputStream clientOutputStream =
-                    clientSocketCreatedFromFileDescriptor.getOutputStream();
-            InputStream serverInputStream = serverSocket.getInputStream();
-
-            clientOutputStream.write(12);
-            assertEquals(12, serverInputStream.read());
-
-            // Closing clientSocketCreatedFromFileDescriptor does not close the file descriptor.
-            clientSocketCreatedFromFileDescriptor.close();
-            assertTrue(fileDescriptor.valid());
-
-            // .. while closing the LocalSocket that owned the file descriptor does.
-            socketPair.clientSocket.close();
-            assertFalse(fileDescriptor.valid());
-        }
-    }
-
-    public void testFlush() throws Exception {
-        String address = ADDRESS_PREFIX + "_testFlush";
-
-        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
-            LocalSocket clientSocket = socketPair.clientSocket;
-            LocalSocket serverSocket = socketPair.serverSocket.accept();
-
-            OutputStream clientOutputStream = clientSocket.getOutputStream();
-            InputStream serverInputStream = serverSocket.getInputStream();
-            testFlushWorks(clientOutputStream, serverInputStream);
-
-            OutputStream serverOutputStream = serverSocket.getOutputStream();
-            InputStream clientInputStream = clientSocket.getInputStream();
-            testFlushWorks(serverOutputStream, clientInputStream);
-
-            serverSocket.close();
-        }
-    }
-
-    private void testFlushWorks(OutputStream outputStream, InputStream inputStream)
-            throws Exception {
-        final int bytesToTransfer = 50;
-        StreamReader inputStreamReader = new StreamReader(inputStream, bytesToTransfer);
-
-        byte[] buffer = new byte[bytesToTransfer];
-        outputStream.write(buffer);
-        assertEquals(bytesToTransfer, inputStream.available());
-
-        // Start consuming the data.
-        inputStreamReader.start();
-
-        // This doesn't actually flush any buffers, it just polls until the reader has read all the
-        // bytes.
-        outputStream.flush();
-
-        inputStreamReader.waitForCompletion(5000);
-        inputStreamReader.assertBytesRead(bytesToTransfer);
-        assertEquals(0, inputStream.available());
-    }
-
-    private static class StreamReader extends Thread {
-        private final InputStream is;
-        private final int expectedByteCount;
-        private final CountDownLatch completeLatch = new CountDownLatch(1);
-
-        private volatile Exception exception;
-        private int bytesRead;
-
-        private StreamReader(InputStream is, int expectedByteCount) {
-            this.is = is;
-            this.expectedByteCount = expectedByteCount;
-        }
-
-        @Override
-        public void run() {
-            try {
-                byte[] buffer = new byte[10];
-                int readCount;
-                while ((readCount = is.read(buffer)) >= 0) {
-                    bytesRead += readCount;
-                    if (bytesRead >= expectedByteCount) {
-                        break;
-                    }
-                }
-            } catch (IOException e) {
-                exception = e;
-            } finally {
-                completeLatch.countDown();
-            }
-        }
-
-        public void waitForCompletion(long waitMillis) throws Exception {
-            if (!completeLatch.await(waitMillis, TimeUnit.MILLISECONDS)) {
-                fail("Timeout waiting for completion");
-            }
-            if (exception != null) {
-                throw new Exception("Read failed", exception);
-            }
-        }
-
-        public void assertBytesRead(int expected) {
-            assertEquals(expected, bytesRead);
-        }
-    }
-
-    private static class Result {
-        private final String type;
-        private final Exception e;
-
-        private Result(String type, Exception e) {
-            this.type = type;
-            this.e = e;
-        }
-
-        static Result noException(String description) {
-            return new Result(description, null);
-        }
-
-        static Result exception(Exception e) {
-            return new Result(e.getClass().getName(), e);
-        }
-
-        void assertThrewIOException(String expectedMessage) {
-            assertEquals("Unexpected result type", IOException.class.getName(), type);
-            assertEquals("Unexpected exception message", expectedMessage, e.getMessage());
-        }
-    }
-
-    private static Result runInSeparateThread(int allowedTime, final Callable<Result> callable)
-            throws Exception {
-        ExecutorService service = Executors.newSingleThreadScheduledExecutor();
-        Future<Result> future = service.submit(callable);
-        Result result = future.get(allowedTime, TimeUnit.MILLISECONDS);
-        if (!future.isDone()) {
-            fail("Worker thread appears blocked");
-        }
-        return result;
-    }
-
-    private static class LocalSocketPair implements AutoCloseable {
-        static LocalSocketPair createConnectedSocketPair(String address) throws Exception {
-            LocalServerSocket localServerSocket = new LocalServerSocket(address);
-            final LocalSocket clientSocket = new LocalSocket();
-
-            // Establish connection between client and server
-            LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
-            clientSocket.connect(locSockAddr);
-            assertTrue(clientSocket.isConnected());
-            return new LocalSocketPair(localServerSocket, clientSocket);
-        }
-
-        final LocalServerSocket serverSocket;
-        final LocalSocket clientSocket;
-
-        LocalSocketPair(LocalServerSocket serverSocket, LocalSocket clientSocket) {
-            this.serverSocket = serverSocket;
-            this.clientSocket = clientSocket;
-        }
-
-        public void close() throws Exception {
-            serverSocket.close();
-            clientSocket.close();
-        }
-    }
-}
diff --git a/tests/mts/Android.bp b/tests/mts/Android.bp
index a56f76e..2c44010 100644
--- a/tests/mts/Android.bp
+++ b/tests/mts/Android.bp
@@ -23,6 +23,9 @@
         "general-tests",
         "mts-tethering",
     ],
+    defaults: [
+        "connectivity-mainline-presubmit-cc-defaults",
+    ],
     require_root: true,
     static_libs: [
         "libbase",
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 48751f4..0bef0e2 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -88,7 +88,9 @@
         "java/com/android/server/connectivity/NetdEventListenerServiceTest.java",
         "java/com/android/server/connectivity/VpnTest.java",
         "java/com/android/server/net/ipmemorystore/*.java",
+        "java/com/android/server/net/BpfInterfaceMapUpdaterTest.java",
         "java/com/android/server/net/NetworkStats*.java",
+        "java/com/android/server/net/TestableUsageCallback.kt",
     ]
 }
 
diff --git a/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java b/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
index 6e51069..561e621 100644
--- a/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
+++ b/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
@@ -240,6 +240,27 @@
         assertFalse(stats.hasNextBucket());
     }
 
+
+    @Test
+    public void testQueryDetailsForDevice() throws Exception {
+        final long startTime = 1;
+        final long endTime = 100;
+
+        reset(mStatsSession);
+        when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession);
+        when(mStatsSession.getHistoryIntervalForNetwork(any(NetworkTemplate.class),
+                anyInt(), anyLong(), anyLong()))
+                .thenReturn(new NetworkStatsHistory(10, 0));
+        final NetworkTemplate template = new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
+                .setMeteredness(NetworkStats.Bucket.METERED_YES).build();
+        NetworkStats stats = mManager.queryDetailsForDevice(template, startTime, endTime);
+
+        verify(mStatsSession, times(1)).getHistoryIntervalForNetwork(
+                eq(template), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
+
+        assertFalse(stats.hasNextBucket());
+    }
+
     private void assertBucketMatches(Entry expected, NetworkStats.Bucket actual) {
         assertEquals(expected.uid, actual.getUid());
         assertEquals(expected.rxBytes, actual.getRxBytes());
diff --git a/tests/unit/java/android/net/NetworkIdentityTest.kt b/tests/unit/java/android/net/NetworkIdentityTest.kt
index b1ffc92..ec0420e 100644
--- a/tests/unit/java/android/net/NetworkIdentityTest.kt
+++ b/tests/unit/java/android/net/NetworkIdentityTest.kt
@@ -17,7 +17,11 @@
 package android.net
 
 import android.content.Context
+import android.net.ConnectivityManager.MAX_NETWORK_TYPE
+import android.net.ConnectivityManager.TYPE_ETHERNET
 import android.net.ConnectivityManager.TYPE_MOBILE
+import android.net.ConnectivityManager.TYPE_NONE
+import android.net.ConnectivityManager.TYPE_WIFI
 import android.net.NetworkIdentity.OEM_NONE
 import android.net.NetworkIdentity.OEM_PAID
 import android.net.NetworkIdentity.OEM_PRIVATE
@@ -30,10 +34,12 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
 import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
 import kotlin.test.assertFalse
 import kotlin.test.assertTrue
 
 private const val TEST_IMSI = "testimsi"
+private const val TEST_WIFI_KEY = "testwifikey"
 
 @RunWith(DevSdkIgnoreRunner::class)
 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
@@ -74,12 +80,12 @@
     }
 
     @Test
-    fun testGetMetered() {
+    fun testIsMetered() {
         // Verify network is metered.
         val netIdent1 = NetworkIdentity.buildNetworkIdentity(mockContext,
                 buildMobileNetworkStateSnapshot(NetworkCapabilities(), TEST_IMSI),
                 false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
-        assertTrue(netIdent1.getMetered())
+        assertTrue(netIdent1.isMetered())
 
         // Verify network is not metered because it has NET_CAPABILITY_NOT_METERED capability.
         val capsNotMetered = NetworkCapabilities.Builder().apply {
@@ -88,7 +94,7 @@
         val netIdent2 = NetworkIdentity.buildNetworkIdentity(mockContext,
                 buildMobileNetworkStateSnapshot(capsNotMetered, TEST_IMSI),
                 false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
-        assertFalse(netIdent2.getMetered())
+        assertFalse(netIdent2.isMetered())
 
         // Verify network is not metered because it has NET_CAPABILITY_TEMPORARILY_NOT_METERED
         // capability .
@@ -98,6 +104,120 @@
         val netIdent3 = NetworkIdentity.buildNetworkIdentity(mockContext,
                 buildMobileNetworkStateSnapshot(capsTempNotMetered, TEST_IMSI),
                 false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
-        assertFalse(netIdent3.getMetered())
+        assertFalse(netIdent3.isMetered())
+    }
+
+    @Test
+    fun testBuilder() {
+        val oemPrivateRoamingNotMeteredCap = NetworkCapabilities().apply {
+            addCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)
+            addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+        }
+        val identFromSnapshot = NetworkIdentity.Builder().setNetworkStateSnapshot(
+                buildMobileNetworkStateSnapshot(oemPrivateRoamingNotMeteredCap, TEST_IMSI))
+                .setDefaultNetwork(true)
+                .setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
+                .build()
+        val identFromLegacyBuild = NetworkIdentity.buildNetworkIdentity(mockContext,
+                buildMobileNetworkStateSnapshot(oemPrivateRoamingNotMeteredCap, TEST_IMSI),
+                true /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identFromConstructor = NetworkIdentity(TYPE_MOBILE,
+                TelephonyManager.NETWORK_TYPE_UMTS,
+                TEST_IMSI,
+                null /* wifiNetworkKey */,
+                true /* roaming */,
+                false /* metered */,
+                true /* defaultNetwork */,
+                NetworkTemplate.OEM_MANAGED_PRIVATE)
+        assertEquals(identFromLegacyBuild, identFromSnapshot)
+        assertEquals(identFromConstructor, identFromSnapshot)
+
+        // Assert non-wifi can't have wifi network key.
+        assertFailsWith<IllegalArgumentException> {
+            NetworkIdentity.Builder()
+                    .setType(TYPE_ETHERNET)
+                    .setWifiNetworkKey(TEST_WIFI_KEY)
+                    .build()
+        }
+
+        // Assert non-mobile can't have ratType.
+        assertFailsWith<IllegalArgumentException> {
+            NetworkIdentity.Builder()
+                    .setType(TYPE_WIFI)
+                    .setRatType(TelephonyManager.NETWORK_TYPE_LTE)
+                    .build()
+        }
+    }
+
+    @Test
+    fun testBuilder_type() {
+        // Assert illegal type values cannot make an identity.
+        listOf(Integer.MIN_VALUE, TYPE_NONE - 1, MAX_NETWORK_TYPE + 1, Integer.MAX_VALUE)
+                .forEach { type ->
+                    assertFailsWith<IllegalArgumentException> {
+                        NetworkIdentity.Builder().setType(type).build()
+                    }
+                }
+
+        // Verify legitimate type values can make an identity.
+        for (type in TYPE_NONE..MAX_NETWORK_TYPE) {
+            NetworkIdentity.Builder().setType(type).build().also {
+                assertEquals(it.type, type)
+            }
+        }
+    }
+
+    @Test
+    fun testBuilder_ratType() {
+        // Assert illegal ratTypes cannot make an identity.
+        listOf(Integer.MIN_VALUE, NetworkTemplate.NETWORK_TYPE_ALL,
+                TelephonyManager.NETWORK_TYPE_UNKNOWN - 1, Integer.MAX_VALUE)
+                .forEach {
+                    assertFailsWith<IllegalArgumentException> {
+                        NetworkIdentity.Builder()
+                                .setType(TYPE_MOBILE)
+                                .setRatType(it)
+                                .build()
+                    }
+                }
+
+        // Verify legitimate ratTypes can make an identity.
+        TelephonyManager.getAllNetworkTypes().toMutableList().also {
+            it.add(TelephonyManager.NETWORK_TYPE_UNKNOWN)
+        }.forEach { rat ->
+            NetworkIdentity.Builder()
+                    .setType(TYPE_MOBILE)
+                    .setRatType(rat)
+                    .build().also {
+                        assertEquals(it.ratType, rat)
+                    }
+        }
+    }
+
+    @Test
+    fun testBuilder_oemManaged() {
+        // Assert illegal oemManage values cannot make an identity.
+        listOf(Integer.MIN_VALUE, NetworkTemplate.OEM_MANAGED_ALL, NetworkTemplate.OEM_MANAGED_YES,
+                Integer.MAX_VALUE)
+                .forEach {
+                    assertFailsWith<IllegalArgumentException> {
+                        NetworkIdentity.Builder()
+                                .setType(TYPE_MOBILE)
+                                .setRatType(it)
+                                .build()
+                    }
+                }
+
+        // Verify legitimate oem managed values can make an identity.
+        listOf(NetworkTemplate.OEM_MANAGED_NO, NetworkTemplate.OEM_MANAGED_PAID,
+                NetworkTemplate.OEM_MANAGED_PRIVATE, NetworkTemplate.OEM_MANAGED_PAID or
+                NetworkTemplate.OEM_MANAGED_PRIVATE)
+                .forEach { oemManaged ->
+                    NetworkIdentity.Builder()
+                            .setOemManaged(oemManaged)
+                            .build().also {
+                                assertEquals(it.oemManaged, oemManaged)
+                            }
+                }
     }
 }
diff --git a/tests/unit/java/android/net/NetworkStatsAccessTest.java b/tests/unit/java/android/net/NetworkStatsAccessTest.java
index e4fc118..97a93ca 100644
--- a/tests/unit/java/android/net/NetworkStatsAccessTest.java
+++ b/tests/unit/java/android/net/NetworkStatsAccessTest.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.when;
 
@@ -25,7 +27,6 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.os.Build;
 import android.telephony.TelephonyManager;
 
 import androidx.test.filters.SmallTest;
@@ -42,7 +43,7 @@
 
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
 public class NetworkStatsAccessTest {
     private static final String TEST_PKG = "com.example.test";
     private static final int TEST_PID = 1234;
diff --git a/tests/unit/java/android/net/NetworkStatsCollectionTest.java b/tests/unit/java/android/net/NetworkStatsCollectionTest.java
index 1c557d6..2e82986 100644
--- a/tests/unit/java/android/net/NetworkStatsCollectionTest.java
+++ b/tests/unit/java/android/net/NetworkStatsCollectionTest.java
@@ -29,6 +29,7 @@
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 
 import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
 import static com.android.testutils.MiscAsserts.assertThrows;
 
 import static org.junit.Assert.assertArrayEquals;
@@ -37,7 +38,6 @@
 import static org.junit.Assert.fail;
 
 import android.content.res.Resources;
-import android.os.Build;
 import android.os.Process;
 import android.os.UserHandle;
 import android.telephony.SubscriptionPlan;
@@ -59,6 +59,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -78,7 +79,7 @@
  */
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
 public class NetworkStatsCollectionTest {
 
     private static final String TEST_FILE = "test.bin";
@@ -195,8 +196,8 @@
         // record empty data straddling between buckets
         final NetworkStats.Entry entry = new NetworkStats.Entry();
         entry.rxBytes = 32;
-        collection.recordData(null, UID_ALL, SET_DEFAULT, TAG_NONE, 30 * MINUTE_IN_MILLIS,
-                90 * MINUTE_IN_MILLIS, entry);
+        collection.recordData(Mockito.mock(NetworkIdentitySet.class), UID_ALL, SET_DEFAULT,
+                TAG_NONE, 30 * MINUTE_IN_MILLIS, 90 * MINUTE_IN_MILLIS, entry);
 
         // assert that we report boundary in atomic buckets
         assertEquals(0, collection.getStartMillis());
diff --git a/tests/unit/java/android/net/NetworkStatsHistoryTest.java b/tests/unit/java/android/net/NetworkStatsHistoryTest.java
index c5f8c00..c170605 100644
--- a/tests/unit/java/android/net/NetworkStatsHistoryTest.java
+++ b/tests/unit/java/android/net/NetworkStatsHistoryTest.java
@@ -56,6 +56,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
+import java.util.List;
 import java.util.Random;
 
 @RunWith(DevSdkIgnoreRunner.class)
@@ -532,6 +533,40 @@
         assertEquals(512L + 4096L, stats.getTotalBytes());
     }
 
+    @Test
+    public void testBuilder() {
+        final NetworkStatsHistory.Entry entry1 = new NetworkStatsHistory.Entry(10, 30, 40,
+                4, 50, 5, 60);
+        final NetworkStatsHistory.Entry entry2 = new NetworkStatsHistory.Entry(30, 15, 3,
+                41, 7, 1, 0);
+        final NetworkStatsHistory.Entry entry3 = new NetworkStatsHistory.Entry(7, 301, 11,
+                14, 31, 2, 80);
+
+        final NetworkStatsHistory statsEmpty = new NetworkStatsHistory
+                .Builder(HOUR_IN_MILLIS, 10).build();
+        assertEquals(0, statsEmpty.getEntries().size());
+        assertEquals(HOUR_IN_MILLIS, statsEmpty.getBucketDuration());
+
+        NetworkStatsHistory statsSingle = new NetworkStatsHistory
+                .Builder(HOUR_IN_MILLIS, 8)
+                .addEntry(entry1)
+                .build();
+        assertEquals(1, statsSingle.getEntries().size());
+        assertEquals(HOUR_IN_MILLIS, statsSingle.getBucketDuration());
+        assertEquals(entry1, statsSingle.getEntries().get(0));
+
+        NetworkStatsHistory statsMultiple = new NetworkStatsHistory
+                .Builder(SECOND_IN_MILLIS, 0)
+                .addEntry(entry1).addEntry(entry2).addEntry(entry3)
+                .build();
+        final List<NetworkStatsHistory.Entry> entries = statsMultiple.getEntries();
+        assertEquals(3, entries.size());
+        assertEquals(SECOND_IN_MILLIS, statsMultiple.getBucketDuration());
+        assertEquals(entry1, entries.get(0));
+        assertEquals(entry2, entries.get(1));
+        assertEquals(entry3, entries.get(2));
+    }
+
     private static void assertIndexBeforeAfter(
             NetworkStatsHistory stats, int before, int after, long time) {
         assertEquals("unexpected before", before, stats.getIndexBefore(time));
diff --git a/tests/unit/java/android/net/NetworkStatsTest.java b/tests/unit/java/android/net/NetworkStatsTest.java
index be2857e..b0cc16c 100644
--- a/tests/unit/java/android/net/NetworkStatsTest.java
+++ b/tests/unit/java/android/net/NetworkStatsTest.java
@@ -37,6 +37,7 @@
 import static android.net.NetworkStats.UID_ALL;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.os.Build;
@@ -53,8 +54,10 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.Iterator;
 
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
@@ -1037,6 +1040,29 @@
         assertEquals(secondEntry, stats.getValues(1, null));
     }
 
+    @Test
+    public void testIterator() {
+        final NetworkStats emptyStats = new NetworkStats(0, 0);
+        final Iterator emptyIterator = emptyStats.iterator();
+        assertFalse(emptyIterator.hasNext());
+
+        final int numEntries = 10;
+        final ArrayList<NetworkStats.Entry> entries = new ArrayList<>();
+        final NetworkStats stats = new NetworkStats(TEST_START, 1);
+        for (int i = 0; i < numEntries; ++i) {
+            NetworkStats.Entry entry = new NetworkStats.Entry("test1", 10100, SET_DEFAULT,
+                    TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO,
+                    i * 10L /* rxBytes */, i * 3L /* rxPackets */,
+                    i * 15L /* txBytes */, i * 2L /* txPackets */, 0L /* operations */);
+            stats.insertEntry(entry);
+            entries.add(entry);
+        }
+
+        for (NetworkStats.Entry e : stats) {
+            assertEquals(e, entries.remove(0));
+        }
+    }
+
     private static void assertContains(NetworkStats stats,  String iface, int uid, int set,
             int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets,
             long txBytes, long txPackets, long operations) {
diff --git a/tests/unit/java/android/net/NetworkTemplateTest.kt b/tests/unit/java/android/net/NetworkTemplateTest.kt
index 15db45c..048597f 100644
--- a/tests/unit/java/android/net/NetworkTemplateTest.kt
+++ b/tests/unit/java/android/net/NetworkTemplateTest.kt
@@ -22,7 +22,6 @@
 import android.net.NetworkIdentity.OEM_NONE
 import android.net.NetworkIdentity.OEM_PAID
 import android.net.NetworkIdentity.OEM_PRIVATE
-import android.net.NetworkIdentity.SUBTYPE_COMBINED
 import android.net.NetworkIdentity.buildNetworkIdentity
 import android.net.NetworkStats.DEFAULT_NETWORK_ALL
 import android.net.NetworkStats.METERED_ALL
@@ -57,6 +56,7 @@
 import com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT
 import com.android.testutils.DevSdkIgnoreRule
 import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.SC_V2
 import com.android.testutils.assertParcelSane
 import org.junit.Before
 import org.junit.Test
@@ -95,7 +95,7 @@
         oemManaged: Int = OEM_NONE,
         metered: Boolean = true
     ): NetworkStateSnapshot {
-        `when`(mockWifiInfo.getCurrentNetworkKey()).thenReturn(wifiKey)
+        `when`(mockWifiInfo.getNetworkKey()).thenReturn(wifiKey)
         val lp = LinkProperties()
         val caps = NetworkCapabilities().apply {
             setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !metered)
@@ -312,7 +312,7 @@
         val identLteMetered = buildNetworkIdentity(
                 mockContext, stateMobileImsi1Metered, false, TelephonyManager.NETWORK_TYPE_LTE)
         val identCombinedMetered = buildNetworkIdentity(
-                mockContext, stateMobileImsi1Metered, false, SUBTYPE_COMBINED)
+                mockContext, stateMobileImsi1Metered, false, NetworkTemplate.NETWORK_TYPE_ALL)
         val identImsi2UmtsMetered = buildNetworkIdentity(mockContext,
                 buildMobileNetworkState(TEST_IMSI2), false, TelephonyManager.NETWORK_TYPE_UMTS)
         val identWifi = buildNetworkIdentity(
@@ -326,7 +326,7 @@
         val identLteNonMetered = buildNetworkIdentity(
                 mockContext, stateMobileImsi1NonMetered, false, TelephonyManager.NETWORK_TYPE_LTE)
         val identCombinedNonMetered = buildNetworkIdentity(
-                mockContext, stateMobileImsi1NonMetered, false, SUBTYPE_COMBINED)
+                mockContext, stateMobileImsi1NonMetered, false, NetworkTemplate.NETWORK_TYPE_ALL)
         val identImsi2UmtsNonMetered = buildNetworkIdentity(mockContext,
                 stateMobileImsi2NonMetered, false, TelephonyManager.NETWORK_TYPE_UMTS)
 
@@ -556,7 +556,7 @@
         }
     }
 
-    @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S)
+    @DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
     @Test
     fun testBuilderMatchRules() {
         // Verify unknown match rules cannot construct templates.
@@ -657,7 +657,7 @@
         }
     }
 
-    @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S)
+    @DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
     @Test
     fun testBuilderWifiNetworkKeys() {
         // Verify template builder which generates same template with the given different
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index abb34dc..652aee9 100644
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -101,6 +101,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VSIM;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
@@ -338,6 +339,7 @@
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
 import com.android.server.connectivity.ProxyTracker;
 import com.android.server.connectivity.QosCallbackTracker;
+import com.android.server.connectivity.UidRangeUtils;
 import com.android.server.connectivity.Vpn;
 import com.android.server.connectivity.VpnProfileStore;
 import com.android.server.net.NetworkPinner;
@@ -350,6 +352,7 @@
 import com.android.testutils.TestableNetworkOfferCallback;
 
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -443,6 +446,10 @@
     private static final int TEST_WORK_PROFILE_USER_ID = 2;
     private static final int TEST_WORK_PROFILE_APP_UID =
             UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID);
+    private static final int TEST_APP_ID_2 = 104;
+    private static final int TEST_WORK_PROFILE_APP_UID_2 =
+            UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID_2);
+
     private static final String CLAT_PREFIX = "v4-";
     private static final String MOBILE_IFNAME = "test_rmnet_data0";
     private static final String CLAT_MOBILE_IFNAME = CLAT_PREFIX + MOBILE_IFNAME;
@@ -492,6 +499,8 @@
     private TestNetworkCallback mSystemDefaultNetworkCallback;
     private TestNetworkCallback mProfileDefaultNetworkCallback;
     private TestNetworkCallback mTestPackageDefaultNetworkCallback;
+    private TestNetworkCallback mProfileDefaultNetworkCallbackAsAppUid2;
+    private TestNetworkCallback mTestPackageDefaultNetworkCallback2;
 
     // State variables required to emulate NetworkPolicyManagerService behaviour.
     private int mBlockedReasons = BLOCKED_REASON_NONE;
@@ -12247,6 +12256,8 @@
     private void registerDefaultNetworkCallbacks() {
         if (mSystemDefaultNetworkCallback != null || mDefaultNetworkCallback != null
                 || mProfileDefaultNetworkCallback != null
+                || mProfileDefaultNetworkCallbackAsAppUid2 != null
+                || mTestPackageDefaultNetworkCallback2 != null
                 || mTestPackageDefaultNetworkCallback != null) {
             throw new IllegalStateException("Default network callbacks already registered");
         }
@@ -12257,12 +12268,18 @@
         mDefaultNetworkCallback = new TestNetworkCallback();
         mProfileDefaultNetworkCallback = new TestNetworkCallback();
         mTestPackageDefaultNetworkCallback = new TestNetworkCallback();
+        mProfileDefaultNetworkCallbackAsAppUid2 = new TestNetworkCallback();
+        mTestPackageDefaultNetworkCallback2 = new TestNetworkCallback();
         mCm.registerSystemDefaultNetworkCallback(mSystemDefaultNetworkCallback,
                 new Handler(ConnectivityThread.getInstanceLooper()));
         mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback);
         registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallback,
                 TEST_WORK_PROFILE_APP_UID);
         registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback, TEST_PACKAGE_UID);
+        registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallbackAsAppUid2,
+                TEST_WORK_PROFILE_APP_UID_2);
+        registerDefaultNetworkCallbackAsUid(mTestPackageDefaultNetworkCallback2,
+                TEST_PACKAGE_UID2);
         // TODO: test using ConnectivityManager#registerDefaultNetworkCallbackAsUid as well.
         mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED);
     }
@@ -12280,6 +12297,12 @@
         if (null != mTestPackageDefaultNetworkCallback) {
             mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback);
         }
+        if (null != mProfileDefaultNetworkCallbackAsAppUid2) {
+            mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallbackAsAppUid2);
+        }
+        if (null != mTestPackageDefaultNetworkCallback2) {
+            mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback2);
+        }
     }
 
     private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(
@@ -13708,10 +13731,34 @@
     }
 
     private UidRangeParcel[] uidRangeFor(final UserHandle handle) {
-        UidRange range = UidRange.createForUser(handle);
+        final UidRange range = UidRange.createForUser(handle);
         return new UidRangeParcel[] { new UidRangeParcel(range.start, range.stop) };
     }
 
+    private UidRangeParcel[] uidRangeFor(final UserHandle handle,
+            ProfileNetworkPreference profileNetworkPreference) {
+        final Set<UidRange> uidRangeSet;
+        UidRange range = UidRange.createForUser(handle);
+        if (profileNetworkPreference.getIncludedUids().size() != 0) {
+            uidRangeSet = UidRangeUtils.convertListToUidRange(
+                    profileNetworkPreference.getIncludedUids());
+        } else if (profileNetworkPreference.getExcludedUids().size() != 0)  {
+            uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange(
+                    range, UidRangeUtils.convertListToUidRange(
+                            profileNetworkPreference.getExcludedUids()));
+        } else {
+            uidRangeSet = new ArraySet<>();
+            uidRangeSet.add(range);
+        }
+        UidRangeParcel[] uidRangeParcels = new UidRangeParcel[uidRangeSet.size()];
+        int i = 0;
+        for (UidRange range1 : uidRangeSet) {
+            uidRangeParcels[i] = new UidRangeParcel(range1.start, range1.stop);
+            i++;
+        }
+        return uidRangeParcels;
+    }
+
     private static class TestOnCompleteListener implements Runnable {
         final class OnComplete {}
         final ArrayTrackRecord<OnComplete>.ReadHead mHistory =
@@ -13734,6 +13781,14 @@
         return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc);
     }
 
+    private TestNetworkAgentWrapper makeEnterpriseNetworkAgent(int enterpriseId) throws Exception {
+        final NetworkCapabilities workNc = new NetworkCapabilities();
+        workNc.addCapability(NET_CAPABILITY_ENTERPRISE);
+        workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+        workNc.addEnterpriseId(enterpriseId);
+        return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc);
+    }
+
     private TestNetworkCallback mEnterpriseCallback;
     private UserHandle setupEnterpriseNetwork() {
         final UserHandle userHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID);
@@ -13762,21 +13817,27 @@
      */
     public void testPreferenceForUserNetworkUpDownForGivenPreference(
             ProfileNetworkPreference profileNetworkPreference,
-            boolean connectWorkProfileAgentAhead) throws Exception {
+            boolean connectWorkProfileAgentAhead,
+            UserHandle testHandle,
+            TestNetworkCallback profileDefaultNetworkCallback,
+            TestNetworkCallback disAllowProfileDefaultNetworkCallback) throws Exception {
         final InOrder inOrder = inOrder(mMockNetd);
-        final UserHandle testHandle = setupEnterpriseNetwork();
-        registerDefaultNetworkCallbacks();
 
         mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
 
         mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
-        mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        profileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            disAllowProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(
+                    mCellNetworkAgent);
+        }
         inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical(
                 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE));
 
-        final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent();
+        final TestNetworkAgentWrapper workAgent =
+                makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId());
         if (connectWorkProfileAgentAhead) {
             workAgent.connect(false);
         }
@@ -13790,7 +13851,7 @@
                 == PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK) {
             allowFallback = false;
         }
-        if (allowFallback) {
+        if (allowFallback && !connectWorkProfileAgentAhead) {
             // Setting a network preference for this user will create a new set of routing rules for
             // the UID range that corresponds to this user, inorder to define the default network
             // for these apps separately. This is true because the multi-layer request relevant to
@@ -13800,33 +13861,43 @@
             // system default is not handled specially, the rules are always active as long as
             // a preference is set.
             inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
-                    mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle),
+                    mCellNetworkAgent.getNetwork().netId,
+                    uidRangeFor(testHandle, profileNetworkPreference),
                     PREFERENCE_ORDER_PROFILE));
         }
 
         // The enterprise network is not ready yet.
         assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback);
-        if (allowFallback) {
-            assertNoCallbacks(mProfileDefaultNetworkCallback);
+        if (allowFallback && !connectWorkProfileAgentAhead) {
+            assertNoCallbacks(profileDefaultNetworkCallback);
         } else if (!connectWorkProfileAgentAhead) {
-            mProfileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+            profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+            if (disAllowProfileDefaultNetworkCallback != null) {
+                assertNoCallbacks(disAllowProfileDefaultNetworkCallback);
+            }
         }
 
         if (!connectWorkProfileAgentAhead) {
             workAgent.connect(false);
         }
 
-        mProfileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent);
+        profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent);
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            disAllowProfileDefaultNetworkCallback.assertNoCallback();
+        }
         mSystemDefaultNetworkCallback.assertNoCallback();
         mDefaultNetworkCallback.assertNoCallback();
         inOrder.verify(mMockNetd).networkCreate(
                 nativeNetworkConfigPhysical(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM));
         inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
-                workAgent.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE));
+                workAgent.getNetwork().netId,
+                uidRangeFor(testHandle, profileNetworkPreference),
+                PREFERENCE_ORDER_PROFILE));
 
-        if (allowFallback) {
+        if (allowFallback && !connectWorkProfileAgentAhead) {
             inOrder.verify(mMockNetd).networkRemoveUidRangesParcel(new NativeUidRangeConfig(
-                    mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle),
+                    mCellNetworkAgent.getNetwork().netId,
+                    uidRangeFor(testHandle, profileNetworkPreference),
                     PREFERENCE_ORDER_PROFILE));
         }
 
@@ -13834,14 +13905,23 @@
         // not to the other apps.
         workAgent.setNetworkValid(true /* isStrictMode */);
         workAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
-        mProfileDefaultNetworkCallback.expectCapabilitiesThat(workAgent,
+        profileDefaultNetworkCallback.expectCapabilitiesThat(workAgent,
                 nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED)
-                        && nc.hasCapability(NET_CAPABILITY_ENTERPRISE));
+                        && nc.hasCapability(NET_CAPABILITY_ENTERPRISE)
+                        && nc.hasEnterpriseId(
+                                profileNetworkPreference.getPreferenceEnterpriseId())
+                        && nc.getEnterpriseIds().length == 1);
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            assertNoCallbacks(disAllowProfileDefaultNetworkCallback);
+        }
         assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback);
 
         workAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
-        mProfileDefaultNetworkCallback.expectCapabilitiesThat(workAgent, nc ->
+        profileDefaultNetworkCallback.expectCapabilitiesThat(workAgent, nc ->
                 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            assertNoCallbacks(disAllowProfileDefaultNetworkCallback);
+        }
         assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback);
 
         // Conversely, change a capability on the system-wide default network and make sure
@@ -13851,7 +13931,11 @@
                 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
         mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc ->
                 nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-        mProfileDefaultNetworkCallback.assertNoCallback();
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            disAllowProfileDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc ->
+                    nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+        }
+        profileDefaultNetworkCallback.assertNoCallback();
 
         // Disconnect and reconnect the system-wide default network and make sure that the
         // apps on this network see the appropriate callbacks, and the app on the work profile
@@ -13859,28 +13943,41 @@
         mCellNetworkAgent.disconnect();
         mSystemDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
         mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
-        mProfileDefaultNetworkCallback.assertNoCallback();
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            disAllowProfileDefaultNetworkCallback.expectCallback(
+                    CallbackEntry.LOST, mCellNetworkAgent);
+        }
+        profileDefaultNetworkCallback.assertNoCallback();
         inOrder.verify(mMockNetd).networkDestroy(mCellNetworkAgent.getNetwork().netId);
 
         mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
         mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
-        mProfileDefaultNetworkCallback.assertNoCallback();
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            disAllowProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(
+                    mCellNetworkAgent);
+
+        }
+        profileDefaultNetworkCallback.assertNoCallback();
         inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical(
                 mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE));
 
         // When the agent disconnects, test that the app on the work profile falls back to the
         // default network.
         workAgent.disconnect();
-        mProfileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent);
+        profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent);
         if (allowFallback) {
-            mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+            profileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+            if (disAllowProfileDefaultNetworkCallback != null) {
+                assertNoCallbacks(disAllowProfileDefaultNetworkCallback);
+            }
         }
         assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback);
         if (allowFallback) {
             inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
-                    mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle),
+                    mCellNetworkAgent.getNetwork().netId,
+                    uidRangeFor(testHandle, profileNetworkPreference),
                     PREFERENCE_ORDER_PROFILE));
         }
         inOrder.verify(mMockNetd).networkDestroy(workAgent.getNetwork().netId);
@@ -13888,8 +13985,12 @@
         mCellNetworkAgent.disconnect();
         mSystemDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
         mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            disAllowProfileDefaultNetworkCallback.expectCallback(
+                    CallbackEntry.LOST, mCellNetworkAgent);
+        }
         if (allowFallback) {
-            mProfileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+            profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
         }
 
         // Waiting for the handler to be idle before checking for networkDestroy is necessary
@@ -13900,33 +14001,47 @@
         // If the control comes here, callbacks seem to behave correctly in the presence of
         // a default network when the enterprise network goes up and down. Now, make sure they
         // also behave correctly in the absence of a system-wide default network.
-        final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent();
+        final TestNetworkAgentWrapper workAgent2 =
+                makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId());
         workAgent2.connect(false);
 
-        mProfileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent2);
+        profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent2);
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            assertNoCallbacks(disAllowProfileDefaultNetworkCallback);
+        }
         assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback);
         inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical(
                 workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM));
         inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
-                workAgent2.getNetwork().netId, uidRangeFor(testHandle), PREFERENCE_ORDER_PROFILE));
+                workAgent2.getNetwork().netId,
+                uidRangeFor(testHandle, profileNetworkPreference), PREFERENCE_ORDER_PROFILE));
 
         workAgent2.setNetworkValid(true /* isStrictMode */);
         workAgent2.mNetworkMonitor.forceReevaluation(Process.myUid());
-        mProfileDefaultNetworkCallback.expectCapabilitiesThat(workAgent2,
+        profileDefaultNetworkCallback.expectCapabilitiesThat(workAgent2,
                 nc -> nc.hasCapability(NET_CAPABILITY_ENTERPRISE)
-                        && !nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
+                        && !nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
+                        && nc.hasEnterpriseId(
+                        profileNetworkPreference.getPreferenceEnterpriseId())
+                        && nc.getEnterpriseIds().length == 1);
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            assertNoCallbacks(disAllowProfileDefaultNetworkCallback);
+        }
         assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback);
         inOrder.verify(mMockNetd, never()).networkAddUidRangesParcel(any());
 
         // When the agent disconnects, test that the app on the work profile fall back to the
         // default network.
         workAgent2.disconnect();
-        mProfileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent2);
+        profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent2);
+        if (disAllowProfileDefaultNetworkCallback != null) {
+            assertNoCallbacks(disAllowProfileDefaultNetworkCallback);
+        }
         assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback);
         inOrder.verify(mMockNetd).networkDestroy(workAgent2.getNetwork().netId);
 
         assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback,
-                mProfileDefaultNetworkCallback);
+                profileDefaultNetworkCallback);
 
         // Callbacks will be unregistered by tearDown()
     }
@@ -13938,11 +14053,15 @@
      */
     @Test
     public void testPreferenceForUserNetworkUpDown() throws Exception {
+        final UserHandle testHandle = setupEnterpriseNetwork();
+        registerDefaultNetworkCallbacks();
         ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
                 new ProfileNetworkPreference.Builder();
         profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
         testPreferenceForUserNetworkUpDownForGivenPreference(
-                profileNetworkPreferenceBuilder.build(), false);
+                profileNetworkPreferenceBuilder.build(), false,
+                testHandle, mProfileDefaultNetworkCallback, null);
     }
 
     /**
@@ -13952,12 +14071,16 @@
      */
     @Test
     public void testPreferenceForUserNetworkUpDownWithNoFallback() throws Exception {
+        final UserHandle testHandle = setupEnterpriseNetwork();
         ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
                 new ProfileNetworkPreference.Builder();
         profileNetworkPreferenceBuilder.setPreference(
                 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        registerDefaultNetworkCallbacks();
         testPreferenceForUserNetworkUpDownForGivenPreference(
-                profileNetworkPreferenceBuilder.build(), false);
+                profileNetworkPreferenceBuilder.build(), false,
+                testHandle, mProfileDefaultNetworkCallback, null);
     }
 
     /**
@@ -13969,12 +14092,227 @@
     @Test
     public void testPreferenceForUserNetworkUpDownWithNoFallbackWithAlreadyConnectedWorkAgent()
             throws Exception {
+        final UserHandle testHandle = setupEnterpriseNetwork();
         ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
                 new ProfileNetworkPreference.Builder();
         profileNetworkPreferenceBuilder.setPreference(
                 PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        registerDefaultNetworkCallbacks();
         testPreferenceForUserNetworkUpDownForGivenPreference(
-                profileNetworkPreferenceBuilder.build(), true);
+                profileNetworkPreferenceBuilder.build(), true, testHandle,
+                mProfileDefaultNetworkCallback, null);
+    }
+
+    /**
+     * Make sure per-profile networking preference for specific uid of test handle
+     * behaves as expected
+     */
+    @Test
+    public void testPreferenceForDefaultUidOfTestHandle() throws Exception {
+        final UserHandle testHandle = setupEnterpriseNetwork();
+        ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        profileNetworkPreferenceBuilder.setIncludedUids(
+                List.of(testHandle.getUid(TEST_WORK_PROFILE_APP_UID)));
+        registerDefaultNetworkCallbacks();
+        testPreferenceForUserNetworkUpDownForGivenPreference(
+                profileNetworkPreferenceBuilder.build(), false, testHandle,
+                mProfileDefaultNetworkCallback, null);
+    }
+
+    /**
+     * Make sure per-profile networking preference for specific uid of test handle
+     * behaves as expected
+     */
+    @Test
+    public void testPreferenceForSpecificUidOfOnlyOneApp() throws Exception {
+        final UserHandle testHandle = setupEnterpriseNetwork();
+        ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        profileNetworkPreferenceBuilder.setIncludedUids(
+                List.of(testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)));
+        registerDefaultNetworkCallbacks();
+        testPreferenceForUserNetworkUpDownForGivenPreference(
+                profileNetworkPreferenceBuilder.build(), false,
+                testHandle, mProfileDefaultNetworkCallbackAsAppUid2, null);
+    }
+
+    /**
+     * Make sure per-profile networking preference for specific uid of test handle
+     * behaves as expected
+     */
+    @Test
+    public void testPreferenceForDisallowSpecificUidOfApp() throws Exception {
+        final UserHandle testHandle = setupEnterpriseNetwork();
+        ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        profileNetworkPreferenceBuilder.setExcludedUids(
+                List.of(testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)));
+        registerDefaultNetworkCallbacks();
+        testPreferenceForUserNetworkUpDownForGivenPreference(
+                profileNetworkPreferenceBuilder.build(), false,
+                testHandle, mProfileDefaultNetworkCallback,
+                mProfileDefaultNetworkCallbackAsAppUid2);
+    }
+
+    /**
+     * Make sure per-profile networking preference for specific uid of test handle
+     * invalid uid inputs
+     */
+    @Test
+    public void testPreferenceForInvalidUids() throws Exception {
+        final UserHandle testHandle = setupEnterpriseNetwork();
+        ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        profileNetworkPreferenceBuilder.setExcludedUids(
+                List.of(testHandle.getUid(0) - 1));
+        final TestOnCompleteListener listener = new TestOnCompleteListener();
+        Assert.assertThrows(IllegalArgumentException.class, () -> mCm.setProfileNetworkPreferences(
+                testHandle, List.of(profileNetworkPreferenceBuilder.build()),
+                r -> r.run(), listener));
+
+        profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        profileNetworkPreferenceBuilder.setIncludedUids(
+                List.of(testHandle.getUid(0) - 1));
+        Assert.assertThrows(IllegalArgumentException.class,
+                () -> mCm.setProfileNetworkPreferences(
+                        testHandle, List.of(profileNetworkPreferenceBuilder.build()),
+                        r -> r.run(), listener));
+
+
+        profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        profileNetworkPreferenceBuilder.setIncludedUids(
+                List.of(testHandle.getUid(0) - 1));
+        profileNetworkPreferenceBuilder.setExcludedUids(
+                List.of(testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)));
+        Assert.assertThrows(IllegalArgumentException.class,
+                () -> mCm.setProfileNetworkPreferences(
+                        testHandle, List.of(profileNetworkPreferenceBuilder.build()),
+                        r -> r.run(), listener));
+
+        ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder2 =
+                new ProfileNetworkPreference.Builder();
+        profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        profileNetworkPreferenceBuilder2.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        profileNetworkPreferenceBuilder2.setIncludedUids(
+                List.of(testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)));
+        profileNetworkPreferenceBuilder.setIncludedUids(
+                List.of(testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)));
+        Assert.assertThrows(IllegalArgumentException.class,
+                () -> mCm.setProfileNetworkPreferences(
+                        testHandle, List.of(profileNetworkPreferenceBuilder.build(),
+                                profileNetworkPreferenceBuilder2.build()),
+                        r -> r.run(), listener));
+
+        profileNetworkPreferenceBuilder2.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        profileNetworkPreferenceBuilder2.setExcludedUids(
+                List.of(testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)));
+        profileNetworkPreferenceBuilder.setExcludedUids(
+                List.of(testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)));
+        Assert.assertThrows(IllegalArgumentException.class,
+                () -> mCm.setProfileNetworkPreferences(
+                        testHandle, List.of(profileNetworkPreferenceBuilder.build(),
+                                profileNetworkPreferenceBuilder2.build()),
+                        r -> r.run(), listener));
+
+        profileNetworkPreferenceBuilder2.setPreference(
+                PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
+        profileNetworkPreferenceBuilder2.setExcludedUids(
+                List.of(testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)));
+        profileNetworkPreferenceBuilder.setExcludedUids(
+                List.of(testHandle.getUid(TEST_WORK_PROFILE_APP_UID_2)));
+        Assert.assertThrows(IllegalArgumentException.class,
+                () -> mCm.setProfileNetworkPreferences(
+                        testHandle, List.of(profileNetworkPreferenceBuilder.build(),
+                                profileNetworkPreferenceBuilder2.build()),
+                        r -> r.run(), listener));
+    }
+
+    /**
+     * Make sure per-profile networking preference behaves as expected when the enterprise network
+     * goes up and down while the preference is active. Make sure they behave as expected whether
+     * there is a general default network or not when configured to fallback to default network
+     * along with already connected enterprise work agent
+     */
+    @Test
+    public void testPreferenceForUserNetworkUpDownWithFallbackWithAlreadyConnectedWorkAgent()
+            throws Exception {
+        final UserHandle testHandle = setupEnterpriseNetwork();
+        ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        registerDefaultNetworkCallbacks();
+        testPreferenceForUserNetworkUpDownForGivenPreference(
+                profileNetworkPreferenceBuilder.build(), true,
+                testHandle, mProfileDefaultNetworkCallback,
+                null);
+    }
+
+    /**
+     * Make sure per-profile networking preference behaves as expected when the enterprise network
+     * goes up and down while the preference is active for a given enterprise identifier
+     */
+    @Test
+    public void testPreferenceForUserNetworkUpDownWithDefaultEnterpriseId()
+            throws Exception {
+        final UserHandle testHandle = setupEnterpriseNetwork();
+        ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        profileNetworkPreferenceBuilder.setPreference(
+                PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        registerDefaultNetworkCallbacks();
+        testPreferenceForUserNetworkUpDownForGivenPreference(
+                profileNetworkPreferenceBuilder.build(), true,
+                testHandle, mProfileDefaultNetworkCallback,
+                null);
+    }
+
+    /**
+     * Make sure per-profile networking preference behaves as expected when the enterprise network
+     * goes up and down while the preference is active for a given enterprise identifier
+     */
+    @Test
+    public void testPreferenceForUserNetworkUpDownWithId2()
+            throws Exception {
+        final UserHandle testHandle = setupEnterpriseNetwork();
+        ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        profileNetworkPreferenceBuilder.setPreference(
+                PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(
+                NetworkCapabilities.NET_ENTERPRISE_ID_2);
+        registerDefaultNetworkCallbacks();
+        testPreferenceForUserNetworkUpDownForGivenPreference(
+                profileNetworkPreferenceBuilder.build(), true,
+                testHandle, mProfileDefaultNetworkCallback, null);
+    }
+
+    /**
+     * Make sure per-profile networking preference behaves as expected when the enterprise network
+     * goes up and down while the preference is active for a given enterprise identifier
+     */
+    @Test
+    public void testPreferenceForUserNetworkUpDownWithInvalidId()
+            throws Exception {
+        ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        profileNetworkPreferenceBuilder.setPreference(
+                PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(0);
+        registerDefaultNetworkCallbacks();
+        assertThrows("Should not be able to set invalid enterprise id",
+                IllegalStateException.class, () -> profileNetworkPreferenceBuilder.build());
     }
 
     /**
@@ -14127,10 +14465,15 @@
     public void testProfileNetworkPrefWrongPreference() throws Exception {
         final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID);
         mServiceContext.setWorkProfile(testHandle, true);
+        ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        profileNetworkPreferenceBuilder.setPreference(
+                PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK + 1);
+        profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
         assertThrows("Should not be able to set an illegal preference",
                 IllegalArgumentException.class,
-                () -> mCm.setProfileNetworkPreference(testHandle,
-                        PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK + 1,
+                () -> mCm.setProfileNetworkPreferences(testHandle,
+                        List.of(profileNetworkPreferenceBuilder.build()),
                         null, null));
     }
 
diff --git a/tests/unit/java/com/android/server/NetworkManagementServiceTest.java b/tests/unit/java/com/android/server/NetworkManagementServiceTest.java
index ea29da0..0c58582 100644
--- a/tests/unit/java/com/android/server/NetworkManagementServiceTest.java
+++ b/tests/unit/java/com/android/server/NetworkManagementServiceTest.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -32,6 +33,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.net.ConnectivityManager;
 import android.net.INetd;
 import android.net.INetdUnsolicitedEventListener;
 import android.net.LinkAddress;
@@ -71,6 +73,7 @@
 public class NetworkManagementServiceTest {
     private NetworkManagementService mNMService;
     @Mock private Context mContext;
+    @Mock private ConnectivityManager mCm;
     @Mock private IBatteryStats.Stub mBatteryStatsService;
     @Mock private INetd.Stub mNetdService;
 
@@ -113,6 +116,9 @@
         MockitoAnnotations.initMocks(this);
         doNothing().when(mNetdService)
                 .registerUnsolicitedEventListener(mUnsolListenerCaptor.capture());
+        doReturn(Context.CONNECTIVITY_SERVICE).when(mContext).getSystemServiceName(
+                eq(ConnectivityManager.class));
+        doReturn(mCm).when(mContext).getSystemService(eq(Context.CONNECTIVITY_SERVICE));
         // Start the service and wait until it connects to our socket.
         mNMService = NetworkManagementService.create(mContext, mDeps);
     }
@@ -239,6 +245,7 @@
         mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, true);
         assertTrue("Should be true since mobile data usage is restricted",
                 mNMService.isNetworkRestricted(TEST_UID));
+        verify(mCm).updateMeteredNetworkDenyList(TEST_UID, true /* enabled */);
 
         mNMService.setDataSaverModeEnabled(true);
         verify(mNetdService).bandwidthEnableDataSaver(true);
@@ -246,13 +253,16 @@
         mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, false);
         assertTrue("Should be true since data saver is on and the uid is not allowlisted",
                 mNMService.isNetworkRestricted(TEST_UID));
+        verify(mCm).updateMeteredNetworkDenyList(TEST_UID, true /* false */);
 
         mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, true);
         assertFalse("Should be false since data saver is on and the uid is allowlisted",
                 mNMService.isNetworkRestricted(TEST_UID));
+        verify(mCm).updateMeteredNetworkAllowList(TEST_UID, true /* enabled */);
 
         // remove uid from allowlist and turn datasaver off again
         mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, false);
+        verify(mCm).updateMeteredNetworkAllowList(TEST_UID, false /* enabled */);
         mNMService.setDataSaverModeEnabled(false);
         verify(mNetdService).bandwidthEnableDataSaver(false);
         assertFalse("Network should not be restricted when data saver is off",
@@ -306,12 +316,14 @@
         for (int chain : chains) {
             final ArrayMap<Integer, Boolean> expectedValues = expected.get(chain);
             mNMService.setFirewallChainEnabled(chain, true);
+            verify(mCm).setFirewallChainEnabled(chain, true /* enabled */);
             for (int state : states) {
                 mNMService.setFirewallUidRule(chain, TEST_UID, state);
                 assertEquals(errorMsg.apply(chain, state),
                         expectedValues.get(state), mNMService.isNetworkRestricted(TEST_UID));
             }
             mNMService.setFirewallChainEnabled(chain, false);
+            verify(mCm).setFirewallChainEnabled(chain, false /* enabled */);
         }
     }
 }
diff --git a/tests/unit/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java b/tests/unit/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
index c86e699..ec51537 100644
--- a/tests/unit/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
@@ -296,7 +296,7 @@
                 false /* roaming */);
 
         verify(mStatsManager, times(1)).registerUsageCallback(
-                any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any());
+                any(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any());
     }
 
     @Test
@@ -315,7 +315,7 @@
 
         // Daily budget should be 15MB (5% of daily quota), 7MB used today: callback set for 8MB
         verify(mStatsManager, times(1)).registerUsageCallback(
-                any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any());
+                any(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any());
     }
 
     @Test
@@ -334,7 +334,7 @@
 
         // Daily budget should be 15MB (5% of daily quota), 7MB used today: callback set for 8MB
         verify(mStatsManager, times(1)).registerUsageCallback(
-                any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any());
+                any(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any());
     }
 
     @Test
@@ -351,7 +351,7 @@
 
         // Default global setting should be used: 12 - 7 = 5
         verify(mStatsManager, times(1)).registerUsageCallback(
-                any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(5)), any(), any());
+                any(), eq(DataUnit.MEGABYTES.toBytes(5)), any(), any());
     }
 
     @Test
@@ -366,7 +366,7 @@
                 false /* roaming */);
 
         verify(mStatsManager, times(1)).registerUsageCallback(
-                any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any());
+                any(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any());
 
         // Update setting
         setDefaultQuotaGlobalSetting(DataUnit.MEGABYTES.toBytes(14));
@@ -376,7 +376,7 @@
         // Callback must have been re-registered with new setting
         verify(mStatsManager, times(1)).unregisterUsageCallback(any());
         verify(mStatsManager, times(1)).registerUsageCallback(
-                any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any());
+                any(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any());
     }
 
     @Test
@@ -391,7 +391,7 @@
                 false /* roaming */);
 
         verify(mStatsManager, times(1)).registerUsageCallback(
-                any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any());
+                any(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any());
 
         when(mResources.getInteger(R.integer.config_networkDefaultDailyMultipathQuotaBytes))
                 .thenReturn((int) DataUnit.MEGABYTES.toBytes(16));
@@ -402,6 +402,6 @@
 
         // Uses the new setting (16 - 2 = 14MB)
         verify(mStatsManager, times(1)).registerUsageCallback(
-                any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(14)), any(), any());
+                any(), eq(DataUnit.MEGABYTES.toBytes(14)), any(), any());
     }
 }
diff --git a/tests/unit/java/com/android/server/connectivity/UidRangeUtilsTest.java b/tests/unit/java/com/android/server/connectivity/UidRangeUtilsTest.java
new file mode 100644
index 0000000..b8c2673
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/UidRangeUtilsTest.java
@@ -0,0 +1,354 @@
+/*
+ * 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.server.connectivity;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.UidRange;
+import android.os.Build;
+import android.util.ArraySet;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Tests for UidRangeUtils.
+ *
+ * Build, install and run with:
+ *  runtest frameworks-net -c com.android.server.connectivity.UidRangeUtilsTest
+ */
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+public class UidRangeUtilsTest {
+    private static void assertInSameRange(@NonNull final String msg,
+            @Nullable final UidRange r1,
+            @Nullable final Set<UidRange> s2) {
+        assertTrue(msg + " : " + s2 + " unexpectedly is not in range of " + r1,
+                UidRangeUtils.isRangeSetInUidRange(r1, s2));
+    }
+
+    private static void assertNotInSameRange(@NonNull final String msg,
+            @Nullable final UidRange r1, @Nullable final Set<UidRange> s2) {
+        assertFalse(msg + " : " + s2 + " unexpectedly is in range of " + r1,
+                UidRangeUtils.isRangeSetInUidRange(r1, s2));
+    }
+
+    @Test @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testRangeSetInUidRange() {
+        final UidRange uids1 = new UidRange(1, 100);
+        final UidRange uids2 = new UidRange(3, 300);
+        final UidRange uids3 = new UidRange(1, 1000);
+        final UidRange uids4 = new UidRange(1, 100);
+        final UidRange uids5 = new UidRange(2, 20);
+        final UidRange uids6 = new UidRange(3, 30);
+
+        assertThrows(NullPointerException.class,
+                () -> UidRangeUtils.isRangeSetInUidRange(null, null));
+        assertThrows(NullPointerException.class,
+                () -> UidRangeUtils.isRangeSetInUidRange(uids1, null));
+
+        final ArraySet<UidRange> set1 = new ArraySet<>();
+        final ArraySet<UidRange> set2 = new ArraySet<>();
+
+        assertThrows(NullPointerException.class,
+                () -> UidRangeUtils.isRangeSetInUidRange(null, set1));
+        assertInSameRange("uids1 <=> empty", uids1, set2);
+
+        set2.add(uids1);
+        assertInSameRange("uids1 <=> uids1", uids1, set2);
+
+        set2.clear();
+        set2.add(uids2);
+        assertNotInSameRange("uids1 <=> uids2", uids1, set2);
+        set2.clear();
+        set2.add(uids3);
+        assertNotInSameRange("uids1 <=> uids3", uids1, set2);
+        set2.clear();
+        set2.add(uids4);
+        assertInSameRange("uids1 <=> uids4", uids1, set2);
+
+        set2.clear();
+        set2.add(uids5);
+        set2.add(uids6);
+        assertInSameRange("uids1 <=> uids5, 6", uids1, set2);
+
+        set2.clear();
+        set2.add(uids2);
+        set2.add(uids6);
+        assertNotInSameRange("uids1 <=> uids2, 6", uids1, set2);
+    }
+
+    @Test @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testRemoveRangeSetFromUidRange() {
+        final UidRange uids1 = new UidRange(1, 100);
+        final UidRange uids2 = new UidRange(3, 300);
+        final UidRange uids3 = new UidRange(1, 1000);
+        final UidRange uids4 = new UidRange(1, 100);
+        final UidRange uids5 = new UidRange(2, 20);
+        final UidRange uids6 = new UidRange(3, 30);
+        final UidRange uids7 = new UidRange(30, 39);
+
+        final UidRange uids8 = new UidRange(1, 1);
+        final UidRange uids9 = new UidRange(21, 100);
+        final UidRange uids10 = new UidRange(1, 2);
+        final UidRange uids11 = new UidRange(31, 100);
+
+        final UidRange uids12 = new UidRange(1, 1);
+        final UidRange uids13 = new UidRange(21, 29);
+        final UidRange uids14 = new UidRange(40, 100);
+
+        final UidRange uids15 = new UidRange(3, 30);
+        final UidRange uids16 = new UidRange(31, 39);
+
+        assertThrows(NullPointerException.class,
+                () -> UidRangeUtils.removeRangeSetFromUidRange(null, null));
+        Set<UidRange> expected = new ArraySet<>();
+        expected.add(uids1);
+        assertThrows(NullPointerException.class,
+                () -> UidRangeUtils.removeRangeSetFromUidRange(uids1, null));
+        assertEquals(expected, UidRangeUtils.removeRangeSetFromUidRange(uids1, new ArraySet<>()));
+
+        expected.clear();
+        final ArraySet<UidRange> set2 = new ArraySet<>();
+        set2.add(uids1);
+        assertEquals(expected, UidRangeUtils.removeRangeSetFromUidRange(uids1, set2));
+        set2.clear();
+        set2.add(uids4);
+        assertEquals(expected, UidRangeUtils.removeRangeSetFromUidRange(uids1, set2));
+
+        expected.add(uids10);
+        set2.clear();
+        set2.add(uids2);
+        assertEquals(expected, UidRangeUtils.removeRangeSetFromUidRange(uids1, set2));
+
+        expected.clear();
+        set2.clear();
+        set2.add(uids3);
+        assertEquals(expected, UidRangeUtils.removeRangeSetFromUidRange(uids1, set2));
+
+        set2.clear();
+        set2.add(uids3);
+        set2.add(uids6);
+        assertThrows(IllegalArgumentException.class,
+                () -> UidRangeUtils.removeRangeSetFromUidRange(uids1, set2));
+
+        expected.clear();
+        expected.add(uids8);
+        expected.add(uids9);
+        set2.clear();
+        set2.add(uids5);
+        assertEquals(expected, UidRangeUtils.removeRangeSetFromUidRange(uids1, set2));
+
+        expected.clear();
+        expected.add(uids10);
+        expected.add(uids11);
+        set2.clear();
+        set2.add(uids6);
+        assertEquals(expected, UidRangeUtils.removeRangeSetFromUidRange(uids1, set2));
+
+        expected.clear();
+        expected.add(uids12);
+        expected.add(uids13);
+        expected.add(uids14);
+        set2.clear();
+        set2.add(uids5);
+        set2.add(uids7);
+        assertEquals(expected, UidRangeUtils.removeRangeSetFromUidRange(uids1, set2));
+
+        expected.clear();
+        expected.add(uids10);
+        expected.add(uids14);
+        set2.clear();
+        set2.add(uids15);
+        set2.add(uids16);
+        assertEquals(expected, UidRangeUtils.removeRangeSetFromUidRange(uids1, set2));
+    }
+
+    private static void assertRangeOverlaps(@NonNull final String msg,
+            @Nullable final Set<UidRange> s1,
+            @Nullable final Set<UidRange> s2) {
+        assertTrue(msg + " : " + s2 + " unexpectedly does not overlap with " + s1,
+                UidRangeUtils.doesRangeSetOverlap(s1, s2));
+    }
+
+    private static void assertRangeDoesNotOverlap(@NonNull final String msg,
+            @Nullable final Set<UidRange> s1, @Nullable final Set<UidRange> s2) {
+        assertFalse(msg + " : " + s2 + " unexpectedly ovelaps with " + s1,
+                UidRangeUtils.doesRangeSetOverlap(s1, s2));
+    }
+
+    @Test @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testRangeSetOverlap() {
+        final UidRange uids1 = new UidRange(1, 100);
+        final UidRange uids2 = new UidRange(3, 300);
+        final UidRange uids3 = new UidRange(1, 1000);
+        final UidRange uids4 = new UidRange(1, 100);
+        final UidRange uids5 = new UidRange(2, 20);
+        final UidRange uids6 = new UidRange(3, 30);
+        final UidRange uids7 = new UidRange(0, 0);
+        final UidRange uids8 = new UidRange(1, 500);
+        final UidRange uids9 = new UidRange(101, 200);
+
+        assertThrows(NullPointerException.class,
+                () -> UidRangeUtils.doesRangeSetOverlap(null, null));
+
+        final ArraySet<UidRange> set1 = new ArraySet<>();
+        final ArraySet<UidRange> set2 = new ArraySet<>();
+        assertThrows(NullPointerException.class,
+                () -> UidRangeUtils.doesRangeSetOverlap(set1, null));
+        assertThrows(NullPointerException.class,
+                () -> UidRangeUtils.doesRangeSetOverlap(null, set2));
+        assertRangeDoesNotOverlap("empty <=> null", set1, set2);
+
+        set2.add(uids1);
+        set1.add(uids1);
+        assertRangeOverlaps("uids1 <=> uids1", set1, set2);
+
+        set1.clear();
+        set1.add(uids1);
+        set2.clear();
+        set2.add(uids2);
+        assertRangeOverlaps("uids1 <=> uids2", set1, set2);
+
+        set1.clear();
+        set1.add(uids1);
+        set2.clear();
+        set2.add(uids3);
+        assertRangeOverlaps("uids1 <=> uids3", set1, set2);
+
+        set1.clear();
+        set1.add(uids1);
+        set2.clear();
+        set2.add(uids4);
+        assertRangeOverlaps("uids1 <=> uids4", set1, set2);
+
+        set1.clear();
+        set1.add(uids1);
+        set2.clear();
+        set2.add(uids5);
+        set2.add(uids6);
+        assertRangeOverlaps("uids1 <=> uids5,6", set1, set2);
+
+        set1.clear();
+        set1.add(uids1);
+        set2.clear();
+        set2.add(uids7);
+        assertRangeDoesNotOverlap("uids1 <=> uids7", set1, set2);
+
+        set1.clear();
+        set1.add(uids1);
+        set2.clear();
+        set2.add(uids9);
+        assertRangeDoesNotOverlap("uids1 <=> uids9", set1, set2);
+
+        set1.clear();
+        set1.add(uids1);
+        set2.clear();
+        set2.add(uids8);
+        assertRangeOverlaps("uids1 <=> uids8", set1, set2);
+
+
+        set1.clear();
+        set1.add(uids1);
+        set2.clear();
+        set2.add(uids8);
+        set2.add(uids7);
+        assertRangeOverlaps("uids1 <=> uids7, 8", set1, set2);
+    }
+
+    @Test @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testConvertListToUidRange() {
+        final UidRange uids1 = new UidRange(1, 1);
+        final UidRange uids2 = new UidRange(1, 2);
+        final UidRange uids3 = new UidRange(100, 100);
+        final UidRange uids4 = new UidRange(10, 10);
+
+        final UidRange uids5 = new UidRange(10, 14);
+        final UidRange uids6 = new UidRange(20, 24);
+
+        final Set<UidRange> expected = new ArraySet<>();
+        final List<Integer> input = new ArrayList<Integer>();
+
+        assertThrows(NullPointerException.class, () -> UidRangeUtils.convertListToUidRange(null));
+        assertEquals(expected, UidRangeUtils.convertListToUidRange(input));
+
+        input.add(1);
+        expected.add(uids1);
+        assertEquals(expected, UidRangeUtils.convertListToUidRange(input));
+
+        input.add(2);
+        expected.clear();
+        expected.add(uids2);
+        assertEquals(expected, UidRangeUtils.convertListToUidRange(input));
+
+        input.clear();
+        input.add(1);
+        input.add(100);
+        expected.clear();
+        expected.add(uids1);
+        expected.add(uids3);
+        assertEquals(expected, UidRangeUtils.convertListToUidRange(input));
+
+        input.clear();
+        input.add(100);
+        input.add(1);
+        expected.clear();
+        expected.add(uids1);
+        expected.add(uids3);
+        assertEquals(expected, UidRangeUtils.convertListToUidRange(input));
+
+        input.clear();
+        input.add(100);
+        input.add(1);
+        input.add(2);
+        input.add(1);
+        input.add(10);
+        expected.clear();
+        expected.add(uids2);
+        expected.add(uids4);
+        expected.add(uids3);
+        assertEquals(expected, UidRangeUtils.convertListToUidRange(input));
+
+        input.clear();
+        input.add(10);
+        input.add(11);
+        input.add(12);
+        input.add(13);
+        input.add(14);
+        input.add(20);
+        input.add(21);
+        input.add(22);
+        input.add(23);
+        input.add(24);
+        expected.clear();
+        expected.add(uids5);
+        expected.add(uids6);
+        assertEquals(expected, UidRangeUtils.convertListToUidRange(input));
+    }
+}
diff --git a/tests/unit/java/com/android/server/net/BpfInterfaceMapUpdaterTest.java b/tests/unit/java/com/android/server/net/BpfInterfaceMapUpdaterTest.java
new file mode 100644
index 0000000..987b7b7
--- /dev/null
+++ b/tests/unit/java/com/android/server/net/BpfInterfaceMapUpdaterTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.server.net;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.INetd;
+import android.net.MacAddress;
+import android.os.Handler;
+import android.os.test.TestLooper;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
+import com.android.net.module.util.IBpfMap;
+import com.android.net.module.util.InterfaceParams;
+import com.android.net.module.util.Struct.U32;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class BpfInterfaceMapUpdaterTest {
+    private static final int TEST_INDEX = 1;
+    private static final int TEST_INDEX2 = 2;
+    private static final String TEST_INTERFACE_NAME = "test1";
+    private static final String TEST_INTERFACE_NAME2 = "test2";
+
+    private final TestLooper mLooper = new TestLooper();
+    private BaseNetdUnsolicitedEventListener mListener;
+    private BpfInterfaceMapUpdater mUpdater;
+    @Mock private IBpfMap<U32, InterfaceMapValue> mBpfMap;
+    @Mock private INetd mNetd;
+    @Mock private Context mContext;
+
+    private class TestDependencies extends BpfInterfaceMapUpdater.Dependencies {
+        @Override
+        public IBpfMap<U32, InterfaceMapValue> getInterfaceMap() {
+            return mBpfMap;
+        }
+
+        @Override
+        public InterfaceParams getInterfaceParams(String ifaceName) {
+            if (ifaceName.equals(TEST_INTERFACE_NAME)) {
+                return new InterfaceParams(TEST_INTERFACE_NAME, TEST_INDEX,
+                        MacAddress.ALL_ZEROS_ADDRESS);
+            } else if (ifaceName.equals(TEST_INTERFACE_NAME2)) {
+                return new InterfaceParams(TEST_INTERFACE_NAME2, TEST_INDEX2,
+                        MacAddress.ALL_ZEROS_ADDRESS);
+            }
+
+            return null;
+        }
+
+        @Override
+        public INetd getINetd(Context ctx) {
+            return mNetd;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        when(mNetd.interfaceGetList()).thenReturn(new String[] {TEST_INTERFACE_NAME});
+        mUpdater = new BpfInterfaceMapUpdater(mContext, new Handler(mLooper.getLooper()),
+                new TestDependencies());
+    }
+
+    private void verifyStartUpdater() throws Exception {
+        mUpdater.start();
+        mLooper.dispatchAll();
+        final ArgumentCaptor<BaseNetdUnsolicitedEventListener> listenerCaptor =
+                ArgumentCaptor.forClass(BaseNetdUnsolicitedEventListener.class);
+        verify(mNetd).registerUnsolicitedEventListener(listenerCaptor.capture());
+        mListener = listenerCaptor.getValue();
+        verify(mBpfMap).updateEntry(eq(new U32(TEST_INDEX)),
+                eq(new InterfaceMapValue(TEST_INTERFACE_NAME)));
+    }
+
+    @Test
+    public void testUpdateInterfaceMap() throws Exception {
+        verifyStartUpdater();
+
+        mListener.onInterfaceAdded(TEST_INTERFACE_NAME2);
+        mLooper.dispatchAll();
+        verify(mBpfMap).updateEntry(eq(new U32(TEST_INDEX2)),
+                eq(new InterfaceMapValue(TEST_INTERFACE_NAME2)));
+
+        // Check that when onInterfaceRemoved is called, nothing happens.
+        mListener.onInterfaceRemoved(TEST_INTERFACE_NAME);
+        mLooper.dispatchAll();
+        verifyNoMoreInteractions(mBpfMap);
+    }
+}
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
index 8340a13..0e2c293 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -32,9 +32,12 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
 
+import android.content.Context;
 import android.content.res.Resources;
-import android.net.INetd;
+import android.net.ConnectivityManager;
 import android.net.NetworkStats;
 import android.net.TrafficStats;
 import android.net.UnderlyingNetworkInfo;
@@ -73,8 +76,8 @@
 
     private File mTestProc;
     private NetworkStatsFactory mFactory;
-    @Mock
-    private INetd mNetd;
+    @Mock private Context mContext;
+    @Mock private ConnectivityManager mCm;
 
     @Before
     public void setUp() throws Exception {
@@ -85,7 +88,10 @@
         // applications. So in order to have a test support native library, the native code
         // related to networkStatsFactory is compiled to a minimal native library and loaded here.
         System.loadLibrary("networkstatsfactorytestjni");
-        mFactory = new NetworkStatsFactory(mTestProc, false, mNetd);
+        doReturn(Context.CONNECTIVITY_SERVICE).when(mContext).getSystemServiceName(
+                eq(ConnectivityManager.class));
+        doReturn(mCm).when(mContext).getSystemService(eq(Context.CONNECTIVITY_SERVICE));
+        mFactory = new NetworkStatsFactory(mContext, mTestProc, false);
         mFactory.updateUnderlyingNetworkInfos(new UnderlyingNetworkInfo[0]);
     }
 
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
index 416549c..6a7da9e 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -29,25 +29,23 @@
 import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 
-import android.app.usage.NetworkStatsManager;
 import android.net.DataUsageRequest;
 import android.net.NetworkIdentity;
 import android.net.NetworkIdentitySet;
 import android.net.NetworkStats;
 import android.net.NetworkStatsAccess;
 import android.net.NetworkTemplate;
-import android.os.Build;
-import android.os.ConditionVariable;
-import android.os.Handler;
+import android.net.netstats.IUsageCallback;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Messenger;
 import android.os.Process;
 import android.os.UserHandle;
 import android.telephony.TelephonyManager;
@@ -55,7 +53,6 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.server.net.NetworkStatsServiceTest.LatchedHandler;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRunner;
 import com.android.testutils.HandlerUtils;
@@ -74,7 +71,7 @@
  */
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
 public class NetworkStatsObserversTest {
     private static final String TEST_IFACE = "test0";
     private static final String TEST_IFACE2 = "test1";
@@ -96,21 +93,15 @@
     private static final long WAIT_TIMEOUT_MS = 500;
     private static final long THRESHOLD_BYTES = 2 * MB_IN_BYTES;
     private static final long BASE_BYTES = 7 * MB_IN_BYTES;
-    private static final int INVALID_TYPE = -1;
-
-    private long mElapsedRealtime;
 
     private HandlerThread mObserverHandlerThread;
-    private Handler mObserverNoopHandler;
-
-    private LatchedHandler mHandler;
 
     private NetworkStatsObservers mStatsObservers;
-    private Messenger mMessenger;
     private ArrayMap<String, NetworkIdentitySet> mActiveIfaces;
     private ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces;
 
-    @Mock private IBinder mockBinder;
+    @Mock private IBinder mUsageCallbackBinder;
+    @Mock private IUsageCallback mUsageCallback;
 
     @Before
     public void setUp() throws Exception {
@@ -126,11 +117,9 @@
             }
         };
 
-        mHandler = new LatchedHandler(Looper.getMainLooper(), new ConditionVariable());
-        mMessenger = new Messenger(mHandler);
-
         mActiveIfaces = new ArrayMap<>();
         mActiveUidIfaces = new ArrayMap<>();
+        Mockito.when(mUsageCallback.asBinder()).thenReturn(mUsageCallbackBinder);
     }
 
     @Test
@@ -139,7 +128,7 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdTooLowBytes);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateWifi, request.template));
@@ -152,7 +141,7 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, highThresholdBytes);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateWifi, request.template));
@@ -164,13 +153,13 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, THRESHOLD_BYTES);
 
-        DataUsageRequest request1 = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request1 = mStatsObservers.register(inputRequest, mUsageCallback,
                 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
         assertTrue(request1.requestId > 0);
         assertTrue(Objects.equals(sTemplateWifi, request1.template));
         assertEquals(THRESHOLD_BYTES, request1.thresholdInBytes);
 
-        DataUsageRequest request2 = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request2 = mStatsObservers.register(inputRequest, mUsageCallback,
                 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
         assertTrue(request2.requestId > request1.requestId);
         assertTrue(Objects.equals(sTemplateWifi, request2.template));
@@ -190,17 +179,19 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateImsi1, request.template));
         assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
-        Mockito.verify(mockBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+        Mockito.verify(mUsageCallbackBinder).linkToDeath(any(IBinder.DeathRecipient.class),
+                anyInt());
 
         mStatsObservers.unregister(request, Process.SYSTEM_UID);
         waitForObserverToIdle();
 
-        Mockito.verify(mockBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+        Mockito.verify(mUsageCallbackBinder).unlinkToDeath(any(IBinder.DeathRecipient.class),
+                anyInt());
     }
 
     @Test
@@ -208,17 +199,18 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 UID_RED, NetworkStatsAccess.Level.DEVICE);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateImsi1, request.template));
         assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
-        Mockito.verify(mockBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+        Mockito.verify(mUsageCallbackBinder)
+                .linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
 
         mStatsObservers.unregister(request, UID_BLUE);
         waitForObserverToIdle();
 
-        Mockito.verifyZeroInteractions(mockBinder);
+        Mockito.verifyZeroInteractions(mUsageCallbackBinder);
     }
 
     private NetworkIdentitySet makeTestIdentSet() {
@@ -235,7 +227,7 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -259,7 +251,7 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -289,7 +281,7 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -312,7 +304,7 @@
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
-        assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
+        Mockito.verify(mUsageCallback).onThresholdReached(any());
     }
 
     @Test
@@ -320,7 +312,7 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 UID_RED, NetworkStatsAccess.Level.DEFAULT);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -345,7 +337,7 @@
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
-        assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
+        Mockito.verify(mUsageCallback).onThresholdReached(any());
     }
 
     @Test
@@ -353,7 +345,7 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 UID_BLUE, NetworkStatsAccess.Level.DEFAULT);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -385,7 +377,7 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 UID_BLUE, NetworkStatsAccess.Level.USER);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -410,7 +402,7 @@
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
-        assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
+        Mockito.verify(mUsageCallback).onThresholdReached(any());
     }
 
     @Test
@@ -418,7 +410,7 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
 
-        DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
+        DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
                 UID_RED, NetworkStatsAccess.Level.USER);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -447,6 +439,5 @@
 
     private void waitForObserverToIdle() {
         HandlerUtils.waitForIdle(mObserverHandlerThread, WAIT_TIMEOUT_MS);
-        HandlerUtils.waitForIdle(mHandler, WAIT_TIMEOUT_MS);
     }
 }
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index 40587c5..94a4f3d 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -66,21 +66,20 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.annotation.NonNull;
 import android.app.AlarmManager;
-import android.app.usage.NetworkStatsManager;
 import android.content.Context;
 import android.content.Intent;
 import android.database.ContentObserver;
@@ -101,13 +100,9 @@
 import android.net.netstats.provider.INetworkStatsProviderCallback;
 import android.net.wifi.WifiInfo;
 import android.os.Build;
-import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
 import android.os.PowerManager;
 import android.os.SimpleClock;
 import android.provider.Settings;
@@ -117,8 +112,8 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.net.module.util.LocationPermissionChecker;
 import com.android.server.net.NetworkStatsService.AlertObserver;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
@@ -188,11 +183,15 @@
     private @Mock TetheringManager mTetheringManager;
     private @Mock NetworkStatsFactory mStatsFactory;
     private @Mock NetworkStatsSettings mSettings;
-    private @Mock IBinder mBinder;
+    private @Mock IBinder mUsageCallbackBinder;
+    private TestableUsageCallback mUsageCallback;
     private @Mock AlarmManager mAlarmManager;
     @Mock
     private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
+    private @Mock BpfInterfaceMapUpdater mBpfInterfaceMapUpdater;
     private HandlerThread mHandlerThread;
+    @Mock
+    private LocationPermissionChecker mLocationPermissionChecker;
 
     private NetworkStatsService mService;
     private INetworkStatsSession mSession;
@@ -262,7 +261,9 @@
         MockitoAnnotations.initMocks(this);
         final Context context = InstrumentationRegistry.getContext();
         mServiceContext = new MockContext(context);
-        when(sWifiInfo.getCurrentNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY);
+        when(mLocationPermissionChecker.checkCallersLocationPermission(
+                any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
+        when(sWifiInfo.getNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY);
         mStatsDir = TestIoUtils.createTemporaryDirectory(getClass().getSimpleName());
 
         PowerManager powerManager = (PowerManager) mServiceContext.getSystemService(
@@ -309,6 +310,8 @@
         verify(mTetheringManager).registerTetheringEventCallback(
                 any(), tetheringEventCbCaptor.capture());
         mTetheringEventCallback = tetheringEventCbCaptor.getValue();
+
+        mUsageCallback = new TestableUsageCallback(mUsageCallbackBinder);
     }
 
     @NonNull
@@ -334,6 +337,16 @@
                 return mContentObserver = super.makeContentObserver(handler, settings, monitor);
             }
 
+            @Override
+            public LocationPermissionChecker makeLocationPermissionChecker(final Context context) {
+                return mLocationPermissionChecker;
+            }
+
+            @Override
+            public BpfInterfaceMapUpdater makeBpfInterfaceMapUpdater(
+                    @NonNull Context ctx, @NonNull Handler handler) {
+                return mBpfInterfaceMapUpdater;
+            }
         };
     }
 
@@ -985,7 +998,7 @@
     }
 
     @Test
-    public void testDetailedUidStats() throws Exception {
+    public void testUidStatsForTransport() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
@@ -1011,7 +1024,7 @@
                 .insertEntry(entry3));
         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
 
-        NetworkStats stats = mService.getDetailedUidStats(INTERFACES_ALL);
+        NetworkStats stats = mService.getUidStatsForTransport(NetworkCapabilities.TRANSPORT_WIFI);
 
         assertEquals(3, stats.size());
         entry1.operations = 1;
@@ -1022,68 +1035,6 @@
     }
 
     @Test
-    public void testDetailedUidStats_Filtered() throws Exception {
-        // pretend that network comes online
-        expectDefaultSettings();
-
-        final String stackedIface = "stacked-test0";
-        final LinkProperties stackedProp = new LinkProperties();
-        stackedProp.setInterfaceName(stackedIface);
-        final NetworkStateSnapshot wifiState = buildWifiState();
-        wifiState.getLinkProperties().addStackedLink(stackedProp);
-        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {wifiState};
-
-        expectNetworkStatsSummary(buildEmptyStats());
-        expectNetworkStatsUidDetail(buildEmptyStats());
-
-        mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
-                new UnderlyingNetworkInfo[0]);
-
-        NetworkStats.Entry uidStats = new NetworkStats.Entry(
-                TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L);
-        // Stacked on matching interface
-        NetworkStats.Entry tetheredStats1 = new NetworkStats.Entry(
-                stackedIface, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L);
-        TetherStatsParcel tetherStatsParcel1 =
-                buildTetherStatsParcel(stackedIface, 1024L, 8L, 512L, 4L, 0);
-        // Different interface
-        TetherStatsParcel tetherStatsParcel2 =
-                buildTetherStatsParcel("otherif", 1024L, 8L, 512L, 4L, 0);
-
-        final String[] ifaceFilter = new String[] { TEST_IFACE };
-        final String[] augmentedIfaceFilter = new String[] { stackedIface, TEST_IFACE };
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectDefaultSettings();
-        expectNetworkStatsSummary(buildEmptyStats());
-        when(mStatsFactory.augmentWithStackedInterfaces(eq(ifaceFilter)))
-                .thenReturn(augmentedIfaceFilter);
-        when(mStatsFactory.readNetworkStatsDetail(eq(UID_ALL), any(), eq(TAG_ALL)))
-                .thenReturn(new NetworkStats(getElapsedRealtime(), 1)
-                        .insertEntry(uidStats));
-        final TetherStatsParcel[] tetherStatsParcels =  {tetherStatsParcel1, tetherStatsParcel2};
-        when(mNetd.tetherGetStats()).thenReturn(tetherStatsParcels);
-
-        NetworkStats stats = mService.getDetailedUidStats(ifaceFilter);
-
-        // mStatsFactory#readNetworkStatsDetail() has the following invocations:
-        // 1) NetworkStatsService#systemReady from #setUp.
-        // 2) mService#notifyNetworkStatus in the test above.
-        //
-        // Additionally, we should have one call from the above call to mService#getDetailedUidStats
-        // with the augmented ifaceFilter.
-        verify(mStatsFactory, times(2)).readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
-        verify(mStatsFactory, times(1)).readNetworkStatsDetail(
-                eq(UID_ALL),
-                eq(augmentedIfaceFilter),
-                eq(TAG_ALL));
-        assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), TEST_IFACE));
-        assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), stackedIface));
-        assertEquals(2, stats.size());
-        assertEquals(uidStats, stats.getValues(0, null));
-        assertEquals(tetheredStats1, stats.getValues(1, null));
-    }
-
-    @Test
     public void testForegroundBackground() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
@@ -1294,20 +1245,14 @@
         DataUsageRequest inputRequest = new DataUsageRequest(
                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdInBytes);
 
-        // Create a messenger that waits for callback activity
-        ConditionVariable cv = new ConditionVariable(false);
-        LatchedHandler latchedHandler = new LatchedHandler(Looper.getMainLooper(), cv);
-        Messenger messenger = new Messenger(latchedHandler);
-
         // Force poll
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
         // Register and verify request and that binder was called
-        DataUsageRequest request =
-                mService.registerUsageCallback(mServiceContext.getOpPackageName(), inputRequest,
-                        messenger, mBinder);
+        DataUsageRequest request = mService.registerUsageCallback(
+                mServiceContext.getOpPackageName(), inputRequest, mUsageCallback);
         assertTrue(request.requestId > 0);
         assertTrue(Objects.equals(sTemplateWifi, request.template));
         long minThresholdInBytes = 2 * 1024 * 1024; // 2 MB
@@ -1316,7 +1261,7 @@
         HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
 
         // Make sure that the caller binder gets connected
-        verify(mBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+        verify(mUsageCallbackBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
 
         // modify some number on wifi, and trigger poll event
         // not enough traffic to call data usage callback
@@ -1331,7 +1276,7 @@
         assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
 
         // make sure callback has not being called
-        assertEquals(INVALID_TYPE, latchedHandler.lastMessageType);
+        mUsageCallback.assertNoCallback();
 
         // and bump forward again, with counters going higher. this is
         // important, since it will trigger the data usage callback
@@ -1346,23 +1291,21 @@
         assertNetworkTotal(sTemplateWifi, 4096000L, 4L, 8192000L, 8L, 0);
 
 
-        // Wait for the caller to ack receipt of CALLBACK_LIMIT_REACHED
-        assertTrue(cv.block(WAIT_TIMEOUT));
-        assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, latchedHandler.lastMessageType);
-        cv.close();
+        // Wait for the caller to invoke expectOnThresholdReached.
+        mUsageCallback.expectOnThresholdReached();
 
         // Allow binder to disconnect
-        when(mBinder.unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt())).thenReturn(true);
+        when(mUsageCallbackBinder.unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt()))
+                .thenReturn(true);
 
         // Unregister request
         mService.unregisterUsageRequest(request);
 
-        // Wait for the caller to ack receipt of CALLBACK_RELEASED
-        assertTrue(cv.block(WAIT_TIMEOUT));
-        assertEquals(NetworkStatsManager.CALLBACK_RELEASED, latchedHandler.lastMessageType);
+        // Wait for the caller to invoke expectOnCallbackReleased.
+        mUsageCallback.expectOnCallbackReleased();
 
         // Make sure that the caller binder gets disconnected
-        verify(mBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+        verify(mUsageCallbackBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
     }
 
     @Test
@@ -1688,6 +1631,28 @@
         provider.expectOnRequestStatsUpdate(0 /* unused */);
     }
 
+    /**
+     * Verify the service will throw exceptions if the template is location sensitive but
+     * the permission is not granted.
+     */
+    @Test
+    public void testEnforceTemplateLocationPermission() throws Exception {
+        when(mLocationPermissionChecker.checkCallersLocationPermission(
+                any(), any(), anyInt(), anyBoolean(), any())).thenReturn(false);
+        initWifiStats(buildWifiState(true, TEST_IFACE, IMSI_1));
+        assertThrows(SecurityException.class, () ->
+                assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0));
+        // Templates w/o wifi network keys can query stats as usual.
+        assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
+        assertNetworkTotal(sTemplateImsi1, 0L, 0L, 0L, 0L, 0);
+
+        when(mLocationPermissionChecker.checkCallersLocationPermission(
+                any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
+        assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
+        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
+        assertNetworkTotal(sTemplateImsi1, 0L, 0L, 0L, 0L, 0);
+    }
+
     private static File getBaseDir(File statsDir) {
         File baseDir = new File(statsDir, "netstats");
         baseDir.mkdirs();
@@ -1703,7 +1668,8 @@
     private void assertNetworkTotal(NetworkTemplate template, long start, long end, long rxBytes,
             long rxPackets, long txBytes, long txPackets, int operations) throws Exception {
         // verify history API
-        final NetworkStatsHistory history = mSession.getHistoryForNetwork(template, FIELD_ALL);
+        final NetworkStatsHistory history =
+                mSession.getHistoryIntervalForNetwork(template, FIELD_ALL, start, end);
         assertValues(history, start, end, rxBytes, rxPackets, txBytes, txPackets, operations);
 
         // verify summary API
@@ -1915,21 +1881,4 @@
     private void waitForIdle() {
         HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
     }
-
-    static class LatchedHandler extends Handler {
-        private final ConditionVariable mCv;
-        int lastMessageType = INVALID_TYPE;
-
-        LatchedHandler(Looper looper, ConditionVariable cv) {
-            super(looper);
-            mCv = cv;
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            lastMessageType = msg.what;
-            mCv.open();
-            super.handleMessage(msg);
-        }
-    }
 }
diff --git a/tests/unit/java/com/android/server/net/TestableUsageCallback.kt b/tests/unit/java/com/android/server/net/TestableUsageCallback.kt
new file mode 100644
index 0000000..44f588c
--- /dev/null
+++ b/tests/unit/java/com/android/server/net/TestableUsageCallback.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.server.net
+
+import android.net.DataUsageRequest
+import android.net.netstats.IUsageCallback
+import android.os.IBinder
+import java.util.concurrent.LinkedBlockingQueue
+import java.util.concurrent.TimeUnit
+import kotlin.test.assertEquals
+import kotlin.test.fail
+
+private const val DEFAULT_TIMEOUT_MS = 200L
+
+// TODO: Move the class to static libs once all downstream have IUsageCallback definition.
+open class TestableUsageCallback(private val binder: IBinder) : IUsageCallback.Stub() {
+    sealed class CallbackType {
+        object OnThresholdReached : CallbackType()
+        object OnCallbackReleased : CallbackType()
+    }
+
+    // TODO: Change to use ArrayTrackRecord once moved into to the module.
+    private val history = LinkedBlockingQueue<CallbackType>()
+
+    override fun onThresholdReached(request: DataUsageRequest) {
+        history.add(CallbackType.OnThresholdReached)
+    }
+
+    override fun onCallbackReleased(request: DataUsageRequest) {
+        history.add(CallbackType.OnCallbackReleased)
+    }
+
+    fun expectOnThresholdReached() {
+        assertEquals(CallbackType.OnThresholdReached,
+                history.poll(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS))
+    }
+
+    fun expectOnCallbackReleased() {
+        assertEquals(CallbackType.OnCallbackReleased,
+                history.poll(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS))
+    }
+
+    @JvmOverloads
+    fun assertNoCallback(timeout: Long = DEFAULT_TIMEOUT_MS) {
+        val cb = history.poll(timeout, TimeUnit.MILLISECONDS)
+        cb?.let { fail("Expected no callback but got $cb") }
+    }
+
+    override fun asBinder(): IBinder {
+        return binder
+    }
+}
\ No newline at end of file
