Revert "Wait for IP Addresses cleared before transition to StoppedState."

This reverts commit 45e2744137fd26d9468adfb7690538d579251791.

Reason for revert: per release note review, got some critical comments for example, we should remove the timeout message and consider how to improve the state machine usage.

Bug: Bug: 240616892
Test: atest NetworkStackIntegrationTests
Change-Id: I84ed417c1d5ebe0e58957f7bf539afa0af7a0871
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 694c4ee..c6c637d 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -35,7 +35,6 @@
 import static com.android.net.module.util.NetworkStackConstants.ETHER_BROADCAST;
 import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_ROUTERS_MULTICAST;
 import static com.android.net.module.util.NetworkStackConstants.VENDOR_SPECIFIC_IE_ID;
-import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_CLEAR_ADDRESSES_ON_STOP_VERSION;
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_DISABLE_ACCEPT_RA_VERSION;
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_GARP_NA_ROAMING_VERSION;
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_GRATUITOUS_NA_VERSION;
@@ -481,16 +480,6 @@
     private static final int CMD_ADDRESSES_CLEARED                = 100;
     private static final int CMD_JUMP_RUNNING_TO_STOPPING         = 101;
     private static final int CMD_JUMP_STOPPING_TO_STOPPED         = 102;
-    private static final int CMD_JUMP_STOPPING_TO_CLEAR_ADDRESSES_ON_STOP = 103;
-    private static final int EVENT_CLEAR_ADDRESSES_TIMEOUT        = 104;
-
-    // Used to time out the wait for IP addresses cleared. This timeout is
-    // necessary because netlink events will get lost if ENOBUFS happens,
-    // then RTM_DELADDR might never arrive, which results in never exiting
-    // ClearAddressesOnStopState.
-    @VisibleForTesting
-    static final String CONFIG_CLEAR_ADDRESSES_TIMEOUT = "ipclient_clear_addresses_timeout";
-    private static final int DEFAULT_CLEAR_ADDRESSES_TIMEOUT_MS = 2000;
 
     // IpClient shares a handler with DhcpClient: commands must not overlap
     public static final int DHCPCLIENT_CMD_BASE = 1000;
@@ -545,11 +534,10 @@
 
     private final State mStoppedState = new StoppedState();
     private final State mStoppingState = new StoppingState();
+    private final State mClearingIpAddressesState = new ClearingIpAddressesState();
     private final State mStartedState = new StartedState();
     private final State mRunningState = new RunningState();
     private final State mPreconnectingState = new PreconnectingState();
-    private final State mClearAddressesOnStopState = new ClearAddressesOnStopState();
-    private final State mClearAddressesOnStartState = new ClearAddressesOnStartState();
 
     private final String mTag;
     private final Context mContext;
@@ -596,7 +584,6 @@
     private long mStartTimeMillis;
     private MacAddress mCurrentBssid;
     private boolean mHasDisabledIpv6OrAcceptRaOnProvLoss;
-    private boolean mClearAddressesOnStop;
 
     /**
      * Reading the snapshot is an asynchronous operation initiated by invoking
@@ -911,11 +898,10 @@
         // CHECKSTYLE:OFF IndentationCheck
         addState(mStoppedState);
         addState(mStartedState);
-            addState(mClearAddressesOnStartState, mStartedState);
             addState(mPreconnectingState, mStartedState);
+            addState(mClearingIpAddressesState, mStartedState);
             addState(mRunningState, mStartedState);
         addState(mStoppingState);
-        addState(mClearAddressesOnStopState);
         // CHECKSTYLE:ON IndentationCheck
 
         setInitialState(mStoppedState);
@@ -977,11 +963,6 @@
                 true /* defaultEnabled */);
     }
 
-    private boolean shouldClearAddressesOnStop() {
-        return mDependencies.isFeatureEnabled(mContext, IPCLIENT_CLEAR_ADDRESSES_ON_STOP_VERSION,
-                false /* defaultEnabled */);
-    }
-
     @Override
     protected void onQuitting() {
         mCallback.onQuit();
@@ -2087,11 +2068,6 @@
     class StoppedState extends State {
         @Override
         public void enter() {
-            // It's necessary to disable IPv6 stack at StoppedState#enter, which cleans up the
-            // IPv6 link-local address and default IPv6 link-local route(fe80::/64 -> ::) which
-            // are generated on interface creation. The IPv6 link-local address and route will
-            // come back later during provisioning, otherwise, there is no way to syncup the
-            // initial link-local address and route to mLinkProperties.
             stopAllIP();
             mHasDisabledIpv6OrAcceptRaOnProvLoss = false;
             mGratuitousNaTargetAddresses.clear();
@@ -2119,9 +2095,8 @@
                     break;
 
                 case CMD_START:
-                    mClearAddressesOnStop = shouldClearAddressesOnStop();
                     mConfiguration = (android.net.shared.ProvisioningConfiguration) msg.obj;
-                    transitionTo(mClearAddressesOnStartState);
+                    transitionTo(mClearingIpAddressesState);
                     break;
 
                 case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
@@ -2168,10 +2143,7 @@
         public void enter() {
             if (mDhcpClient == null) {
                 // There's no DHCPv4 for which to wait; proceed to stopped.
-                deferMessage(obtainMessage(
-                        mClearAddressesOnStop
-                                ? CMD_JUMP_STOPPING_TO_CLEAR_ADDRESSES_ON_STOP
-                                : CMD_JUMP_STOPPING_TO_STOPPED));
+                deferMessage(obtainMessage(CMD_JUMP_STOPPING_TO_STOPPED));
             } else {
                 mDhcpClient.sendMessage(DhcpClient.CMD_STOP_DHCP);
                 mDhcpClient.doQuit();
@@ -2188,10 +2160,6 @@
                     transitionTo(mStoppedState);
                     break;
 
-                case CMD_JUMP_STOPPING_TO_CLEAR_ADDRESSES_ON_STOP:
-                    transitionTo(mClearAddressesOnStopState);
-                    break;
-
                 case CMD_STOP:
                     break;
 
@@ -2201,9 +2169,7 @@
 
                 case DhcpClient.CMD_ON_QUIT:
                     mDhcpClient = null;
-                    transitionTo(mClearAddressesOnStop
-                            ? mClearAddressesOnStopState
-                            : mStoppedState);
+                    transitionTo(mStoppedState);
                     break;
 
                 default:
@@ -2259,65 +2225,7 @@
                 isUsingPreconnection(), options));
     }
 
-    abstract class ClearAddressesState extends State {
-        protected abstract State getTargetState();
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_ADDRESSES_CLEARED:
-                    transitionTo(getTargetState());
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    if (readyToProceed()) {
-                        transitionTo(getTargetState());
-                    }
-                    break;
-
-                case EVENT_CLEAR_ADDRESSES_TIMEOUT:
-                    transitionTo(mStoppedState);
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        // Usually NetworkAgent will be unregistered along with stopping IpClient, then network will
-        // be destroyed and IPv6 relevant routes will be removed from interface, but IPv4 relevant
-        // routes won't be removed if any. Disabling IPv6 stack also results in the removal of all
-        // IPv6 addresses and relevant routes.
-        private boolean readyToProceed() {
-            return !mLinkProperties.hasIpv4Address() && !mLinkProperties.hasGlobalIpv6Address()
-                    && !mLinkProperties.hasIpv6DefaultRoute();
-        }
-
-        protected void ensureIpAddressesCleared() {
-            if (readyToProceed()) {
-                deferMessage(obtainMessage(CMD_ADDRESSES_CLEARED));
-            } else {
-                // Clear all IPv4 and IPv6 before proceeding to RunningState.
-                // Clean up any leftover state from an abnormal exit from
-                // tethering or during an IpClient restart.
-                stopAllIP();
-
-                // Set a timeout for waiting the RTM_DELADDR netlink events.
-                sendMessageDelayed(EVENT_CLEAR_ADDRESSES_TIMEOUT,
-                        mDependencies.getDeviceConfigPropertyInt(CONFIG_CLEAR_ADDRESSES_TIMEOUT,
-                                DEFAULT_CLEAR_ADDRESSES_TIMEOUT_MS));
-            }
-        }
-    }
-
-    class ClearAddressesOnStartState extends ClearAddressesState {
-        @Override
-        protected State getTargetState() {
-            return isUsingPreconnection() ? mPreconnectingState : mRunningState;
-        }
-
+    class ClearingIpAddressesState extends State {
         @Override
         public void enter() {
             // Ensure that interface parameters are fetched on the handler thread so they are
@@ -2332,14 +2240,33 @@
             }
 
             mLinkObserver.setInterfaceParams(mInterfaceParams);
+
+            if (readyToProceed()) {
+                deferMessage(obtainMessage(CMD_ADDRESSES_CLEARED));
+            } else {
+                // Clear all IPv4 and IPv6 before proceeding to RunningState.
+                // Clean up any leftover state from an abnormal exit from
+                // tethering or during an IpClient restart.
+                stopAllIP();
+            }
+
             mCallback.setNeighborDiscoveryOffload(true);
-            ensureIpAddressesCleared();
         }
 
         @Override
         public boolean processMessage(Message msg) {
-            if (super.processMessage(msg) == HANDLED) return HANDLED;
             switch (msg.what) {
+                case CMD_ADDRESSES_CLEARED:
+                    transitionTo(isUsingPreconnection() ? mPreconnectingState : mRunningState);
+                    break;
+
+                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    if (readyToProceed()) {
+                        transitionTo(isUsingPreconnection() ? mPreconnectingState : mRunningState);
+                    }
+                    break;
+
                 case CMD_STOP:
                 case EVENT_PROVISIONING_TIMEOUT:
                     // Fall through to StartedState.
@@ -2355,29 +2282,9 @@
             }
             return HANDLED;
         }
-    }
 
-    class ClearAddressesOnStopState extends ClearAddressesState {
-        @Override
-        protected State getTargetState() {
-            return mStoppedState;
-        }
-
-        @Override
-        public void enter() {
-            ensureIpAddressesCleared();
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            if (super.processMessage(msg) == HANDLED) return HANDLED;
-            switch (msg.what) {
-                default:
-                    // Any messages which are not processed in ClearAddressesState will be
-                    // deferred to StoppedState.
-                    deferMessage(msg);
-            }
-            return HANDLED;
+        private boolean readyToProceed() {
+            return !mLinkProperties.hasIpv4Address() && !mLinkProperties.hasGlobalIpv6Address();
         }
     }
 
@@ -2564,6 +2471,8 @@
                 mApfFilter.shutdown();
                 mApfFilter = null;
             }
+
+            resetLinkProperties();
         }
 
         private void enqueueJumpToStoppingState(final DisconnectCode code) {
diff --git a/src/com/android/networkstack/util/NetworkStackUtils.java b/src/com/android/networkstack/util/NetworkStackUtils.java
index 6af742c..670a320 100755
--- a/src/com/android/networkstack/util/NetworkStackUtils.java
+++ b/src/com/android/networkstack/util/NetworkStackUtils.java
@@ -259,13 +259,6 @@
     public static final String IP_REACHABILITY_MCAST_RESOLICIT_VERSION =
             "ip_reachability_mcast_resolicit_version";
 
-    /**
-     * Experiment flag to wait for IP addresses cleared completely before transition to
-     * IpClient#StoppedState from IpClient#StoppingState.
-     */
-    public static final String IPCLIENT_CLEAR_ADDRESSES_ON_STOP_VERSION =
-            "ipclient_clear_addresses_on_stop_version";
-
     static {
         System.loadLibrary("networkstackutilsjni");
     }
diff --git a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
index 34d4a07..6098607 100644
--- a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -642,7 +642,6 @@
         when(mCb.getInterfaceVersion()).thenReturn(IpClient.VERSION_ADDED_REACHABILITY_FAILURE);
 
         mDependencies.setDeviceConfigProperty(IpClient.CONFIG_MIN_RDNSS_LIFETIME, 67);
-        mDependencies.setDeviceConfigProperty(IpClient.CONFIG_CLEAR_ADDRESSES_TIMEOUT, 50);
         mDependencies.setDeviceConfigProperty(DhcpClient.DHCP_RESTART_CONFIG_DELAY, 10);
         mDependencies.setDeviceConfigProperty(DhcpClient.ARP_FIRST_PROBE_DELAY_MS, 10);
         mDependencies.setDeviceConfigProperty(DhcpClient.ARP_PROBE_MIN_MS, 10);
@@ -2187,7 +2186,7 @@
     }
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
-    public void testClearAddressesOnStartState() throws Exception {
+    public void testIpClientClearingIpAddressState() throws Exception {
         doIPv4OnlyProvisioningAndExitWithLeftAddress();
 
         ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
@@ -2208,7 +2207,7 @@
     }
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
-    public void testClearAddressesOnStartState_enablePreconnection() throws Exception {
+    public void testIpClientClearingIpAddressState_enablePreconnection() throws Exception {
         doIPv4OnlyProvisioningAndExitWithLeftAddress();
 
         // Enter ClearingIpAddressesState to clear the remaining IPv4 addresses and transition to
@@ -2813,7 +2812,7 @@
                 true /* shouldReplyNakOnRoam */);
     }
 
-    private LinkProperties performDualStackProvisioning() throws Exception {
+    private void performDualStackProvisioning() throws Exception {
         final InOrder inOrder = inOrder(mCb);
         final CompletableFuture<LinkProperties> lpFuture = new CompletableFuture<>();
         final String dnsServer = "2001:4860:4860::64";
@@ -2839,10 +2838,9 @@
         assertTrue(lp.getDnsServers().contains(SERVER_ADDR));
 
         reset(mCb);
-        return lp;
     }
 
-    private LinkProperties doDualStackProvisioning(boolean shouldDisableAcceptRa) throws Exception {
+    private void doDualStackProvisioning(boolean shouldDisableAcceptRa) throws Exception {
         when(mCm.shouldAvoidBadWifi()).thenReturn(true);
 
         final ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
@@ -2857,7 +2855,7 @@
                 false /* isDhcpIpConflictDetectEnabled */, false /* isIPv6OnlyPreferredEnabled */);
         mIpc.startProvisioning(config);
 
-        return performDualStackProvisioning();
+        performDualStackProvisioning();
     }
 
     @Test @SignatureRequiredTest(reason = "signature perms are required due to mocked callabck")
@@ -4025,27 +4023,6 @@
         assertFalse(lp.hasIpv6DefaultRoute());
     }
 
-    @Test @SignatureRequiredTest(reason = "Need MANAGE_TEST_NETWORKS perm to create NetworkAgent")
-    public void testClearAddressesOnStopState() throws Exception {
-        setFeatureEnabled(NetworkStackUtils.IPCLIENT_CLEAR_ADDRESSES_ON_STOP_VERSION, true);
-        mNetworkAgentThread =
-                new HandlerThread(IpClientIntegrationTestCommon.class.getSimpleName());
-        mNetworkAgentThread.start();
-
-        final LinkProperties lp = doDualStackProvisioning(false /* shouldDisableAcceptRa */);
-        runAsShell(MANAGE_TEST_NETWORKS, () -> createTestNetworkAgentAndRegister(lp));
-
-        // Verify the link addresses and IPv6 routes get removed before transition to StoppedState..
-        mNetworkAgent.unregister();
-        mNetworkAgentThread.quitSafely();
-        mIIpClient.shutdown();
-        verify(mCb, timeout(TEST_TIMEOUT_MS)).onLinkPropertiesChange(argThat(
-                x -> x.getAddresses().size() == 0
-                        && !x.hasIpv6DefaultRoute()
-                        && x.getDnsServers().size() == 0));
-        awaitIpClientShutdown();
-    }
-
     @Test
     public void testMulticastNsFromIPv6Gua() throws Exception {
         final ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()