diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 98b624b..a7064e8 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -35,15 +35,9 @@
 import static android.net.ip.IpServer.STATE_TETHERED;
 import static android.net.ip.IpServer.STATE_UNAVAILABLE;
 import static android.net.ip.IpServer.getTetherableIpv6Prefixes;
-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;
-import static com.android.net.module.util.netlink.StructNdMsg.NUD_FAILED;
-import static com.android.net.module.util.netlink.StructNdMsg.NUD_REACHABLE;
-import static com.android.net.module.util.netlink.StructNdMsg.NUD_STALE;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -57,7 +51,6 @@
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -66,7 +59,6 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -83,8 +75,6 @@
 import android.net.MacAddress;
 import android.net.RouteInfo;
 import android.net.RoutingCoordinatorManager;
-import android.net.TetherOffloadRuleParcel;
-import android.net.TetherStatsParcel;
 import android.net.dhcp.DhcpServerCallbacks;
 import android.net.dhcp.DhcpServingParamsParcel;
 import android.net.dhcp.IDhcpEventCallbacks;
@@ -96,40 +86,17 @@
 import android.os.RemoteException;
 import android.os.test.TestLooper;
 import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.modules.utils.build.SdkLevel;
-import com.android.net.module.util.BpfMap;
 import com.android.net.module.util.InterfaceParams;
-import com.android.net.module.util.NetworkStackConstants;
 import com.android.net.module.util.SdkUtil.LateSdk;
 import com.android.net.module.util.SharedLog;
-import com.android.net.module.util.Struct.S32;
-import com.android.net.module.util.bpf.Tether4Key;
-import com.android.net.module.util.bpf.Tether4Value;
-import com.android.net.module.util.bpf.TetherStatsKey;
-import com.android.net.module.util.bpf.TetherStatsValue;
-import com.android.net.module.util.ip.ConntrackMonitor;
 import com.android.net.module.util.ip.IpNeighborMonitor;
-import com.android.net.module.util.ip.IpNeighborMonitor.NeighborEvent;
-import com.android.net.module.util.ip.IpNeighborMonitor.NeighborEventConsumer;
 import com.android.networkstack.tethering.BpfCoordinator;
-import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
-import com.android.networkstack.tethering.BpfCoordinator.Ipv6DownstreamRule;
 import com.android.networkstack.tethering.PrivateAddressCoordinator;
-import com.android.networkstack.tethering.Tether6Value;
-import com.android.networkstack.tethering.TetherDevKey;
-import com.android.networkstack.tethering.TetherDevValue;
-import com.android.networkstack.tethering.TetherDownstream6Key;
-import com.android.networkstack.tethering.TetherLimitKey;
-import com.android.networkstack.tethering.TetherLimitValue;
-import com.android.networkstack.tethering.TetherUpstream6Key;
 import com.android.networkstack.tethering.TetheringConfiguration;
 import com.android.networkstack.tethering.metrics.TetheringMetrics;
 import com.android.networkstack.tethering.util.InterfaceSet;
@@ -143,18 +110,13 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
 import org.mockito.Captor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.mockito.verification.VerificationMode;
 
 import java.net.Inet4Address;
-import java.net.Inet6Address;
 import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
 
@@ -219,16 +181,8 @@
             new LateSdk<>(SdkLevel.isAtLeastS() ? mock(RoutingCoordinatorManager.class) : null);
     @Mock private NetworkStatsManager mStatsManager;
     @Mock private TetheringConfiguration mTetherConfig;
-    @Mock private ConntrackMonitor mConntrackMonitor;
     @Mock private TetheringMetrics mTetheringMetrics;
-    @Mock private BpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map;
-    @Mock private BpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map;
-    @Mock private BpfMap<TetherDownstream6Key, Tether6Value> mBpfDownstream6Map;
-    @Mock private BpfMap<TetherUpstream6Key, Tether6Value> mBpfUpstream6Map;
-    @Mock private BpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap;
-    @Mock private BpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap;
-    @Mock private BpfMap<TetherDevKey, TetherDevValue> mBpfDevMap;
-    @Mock private BpfMap<S32, S32> mBpfErrorMap;
+    @Mock private BpfCoordinator mBpfCoordinator;
 
     @Captor private ArgumentCaptor<DhcpServingParamsParcel> mDhcpParamsCaptor;
 
@@ -238,9 +192,6 @@
             ArgumentCaptor.forClass(LinkProperties.class);
     private IpServer mIpServer;
     private InterfaceConfigurationParcel mInterfaceConfiguration;
-    private NeighborEventConsumer mNeighborEventConsumer;
-    private BpfCoordinator mBpfCoordinator;
-    private BpfCoordinator.Dependencies mBpfDeps;
 
     private void initStateMachine(int interfaceType) throws Exception {
         initStateMachine(interfaceType, false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD);
@@ -262,22 +213,20 @@
             mInterfaceConfiguration.prefixLength = BLUETOOTH_DHCP_PREFIX_LENGTH;
         }
 
-        ArgumentCaptor<NeighborEventConsumer> neighborCaptor =
-                ArgumentCaptor.forClass(NeighborEventConsumer.class);
-        doReturn(mIpNeighborMonitor).when(mDependencies).getIpNeighborMonitor(any(), any(),
-                neighborCaptor.capture());
+        doReturn(mIpNeighborMonitor).when(mDependencies).getIpNeighborMonitor(any(), any(), any());
 
         when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(usingBpfOffload);
         when(mTetherConfig.useLegacyDhcpServer()).thenReturn(usingLegacyDhcp);
         when(mTetherConfig.getP2pLeasesSubnetPrefixLength()).thenReturn(P2P_SUBNET_PREFIX_LENGTH);
+        when(mBpfCoordinator.isUsingBpfOffload()).thenReturn(usingBpfOffload);
         mIpServer = createIpServer(interfaceType);
+        verify(mIpNeighborMonitor).start();
         mIpServer.start();
-        mNeighborEventConsumer = neighborCaptor.getValue();
 
         // Starting the state machine always puts us in a consistent state and notifies
         // the rest of the world that we've changed from an unknown to available state.
         mLooper.dispatchAll();
-        reset(mNetd, mCallback);
+        reset(mNetd, mCallback, mIpNeighborMonitor);
 
         when(mRaDaemon.start()).thenReturn(true);
     }
@@ -294,23 +243,17 @@
         initStateMachine(interfaceType, usingLegacyDhcp, usingBpfOffload);
         dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
         if (upstreamIface != null) {
+            InterfaceParams interfaceParams = mDependencies.getInterfaceParams(upstreamIface);
+            assertNotNull("missing upstream interface: " + upstreamIface, interfaceParams);
             LinkProperties lp = new LinkProperties();
             lp.setInterfaceName(upstreamIface);
             lp.setLinkAddresses(upstreamAddresses);
             dispatchTetherConnectionChanged(upstreamIface, lp, 0);
-            if (usingBpfOffload && !lp.getLinkAddresses().isEmpty()) {
-                Set<IpPrefix> upstreamPrefixes = getTetherableIpv6Prefixes(lp.getLinkAddresses());
-                InterfaceParams interfaceParams = mDependencies.getInterfaceParams(upstreamIface);
-                assertNotNull("missing upstream interface: " + upstreamIface, interfaceParams);
-                verify(mBpfCoordinator).updateAllIpv6Rules(
-                        mIpServer, TEST_IFACE_PARAMS, interfaceParams.index, upstreamPrefixes);
-                verifyStartUpstreamIpv6Forwarding(null, interfaceParams.index, upstreamPrefixes);
-            } else {
-                verifyNoUpstreamIpv6ForwardingChange(null);
-            }
+            Set<IpPrefix> upstreamPrefixes = getTetherableIpv6Prefixes(lp.getLinkAddresses());
+            verify(mBpfCoordinator).updateAllIpv6Rules(
+                    mIpServer, TEST_IFACE_PARAMS, interfaceParams.index, upstreamPrefixes);
         }
-        reset(mCallback, mAddressCoordinator);
-        resetNetdBpfMapAndCoordinator();
+        reset(mNetd, mBpfCoordinator, mCallback, mAddressCoordinator);
         when(mAddressCoordinator.requestDownstreamAddress(any(), anyInt(),
                 anyBoolean())).thenReturn(mTestAddress);
     }
@@ -363,80 +306,6 @@
     private IpServer createIpServer(final int interfaceType) {
         mLooper = new TestLooper();
         mHandler = new Handler(mLooper.getLooper());
-        mBpfDeps = new BpfCoordinator.Dependencies() {
-                    @NonNull
-                    public Handler getHandler() {
-                        return mHandler;
-                    }
-
-                    @NonNull
-                    public INetd getNetd() {
-                        return mNetd;
-                    }
-
-                    @NonNull
-                    public NetworkStatsManager getNetworkStatsManager() {
-                        return mStatsManager;
-                    }
-
-                    @NonNull
-                    public SharedLog getSharedLog() {
-                        return mSharedLog;
-                    }
-
-                    @Nullable
-                    public TetheringConfiguration getTetherConfig() {
-                        return mTetherConfig;
-                    }
-
-                    @NonNull
-                    public ConntrackMonitor getConntrackMonitor(
-                            ConntrackMonitor.ConntrackEventConsumer consumer) {
-                        return mConntrackMonitor;
-                    }
-
-                    @Nullable
-                    public BpfMap<Tether4Key, Tether4Value> getBpfDownstream4Map() {
-                        return mBpfDownstream4Map;
-                    }
-
-                    @Nullable
-                    public BpfMap<Tether4Key, Tether4Value> getBpfUpstream4Map() {
-                        return mBpfUpstream4Map;
-                    }
-
-                    @Nullable
-                    public BpfMap<TetherDownstream6Key, Tether6Value> getBpfDownstream6Map() {
-                        return mBpfDownstream6Map;
-                    }
-
-                    @Nullable
-                    public BpfMap<TetherUpstream6Key, Tether6Value> getBpfUpstream6Map() {
-                        return mBpfUpstream6Map;
-                    }
-
-                    @Nullable
-                    public BpfMap<TetherStatsKey, TetherStatsValue> getBpfStatsMap() {
-                        return mBpfStatsMap;
-                    }
-
-                    @Nullable
-                    public BpfMap<TetherLimitKey, TetherLimitValue> getBpfLimitMap() {
-                        return mBpfLimitMap;
-                    }
-
-                    @Nullable
-                    public BpfMap<TetherDevKey, TetherDevValue> getBpfDevMap() {
-                        return mBpfDevMap;
-                    }
-
-                    @Nullable
-                    public BpfMap<S32, S32> getBpfErrorMap() {
-                        return mBpfErrorMap;
-                    }
-                };
-
-        mBpfCoordinator = spy(new BpfCoordinator(mBpfDeps));
         return new IpServer(IFACE_NAME, mHandler, interfaceType, mSharedLog, mNetd, mBpfCoordinator,
                 mRoutingCoordinatorManager, mCallback, mTetherConfig, mAddressCoordinator,
                 mTetheringMetrics, mDependencies);
@@ -886,346 +755,19 @@
         verify(mDependencies, never()).makeDhcpServer(any(), any(), any());
     }
 
-    private InetAddress addr(String addr) throws Exception {
-        return InetAddresses.parseNumericAddress(addr);
-    }
-
-    private void recvNewNeigh(int ifindex, InetAddress addr, short nudState, MacAddress mac) {
-        mNeighborEventConsumer.accept(new NeighborEvent(0, RTM_NEWNEIGH, ifindex, addr,
-                nudState, mac));
-        mLooper.dispatchAll();
-    }
-
-    private void recvDelNeigh(int ifindex, InetAddress addr, short nudState, MacAddress mac) {
-        mNeighborEventConsumer.accept(new NeighborEvent(0, RTM_DELNEIGH, ifindex, addr,
-                nudState, mac));
-        mLooper.dispatchAll();
-    }
-
-    /**
-     * Custom ArgumentMatcher for TetherOffloadRuleParcel. This is needed because generated stable
-     * AIDL classes don't have equals(), so we cannot just use eq(). A custom assert, such as:
-     *
-     * private void checkFooCalled(StableParcelable p, ...) {
-     *     ArgumentCaptor<FooParam> captor = ArgumentCaptor.forClass(FooParam.class);
-     *     verify(mMock).foo(captor.capture());
-     *     Foo foo = captor.getValue();
-     *     assertFooMatchesExpectations(foo);
-     * }
-     *
-     * almost works, but not quite. This is because if the code under test calls foo() twice, the
-     * first call to checkFooCalled() matches both the calls, putting both calls into the captor,
-     * and then fails with TooManyActualInvocations. It also makes it harder to use other mockito
-     * features such as never(), inOrder(), etc.
-     *
-     * This approach isn't great because if the match fails, the error message is unhelpful
-     * (actual: "android.net.TetherOffloadRuleParcel@8c827b0" or some such), but at least it does
-     * work.
-     *
-     * TODO: consider making the error message more readable by adding a method that catching the
-     * AssertionFailedError and throwing a new assertion with more details. See
-     * NetworkMonitorTest#verifyNetworkTested.
-     *
-     * See ConnectivityServiceTest#assertRoutesAdded for an alternative approach which solves the
-     * TooManyActualInvocations problem described above by forcing the caller of the custom assert
-     * method to specify all expected invocations in one call. This is useful when the stable
-     * parcelable class being asserted on has a corresponding Java object (eg., RouteInfo and
-     * RouteInfoParcelable), and the caller can just pass in a list of them. It not useful here
-     * because there is no such object.
-     */
-    private static class TetherOffloadRuleParcelMatcher implements
-            ArgumentMatcher<TetherOffloadRuleParcel> {
-        public final int upstreamIfindex;
-        public final InetAddress dst;
-        public final MacAddress dstMac;
-
-        TetherOffloadRuleParcelMatcher(int upstreamIfindex, InetAddress dst, MacAddress dstMac) {
-            this.upstreamIfindex = upstreamIfindex;
-            this.dst = dst;
-            this.dstMac = dstMac;
-        }
-
-        public boolean matches(TetherOffloadRuleParcel parcel) {
-            return upstreamIfindex == parcel.inputInterfaceIndex
-                    && (TEST_IFACE_PARAMS.index == parcel.outputInterfaceIndex)
-                    && Arrays.equals(dst.getAddress(), parcel.destination)
-                    && (128 == parcel.prefixLength)
-                    && Arrays.equals(TEST_IFACE_PARAMS.macAddr.toByteArray(), parcel.srcL2Address)
-                    && Arrays.equals(dstMac.toByteArray(), parcel.dstL2Address);
-        }
-
-        public String toString() {
-            return String.format("TetherOffloadRuleParcelMatcher(%d, %s, %s",
-                    upstreamIfindex, dst.getHostAddress(), dstMac);
-        }
-    }
-
-    @NonNull
-    private static TetherOffloadRuleParcel matches(
-            int upstreamIfindex, InetAddress dst, MacAddress dstMac) {
-        return argThat(new TetherOffloadRuleParcelMatcher(upstreamIfindex, dst, dstMac));
-    }
-
-    @NonNull
-    private static Ipv6DownstreamRule makeDownstreamRule(int upstreamIfindex,
-            @NonNull InetAddress dst, @NonNull MacAddress dstMac) {
-        return new Ipv6DownstreamRule(upstreamIfindex, TEST_IFACE_PARAMS.index,
-                (Inet6Address) dst, TEST_IFACE_PARAMS.macAddr, dstMac);
-    }
-
-    @NonNull
-    private static TetherDownstream6Key makeDownstream6Key(int upstreamIfindex,
-            @NonNull MacAddress upstreamMac, @NonNull final InetAddress dst) {
-        return new TetherDownstream6Key(upstreamIfindex, upstreamMac, dst.getAddress());
-    }
-
-    @NonNull
-    private static Tether6Value makeDownstream6Value(@NonNull final MacAddress dstMac) {
-        return new Tether6Value(TEST_IFACE_PARAMS.index, dstMac,
-                TEST_IFACE_PARAMS.macAddr, ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
-    }
-
-    private static long prefixToLong(IpPrefix prefix) {
-        return ByteBuffer.wrap(prefix.getRawAddress()).getLong();
-    }
-
-    private <T> T verifyWithOrder(@Nullable InOrder inOrder, @NonNull T t) {
-        return verifyWithOrder(inOrder, t, times(1));
-    }
-
-    private <T> T verifyWithOrder(@Nullable InOrder inOrder, @NonNull T t, VerificationMode mode) {
-        if (inOrder != null) {
-            return inOrder.verify(t, mode);
-        } else {
-            return verify(t, mode);
-        }
-    }
-
-    private void verifyTetherOffloadRuleAdd(@Nullable InOrder inOrder, int upstreamIfindex,
-            @NonNull MacAddress upstreamMac, @NonNull final InetAddress dst,
-            @NonNull final MacAddress dstMac) throws Exception {
-        if (mBpfDeps.isAtLeastS()) {
-            verifyWithOrder(inOrder, mBpfDownstream6Map).updateEntry(
-                    makeDownstream6Key(upstreamIfindex, upstreamMac, dst),
-                    makeDownstream6Value(dstMac));
-        } else {
-            verifyWithOrder(inOrder, mNetd).tetherOffloadRuleAdd(matches(upstreamIfindex, dst,
-                    dstMac));
-        }
-    }
-
-    private void verifyNeverTetherOffloadRuleAdd(int upstreamIfindex,
-            @NonNull MacAddress upstreamMac, @NonNull final InetAddress dst,
-            @NonNull final MacAddress dstMac) throws Exception {
-        if (mBpfDeps.isAtLeastS()) {
-            verify(mBpfDownstream6Map, never()).updateEntry(
-                    makeDownstream6Key(upstreamIfindex, upstreamMac, dst),
-                    makeDownstream6Value(dstMac));
-        } else {
-            verify(mNetd, never()).tetherOffloadRuleAdd(matches(upstreamIfindex, dst, dstMac));
-        }
-    }
-
-    private void verifyNeverTetherOffloadRuleAdd() throws Exception {
-        if (mBpfDeps.isAtLeastS()) {
-            verify(mBpfDownstream6Map, never()).updateEntry(any(), any());
-        } else {
-            verify(mNetd, never()).tetherOffloadRuleAdd(any());
-        }
-    }
-
-    private void verifyTetherOffloadRuleRemove(@Nullable InOrder inOrder, int upstreamIfindex,
-            @NonNull MacAddress upstreamMac, @NonNull final InetAddress dst,
-            @NonNull final MacAddress dstMac) throws Exception {
-        if (mBpfDeps.isAtLeastS()) {
-            verifyWithOrder(inOrder, mBpfDownstream6Map).deleteEntry(makeDownstream6Key(
-                    upstreamIfindex, upstreamMac, dst));
-        } else {
-            // |dstMac| is not required for deleting rules. Used bacause tetherOffloadRuleRemove
-            // uses a whole rule to be a argument.
-            // See system/netd/server/TetherController.cpp/TetherController#removeOffloadRule.
-            verifyWithOrder(inOrder, mNetd).tetherOffloadRuleRemove(matches(upstreamIfindex, dst,
-                    dstMac));
-        }
-    }
-
-    private void verifyNeverTetherOffloadRuleRemove() throws Exception {
-        if (mBpfDeps.isAtLeastS()) {
-            verify(mBpfDownstream6Map, never()).deleteEntry(any());
-        } else {
-            verify(mNetd, never()).tetherOffloadRuleRemove(any());
-        }
-    }
-
-    private void verifyStartUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int upstreamIfindex,
-            @NonNull Set<IpPrefix> upstreamPrefixes) throws Exception {
-        if (!mBpfDeps.isAtLeastS()) return;
-        ArrayMap<TetherUpstream6Key, Tether6Value> expected = new ArrayMap<>();
-        for (IpPrefix upstreamPrefix : upstreamPrefixes) {
-            long prefix64 = prefixToLong(upstreamPrefix);
-            final TetherUpstream6Key key = new TetherUpstream6Key(TEST_IFACE_PARAMS.index,
-                    TEST_IFACE_PARAMS.macAddr, prefix64);
-            final Tether6Value value = new Tether6Value(upstreamIfindex,
-                    MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
-                    ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
-            expected.put(key, value);
-        }
-        ArgumentCaptor<TetherUpstream6Key> keyCaptor =
-                ArgumentCaptor.forClass(TetherUpstream6Key.class);
-        ArgumentCaptor<Tether6Value> valueCaptor =
-                ArgumentCaptor.forClass(Tether6Value.class);
-        verifyWithOrder(inOrder, mBpfUpstream6Map, times(expected.size())).insertEntry(
-                keyCaptor.capture(), valueCaptor.capture());
-        List<TetherUpstream6Key> keys = keyCaptor.getAllValues();
-        List<Tether6Value> values = valueCaptor.getAllValues();
-        ArrayMap<TetherUpstream6Key, Tether6Value> captured = new ArrayMap<>();
-        for (int i = 0; i < keys.size(); i++) {
-            captured.put(keys.get(i), values.get(i));
-        }
-        assertEquals(expected, captured);
-    }
-
-    private void verifyStopUpstreamIpv6Forwarding(@Nullable InOrder inOrder,
-            @NonNull Set<IpPrefix> upstreamPrefixes) throws Exception {
-        if (!mBpfDeps.isAtLeastS()) return;
-        Set<TetherUpstream6Key> expected = new ArraySet<>();
-        for (IpPrefix upstreamPrefix : upstreamPrefixes) {
-            long prefix64 = prefixToLong(upstreamPrefix);
-            final TetherUpstream6Key key = new TetherUpstream6Key(TEST_IFACE_PARAMS.index,
-                    TEST_IFACE_PARAMS.macAddr, prefix64);
-            expected.add(key);
-        }
-        ArgumentCaptor<TetherUpstream6Key> keyCaptor =
-                ArgumentCaptor.forClass(TetherUpstream6Key.class);
-        verifyWithOrder(inOrder, mBpfUpstream6Map, times(expected.size())).deleteEntry(
-                keyCaptor.capture());
-        assertEquals(expected, new ArraySet(keyCaptor.getAllValues()));
-    }
-
-    private void verifyNoUpstreamIpv6ForwardingChange(@Nullable InOrder inOrder) throws Exception {
-        if (!mBpfDeps.isAtLeastS()) return;
-        if (inOrder != null) {
-            inOrder.verify(mBpfUpstream6Map, never()).deleteEntry(any());
-            inOrder.verify(mBpfUpstream6Map, never()).insertEntry(any(), any());
-            inOrder.verify(mBpfUpstream6Map, never()).updateEntry(any(), any());
-        } else {
-            verify(mBpfUpstream6Map, never()).deleteEntry(any());
-            verify(mBpfUpstream6Map, never()).insertEntry(any(), any());
-            verify(mBpfUpstream6Map, never()).updateEntry(any(), any());
-        }
-    }
-
-    @NonNull
-    private static TetherStatsParcel buildEmptyTetherStatsParcel(int ifIndex) {
-        TetherStatsParcel parcel = new TetherStatsParcel();
-        parcel.ifIndex = ifIndex;
-        return parcel;
-    }
-
-    private void resetNetdBpfMapAndCoordinator() throws Exception {
-        reset(mNetd, mBpfDownstream6Map, mBpfUpstream6Map, mBpfCoordinator);
-        // When the last rule is removed, tetherOffloadGetAndClearStats will log a WTF (and
-        // potentially crash the test) if the stats map is empty.
-        when(mNetd.tetherOffloadGetStats()).thenReturn(new TetherStatsParcel[0]);
-        when(mNetd.tetherOffloadGetAndClearStats(UPSTREAM_IFINDEX))
-                .thenReturn(buildEmptyTetherStatsParcel(UPSTREAM_IFINDEX));
-        when(mNetd.tetherOffloadGetAndClearStats(UPSTREAM_IFINDEX2))
-                .thenReturn(buildEmptyTetherStatsParcel(UPSTREAM_IFINDEX2));
-        // When the last rule is removed, tetherOffloadGetAndClearStats will log a WTF (and
-        // potentially crash the test) if the stats map is empty.
-        final TetherStatsValue allZeros = new TetherStatsValue(0, 0, 0, 0, 0, 0);
-        when(mBpfStatsMap.getValue(new TetherStatsKey(UPSTREAM_IFINDEX))).thenReturn(allZeros);
-        when(mBpfStatsMap.getValue(new TetherStatsKey(UPSTREAM_IFINDEX2))).thenReturn(allZeros);
-    }
-
     @Test
-    public void addRemoveipv6ForwardingRules() throws Exception {
+    public void ipv6UpstreamInterfaceChanges() throws Exception {
         initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, UPSTREAM_ADDRESSES,
                 false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD);
 
-        final int myIfindex = TEST_IFACE_PARAMS.index;
-        final int notMyIfindex = myIfindex - 1;
-
-        final InetAddress neighA = InetAddresses.parseNumericAddress("2001:db8::1");
-        final InetAddress neighB = InetAddresses.parseNumericAddress("2001:db8::2");
-        final InetAddress neighLL = InetAddresses.parseNumericAddress("fe80::1");
-        final InetAddress neighMC = InetAddresses.parseNumericAddress("ff02::1234");
-        final MacAddress macNull = MacAddress.fromString("00:00:00:00:00:00");
-        final MacAddress macA = MacAddress.fromString("00:00:00:00:00:0a");
-        final MacAddress macB = MacAddress.fromString("11:22:33:00:00:0b");
-
-        resetNetdBpfMapAndCoordinator();
-        verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
-
-        // TODO: Perhaps verify the interaction of tetherOffloadSetInterfaceQuota and
-        // tetherOffloadGetAndClearStats in netd while the rules are changed.
-
-        // Events on other interfaces are ignored.
-        recvNewNeigh(notMyIfindex, neighA, NUD_REACHABLE, macA);
-        verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
-
-        // Events on this interface are received and sent to BpfCoordinator.
-        recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
-        verify(mBpfCoordinator).addIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighA, macA));
-        verifyTetherOffloadRuleAdd(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
-        resetNetdBpfMapAndCoordinator();
-
-        recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
-        verify(mBpfCoordinator).addIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighB, macB));
-        verifyTetherOffloadRuleAdd(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
-        resetNetdBpfMapAndCoordinator();
-
-        // Link-local and multicast neighbors are ignored.
-        recvNewNeigh(myIfindex, neighLL, NUD_REACHABLE, macA);
-        verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
-        recvNewNeigh(myIfindex, neighMC, NUD_REACHABLE, macA);
-        verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
-
-        // A neighbor that is no longer valid causes the rule to be removed.
-        // NUD_FAILED events do not have a MAC address.
-        recvNewNeigh(myIfindex, neighA, NUD_FAILED, null);
-        verify(mBpfCoordinator).removeIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighA, macNull));
-        verifyTetherOffloadRuleRemove(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macNull);
-        resetNetdBpfMapAndCoordinator();
-
-        // A neighbor that is deleted causes the rule to be removed.
-        recvDelNeigh(myIfindex, neighB, NUD_STALE, macB);
-        verify(mBpfCoordinator).removeIpv6DownstreamRule(
-                mIpServer,  makeDownstreamRule(UPSTREAM_IFINDEX, neighB, macNull));
-        verifyTetherOffloadRuleRemove(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macNull);
-        resetNetdBpfMapAndCoordinator();
-
         // Upstream interface changes result in updating the rules.
-        recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
-        recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
-        resetNetdBpfMapAndCoordinator();
-
-        InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
         LinkProperties lp = new LinkProperties();
         lp.setInterfaceName(UPSTREAM_IFACE2);
         lp.setLinkAddresses(UPSTREAM_ADDRESSES);
         dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp, -1);
         verify(mBpfCoordinator).updateAllIpv6Rules(
                 mIpServer, TEST_IFACE_PARAMS, UPSTREAM_IFINDEX2, UPSTREAM_PREFIXES);
-        verifyTetherOffloadRuleRemove(inOrder,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
-        verifyTetherOffloadRuleRemove(inOrder,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
-        verifyStopUpstreamIpv6Forwarding(inOrder, UPSTREAM_PREFIXES);
-        verifyStartUpstreamIpv6Forwarding(inOrder, UPSTREAM_IFINDEX2, UPSTREAM_PREFIXES);
-        verifyTetherOffloadRuleAdd(inOrder,
-                UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighA, macA);
-        verifyTetherOffloadRuleAdd(inOrder,
-                UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighB, macB);
-        verifyNoUpstreamIpv6ForwardingChange(inOrder);
-        resetNetdBpfMapAndCoordinator();
+        reset(mBpfCoordinator);
 
         // Upstream link addresses change result in updating the rules.
         LinkProperties lp2 = new LinkProperties();
@@ -1234,17 +776,7 @@
         dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp2, -1);
         verify(mBpfCoordinator).updateAllIpv6Rules(
                 mIpServer, TEST_IFACE_PARAMS, UPSTREAM_IFINDEX2, UPSTREAM_PREFIXES2);
-        verifyTetherOffloadRuleRemove(inOrder,
-                UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighA, macA);
-        verifyTetherOffloadRuleRemove(inOrder,
-                UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighB, macB);
-        verifyStopUpstreamIpv6Forwarding(inOrder, UPSTREAM_PREFIXES);
-        verifyStartUpstreamIpv6Forwarding(inOrder, UPSTREAM_IFINDEX2, UPSTREAM_PREFIXES2);
-        verifyTetherOffloadRuleAdd(inOrder,
-                UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighA, macA);
-        verifyTetherOffloadRuleAdd(inOrder,
-                UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighB, macB);
-        resetNetdBpfMapAndCoordinator();
+        reset(mBpfCoordinator);
 
         // When the upstream is lost, rules are removed.
         dispatchTetherConnectionChanged(null, null, 0);
@@ -1254,156 +786,51 @@
         // See dispatchTetherConnectionChanged.
         verify(mBpfCoordinator, times(2)).updateAllIpv6Rules(
                 mIpServer, TEST_IFACE_PARAMS, NO_UPSTREAM, NO_PREFIXES);
-        verifyStopUpstreamIpv6Forwarding(inOrder, UPSTREAM_PREFIXES2);
-        verifyTetherOffloadRuleRemove(null,
-                UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighA, macA);
-        verifyTetherOffloadRuleRemove(null,
-                UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighB, macB);
-        // Upstream lost doesn't clear the downstream rules from BpfCoordinator.
-        // Do that here.
-        recvDelNeigh(myIfindex, neighA, NUD_STALE, macA);
-        recvDelNeigh(myIfindex, neighB, NUD_STALE, macB);
-        verify(mBpfCoordinator).removeIpv6DownstreamRule(
-                mIpServer,  makeDownstreamRule(NO_UPSTREAM, neighA, macNull));
-        verify(mBpfCoordinator).removeIpv6DownstreamRule(
-                mIpServer,  makeDownstreamRule(NO_UPSTREAM, neighB, macNull));
-        resetNetdBpfMapAndCoordinator();
+        reset(mBpfCoordinator);
 
-        // If the upstream is IPv4-only, no IPv6 rules are added to BPF map.
+        // If the upstream is IPv4-only, no rules are added.
         dispatchTetherConnectionChanged(UPSTREAM_IFACE);
-        resetNetdBpfMapAndCoordinator();
-        recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
-        verifyNoUpstreamIpv6ForwardingChange(null);
-        // Downstream rules are only added to BpfCoordinator but not BPF map.
-        verify(mBpfCoordinator).addIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(NO_UPSTREAM, neighA, macA));
-        verifyNeverTetherOffloadRuleAdd();
-        verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
+        verify(mBpfCoordinator, never()).updateAllIpv6Rules(
+                mIpServer, TEST_IFACE_PARAMS, NO_UPSTREAM, NO_PREFIXES);
+        reset(mBpfCoordinator);
 
-        // Rules can be added again once upstream IPv6 connectivity is available. The existing rules
-        // with an upstream of NO_UPSTREAM are reapplied.
+        // Rules are added again once upstream IPv6 connectivity is available.
         lp.setInterfaceName(UPSTREAM_IFACE);
         dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, -1);
-        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX, UPSTREAM_PREFIXES);
-        verify(mBpfCoordinator).addIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighA, macA));
-        verifyTetherOffloadRuleAdd(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
-        recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
-        verify(mBpfCoordinator).addIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighB, macB));
-        verifyTetherOffloadRuleAdd(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
+        verify(mBpfCoordinator).updateAllIpv6Rules(
+                mIpServer, TEST_IFACE_PARAMS, UPSTREAM_IFINDEX, UPSTREAM_PREFIXES);
+        reset(mBpfCoordinator);
 
         // If upstream IPv6 connectivity is lost, rules are removed.
-        resetNetdBpfMapAndCoordinator();
         dispatchTetherConnectionChanged(UPSTREAM_IFACE, null, 0);
         verify(mBpfCoordinator).updateAllIpv6Rules(
                 mIpServer, TEST_IFACE_PARAMS, NO_UPSTREAM, NO_PREFIXES);
-        verifyTetherOffloadRuleRemove(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
-        verifyStopUpstreamIpv6Forwarding(null, UPSTREAM_PREFIXES);
+        reset(mBpfCoordinator);
 
-        // When upstream IPv6 connectivity comes back, upstream rules are added and downstream rules
-        // are reapplied.
+        // When upstream IPv6 connectivity comes back, rules are added.
         lp.setInterfaceName(UPSTREAM_IFACE);
         dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, -1);
-        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX, UPSTREAM_PREFIXES);
-        verify(mBpfCoordinator).addIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighA, macA));
-        verifyTetherOffloadRuleAdd(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
-        verify(mBpfCoordinator).addIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighB, macB));
-        verifyTetherOffloadRuleAdd(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
-        resetNetdBpfMapAndCoordinator();
+        verify(mBpfCoordinator).updateAllIpv6Rules(
+                mIpServer, TEST_IFACE_PARAMS, UPSTREAM_IFINDEX, UPSTREAM_PREFIXES);
+        reset(mBpfCoordinator);
 
         // When the downstream interface goes down, rules are removed.
         mIpServer.stop();
         mLooper.dispatchAll();
         verify(mBpfCoordinator).clearAllIpv6Rules(mIpServer);
-        verifyStopUpstreamIpv6Forwarding(null, UPSTREAM_PREFIXES);
-        verifyTetherOffloadRuleRemove(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
-        verifyTetherOffloadRuleRemove(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
-        verify(mIpNeighborMonitor).stop();
-        resetNetdBpfMapAndCoordinator();
-    }
-
-    @Test
-    public void enableDisableUsingBpfOffload() throws Exception {
-        final int myIfindex = TEST_IFACE_PARAMS.index;
-        final InetAddress neigh = InetAddresses.parseNumericAddress("2001:db8::1");
-        final MacAddress macA = MacAddress.fromString("00:00:00:00:00:0a");
-        final MacAddress macNull = MacAddress.fromString("00:00:00:00:00:00");
-
-        // Expect that rules can be only added/removed when the BPF offload config is enabled.
-        // Note that the BPF offload disabled case is not a realistic test case. Because IP
-        // neighbor monitor doesn't start if BPF offload is disabled, there should have no
-        // neighbor event listening. This is used for testing the protection check just in case.
-        // TODO: Perhaps remove the BPF offload disabled case test once this check isn't needed
-        // anymore.
-
-        // [1] Enable BPF offload.
-        // A neighbor that is added or deleted causes the rule to be added or removed.
-        initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, UPSTREAM_ADDRESSES,
-                false /* usingLegacyDhcp */, true /* usingBpfOffload */);
-        resetNetdBpfMapAndCoordinator();
-
-        recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, macA);
-        verify(mBpfCoordinator).addIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neigh, macA));
-        verifyTetherOffloadRuleAdd(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neigh, macA);
-        resetNetdBpfMapAndCoordinator();
-
-        recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
-        verify(mBpfCoordinator).removeIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neigh, macNull));
-        verifyTetherOffloadRuleRemove(null,
-                UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neigh, macNull);
-        resetNetdBpfMapAndCoordinator();
-
-        // Upstream IPv6 connectivity change causes upstream rules change.
-        LinkProperties lp2 = new LinkProperties();
-        lp2.setInterfaceName(UPSTREAM_IFACE2);
-        lp2.setLinkAddresses(UPSTREAM_ADDRESSES2);
-        dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp2, 0);
         verify(mBpfCoordinator).updateAllIpv6Rules(
-                mIpServer, TEST_IFACE_PARAMS, UPSTREAM_IFINDEX2, UPSTREAM_PREFIXES2);
-        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX2, UPSTREAM_PREFIXES2);
-        resetNetdBpfMapAndCoordinator();
-
-        // [2] Disable BPF offload.
-        // A neighbor that is added or deleted doesn’t cause the rule to be added or removed.
-        initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, UPSTREAM_ADDRESSES,
-                false /* usingLegacyDhcp */, false /* usingBpfOffload */);
-        resetNetdBpfMapAndCoordinator();
-
-        recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, macA);
-        verifyNeverTetherOffloadRuleAdd();
-        resetNetdBpfMapAndCoordinator();
-
-        recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
-        verifyNeverTetherOffloadRuleRemove();
-        resetNetdBpfMapAndCoordinator();
-
-        // Upstream IPv6 connectivity change doesn't cause the rule to be added or removed.
-        dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp2, 0);
-        verifyNoUpstreamIpv6ForwardingChange(null);
-        verifyNeverTetherOffloadRuleRemove();
-        resetNetdBpfMapAndCoordinator();
+                mIpServer, TEST_IFACE_PARAMS, NO_UPSTREAM, NO_PREFIXES);
+        reset(mBpfCoordinator);
     }
 
     @Test
-    public void doesNotStartIpNeighborMonitorIfBpfOffloadDisabled() throws Exception {
+    public void stopNeighborMonitoringWhenInterfaceDown() throws Exception {
         initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, UPSTREAM_ADDRESSES,
-                false /* usingLegacyDhcp */, false /* usingBpfOffload */);
+                false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD);
 
-        // IP neighbor monitor doesn't start if BPF offload is disabled.
-        verify(mIpNeighborMonitor, never()).start();
+        mIpServer.stop();
+        mLooper.dispatchAll();
+        verify(mIpNeighborMonitor).stop();
     }
 
     private LinkProperties buildIpv6OnlyLinkProperties(final String iface) {
@@ -1659,75 +1086,4 @@
     public void testDadProxyUpdates_EnabledAfterR() throws Exception {
         checkDadProxyEnabled(true);
     }
-
-    @Test
-    public void testSkipVirtualNetworkInBpf() throws Exception {
-        initTetheredStateMachine(TETHERING_BLUETOOTH, null);
-        final LinkProperties v6Only = new LinkProperties();
-        v6Only.setInterfaceName(IPSEC_IFACE);
-        dispatchTetherConnectionChanged(IPSEC_IFACE, v6Only, 0);
-
-        verify(mBpfCoordinator).maybeAttachProgram(IFACE_NAME, IPSEC_IFACE);
-        verify(mNetd).tetherAddForward(IFACE_NAME, IPSEC_IFACE);
-        verify(mNetd).ipfwdAddInterfaceForward(IFACE_NAME, IPSEC_IFACE);
-
-        final int myIfindex = TEST_IFACE_PARAMS.index;
-        final InetAddress neigh = InetAddresses.parseNumericAddress("2001:db8::1");
-        final MacAddress mac = MacAddress.fromString("00:00:00:00:00:0a");
-        recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, mac);
-        verify(mBpfCoordinator, never()).addIpv6DownstreamRule(
-                mIpServer, makeDownstreamRule(IPSEC_IFINDEX, neigh, mac));
-    }
-
-    // TODO: move to BpfCoordinatorTest once IpNeighborMonitor is migrated to BpfCoordinator.
-    @Test
-    public void addRemoveTetherClient() throws Exception {
-        initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, UPSTREAM_ADDRESSES,
-                false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD);
-
-        final int myIfindex = TEST_IFACE_PARAMS.index;
-        final int notMyIfindex = myIfindex - 1;
-
-        final InetAddress neighA = InetAddresses.parseNumericAddress("192.168.80.1");
-        final InetAddress neighB = InetAddresses.parseNumericAddress("192.168.80.2");
-        final InetAddress neighLL = InetAddresses.parseNumericAddress("169.254.0.1");
-        final InetAddress neighMC = InetAddresses.parseNumericAddress("224.0.0.1");
-        final MacAddress macNull = MacAddress.fromString("00:00:00:00:00:00");
-        final MacAddress macA = MacAddress.fromString("00:00:00:00:00:0a");
-        final MacAddress macB = MacAddress.fromString("11:22:33:00:00:0b");
-
-        // Events on other interfaces are ignored.
-        recvNewNeigh(notMyIfindex, neighA, NUD_REACHABLE, macA);
-        verifyNoMoreInteractions(mBpfCoordinator);
-
-        // Events on this interface are received and sent to BpfCoordinator.
-        recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
-        verify(mBpfCoordinator).tetherOffloadClientAdd(mIpServer, new ClientInfo(myIfindex,
-                TEST_IFACE_PARAMS.macAddr, (Inet4Address) neighA, macA));
-        clearInvocations(mBpfCoordinator);
-
-        recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
-        verify(mBpfCoordinator).tetherOffloadClientAdd(mIpServer, new ClientInfo(myIfindex,
-                TEST_IFACE_PARAMS.macAddr, (Inet4Address) neighB, macB));
-        clearInvocations(mBpfCoordinator);
-
-        // Link-local and multicast neighbors are ignored.
-        recvNewNeigh(myIfindex, neighLL, NUD_REACHABLE, macA);
-        verifyNoMoreInteractions(mBpfCoordinator);
-        recvNewNeigh(myIfindex, neighMC, NUD_REACHABLE, macA);
-        verifyNoMoreInteractions(mBpfCoordinator);
-        clearInvocations(mBpfCoordinator);
-
-        // A neighbor that is no longer valid causes the client to be removed.
-        // NUD_FAILED events do not have a MAC address.
-        recvNewNeigh(myIfindex, neighA, NUD_FAILED, null);
-        verify(mBpfCoordinator).tetherOffloadClientRemove(mIpServer,  new ClientInfo(myIfindex,
-                TEST_IFACE_PARAMS.macAddr, (Inet4Address) neighA, macNull));
-        clearInvocations(mBpfCoordinator);
-
-        // A neighbor that is deleted causes the client to be removed.
-        recvDelNeigh(myIfindex, neighB, NUD_STALE, macB);
-        verify(mBpfCoordinator).tetherOffloadClientRemove(mIpServer, new ClientInfo(myIfindex,
-                TEST_IFACE_PARAMS.macAddr, (Inet4Address) neighB, macNull));
-    }
 }
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index 7fbb670..6c1721e 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -25,6 +25,8 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.NetworkStats.UID_TETHERING;
+import static android.net.TetheringManager.TETHERING_WIFI;
+import static android.net.ip.IpServer.STATE_TETHERED;
 import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
 import static android.system.OsConstants.ETH_P_IP;
 import static android.system.OsConstants.ETH_P_IPV6;
@@ -43,6 +45,11 @@
 import static com.android.net.module.util.netlink.ConntrackMessage.TupleProto;
 import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_DELETE;
 import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_NEW;
+import static com.android.net.module.util.netlink.NetlinkConstants.RTM_DELNEIGH;
+import static com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWNEIGH;
+import static com.android.net.module.util.netlink.StructNdMsg.NUD_FAILED;
+import static com.android.net.module.util.netlink.StructNdMsg.NUD_REACHABLE;
+import static com.android.net.module.util.netlink.StructNdMsg.NUD_STALE;
 import static com.android.networkstack.tethering.BpfCoordinator.CONNTRACK_TIMEOUT_UPDATE_INTERVAL_MS;
 import static com.android.networkstack.tethering.BpfCoordinator.INVALID_MTU;
 import static com.android.networkstack.tethering.BpfCoordinator.NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED;
@@ -71,11 +78,15 @@
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.argThat;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.usage.NetworkStatsManager;
@@ -88,13 +99,16 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkStats;
+import android.net.RoutingCoordinatorManager;
 import android.net.TetherOffloadRuleParcel;
 import android.net.TetherStatsParcel;
 import android.net.ip.IpServer;
+import android.net.ip.RouterAdvertisementDaemon;
 import android.os.Build;
 import android.os.Handler;
 import android.os.test.TestLooper;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.SparseArray;
 
 import androidx.annotation.NonNull;
@@ -104,10 +118,12 @@
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.modules.utils.build.SdkLevel;
 import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.IBpfMap;
 import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.NetworkStackConstants;
+import com.android.net.module.util.SdkUtil.LateSdk;
 import com.android.net.module.util.SharedLog;
 import com.android.net.module.util.Struct.S32;
 import com.android.net.module.util.bpf.Tether4Key;
@@ -116,6 +132,9 @@
 import com.android.net.module.util.bpf.TetherStatsValue;
 import com.android.net.module.util.ip.ConntrackMonitor;
 import com.android.net.module.util.ip.ConntrackMonitor.ConntrackEventConsumer;
+import com.android.net.module.util.ip.IpNeighborMonitor;
+import com.android.net.module.util.ip.IpNeighborMonitor.NeighborEvent;
+import com.android.net.module.util.ip.IpNeighborMonitor.NeighborEventConsumer;
 import com.android.net.module.util.netlink.ConntrackMessage;
 import com.android.net.module.util.netlink.NetlinkConstants;
 import com.android.net.module.util.netlink.NetlinkUtils;
@@ -123,6 +142,8 @@
 import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
 import com.android.networkstack.tethering.BpfCoordinator.Ipv6DownstreamRule;
 import com.android.networkstack.tethering.BpfCoordinator.Ipv6UpstreamRule;
+import com.android.networkstack.tethering.metrics.TetheringMetrics;
+import com.android.networkstack.tethering.util.InterfaceSet;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -172,19 +193,27 @@
     private static final int UPSTREAM_IFINDEX2 = 1003;
     private static final int DOWNSTREAM_IFINDEX = 2001;
     private static final int DOWNSTREAM_IFINDEX2 = 2002;
+    private static final int IPSEC_IFINDEX = 103;
 
     private static final String UPSTREAM_IFACE = "rmnet0";
     private static final String UPSTREAM_XLAT_IFACE = "v4-rmnet0";
     private static final String UPSTREAM_IFACE2 = "wlan0";
     private static final String DOWNSTREAM_IFACE = "downstream1";
     private static final String DOWNSTREAM_IFACE2 = "downstream2";
+    private static final String IPSEC_IFACE = "ipsec0";
 
     private static final MacAddress DOWNSTREAM_MAC = MacAddress.fromString("12:34:56:78:90:ab");
     private static final MacAddress DOWNSTREAM_MAC2 = MacAddress.fromString("ab:90:78:56:34:12");
 
     private static final MacAddress MAC_A = MacAddress.fromString("00:00:00:00:00:0a");
     private static final MacAddress MAC_B = MacAddress.fromString("11:22:33:00:00:0b");
+    private static final MacAddress MAC_NULL = MacAddress.fromString("00:00:00:00:00:00");
 
+    private static final LinkAddress UPSTREAM_ADDRESS = new LinkAddress("2001:db8:0:1234::168/64");
+    private static final LinkAddress UPSTREAM_ADDRESS2 = new LinkAddress("2001:db8:0:abcd::168/64");
+    private static final Set<LinkAddress> UPSTREAM_ADDRESSES = Set.of(UPSTREAM_ADDRESS);
+    private static final Set<LinkAddress> UPSTREAM_ADDRESSES2 =
+            Set.of(UPSTREAM_ADDRESS, UPSTREAM_ADDRESS2);
     private static final IpPrefix UPSTREAM_PREFIX = new IpPrefix("2001:db8:0:1234::/64");
     private static final IpPrefix UPSTREAM_PREFIX2 = new IpPrefix("2001:db8:0:abcd::/64");
     private static final Set<IpPrefix> UPSTREAM_PREFIXES = Set.of(UPSTREAM_PREFIX);
@@ -196,6 +225,8 @@
             InetAddresses.parseNumericAddress("2001:db8:0:1234::1");
     private static final InetAddress NEIGH_B =
             InetAddresses.parseNumericAddress("2001:db8:0:1234::2");
+    private static final InetAddress NEIGH_LL = InetAddresses.parseNumericAddress("fe80::1");
+    private static final InetAddress NEIGH_MC = InetAddresses.parseNumericAddress("ff02::1234");
 
     private static final Inet4Address REMOTE_ADDR =
             (Inet4Address) InetAddresses.parseNumericAddress("140.112.8.116");
@@ -235,6 +266,9 @@
     private static final InterfaceParams DOWNSTREAM_IFACE_PARAMS2 = new InterfaceParams(
             DOWNSTREAM_IFACE2, DOWNSTREAM_IFINDEX2, DOWNSTREAM_MAC2,
             NetworkStackConstants.ETHER_MTU);
+    private static final InterfaceParams IPSEC_IFACE_PARAMS = new InterfaceParams(
+            IPSEC_IFACE, IPSEC_IFINDEX, MacAddress.ALL_ZEROS_ADDRESS,
+            NetworkStackConstants.ETHER_MTU);
 
     private static final Map<Integer, UpstreamInformation> UPSTREAM_INFORMATIONS = Map.of(
             UPSTREAM_IFINDEX, new UpstreamInformation(UPSTREAM_IFACE_PARAMS,
@@ -414,6 +448,14 @@
     @Mock private IpServer mIpServer2;
     @Mock private TetheringConfiguration mTetherConfig;
     @Mock private ConntrackMonitor mConntrackMonitor;
+    @Mock private IpNeighborMonitor mIpNeighborMonitor;
+    @Mock private RouterAdvertisementDaemon mRaDaemon;
+    @Mock private IpServer.Dependencies mIpServerDeps;
+    @Mock private IpServer.Callback mIpServerCallback;
+    @Mock private PrivateAddressCoordinator mAddressCoordinator;
+    private final LateSdk<RoutingCoordinatorManager> mRoutingCoordinatorManager =
+            new LateSdk<>(SdkLevel.isAtLeastS() ? mock(RoutingCoordinatorManager.class) : null);
+    @Mock private TetheringMetrics mTetheringMetrics;
 
     // Late init since methods must be called by the thread that created this object.
     private TestableNetworkStatsProviderCbBinder mTetherStatsProviderCb;
@@ -422,6 +464,7 @@
     // Late init since the object must be initialized by the BPF coordinator instance because
     // it has to access the non-static function of BPF coordinator.
     private BpfConntrackEventConsumer mConsumer;
+    private NeighborEventConsumer mNeighborEventConsumer;
     private HashMap<IpServer, HashMap<Inet4Address, ClientInfo>> mTetherClients;
 
     private long mElapsedRealtimeNanos = 0;
@@ -429,6 +472,7 @@
     private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
             ArgumentCaptor.forClass(ArrayList.class);
     private final TestLooper mTestLooper = new TestLooper();
+    private final Handler mHandler = new Handler(mTestLooper.getLooper());
     private final IBpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map =
             spy(new TestBpfMap<>(Tether4Key.class, Tether4Value.class));
     private final IBpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map =
@@ -449,7 +493,7 @@
             spy(new BpfCoordinator.Dependencies() {
                     @NonNull
                     public Handler getHandler() {
-                        return new Handler(mTestLooper.getLooper());
+                        return mHandler;
                     }
 
                     @NonNull
@@ -529,6 +573,24 @@
     @Before public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(true /* default value */);
+
+        // Simulate the behavior of RoutingCoordinator
+        if (null != mRoutingCoordinatorManager.value) {
+            doAnswer(it -> {
+                final String fromIface = (String) it.getArguments()[0];
+                final String toIface = (String) it.getArguments()[1];
+                mNetd.tetherAddForward(fromIface, toIface);
+                mNetd.ipfwdAddInterfaceForward(fromIface, toIface);
+                return null;
+            }).when(mRoutingCoordinatorManager.value).addInterfaceForward(any(), any());
+            doAnswer(it -> {
+                final String fromIface = (String) it.getArguments()[0];
+                final String toIface = (String) it.getArguments()[1];
+                mNetd.ipfwdRemoveInterfaceForward(fromIface, toIface);
+                mNetd.tetherRemoveForward(fromIface, toIface);
+                return null;
+            }).when(mRoutingCoordinatorManager.value).removeInterfaceForward(any(), any());
+        }
     }
 
     private void waitForIdle() {
@@ -542,7 +604,68 @@
     }
 
     @NonNull
+    private IpServer makeAndStartIpServer(String interfaceName, BpfCoordinator bpfCoordinator)
+            throws Exception {
+        final LinkAddress testAddress = new LinkAddress("192.168.42.5/24");
+        when(mIpServerDeps.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon);
+        when(mIpServerDeps.getInterfaceParams(DOWNSTREAM_IFACE)).thenReturn(
+                DOWNSTREAM_IFACE_PARAMS);
+        when(mIpServerDeps.getInterfaceParams(UPSTREAM_IFACE)).thenReturn(UPSTREAM_IFACE_PARAMS);
+        when(mIpServerDeps.getInterfaceParams(UPSTREAM_IFACE2)).thenReturn(UPSTREAM_IFACE_PARAMS2);
+        when(mIpServerDeps.getInterfaceParams(IPSEC_IFACE)).thenReturn(IPSEC_IFACE_PARAMS);
+        when(mAddressCoordinator.requestDownstreamAddress(any(), anyInt(),
+                anyBoolean())).thenReturn(testAddress);
+        when(mRaDaemon.start()).thenReturn(true);
+        ArgumentCaptor<NeighborEventConsumer> neighborEventCaptor =
+                ArgumentCaptor.forClass(NeighborEventConsumer.class);
+        doReturn(mIpNeighborMonitor).when(mIpServerDeps).getIpNeighborMonitor(any(), any(),
+                neighborEventCaptor.capture());
+        final IpServer ipServer = new IpServer(
+                interfaceName, mHandler, TETHERING_WIFI, new SharedLog("test"), mNetd,
+                bpfCoordinator, mRoutingCoordinatorManager, mIpServerCallback, mTetherConfig,
+                mAddressCoordinator, mTetheringMetrics, mIpServerDeps);
+        ipServer.start();
+        ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
+        mTestLooper.dispatchAll();
+
+        LinkProperties lp = new LinkProperties();
+        lp.setInterfaceName(UPSTREAM_IFACE);
+        lp.setLinkAddresses(UPSTREAM_ADDRESSES);
+        dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE, lp, 0);
+
+        mNeighborEventConsumer = neighborEventCaptor.getValue();
+        return ipServer;
+    }
+
+    private void dispatchTetherConnectionChanged(IpServer ipServer, String upstreamIface,
+            LinkProperties v6lp, int ttlAdjustment) {
+        dispatchTetherConnectionChanged(ipServer, upstreamIface);
+        ipServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, ttlAdjustment, 0, v6lp);
+        mTestLooper.dispatchAll();
+    }
+
+    private void dispatchTetherConnectionChanged(IpServer ipServer, String upstreamIface) {
+        final InterfaceSet ifs = (upstreamIface != null) ? new InterfaceSet(upstreamIface) : null;
+        ipServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifs);
+        mTestLooper.dispatchAll();
+    }
+
+    private void recvNewNeigh(int ifindex, InetAddress addr, short nudState, MacAddress mac) {
+        mNeighborEventConsumer.accept(new NeighborEvent(0, RTM_NEWNEIGH, ifindex, addr,
+                nudState, mac));
+        mTestLooper.dispatchAll();
+    }
+
+    private void recvDelNeigh(int ifindex, InetAddress addr, short nudState, MacAddress mac) {
+        mNeighborEventConsumer.accept(new NeighborEvent(0, RTM_DELNEIGH, ifindex, addr,
+                nudState, mac));
+        mTestLooper.dispatchAll();
+    }
+
+    @NonNull
     private BpfCoordinator makeBpfCoordinator() throws Exception {
+        // mStatsManager will be invoked twice if BpfCoordinator is created the second time.
+        clearInvocations(mStatsManager);
         final BpfCoordinator coordinator = new BpfCoordinator(mDeps);
 
         mConsumer = coordinator.getBpfConntrackEventConsumerForTesting();
@@ -666,6 +789,51 @@
         }
     }
 
+    private void verifyStartUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int upstreamIfindex,
+            @NonNull Set<IpPrefix> upstreamPrefixes) throws Exception {
+        if (!mDeps.isAtLeastS()) return;
+        ArrayMap<TetherUpstream6Key, Tether6Value> expected = new ArrayMap<>();
+        for (IpPrefix upstreamPrefix : upstreamPrefixes) {
+            long prefix64 = prefixToLong(upstreamPrefix);
+            final TetherUpstream6Key key = new TetherUpstream6Key(DOWNSTREAM_IFACE_PARAMS.index,
+                    DOWNSTREAM_IFACE_PARAMS.macAddr, prefix64);
+            final Tether6Value value = new Tether6Value(upstreamIfindex,
+                    MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS, ETH_P_IPV6,
+                    NetworkStackConstants.ETHER_MTU);
+            expected.put(key, value);
+        }
+        ArgumentCaptor<TetherUpstream6Key> keyCaptor =
+                ArgumentCaptor.forClass(TetherUpstream6Key.class);
+        ArgumentCaptor<Tether6Value> valueCaptor =
+                ArgumentCaptor.forClass(Tether6Value.class);
+        verifyWithOrder(inOrder, mBpfUpstream6Map, times(expected.size())).insertEntry(
+                keyCaptor.capture(), valueCaptor.capture());
+        List<TetherUpstream6Key> keys = keyCaptor.getAllValues();
+        List<Tether6Value> values = valueCaptor.getAllValues();
+        ArrayMap<TetherUpstream6Key, Tether6Value> captured = new ArrayMap<>();
+        for (int i = 0; i < keys.size(); i++) {
+            captured.put(keys.get(i), values.get(i));
+        }
+        assertEquals(expected, captured);
+    }
+
+    private void verifyStopUpstreamIpv6Forwarding(@Nullable InOrder inOrder,
+            @NonNull Set<IpPrefix> upstreamPrefixes) throws Exception {
+        if (!mDeps.isAtLeastS()) return;
+        Set<TetherUpstream6Key> expected = new ArraySet<>();
+        for (IpPrefix upstreamPrefix : upstreamPrefixes) {
+            long prefix64 = prefixToLong(upstreamPrefix);
+            final TetherUpstream6Key key = new TetherUpstream6Key(DOWNSTREAM_IFACE_PARAMS.index,
+                    DOWNSTREAM_IFACE_PARAMS.macAddr, prefix64);
+            expected.add(key);
+        }
+        ArgumentCaptor<TetherUpstream6Key> keyCaptor =
+                ArgumentCaptor.forClass(TetherUpstream6Key.class);
+        verifyWithOrder(inOrder, mBpfUpstream6Map, times(expected.size())).deleteEntry(
+                keyCaptor.capture());
+        assertEquals(expected, new ArraySet(keyCaptor.getAllValues()));
+    }
+
     private void verifyNoUpstreamIpv6ForwardingChange(@Nullable InOrder inOrder) throws Exception {
         if (!mDeps.isAtLeastS()) return;
         if (inOrder != null) {
@@ -708,6 +876,10 @@
         assertEquals(expected, captured);
     }
 
+    private void verifyAddDownstreamRule(@NonNull Ipv6DownstreamRule rule) throws Exception {
+        verifyAddDownstreamRule(null, rule);
+    }
+
     private void verifyAddDownstreamRule(@Nullable InOrder inOrder,
             @NonNull Ipv6DownstreamRule rule) throws Exception {
         if (mDeps.isAtLeastS()) {
@@ -752,6 +924,11 @@
         assertSameElements(expected, keyCaptor.getAllValues());
     }
 
+    private void verifyRemoveDownstreamRule(@NonNull final Ipv6DownstreamRule rule)
+            throws Exception {
+        verifyRemoveDownstreamRule(null, rule);
+    }
+
     private void verifyRemoveDownstreamRule(@Nullable InOrder inOrder,
             @NonNull final Ipv6DownstreamRule rule) throws Exception {
         if (mDeps.isAtLeastS()) {
@@ -1016,8 +1193,37 @@
         mTetherStatsProviderCb.assertNoCallback();
     }
 
-    // The custom ArgumentMatcher simply comes from IpServerTest.
-    // TODO: move both of them into a common utility class for reusing the code.
+    /**
+     * Custom ArgumentMatcher for TetherOffloadRuleParcel. This is needed because generated stable
+     * AIDL classes don't have equals(), so we cannot just use eq(). A custom assert, such as:
+     *
+     * private void checkFooCalled(StableParcelable p, ...) {
+     *     ArgumentCaptor<@FooParam> captor = ArgumentCaptor.forClass(FooParam.class);
+     *     verify(mMock).foo(captor.capture());
+     *     Foo foo = captor.getValue();
+     *     assertFooMatchesExpectations(foo);
+     * }
+     *
+     * almost works, but not quite. This is because if the code under test calls foo() twice, the
+     * first call to checkFooCalled() matches both the calls, putting both calls into the captor,
+     * and then fails with TooManyActualInvocations. It also makes it harder to use other mockito
+     * features such as never(), inOrder(), etc.
+     *
+     * This approach isn't great because if the match fails, the error message is unhelpful
+     * (actual: "android.net.TetherOffloadRuleParcel@8c827b0" or some such), but at least it does
+     * work.
+     *
+     * TODO: consider making the error message more readable by adding a method that catching the
+     * AssertionFailedError and throwing a new assertion with more details. See
+     * NetworkMonitorTest#verifyNetworkTested.
+     *
+     * See ConnectivityServiceTest#assertRoutesAdded for an alternative approach which solves the
+     * TooManyActualInvocations problem described above by forcing the caller of the custom assert
+     * method to specify all expected invocations in one call. This is useful when the stable
+     * parcelable class being asserted on has a corresponding Java object (eg., RouteInfo and
+     * RouteInfoParcelable), and the caller can just pass in a list of them. It not useful here
+     * because there is no such object.
+     */
     private static class TetherOffloadRuleParcelMatcher implements
             ArgumentMatcher<TetherOffloadRuleParcel> {
         public final int upstreamIfindex;
@@ -2064,8 +2270,7 @@
     }
 
     private static long prefixToLong(IpPrefix prefix) {
-        byte[] prefixBytes = Arrays.copyOf(prefix.getRawAddress(), 8);
-        return ByteBuffer.wrap(prefixBytes).getLong();
+        return ByteBuffer.wrap(prefix.getRawAddress()).getLong();
     }
 
     void checkRule4ExistInUpstreamDownstreamMap() throws Exception {
@@ -2135,7 +2340,7 @@
         assertNull(mTetherClients.get(mIpServer2));
     }
 
-    private void asseertClientInfoExist(@NonNull IpServer ipServer,
+    private void assertClientInfoExists(@NonNull IpServer ipServer,
             @NonNull ClientInfo clientInfo) {
         HashMap<Inet4Address, ClientInfo> clients = mTetherClients.get(ipServer);
         assertNotNull(clients);
@@ -2144,16 +2349,16 @@
 
     // Although either ClientInfo for a given downstream (IpServer) is not found or a given
     // client address is not found on a given downstream can be treated "ClientInfo not
-    // exist", we still want to know the real reason exactly. For example, we don't the
+    // exist", we still want to know the real reason exactly. For example, we don't know the
     // exact reason in the following:
-    //   assertNull(clients == null ? clients : clients.get(clientInfo.clientAddress));
+    //   assertNull(clients == null ? clients : clients.get(clientAddress));
     // This helper only verifies the case that the downstream still has at least one client.
     // In other words, ClientInfo for a given IpServer has not been removed yet.
-    private void asseertClientInfoNotExist(@NonNull IpServer ipServer,
-            @NonNull ClientInfo clientInfo) {
+    private void assertClientInfoDoesNotExist(@NonNull IpServer ipServer,
+            @NonNull Inet4Address clientAddress) {
         HashMap<Inet4Address, ClientInfo> clients = mTetherClients.get(ipServer);
         assertNotNull(clients);
-        assertNull(clients.get(clientInfo.clientAddress));
+        assertNull(clients.get(clientAddress));
     }
 
     @Test
@@ -2189,8 +2394,8 @@
         checkRule4NotExistInUpstreamDownstreamMap();
 
         // Client information should be not deleted.
-        asseertClientInfoExist(mIpServer, CLIENT_INFO_A);
-        asseertClientInfoExist(mIpServer2, CLIENT_INFO_B);
+        assertClientInfoExists(mIpServer, CLIENT_INFO_A);
+        assertClientInfoExists(mIpServer2, CLIENT_INFO_B);
     }
 
     @Test
@@ -2205,8 +2410,8 @@
                 PRIVATE_ADDR2, MAC_B);
         coordinator.tetherOffloadClientAdd(mIpServer, clientA);
         coordinator.tetherOffloadClientAdd(mIpServer, clientB);
-        asseertClientInfoExist(mIpServer, clientA);
-        asseertClientInfoExist(mIpServer, clientB);
+        assertClientInfoExists(mIpServer, clientA);
+        assertClientInfoExists(mIpServer, clientB);
 
         // Add the rules for client A and client B.
         final Tether4Key upstream4KeyA = makeUpstream4Key(
@@ -2230,8 +2435,8 @@
         // [2] Remove client information A. Only the rules on client A should be removed and
         // the rules on client B should exist.
         coordinator.tetherOffloadClientRemove(mIpServer, clientA);
-        asseertClientInfoNotExist(mIpServer, clientA);
-        asseertClientInfoExist(mIpServer, clientB);
+        assertClientInfoDoesNotExist(mIpServer, clientA.clientAddress);
+        assertClientInfoExists(mIpServer, clientB);
         assertNull(mBpfUpstream4Map.getValue(upstream4KeyA));
         assertNull(mBpfDownstream4Map.getValue(downstream4KeyA));
         assertEquals(upstream4ValueB, mBpfUpstream4Map.getValue(upstream4KeyB));
@@ -2239,9 +2444,9 @@
 
         // [3] Remove client information B. The rules on client B should be removed.
         // Exactly, ClientInfo for a given IpServer is removed because the last client B
-        // has been removed from the downstream. Can't use the helper #asseertClientInfoExist
+        // has been removed from the downstream. Can't use the helper #assertClientInfoExists
         // to check because the container ClientInfo for a given downstream has been removed.
-        // See #asseertClientInfoExist.
+        // See #assertClientInfoExists.
         coordinator.tetherOffloadClientRemove(mIpServer, clientB);
         assertNull(mTetherClients.get(mIpServer));
         assertNull(mBpfUpstream4Map.getValue(upstream4KeyB));
@@ -2581,4 +2786,296 @@
     public void testUpdateUpstreamNetworkState() throws Exception {
         verifyUpdateUpstreamNetworkState();
     }
+
+    @NonNull
+    private static TetherStatsParcel buildEmptyTetherStatsParcel(int ifIndex) {
+        TetherStatsParcel parcel = new TetherStatsParcel();
+        parcel.ifIndex = ifIndex;
+        return parcel;
+    }
+
+    private void resetNetdAndBpfMaps() throws Exception {
+        reset(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
+        // When the last rule is removed, tetherOffloadGetAndClearStats will log a WTF (and
+        // potentially crash the test) if the stats map is empty.
+        when(mNetd.tetherOffloadGetStats()).thenReturn(new TetherStatsParcel[0]);
+        when(mNetd.tetherOffloadGetAndClearStats(UPSTREAM_IFINDEX))
+                .thenReturn(buildEmptyTetherStatsParcel(UPSTREAM_IFINDEX));
+        when(mNetd.tetherOffloadGetAndClearStats(UPSTREAM_IFINDEX2))
+                .thenReturn(buildEmptyTetherStatsParcel(UPSTREAM_IFINDEX2));
+        // When the last rule is removed, tetherOffloadGetAndClearStats will log a WTF (and
+        // potentially crash the test) if the stats map is empty.
+        final TetherStatsValue allZeros = new TetherStatsValue(0, 0, 0, 0, 0, 0);
+        when(mBpfStatsMap.getValue(new TetherStatsKey(UPSTREAM_IFINDEX))).thenReturn(allZeros);
+        when(mBpfStatsMap.getValue(new TetherStatsKey(UPSTREAM_IFINDEX2))).thenReturn(allZeros);
+    }
+
+    @Test
+    public void addRemoveIpv6ForwardingRules() throws Exception {
+        final int myIfindex = DOWNSTREAM_IFINDEX;
+        final int notMyIfindex = myIfindex - 1;
+        final BpfCoordinator coordinator = makeBpfCoordinator();
+        final IpServer ipServer = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator);
+
+        resetNetdAndBpfMaps();
+        verifyNoMoreInteractions(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
+
+        // TODO: Perhaps verify the interaction of tetherOffloadSetInterfaceQuota and
+        // tetherOffloadGetAndClearStats in netd while the rules are changed.
+
+        // Events on other interfaces are ignored.
+        recvNewNeigh(notMyIfindex, NEIGH_A, NUD_REACHABLE, MAC_A);
+        verifyNoMoreInteractions(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
+
+        // Events on this interface are received and sent to BpfCoordinator.
+        recvNewNeigh(myIfindex, NEIGH_A, NUD_REACHABLE, MAC_A);
+        final Ipv6DownstreamRule ruleA = buildTestDownstreamRule(UPSTREAM_IFINDEX, NEIGH_A, MAC_A);
+        verifyAddDownstreamRule(ruleA);
+        resetNetdAndBpfMaps();
+
+        recvNewNeigh(myIfindex, NEIGH_B, NUD_REACHABLE, MAC_B);
+        final Ipv6DownstreamRule ruleB = buildTestDownstreamRule(UPSTREAM_IFINDEX, NEIGH_B, MAC_B);
+        verifyAddDownstreamRule(ruleB);
+        resetNetdAndBpfMaps();
+
+        // Link-local and multicast neighbors are ignored.
+        recvNewNeigh(myIfindex, NEIGH_LL, NUD_REACHABLE, MAC_A);
+        verifyNoMoreInteractions(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
+        recvNewNeigh(myIfindex, NEIGH_MC, NUD_REACHABLE, MAC_A);
+        verifyNoMoreInteractions(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
+
+        // A neighbor that is no longer valid causes the rule to be removed.
+        // NUD_FAILED events do not have a MAC address.
+        recvNewNeigh(myIfindex, NEIGH_A, NUD_FAILED, null);
+        final Ipv6DownstreamRule ruleANull = buildTestDownstreamRule(
+                UPSTREAM_IFINDEX, NEIGH_A, MAC_NULL);
+        verifyRemoveDownstreamRule(ruleANull);
+        resetNetdAndBpfMaps();
+
+        // A neighbor that is deleted causes the rule to be removed.
+        recvDelNeigh(myIfindex, NEIGH_B, NUD_STALE, MAC_B);
+        final Ipv6DownstreamRule ruleBNull = buildTestDownstreamRule(
+                UPSTREAM_IFINDEX, NEIGH_B, MAC_NULL);
+        verifyRemoveDownstreamRule(ruleBNull);
+        resetNetdAndBpfMaps();
+
+        // Upstream interface changes result in updating the rules.
+        recvNewNeigh(myIfindex, NEIGH_A, NUD_REACHABLE, MAC_A);
+        recvNewNeigh(myIfindex, NEIGH_B, NUD_REACHABLE, MAC_B);
+        resetNetdAndBpfMaps();
+
+        InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
+        LinkProperties lp = new LinkProperties();
+        lp.setInterfaceName(UPSTREAM_IFACE2);
+        lp.setLinkAddresses(UPSTREAM_ADDRESSES);
+        dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE2, lp, -1);
+        final Ipv6DownstreamRule ruleA2 = buildTestDownstreamRule(
+                UPSTREAM_IFINDEX2, NEIGH_A, MAC_A);
+        final Ipv6DownstreamRule ruleB2 = buildTestDownstreamRule(
+                UPSTREAM_IFINDEX2, NEIGH_B, MAC_B);
+        verifyRemoveDownstreamRule(inOrder, ruleA);
+        verifyRemoveDownstreamRule(inOrder, ruleB);
+        verifyStopUpstreamIpv6Forwarding(inOrder, UPSTREAM_PREFIXES);
+        verifyStartUpstreamIpv6Forwarding(inOrder, UPSTREAM_IFINDEX2, UPSTREAM_PREFIXES);
+        verifyAddDownstreamRule(inOrder, ruleA2);
+        verifyAddDownstreamRule(inOrder, ruleB2);
+        verifyNoUpstreamIpv6ForwardingChange(inOrder);
+        resetNetdAndBpfMaps();
+
+        // Upstream link addresses change result in updating the rules.
+        LinkProperties lp2 = new LinkProperties();
+        lp2.setInterfaceName(UPSTREAM_IFACE2);
+        lp2.setLinkAddresses(UPSTREAM_ADDRESSES2);
+        dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE2, lp2, -1);
+        verifyRemoveDownstreamRule(inOrder, ruleA2);
+        verifyRemoveDownstreamRule(inOrder, ruleB2);
+        verifyStopUpstreamIpv6Forwarding(inOrder, UPSTREAM_PREFIXES);
+        verifyStartUpstreamIpv6Forwarding(inOrder, UPSTREAM_IFINDEX2, UPSTREAM_PREFIXES2);
+        verifyAddDownstreamRule(inOrder, ruleA2);
+        verifyAddDownstreamRule(inOrder, ruleB2);
+        resetNetdAndBpfMaps();
+
+        // When the upstream is lost, rules are removed.
+        dispatchTetherConnectionChanged(ipServer, null, null, 0);
+        verifyStopUpstreamIpv6Forwarding(inOrder, UPSTREAM_PREFIXES2);
+        verifyRemoveDownstreamRule(ruleA2);
+        verifyRemoveDownstreamRule(ruleB2);
+        // Upstream lost doesn't clear the downstream rules from the maps.
+        // Do that here.
+        recvDelNeigh(myIfindex, NEIGH_A, NUD_STALE, MAC_A);
+        recvDelNeigh(myIfindex, NEIGH_B, NUD_STALE, MAC_B);
+        resetNetdAndBpfMaps();
+
+        // If the upstream is IPv4-only, no IPv6 rules are added to BPF map.
+        dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE);
+        resetNetdAndBpfMaps();
+        recvNewNeigh(myIfindex, NEIGH_A, NUD_REACHABLE, MAC_A);
+        verifyNoUpstreamIpv6ForwardingChange(null);
+        // Downstream rules are only added to BpfCoordinator but not BPF map.
+        verifyNeverAddDownstreamRule();
+        verifyNoMoreInteractions(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
+
+        // Rules can be added again once upstream IPv6 connectivity is available. The existing rules
+        // with an upstream of NO_UPSTREAM are reapplied.
+        lp.setInterfaceName(UPSTREAM_IFACE);
+        dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE, lp, -1);
+        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX, UPSTREAM_PREFIXES);
+        verifyAddDownstreamRule(ruleA);
+        recvNewNeigh(myIfindex, NEIGH_B, NUD_REACHABLE, MAC_B);
+        verifyAddDownstreamRule(ruleB);
+
+        // If upstream IPv6 connectivity is lost, rules are removed.
+        resetNetdAndBpfMaps();
+        dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE, null, 0);
+        verifyRemoveDownstreamRule(ruleA);
+        verifyRemoveDownstreamRule(ruleB);
+        verifyStopUpstreamIpv6Forwarding(null, UPSTREAM_PREFIXES);
+
+        // When upstream IPv6 connectivity comes back, upstream rules are added and downstream rules
+        // are reapplied.
+        lp.setInterfaceName(UPSTREAM_IFACE);
+        dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE, lp, -1);
+        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX, UPSTREAM_PREFIXES);
+        verifyAddDownstreamRule(ruleA);
+        verifyAddDownstreamRule(ruleB);
+        resetNetdAndBpfMaps();
+
+        // When the downstream interface goes down, rules are removed.
+        ipServer.stop();
+        mTestLooper.dispatchAll();
+        verifyStopUpstreamIpv6Forwarding(null, UPSTREAM_PREFIXES);
+        verifyRemoveDownstreamRule(ruleA);
+        verifyRemoveDownstreamRule(ruleB);
+        verify(mIpNeighborMonitor).stop();
+        resetNetdAndBpfMaps();
+    }
+
+    @Test
+    public void enableDisableUsingBpfOffload() throws Exception {
+        final int myIfindex = DOWNSTREAM_IFINDEX;
+
+        // Expect that rules can be only added/removed when the BPF offload config is enabled.
+        // Note that the BPF offload disabled case is not a realistic test case. Because IP
+        // neighbor monitor doesn't start if BPF offload is disabled, there should have no
+        // neighbor event listening. This is used for testing the protection check just in case.
+        // TODO: Perhaps remove the BPF offload disabled case test once this check isn't needed
+        // anymore.
+
+        // [1] Enable BPF offload.
+        // A neighbor that is added or deleted causes the rule to be added or removed.
+        final BpfCoordinator coordinator = makeBpfCoordinator();
+        final IpServer ipServer = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator);
+        resetNetdAndBpfMaps();
+
+        recvNewNeigh(myIfindex, NEIGH_A, NUD_REACHABLE, MAC_A);
+        final Ipv6DownstreamRule rule = buildTestDownstreamRule(UPSTREAM_IFINDEX, NEIGH_A, MAC_A);
+        verifyAddDownstreamRule(rule);
+        resetNetdAndBpfMaps();
+
+        recvDelNeigh(myIfindex, NEIGH_A, NUD_STALE, MAC_A);
+        final Ipv6DownstreamRule ruleNull = buildTestDownstreamRule(
+                UPSTREAM_IFINDEX, NEIGH_A, MAC_NULL);
+        verifyRemoveDownstreamRule(ruleNull);
+        resetNetdAndBpfMaps();
+
+        // Upstream IPv6 connectivity change causes upstream rules change.
+        LinkProperties lp2 = new LinkProperties();
+        lp2.setInterfaceName(UPSTREAM_IFACE2);
+        lp2.setLinkAddresses(UPSTREAM_ADDRESSES2);
+        dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE2, lp2, 0);
+        verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX2, UPSTREAM_PREFIXES2);
+        resetNetdAndBpfMaps();
+
+        // [2] Disable BPF offload.
+        // A neighbor that is added or deleted doesn’t cause the rule to be added or removed.
+        when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(false);
+        final BpfCoordinator coordinator2 = makeBpfCoordinator();
+        final IpServer ipServer2 = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator2);
+        verifyNoUpstreamIpv6ForwardingChange(null);
+        resetNetdAndBpfMaps();
+
+        recvNewNeigh(myIfindex, NEIGH_A, NUD_REACHABLE, MAC_A);
+        verifyNeverAddDownstreamRule();
+        resetNetdAndBpfMaps();
+
+        recvDelNeigh(myIfindex, NEIGH_A, NUD_STALE, MAC_A);
+        verifyNeverRemoveDownstreamRule();
+        resetNetdAndBpfMaps();
+
+        // Upstream IPv6 connectivity change doesn't cause the rule to be added or removed.
+        dispatchTetherConnectionChanged(ipServer2, UPSTREAM_IFACE2, lp2, 0);
+        verifyNoUpstreamIpv6ForwardingChange(null);
+        verifyNeverRemoveDownstreamRule();
+        resetNetdAndBpfMaps();
+    }
+
+    @Test
+    public void doesNotStartIpNeighborMonitorIfBpfOffloadDisabled() throws Exception {
+        when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(false);
+        final BpfCoordinator coordinator = makeBpfCoordinator();
+        final IpServer ipServer = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator);
+
+        // IP neighbor monitor doesn't start if BPF offload is disabled.
+        verify(mIpNeighborMonitor, never()).start();
+    }
+
+    @Test
+    public void testSkipVirtualNetworkInBpf() throws Exception {
+        final BpfCoordinator coordinator = makeBpfCoordinator();
+        final IpServer ipServer = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator);
+        final LinkProperties v6Only = new LinkProperties();
+        v6Only.setInterfaceName(IPSEC_IFACE);
+        v6Only.setLinkAddresses(UPSTREAM_ADDRESSES);
+
+        resetNetdAndBpfMaps();
+        dispatchTetherConnectionChanged(ipServer, IPSEC_IFACE, v6Only, 0);
+        verify(mNetd).tetherAddForward(DOWNSTREAM_IFACE, IPSEC_IFACE);
+        verify(mNetd).ipfwdAddInterfaceForward(DOWNSTREAM_IFACE, IPSEC_IFACE);
+        verifyNeverAddUpstreamRule();
+
+        recvNewNeigh(DOWNSTREAM_IFINDEX, NEIGH_A, NUD_REACHABLE, MAC_A);
+        verifyNeverAddDownstreamRule();
+    }
+
+    @Test
+    public void addRemoveTetherClient() throws Exception {
+        final BpfCoordinator coordinator = makeBpfCoordinator();
+        final IpServer ipServer = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator);
+        final int myIfindex = DOWNSTREAM_IFINDEX;
+        final int notMyIfindex = myIfindex - 1;
+
+        final InetAddress neighA = InetAddresses.parseNumericAddress("192.168.80.1");
+        final InetAddress neighB = InetAddresses.parseNumericAddress("192.168.80.2");
+        final InetAddress neighLL = InetAddresses.parseNumericAddress("169.254.0.1");
+        final InetAddress neighMC = InetAddresses.parseNumericAddress("224.0.0.1");
+
+        // Events on other interfaces are ignored.
+        recvNewNeigh(notMyIfindex, neighA, NUD_REACHABLE, MAC_A);
+        assertNull(mTetherClients.get(ipServer));
+
+        // Events on this interface are received and sent to BpfCoordinator.
+        recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, MAC_A);
+        assertClientInfoExists(ipServer,
+                new ClientInfo(myIfindex, DOWNSTREAM_MAC, (Inet4Address) neighA, MAC_A));
+
+        recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, MAC_B);
+        assertClientInfoExists(ipServer,
+                new ClientInfo(myIfindex, DOWNSTREAM_MAC, (Inet4Address) neighB, MAC_B));
+
+        // Link-local and multicast neighbors are ignored.
+        recvNewNeigh(myIfindex, neighLL, NUD_REACHABLE, MAC_A);
+        assertClientInfoDoesNotExist(ipServer, (Inet4Address) neighLL);
+        recvNewNeigh(myIfindex, neighMC, NUD_REACHABLE, MAC_A);
+        assertClientInfoDoesNotExist(ipServer, (Inet4Address) neighMC);
+
+        // A neighbor that is no longer valid causes the client to be removed.
+        // NUD_FAILED events do not have a MAC address.
+        recvNewNeigh(myIfindex, neighA, NUD_FAILED, null);
+        assertClientInfoDoesNotExist(ipServer, (Inet4Address) neighA);
+
+        // A neighbor that is deleted causes the client to be removed.
+        recvDelNeigh(myIfindex, neighB, NUD_STALE, MAC_B);
+        // When last client information is deleted, IpServer will be removed from mTetherClients
+        assertNull(mTetherClients.get(ipServer));
+    }
 }
