Merge changes I6d0e5d34,I55af0796 into main am: 75551afe7a

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/3526891

Change-Id: Id2490f4835aac74b056294dfe1325c99e2bac1b8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index 609d759..d0ba431 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -852,16 +852,13 @@
         }
     }
 
-    private void removeRoutesFromNetworkAndLinkProperties(int netId,
-            @NonNull final List<RouteInfo> toBeRemoved) {
+    private void removeRoutesFromNetwork(int netId, @NonNull final List<RouteInfo> toBeRemoved) {
         final int removalFailures = NetdUtils.removeRoutesFromNetwork(
                 mNetd, netId, toBeRemoved);
         if (removalFailures > 0) {
             mLog.e("Failed to remove " + removalFailures
                     + " IPv6 routes from network " + netId + ".");
         }
-
-        for (RouteInfo route : toBeRemoved) mLinkProperties.removeRoute(route);
     }
 
     private void addInterfaceToNetwork(final int netId, @NonNull final String ifaceName) {
@@ -888,7 +885,7 @@
         }
     }
 
-    private void addRoutesToNetworkAndLinkProperties(int netId,
+    private void addRoutesToNetwork(int netId,
             @NonNull final List<RouteInfo> toBeAdded) {
         // It's safe to call addInterfaceToNetwork() even if
         // the interface is already in the network.
@@ -901,16 +898,16 @@
             mLog.e("Failed to add IPv4/v6 routes to local table: " + e);
             return;
         }
-
-        for (RouteInfo route : toBeAdded) mLinkProperties.addRoute(route);
     }
 
     private void configureLocalIPv6Routes(
             ArraySet<IpPrefix> deprecatedPrefixes, ArraySet<IpPrefix> newPrefixes) {
         // [1] Remove the routes that are deprecated.
         if (!deprecatedPrefixes.isEmpty()) {
-            removeRoutesFromNetworkAndLinkProperties(LOCAL_NET_ID,
-                    getLocalRoutesFor(mIfaceName, deprecatedPrefixes));
+            final List<RouteInfo> routesToBeRemoved =
+                    getLocalRoutesFor(mIfaceName, deprecatedPrefixes);
+            removeRoutesFromNetwork(LOCAL_NET_ID, routesToBeRemoved);
+            for (RouteInfo route : routesToBeRemoved) mLinkProperties.removeRoute(route);
         }
 
         // [2] Add only the routes that have not previously been added.
@@ -921,8 +918,10 @@
             }
 
             if (!addedPrefixes.isEmpty()) {
-                addRoutesToNetworkAndLinkProperties(LOCAL_NET_ID,
-                        getLocalRoutesFor(mIfaceName, addedPrefixes));
+                final List<RouteInfo> routesToBeAdded =
+                        getLocalRoutesFor(mIfaceName, addedPrefixes);
+                addRoutesToNetwork(LOCAL_NET_ID, routesToBeAdded);
+                for (RouteInfo route : routesToBeAdded) mLinkProperties.addRoute(route);
             }
         }
     }
@@ -1126,8 +1125,17 @@
             }
 
             try {
-                NetdUtils.tetherInterface(mNetd, LOCAL_NET_ID, mIfaceName,
-                        asIpPrefix(mIpv4Address));
+                // Enable IPv6, disable accepting RA, etc. See TetherController::tetherInterface()
+                // for more detail.
+                mNetd.tetherInterfaceAdd(mIfaceName);
+                NetdUtils.networkAddInterface(mNetd, LOCAL_NET_ID, mIfaceName,
+                        20 /* maxAttempts */, 50 /* pollingIntervalMs */);
+                // Activate a route to dest and IPv6 link local.
+                NetdUtils.modifyRoute(mNetd, NetdUtils.ModifyOperation.ADD, LOCAL_NET_ID,
+                        new RouteInfo(asIpPrefix(mIpv4Address), null, mIfaceName, RTN_UNICAST));
+                NetdUtils.modifyRoute(mNetd, NetdUtils.ModifyOperation.ADD, LOCAL_NET_ID,
+                        new RouteInfo(new IpPrefix("fe80::/64"), null, mIfaceName,
+                                RTN_UNICAST));
             } catch (RemoteException | ServiceSpecificException | IllegalStateException e) {
                 mLog.e("Error Tethering", e);
                 mLastError = TETHER_ERROR_TETHER_IFACE_ERROR;
@@ -1148,8 +1156,13 @@
             // all in sequence.
             stopIPv6();
 
+            // Reset interface for tethering.
             try {
-                NetdUtils.untetherInterface(mNetd, LOCAL_NET_ID, mIfaceName);
+                try {
+                    mNetd.tetherInterfaceRemove(mIfaceName);
+                } finally {
+                    mNetd.networkRemoveInterface(LOCAL_NET_ID, mIfaceName);
+                }
             } catch (RemoteException | ServiceSpecificException e) {
                 mLastError = TETHER_ERROR_UNTETHER_IFACE_ERROR;
                 mLog.e("Failed to untether interface: " + e);
@@ -1227,13 +1240,16 @@
             }
 
             // Remove deprecated routes from downstream network.
-            removeRoutesFromNetworkAndLinkProperties(LOCAL_NET_ID,
-                    List.of(getDirectConnectedRoute(deprecatedLinkAddress)));
+            final List<RouteInfo> routesToBeRemoved =
+                    List.of(getDirectConnectedRoute(deprecatedLinkAddress));
+            removeRoutesFromNetwork(LOCAL_NET_ID, routesToBeRemoved);
+            for (RouteInfo route : routesToBeRemoved) mLinkProperties.removeRoute(route);
             mLinkProperties.removeLinkAddress(deprecatedLinkAddress);
 
             // Add new routes to downstream network.
-            addRoutesToNetworkAndLinkProperties(LOCAL_NET_ID,
-                    List.of(getDirectConnectedRoute(mIpv4Address)));
+            final List<RouteInfo> routesToBeAdded = List.of(getDirectConnectedRoute(mIpv4Address));
+            addRoutesToNetwork(LOCAL_NET_ID, routesToBeAdded);
+            for (RouteInfo route : routesToBeAdded) mLinkProperties.addRoute(route);
             mLinkProperties.addLinkAddress(mIpv4Address);
 
             // Update local DNS caching server with new IPv4 address, otherwise, dnsmasq doesn't
diff --git a/staticlibs/client-libs/netd/com/android/net/module/util/NetdUtils.java b/staticlibs/client-libs/netd/com/android/net/module/util/NetdUtils.java
index 8b2fe58..4af516d 100644
--- a/staticlibs/client-libs/netd/com/android/net/module/util/NetdUtils.java
+++ b/staticlibs/client-libs/netd/com/android/net/module/util/NetdUtils.java
@@ -148,25 +148,6 @@
         netd.tetherStartWithConfiguration(config);
     }
 
-    /** Setup interface for tethering. */
-    public static void tetherInterface(final INetd netd, int netId, final String iface,
-            final IpPrefix dest) throws RemoteException, ServiceSpecificException {
-        tetherInterface(netd, netId, iface, dest, 20 /* maxAttempts */, 50 /* pollingIntervalMs */);
-    }
-
-    /** Setup interface with configurable retries for tethering. */
-    public static void tetherInterface(final INetd netd, int netId, final String iface,
-            final IpPrefix dest, int maxAttempts, int pollingIntervalMs)
-            throws RemoteException, ServiceSpecificException {
-        netd.tetherInterfaceAdd(iface);
-        networkAddInterface(netd, netId, iface, maxAttempts, pollingIntervalMs);
-        // Activate a route to dest and IPv6 link local.
-        modifyRoute(netd, ModifyOperation.ADD, netId,
-                new RouteInfo(dest, null, iface, RTN_UNICAST));
-        modifyRoute(netd, ModifyOperation.ADD, netId,
-                new RouteInfo(new IpPrefix("fe80::/64"), null, iface, RTN_UNICAST));
-    }
-
     /**
      * Retry Netd#networkAddInterface for EBUSY error code.
      * If the same interface (e.g., wlan0) is in client mode and then switches to tethered mode.
@@ -174,7 +155,7 @@
      * in use in netd because the ConnectivityService thread hasn't processed the disconnect yet.
      * See b/158269544 for detail.
      */
-    private static void networkAddInterface(final INetd netd, int netId, final String iface,
+    public static void networkAddInterface(final INetd netd, int netId, final String iface,
             int maxAttempts, int pollingIntervalMs)
             throws ServiceSpecificException, RemoteException {
         for (int i = 1; i <= maxAttempts; i++) {
@@ -193,16 +174,6 @@
         }
     }
 
-    /** Reset interface for tethering. */
-    public static void untetherInterface(final INetd netd, int netId, String iface)
-            throws RemoteException, ServiceSpecificException {
-        try {
-            netd.tetherInterfaceRemove(iface);
-        } finally {
-            netd.networkRemoveInterface(netId, iface);
-        }
-    }
-
     /** Add |routes| to the given network. */
     public static void addRoutesToNetwork(final INetd netd, int netId, final String iface,
             final List<RouteInfo> routes) {
diff --git a/staticlibs/client-libs/tests/unit/src/com/android/net/module/util/NetdUtilsTest.java b/staticlibs/client-libs/tests/unit/src/com/android/net/module/util/NetdUtilsTest.java
index c2fbb56..0241d0a 100644
--- a/staticlibs/client-libs/tests/unit/src/com/android/net/module/util/NetdUtilsTest.java
+++ b/staticlibs/client-libs/tests/unit/src/com/android/net/module/util/NetdUtilsTest.java
@@ -24,13 +24,9 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -39,7 +35,6 @@
 
 import android.net.INetd;
 import android.net.InterfaceConfigurationParcel;
-import android.net.IpPrefix;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 
@@ -61,7 +56,6 @@
     @Mock private INetd mNetd;
 
     private static final String IFACE = "TEST_IFACE";
-    private static final IpPrefix TEST_IPPREFIX = new IpPrefix("192.168.42.1/24");
     private static final int TEST_NET_ID = 123;
 
     @Before
@@ -150,20 +144,21 @@
     }
 
     @Test
-    public void testTetherInterfaceSuccessful() throws Exception {
+    public void testNetworkAddInterfaceSuccessful() throws Exception {
         // Expect #networkAddInterface successful at first tries.
-        verifyTetherInterfaceSucceeds(1);
+        verifyNetworkAddInterfaceSucceeds(1);
 
         // Expect #networkAddInterface successful after 10 tries.
-        verifyTetherInterfaceSucceeds(10);
+        verifyNetworkAddInterfaceSucceeds(10);
     }
 
-    private void runTetherInterfaceWithServiceSpecificException(int expectedTries,
+    private void runNetworkAddInterfaceWithServiceSpecificException(int expectedTries,
             int expectedCode) throws Exception {
         setNetworkAddInterfaceOutcome(new ServiceSpecificException(expectedCode), expectedTries);
 
         try {
-            NetdUtils.tetherInterface(mNetd, TEST_NET_ID, IFACE, TEST_IPPREFIX, 20, 0);
+            NetdUtils.networkAddInterface(mNetd, TEST_NET_ID, IFACE,
+                    20 /* maxAttempts */, 0 /* pollingIntervalMs */);
             fail("Expect throw ServiceSpecificException");
         } catch (ServiceSpecificException e) {
             assertEquals(e.errorCode, expectedCode);
@@ -173,11 +168,12 @@
         reset(mNetd);
     }
 
-    private void runTetherInterfaceWithRemoteException(int expectedTries) throws Exception {
+    private void runNetworkAddInterfaceWithRemoteException(int expectedTries) throws Exception {
         setNetworkAddInterfaceOutcome(new RemoteException(), expectedTries);
 
         try {
-            NetdUtils.tetherInterface(mNetd, TEST_NET_ID, IFACE, TEST_IPPREFIX, 20, 0);
+            NetdUtils.networkAddInterface(mNetd, TEST_NET_ID, IFACE,
+                    20 /* maxAttempts */, 0 /* pollingIntervalMs */);
             fail("Expect throw RemoteException");
         } catch (RemoteException e) { }
 
@@ -186,41 +182,37 @@
     }
 
     private void verifyNetworkAddInterfaceFails(int expectedTries) throws Exception {
-        verify(mNetd).tetherInterfaceAdd(IFACE);
         verify(mNetd, times(expectedTries)).networkAddInterface(TEST_NET_ID, IFACE);
-        verify(mNetd, never()).networkAddRoute(anyInt(), anyString(), any(), any());
-
         verifyNoMoreInteractions(mNetd);
     }
 
-    private void verifyTetherInterfaceSucceeds(int expectedTries) throws Exception {
+    private void verifyNetworkAddInterfaceSucceeds(int expectedTries) throws Exception {
         setNetworkAddInterfaceOutcome(null, expectedTries);
 
-        NetdUtils.tetherInterface(mNetd, TEST_NET_ID, IFACE, TEST_IPPREFIX);
-        verify(mNetd).tetherInterfaceAdd(IFACE);
+        NetdUtils.networkAddInterface(mNetd, TEST_NET_ID, IFACE,
+                20 /* maxAttempts */, 0 /* pollingIntervalMs */);
         verify(mNetd, times(expectedTries)).networkAddInterface(TEST_NET_ID, IFACE);
-        verify(mNetd, times(2)).networkAddRoute(eq(TEST_NET_ID), eq(IFACE), any(), any());
         verifyNoMoreInteractions(mNetd);
         reset(mNetd);
     }
 
     @Test
-    public void testTetherInterfaceFailOnNetworkAddInterface() throws Exception {
+    public void testFailOnNetworkAddInterface() throws Exception {
         // Test throwing ServiceSpecificException with EBUSY failure.
-        runTetherInterfaceWithServiceSpecificException(20, EBUSY);
+        runNetworkAddInterfaceWithServiceSpecificException(20, EBUSY);
 
         // Test throwing ServiceSpecificException with unexpectedError.
         final int unexpectedError = 999;
-        runTetherInterfaceWithServiceSpecificException(1, unexpectedError);
+        runNetworkAddInterfaceWithServiceSpecificException(1, unexpectedError);
 
         // Test throwing ServiceSpecificException with unexpectedError after 7 tries.
-        runTetherInterfaceWithServiceSpecificException(7, unexpectedError);
+        runNetworkAddInterfaceWithServiceSpecificException(7, unexpectedError);
 
         // Test throwing RemoteException.
-        runTetherInterfaceWithRemoteException(1);
+        runNetworkAddInterfaceWithRemoteException(1);
 
         // Test throwing RemoteException after 3 tries.
-        runTetherInterfaceWithRemoteException(3);
+        runNetworkAddInterfaceWithRemoteException(3);
     }
 
     @Test