diff --git a/framework/src/android/net/QosCallbackException.java b/framework/src/android/net/QosCallbackException.java
index b80cff4..72430d2 100644
--- a/framework/src/android/net/QosCallbackException.java
+++ b/framework/src/android/net/QosCallbackException.java
@@ -57,6 +57,9 @@
     private static final String TAG = "QosCallbackException";
 
     // Types of exceptions supported //
+    // The constants are used for the sendQosCallbackError system API, so they must not be changed
+    // as there may be callers relying on their historical values to call that API.
+    // TODO: mark the constants as @SystemApi, since they are necessary to call a system API.
     /** {@hide} */
     public static final int EX_TYPE_FILTER_NONE = 0;
 
@@ -67,13 +70,13 @@
     public static final int EX_TYPE_FILTER_SOCKET_NOT_BOUND = 2;
 
     /** {@hide} */
-    public static final int EX_TYPE_FILTER_SOCKET_NOT_CONNECTED = 3;
+    public static final int EX_TYPE_FILTER_NOT_SUPPORTED = 3;
 
     /** {@hide} */
-    public static final int EX_TYPE_FILTER_NOT_SUPPORTED = 4;
+    public static final int EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED = 4;
 
     /** {@hide} */
-    public static final int EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED = 5;
+    public static final int EX_TYPE_FILTER_SOCKET_NOT_CONNECTED = 5;
 
     /** {@hide} */
     public static final int EX_TYPE_FILTER_SOCKET_REMOTE_ADDRESS_CHANGED = 6;
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index 6599c7f..648ada2 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -25,6 +25,7 @@
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
 import static android.system.OsConstants.EINVAL;
+import static android.system.OsConstants.ENODEV;
 import static android.system.OsConstants.ENOENT;
 import static android.system.OsConstants.EOPNOTSUPP;
 
@@ -60,6 +61,7 @@
 
     private static final String TAG = "BpfNetMaps";
     private final INetd mNetd;
+    private final Dependencies mDeps;
     // Use legacy netd for releases before T.
     private static boolean sInitialized = false;
 
@@ -163,6 +165,19 @@
         sInitialized = true;
     }
 
+    /**
+     * Dependencies of BpfNetMaps, for injection in tests.
+     */
+    @VisibleForTesting
+    public static class Dependencies {
+        /**
+         * Get interface index.
+         */
+        public int getIfIndex(final String ifName) {
+            return Os.if_nametoindex(ifName);
+        }
+    }
+
     /** Constructor used after T that doesn't need to use netd anymore. */
     public BpfNetMaps() {
         this(null);
@@ -171,10 +186,16 @@
     }
 
     public BpfNetMaps(final INetd netd) {
+        this(netd, new Dependencies());
+    }
+
+    @VisibleForTesting
+    public BpfNetMaps(final INetd netd, final Dependencies deps) {
         if (!PRE_T) {
             ensureInitialized();
         }
         mNetd = netd;
+        mDeps = deps;
     }
 
     /**
@@ -419,9 +440,24 @@
             mNetd.firewallAddUidInterfaceRules(ifName, uids);
             return;
         }
-        synchronized (sUidOwnerMap) {
-            final int err = native_addUidInterfaceRules(ifName, uids);
-            maybeThrow(err, "Unable to add uid interface rules");
+        // Null ifName is a wildcard to allow apps to receive packets on all interfaces and ifIndex
+        // is set to 0.
+        final int ifIndex;
+        if (ifName == null) {
+            ifIndex = 0;
+        } else {
+            ifIndex = mDeps.getIfIndex(ifName);
+            if (ifIndex == 0) {
+                throw new ServiceSpecificException(ENODEV,
+                        "Failed to get index of interface " + ifName);
+            }
+        }
+        for (final int uid: uids) {
+            try {
+                addRule(uid, IIF_MATCH, ifIndex, "addUidInterfaceRules");
+            } catch (ServiceSpecificException e) {
+                Log.e(TAG, "addRule failed uid=" + uid + " ifName=" + ifName + ", " + e);
+            }
         }
     }
 
@@ -441,9 +477,12 @@
             mNetd.firewallRemoveUidInterfaceRules(uids);
             return;
         }
-        synchronized (sUidOwnerMap) {
-            final int err = native_removeUidInterfaceRules(uids);
-            maybeThrow(err, "Unable to remove uid interface rules");
+        for (final int uid: uids) {
+            try {
+                removeRule(uid, IIF_MATCH, "removeUidInterfaceRules");
+            } catch (ServiceSpecificException e) {
+                Log.e(TAG, "removeRule failed uid=" + uid + ", " + e);
+            }
         }
     }
 
diff --git a/tests/unit/java/com/android/server/BpfNetMapsTest.java b/tests/unit/java/com/android/server/BpfNetMapsTest.java
index 433b892..98d0905 100644
--- a/tests/unit/java/com/android/server/BpfNetMapsTest.java
+++ b/tests/unit/java/com/android/server/BpfNetMapsTest.java
@@ -41,6 +41,7 @@
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeFalse;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 
 import android.net.INetd;
@@ -81,6 +82,7 @@
     private static final String TEST_IF_NAME = "wlan0";
     private static final int TEST_IF_INDEX = 7;
     private static final int NO_IIF = 0;
+    private static final int NULL_IIF = 0;
     private static final String CHAINNAME = "fw_dozable";
     private static final U32 UID_RULES_CONFIGURATION_KEY = new U32(0);
     private static final List<Integer> FIREWALL_CHAINS = List.of(
@@ -97,6 +99,7 @@
     private BpfNetMaps mBpfNetMaps;
 
     @Mock INetd mNetd;
+    @Mock BpfNetMaps.Dependencies mDeps;
     private final BpfMap<U32, U32> mConfigurationMap = new TestBpfMap<>(U32.class, U32.class);
     private final BpfMap<U32, UidOwnerValue> mUidOwnerMap =
             new TestBpfMap<>(U32.class, UidOwnerValue.class);
@@ -104,9 +107,10 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        doReturn(TEST_IF_INDEX).when(mDeps).getIfIndex(TEST_IF_NAME);
         BpfNetMaps.setConfigurationMapForTest(mConfigurationMap);
         BpfNetMaps.setUidOwnerMapForTest(mUidOwnerMap);
-        mBpfNetMaps = new BpfNetMaps(mNetd);
+        mBpfNetMaps = new BpfNetMaps(mNetd, mDeps);
     }
 
     @Test
@@ -458,4 +462,99 @@
         assertThrows(UnsupportedOperationException.class,
                 () -> mBpfNetMaps.updateUidLockdownRule(TEST_UID, true /* add */));
     }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testAddUidInterfaceRules() throws Exception {
+        final int uid0 = TEST_UIDS[0];
+        final int uid1 = TEST_UIDS[1];
+
+        mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS);
+
+        checkUidOwnerValue(uid0, TEST_IF_INDEX, IIF_MATCH);
+        checkUidOwnerValue(uid1, TEST_IF_INDEX, IIF_MATCH);
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testAddUidInterfaceRulesWithOtherMatch() throws Exception {
+        final int uid0 = TEST_UIDS[0];
+        final int uid1 = TEST_UIDS[1];
+        final long match0 = DOZABLE_MATCH;
+        final long match1 = DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH;
+        mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(NO_IIF, match0));
+        mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(NO_IIF, match1));
+
+        mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS);
+
+        checkUidOwnerValue(uid0, TEST_IF_INDEX, match0 | IIF_MATCH);
+        checkUidOwnerValue(uid1, TEST_IF_INDEX, match1 | IIF_MATCH);
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testAddUidInterfaceRulesWithExistingIifMatch() throws Exception {
+        final int uid0 = TEST_UIDS[0];
+        final int uid1 = TEST_UIDS[1];
+        final long match0 = IIF_MATCH;
+        final long match1 = IIF_MATCH | DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH;
+        mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(TEST_IF_INDEX + 1, match0));
+        mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(NULL_IIF, match1));
+
+        mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS);
+
+        checkUidOwnerValue(uid0, TEST_IF_INDEX, match0);
+        checkUidOwnerValue(uid1, TEST_IF_INDEX, match1);
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testAddUidInterfaceRulesGetIfIndexFail() {
+        doReturn(0).when(mDeps).getIfIndex(TEST_IF_NAME);
+        assertThrows(ServiceSpecificException.class,
+                () -> mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS));
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testAddUidInterfaceRulesWithNullInterface() throws Exception {
+        final int uid0 = TEST_UIDS[0];
+        final int uid1 = TEST_UIDS[1];
+        final long match0 = IIF_MATCH;
+        final long match1 = IIF_MATCH | DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH;
+        mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(TEST_IF_INDEX, match0));
+        mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(NULL_IIF, match1));
+
+        mBpfNetMaps.addUidInterfaceRules(null /* ifName */, TEST_UIDS);
+
+        checkUidOwnerValue(uid0, NULL_IIF, match0);
+        checkUidOwnerValue(uid1, NULL_IIF, match1);
+    }
+
+    private void doTestRemoveUidInterfaceRules(final long iif0, final long match0,
+            final long iif1, final long match1) throws Exception {
+        final int uid0 = TEST_UIDS[0];
+        final int uid1 = TEST_UIDS[1];
+        mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(iif0, match0));
+        mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(iif1, match1));
+
+        mBpfNetMaps.removeUidInterfaceRules(TEST_UIDS);
+
+        checkUidOwnerValue(uid0, NO_IIF, match0 & ~IIF_MATCH);
+        checkUidOwnerValue(uid1, NO_IIF, match1 & ~IIF_MATCH);
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testRemoveUidInterfaceRules() throws Exception {
+        doTestRemoveUidInterfaceRules(TEST_IF_INDEX, IIF_MATCH, NULL_IIF, IIF_MATCH);
+
+        // IIF_MATCH and other matches are enabled
+        doTestRemoveUidInterfaceRules(TEST_IF_INDEX, IIF_MATCH | DOZABLE_MATCH,
+                NULL_IIF, IIF_MATCH | DOZABLE_MATCH | RESTRICTED_MATCH);
+
+        // IIF_MATCH is not enabled
+        doTestRemoveUidInterfaceRules(NO_IIF, DOZABLE_MATCH,
+                NO_IIF, DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH);
+    }
 }
