diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index 659d344..f08429b 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -16,14 +16,13 @@
 
 package android.net.ip;
 
-import static android.net.InetAddresses.parseNumericAddress;
 import static android.net.RouteInfo.RTN_UNICAST;
 import static android.net.TetheringManager.TetheringRequest.checkStaticAddressConfiguration;
 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
 import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-import static android.net.util.NetworkConstants.FF;
 import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
 import static android.net.util.NetworkConstants.asByte;
+import static android.net.util.PrefixUtils.asIpPrefix;
 import static android.net.util.TetheringMessageBase.BASE_IPSERVER;
 import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 
@@ -66,11 +65,11 @@
 import com.android.internal.util.MessageUtils;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.networkstack.tethering.PrivateAddressCoordinator;
 
 import java.io.IOException;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
-import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
@@ -108,27 +107,8 @@
 
     private static final byte DOUG_ADAMS = (byte) 42;
 
-    private static final String USB_NEAR_IFACE_ADDR = "192.168.42.129";
-    private static final int USB_PREFIX_LENGTH = 24;
-    private static final String WIFI_HOST_IFACE_ADDR = "192.168.43.1";
-    private static final int WIFI_HOST_IFACE_PREFIX_LENGTH = 24;
-    private static final String WIFI_P2P_IFACE_ADDR = "192.168.49.1";
-    private static final int WIFI_P2P_IFACE_PREFIX_LENGTH = 24;
-    private static final String ETHERNET_IFACE_ADDR = "192.168.50.1";
-    private static final int ETHERNET_IFACE_PREFIX_LENGTH = 24;
-
-    // TODO: remove this constant after introducing PrivateAddressCoordinator.
-    private static final List<IpPrefix> NCM_PREFIXES = Collections.unmodifiableList(
-            Arrays.asList(
-                    new IpPrefix("192.168.42.0/24"),
-                    new IpPrefix("192.168.51.0/24"),
-                    new IpPrefix("192.168.52.0/24"),
-                    new IpPrefix("192.168.53.0/24")
-    ));
-
     // TODO: have PanService use some visible version of this constant
-    private static final String BLUETOOTH_IFACE_ADDR = "192.168.44.1";
-    private static final int BLUETOOTH_DHCP_PREFIX_LENGTH = 24;
+    private static final String BLUETOOTH_IFACE_ADDR = "192.168.44.1/24";
 
     // TODO: have this configurable
     private static final int DHCP_LEASE_TIME_SECS = 3600;
@@ -167,6 +147,14 @@
          * Notify that the DHCP leases changed in one of the IpServers.
          */
         public void dhcpLeasesChanged() { }
+
+        /**
+         * Request Tethering change.
+         *
+         * @param tetheringType the downstream type of this IpServer.
+         * @param enabled enable or disable tethering.
+         */
+        public void requestEnableTethering(int tetheringType, boolean enabled) { }
     }
 
     /** Capture IpServer dependencies, for injection. */
@@ -196,6 +184,7 @@
                 return 0;
             }
         }
+
         /** Create a DhcpServer instance to be used by IpServer. */
         public abstract void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
                 DhcpServerCallbacks cb);
@@ -225,16 +214,20 @@
     public static final int CMD_NEIGHBOR_EVENT              = BASE_IPSERVER + 11;
     // request from DHCP server that it wants to have a new prefix
     public static final int CMD_NEW_PREFIX_REQUEST          = BASE_IPSERVER + 12;
+    // request from PrivateAddressCoordinator to restart tethering.
+    public static final int CMD_NOTIFY_PREFIX_CONFLICT      = BASE_IPSERVER + 13;
 
     private final State mInitialState;
     private final State mLocalHotspotState;
     private final State mTetheredState;
     private final State mUnavailableState;
+    private final State mWaitingForRestartState;
 
     private final SharedLog mLog;
     private final INetd mNetd;
     private final Callback mCallback;
     private final InterfaceController mInterfaceCtrl;
+    private final PrivateAddressCoordinator mPrivateAddressCoordinator;
 
     private final String mIfaceName;
     private final int mInterfaceType;
@@ -261,7 +254,6 @@
     private int mDhcpServerStartIndex = 0;
     private IDhcpServer mDhcpServer;
     private RaParams mLastRaParams;
-    private LinkAddress mIpv4Address;
 
     private LinkAddress mStaticIpv4ServerAddr;
     private LinkAddress mStaticIpv4ClientAddr;
@@ -316,12 +308,14 @@
 
     private final IpNeighborMonitor mIpNeighborMonitor;
 
+    private LinkAddress mIpv4Address;
+
     // TODO: Add a dependency object to pass the data members or variables from the tethering
     // object. It helps to reduce the arguments of the constructor.
     public IpServer(
             String ifaceName, Looper looper, int interfaceType, SharedLog log,
             INetd netd, Callback callback, boolean usingLegacyDhcp, boolean usingBpfOffload,
-            Dependencies deps) {
+            PrivateAddressCoordinator addressCoordinator, Dependencies deps) {
         super(ifaceName, looper);
         mLog = log.forSubComponent(ifaceName);
         mNetd = netd;
@@ -332,6 +326,7 @@
         mLinkProperties = new LinkProperties();
         mUsingLegacyDhcp = usingLegacyDhcp;
         mUsingBpfOffload = usingBpfOffload;
+        mPrivateAddressCoordinator = addressCoordinator;
         mDeps = deps;
         resetLinkProperties();
         mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
@@ -352,9 +347,11 @@
         mLocalHotspotState = new LocalHotspotState();
         mTetheredState = new TetheredState();
         mUnavailableState = new UnavailableState();
+        mWaitingForRestartState = new WaitingForRestartState();
         addState(mInitialState);
         addState(mLocalHotspotState);
         addState(mTetheredState);
+        addState(mWaitingForRestartState, mTetheredState);
         addState(mUnavailableState);
 
         setInitialState(mInitialState);
@@ -387,6 +384,11 @@
         return new LinkProperties(mLinkProperties);
     }
 
+    /** The address which IpServer is using. */
+    public LinkAddress getAddress() {
+        return mIpv4Address;
+    }
+
     /**
      * Get the latest list of DHCP leases that was reported. Must be called on the IpServer looper
      * thread.
@@ -617,6 +619,7 @@
         // NOTE: All of configureIPv4() will be refactored out of existence
         // into calls to InterfaceController, shared with startIPv4().
         mInterfaceCtrl.clearIPv4Address();
+        mPrivateAddressCoordinator.releaseDownstream(this);
         mIpv4Address = null;
         mStaticIpv4ServerAddr = null;
         mStaticIpv4ClientAddr = null;
@@ -625,43 +628,24 @@
     private boolean configureIPv4(boolean enabled) {
         if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")");
 
-        // TODO: Replace this hard-coded information with dynamically selected
-        // config passed down to us by a higher layer IP-coordinating element.
-        final Inet4Address srvAddr;
-        int prefixLen = 0;
-        try {
-            if (mStaticIpv4ServerAddr != null) {
-                srvAddr = (Inet4Address) mStaticIpv4ServerAddr.getAddress();
-                prefixLen = mStaticIpv4ServerAddr.getPrefixLength();
-            } else if (mInterfaceType == TetheringManager.TETHERING_USB
-                    || mInterfaceType == TetheringManager.TETHERING_NCM) {
-                srvAddr = (Inet4Address) parseNumericAddress(USB_NEAR_IFACE_ADDR);
-                prefixLen = USB_PREFIX_LENGTH;
-            } else if (mInterfaceType == TetheringManager.TETHERING_WIFI) {
-                srvAddr = (Inet4Address) parseNumericAddress(getRandomWifiIPv4Address());
-                prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH;
-            } else if (mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) {
-                srvAddr = (Inet4Address) parseNumericAddress(WIFI_P2P_IFACE_ADDR);
-                prefixLen = WIFI_P2P_IFACE_PREFIX_LENGTH;
-            } else if (mInterfaceType == TetheringManager.TETHERING_ETHERNET) {
-                // TODO: randomize address for tethering too, similarly to wifi
-                srvAddr = (Inet4Address) parseNumericAddress(ETHERNET_IFACE_ADDR);
-                prefixLen = ETHERNET_IFACE_PREFIX_LENGTH;
-            } else {
-                // BT configures the interface elsewhere: only start DHCP.
-                // TODO: make all tethering types behave the same way, and delete the bluetooth
-                // code that calls into NetworkManagementService directly.
-                srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR);
-                mIpv4Address = new LinkAddress(srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
-                return configureDhcp(enabled, mIpv4Address, null /* clientAddress */);
-            }
-            mIpv4Address = new LinkAddress(srvAddr, prefixLen);
-        } catch (IllegalArgumentException e) {
-            mLog.e("Error selecting ipv4 address", e);
-            if (!enabled) stopDhcp();
+        if (enabled) {
+            mIpv4Address = requestIpv4Address();
+        }
+
+        if (mIpv4Address == null) {
+            mLog.e("No available ipv4 address");
             return false;
         }
 
+        if (mInterfaceType == TetheringManager.TETHERING_BLUETOOTH) {
+            // BT configures the interface elsewhere: only start DHCP.
+            // TODO: make all tethering types behave the same way, and delete the bluetooth
+            // code that calls into NetworkManagementService directly.
+            return configureDhcp(enabled, mIpv4Address, null /* clientAddress */);
+        }
+
+        final IpPrefix ipv4Prefix = asIpPrefix(mIpv4Address);
+
         final Boolean setIfaceUp;
         if (mInterfaceType == TetheringManager.TETHERING_WIFI
                 || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) {
@@ -688,21 +672,14 @@
         return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr);
     }
 
-    private Inet4Address getRandomIPv4Address(@NonNull final byte[] rawAddr) {
-        final byte[] ipv4Addr = rawAddr;
-        ipv4Addr[3] = getRandomSanitizedByte(DOUG_ADAMS, asByte(0), asByte(1), FF);
-        try {
-            return (Inet4Address) InetAddress.getByAddress(ipv4Addr);
-        } catch (UnknownHostException e) {
-            mLog.e("Failed to construct Inet4Address from raw IPv4 addr");
-            return null;
-        }
-    }
+    private LinkAddress requestIpv4Address() {
+        if (mStaticIpv4ServerAddr != null) return mStaticIpv4ServerAddr;
 
-    private String getRandomWifiIPv4Address() {
-        final Inet4Address ipv4Addr =
-                getRandomIPv4Address(parseNumericAddress(WIFI_HOST_IFACE_ADDR).getAddress());
-        return ipv4Addr != null ? ipv4Addr.getHostAddress() : WIFI_HOST_IFACE_ADDR;
+        if (mInterfaceType == TetheringManager.TETHERING_BLUETOOTH) {
+            return new LinkAddress(BLUETOOTH_IFACE_ADDR);
+        }
+
+        return mPrivateAddressCoordinator.requestDownstreamAddress(this);
     }
 
     private boolean startIPv6() {
@@ -978,19 +955,6 @@
         }
     }
 
-    // TODO: call PrivateAddressCoordinator.requestDownstreamAddress instead of this temporary
-    // logic.
-    private Inet4Address requestDownstreamAddress(@NonNull final IpPrefix currentPrefix) {
-        final int oldIndex = NCM_PREFIXES.indexOf(currentPrefix);
-        if (oldIndex == -1) {
-            mLog.e("current prefix isn't supported for NCM link: " + currentPrefix);
-            return null;
-        }
-
-        final IpPrefix newPrefix = NCM_PREFIXES.get((oldIndex + 1) % NCM_PREFIXES.size());
-        return getRandomIPv4Address(newPrefix.getRawAddress());
-    }
-
     private void handleNewPrefixRequest(@NonNull final IpPrefix currentPrefix) {
         if (!currentPrefix.contains(mIpv4Address.getAddress())
                 || currentPrefix.getPrefixLength() != mIpv4Address.getPrefixLength()) {
@@ -999,12 +963,12 @@
         }
 
         final LinkAddress deprecatedLinkAddress = mIpv4Address;
-        final Inet4Address srvAddr = requestDownstreamAddress(currentPrefix);
-        if (srvAddr == null) {
+        mIpv4Address = requestIpv4Address();
+        if (mIpv4Address == null) {
             mLog.e("Fail to request a new downstream prefix");
             return;
         }
-        mIpv4Address = new LinkAddress(srvAddr, currentPrefix.getPrefixLength());
+        final Inet4Address srvAddr = (Inet4Address) mIpv4Address.getAddress();
 
         // Add new IPv4 address on the interface.
         if (!mInterfaceCtrl.addAddress(srvAddr, currentPrefix.getPrefixLength())) {
@@ -1162,7 +1126,7 @@
             }
 
             try {
-                NetdUtils.tetherInterface(mNetd, mIfaceName, PrefixUtils.asIpPrefix(mIpv4Address));
+                NetdUtils.tetherInterface(mNetd, mIfaceName, asIpPrefix(mIpv4Address));
             } catch (RemoteException | ServiceSpecificException | IllegalStateException e) {
                 mLog.e("Error Tethering", e);
                 mLastError = TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
@@ -1222,6 +1186,11 @@
                 case CMD_NEW_PREFIX_REQUEST:
                     handleNewPrefixRequest((IpPrefix) message.obj);
                     break;
+                case CMD_NOTIFY_PREFIX_CONFLICT:
+                    mLog.i("restart tethering: " + mInterfaceType);
+                    mCallback.requestEnableTethering(mInterfaceType, false /* enabled */);
+                    transitionTo(mWaitingForRestartState);
+                    break;
                 default:
                     return false;
             }
@@ -1403,6 +1372,28 @@
         }
     }
 
+    class WaitingForRestartState extends State {
+        @Override
+        public boolean processMessage(Message message) {
+            logMessage(this, message.what);
+            switch (message.what) {
+                case CMD_TETHER_UNREQUESTED:
+                    transitionTo(mInitialState);
+                    mLog.i("Untethered (unrequested) and restarting " + mIfaceName);
+                    mCallback.requestEnableTethering(mInterfaceType, true /* enabled */);
+                    break;
+                case CMD_INTERFACE_DOWN:
+                    transitionTo(mUnavailableState);
+                    mLog.i("Untethered (interface down) and restarting" + mIfaceName);
+                    mCallback.requestEnableTethering(mInterfaceType, true /* enabled */);
+                    break;
+                default:
+                    return false;
+            }
+            return true;
+        }
+    }
+
     // Accumulate routes representing "prefixes to be assigned to the local
     // interface", for subsequent modification of local_network routing.
     private static ArrayList<RouteInfo> getLocalRoutesFor(
diff --git a/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java b/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java
new file mode 100644
index 0000000..160a166
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.networkstack.tethering;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.ip.IpServer;
+import android.net.util.PrefixUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * This class coordinate IP addresses conflict problem.
+ *
+ * Tethering downstream IP addresses may conflict with network assigned addresses. This
+ * coordinator is responsible for recording all of network assigned addresses and dispatched
+ * free address to downstream interfaces.
+ *
+ * This class is not thread-safe and should be accessed on the same tethering internal thread.
+ * @hide
+ */
+public class PrivateAddressCoordinator {
+    public static final int PREFIX_LENGTH = 24;
+
+    private static final int MAX_UBYTE = 256;
+    private static final int BYTE_MASK = 0xff;
+    // reserved for bluetooth tethering.
+    private static final int BLUETOOTH_RESERVED = 44;
+    private static final byte DEFAULT_ID = (byte) 42;
+
+    // Upstream monitor would be stopped when tethering is down. When tethering restart, downstream
+    // address may be requested before coordinator get current upstream notification. To ensure
+    // coordinator do not select conflict downstream prefix, mUpstreamPrefixMap would not be cleared
+    // when tethering is down. Instead coordinator would remove all depcreted upstreams from
+    // mUpstreamPrefixMap when tethering is starting. See #maybeRemoveDeprectedUpstreams().
+    private final ArrayMap<Network, List<IpPrefix>> mUpstreamPrefixMap;
+    private final ArraySet<IpServer> mDownstreams;
+    // IANA has reserved the following three blocks of the IP address space for private intranets:
+    // 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
+    // Tethering use 192.168.0.0/16 that has 256 contiguous class C network numbers.
+    private static final String DEFAULT_TETHERING_PREFIX = "192.168.0.0/16";
+    private final IpPrefix mTetheringPrefix;
+    private final ConnectivityManager mConnectivityMgr;
+
+    public PrivateAddressCoordinator(Context context) {
+        mDownstreams = new ArraySet<>();
+        mUpstreamPrefixMap = new ArrayMap<>();
+        mTetheringPrefix = new IpPrefix(DEFAULT_TETHERING_PREFIX);
+        mConnectivityMgr = (ConnectivityManager) context.getSystemService(
+                Context.CONNECTIVITY_SERVICE);
+    }
+
+    /**
+     * Record a new upstream IpPrefix which may conflict with tethering downstreams.
+     * The downstreams will be notified if a conflict is found.
+     */
+    public void updateUpstreamPrefix(final Network network, final LinkProperties lp) {
+        final ArrayList<IpPrefix> ipv4Prefixes = getIpv4Prefixes(lp.getAllLinkAddresses());
+        if (ipv4Prefixes.isEmpty()) {
+            removeUpstreamPrefix(network);
+            return;
+        }
+
+        mUpstreamPrefixMap.put(network, ipv4Prefixes);
+        handleMaybePrefixConflict(ipv4Prefixes);
+    }
+
+    private ArrayList<IpPrefix> getIpv4Prefixes(final List<LinkAddress> linkAddresses) {
+        final ArrayList<IpPrefix> list = new ArrayList<>();
+        for (LinkAddress address : linkAddresses) {
+            if (!address.isIpv4()) continue;
+
+            list.add(PrefixUtils.asIpPrefix(address));
+        }
+
+        return list;
+    }
+
+    private void handleMaybePrefixConflict(final List<IpPrefix> prefixes) {
+        for (IpServer downstream : mDownstreams) {
+            final IpPrefix target = getDownstreamPrefix(downstream);
+            if (target == null) continue;
+
+            for (IpPrefix source : prefixes) {
+                if (isConflictPrefix(source, target)) {
+                    downstream.sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT);
+                    break;
+                }
+            }
+        }
+    }
+
+    /** Remove IpPrefix records corresponding to input network. */
+    public void removeUpstreamPrefix(final Network network) {
+        mUpstreamPrefixMap.remove(network);
+    }
+
+    private void maybeRemoveDeprectedUpstreams() {
+        if (!mDownstreams.isEmpty() || mUpstreamPrefixMap.isEmpty()) return;
+
+        final ArrayList<Network> toBeRemoved = new ArrayList<>();
+        List<Network> allNetworks = Arrays.asList(mConnectivityMgr.getAllNetworks());
+        for (int i = 0; i < mUpstreamPrefixMap.size(); i++) {
+            final Network network = mUpstreamPrefixMap.keyAt(i);
+            if (!allNetworks.contains(network)) toBeRemoved.add(network);
+        }
+
+        mUpstreamPrefixMap.removeAll(toBeRemoved);
+    }
+
+    /**
+     * Pick a random available address and mark its prefix as in use for the provided IpServer,
+     * returns null if there is no available address.
+     */
+    @Nullable
+    public LinkAddress requestDownstreamAddress(final IpServer ipServer) {
+        maybeRemoveDeprectedUpstreams();
+
+        // Address would be 192.168.[subAddress]/24.
+        final byte[] bytes = mTetheringPrefix.getRawAddress();
+        final int subAddress = getRandomSubAddr();
+        final int subNet = (subAddress >> 8) & BYTE_MASK;
+        bytes[3] = getSanitizedAddressSuffix(subAddress, (byte) 0, (byte) 1, (byte) 0xff);
+        for (int i = 0; i < MAX_UBYTE; i++) {
+            final int newSubNet = (subNet + i) & BYTE_MASK;
+            if (newSubNet == BLUETOOTH_RESERVED) continue;
+
+            bytes[2] = (byte) newSubNet;
+            final InetAddress addr;
+            try {
+                addr = InetAddress.getByAddress(bytes);
+            } catch (UnknownHostException e) {
+                throw new IllegalStateException("Invalid address, shouldn't happen.", e);
+            }
+
+            final IpPrefix prefix = new IpPrefix(addr, PREFIX_LENGTH);
+            // Check whether this prefix is in use.
+            if (isDownstreamPrefixInUse(prefix)) continue;
+            // Check whether this prefix is conflict with any current upstream network.
+            if (isConflictWithUpstream(prefix)) continue;
+
+            mDownstreams.add(ipServer);
+            return new LinkAddress(addr, PREFIX_LENGTH);
+        }
+
+        // No available address.
+        return null;
+    }
+
+    /** Get random sub address value. Return value is in 0 ~ 0xffff. */
+    @VisibleForTesting
+    public int getRandomSubAddr() {
+        return ((new Random()).nextInt()) & 0xffff; // subNet is in 0 ~ 0xffff.
+    }
+
+    private byte getSanitizedAddressSuffix(final int source, byte... excluded) {
+        final byte subId = (byte) (source & BYTE_MASK);
+        for (byte value : excluded) {
+            if (subId == value) return DEFAULT_ID;
+        }
+
+        return subId;
+    }
+
+    /** Release downstream record for IpServer. */
+    public void releaseDownstream(final IpServer ipServer) {
+        mDownstreams.remove(ipServer);
+    }
+
+    /** Clear current upstream prefixes records. */
+    public void clearUpstreamPrefixes() {
+        mUpstreamPrefixMap.clear();
+    }
+
+    private boolean isConflictWithUpstream(final IpPrefix source) {
+        for (int i = 0; i < mUpstreamPrefixMap.size(); i++) {
+            final List<IpPrefix> list = mUpstreamPrefixMap.valueAt(i);
+            for (IpPrefix target : list) {
+                if (isConflictPrefix(source, target)) return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isConflictPrefix(final IpPrefix prefix1, final IpPrefix prefix2) {
+        if (prefix2.getPrefixLength() < prefix1.getPrefixLength()) {
+            return prefix2.contains(prefix1.getAddress());
+        }
+
+        return prefix1.contains(prefix2.getAddress());
+    }
+
+    private boolean isDownstreamPrefixInUse(final IpPrefix source) {
+        // This class always generates downstream prefixes with the same prefix length, so
+        // prefixes cannot be contained in each other. They can only be equal to each other.
+        for (IpServer downstream : mDownstreams) {
+            final IpPrefix prefix = getDownstreamPrefix(downstream);
+            if (source.equals(prefix)) return true;
+        }
+        return false;
+    }
+
+    private IpPrefix getDownstreamPrefix(final IpServer downstream) {
+        final LinkAddress address = downstream.getAddress();
+        if (address == null) return null;
+
+        return PrefixUtils.asIpPrefix(address);
+    }
+
+    void dump(final IndentingPrintWriter pw) {
+        pw.decreaseIndent();
+        pw.println("mUpstreamPrefixMap:");
+        pw.increaseIndent();
+        for (int i = 0; i < mUpstreamPrefixMap.size(); i++) {
+            pw.println(mUpstreamPrefixMap.keyAt(i) + " - " + mUpstreamPrefixMap.valueAt(i));
+        }
+        pw.decreaseIndent();
+        pw.println("mDownstreams:");
+        pw.increaseIndent();
+        for (IpServer ipServer : mDownstreams) {
+            pw.println(ipServer.interfaceType() + " - " + ipServer.getAddress());
+        }
+        pw.decreaseIndent();
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 3ce3b45..6eb1012 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -207,6 +207,7 @@
             new SparseArray<>();
 
     // used to synchronize public access to members
+    // TODO(b/153621704): remove mPublicSync to make Tethering lock free
     private final Object mPublicSync;
     private final Context mContext;
     private final ArrayMap<String, TetherState> mTetherStates;
@@ -231,6 +232,7 @@
     private final TetheringThreadExecutor mExecutor;
     private final TetheringNotificationUpdater mNotificationUpdater;
     private final UserManager mUserManager;
+    private final PrivateAddressCoordinator mPrivateAddressCoordinator;
     private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
     // All the usage of mTetheringEventCallback should run in the same thread.
     private ITetheringEventCallback mTetheringEventCallback = null;
@@ -314,6 +316,7 @@
         mExecutor = new TetheringThreadExecutor(mHandler);
         mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
         mNetdCallback = new NetdCallback();
+        mPrivateAddressCoordinator = new PrivateAddressCoordinator(mContext);
 
         // Load tethering configuration.
         updateConfiguration();
@@ -1616,6 +1619,14 @@
             }
         }
 
+        private void addUpstreamPrefixes(final UpstreamNetworkState ns) {
+            mPrivateAddressCoordinator.updateUpstreamPrefix(ns.network, ns.linkProperties);
+        }
+
+        private void removeUpstreamPrefixes(final UpstreamNetworkState ns) {
+            mPrivateAddressCoordinator.removeUpstreamPrefix(ns.network);
+        }
+
         @VisibleForTesting
         void handleUpstreamNetworkMonitorCallback(int arg1, Object o) {
             if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) {
@@ -1624,6 +1635,14 @@
             }
 
             final UpstreamNetworkState ns = (UpstreamNetworkState) o;
+            switch (arg1) {
+                case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
+                    addUpstreamPrefixes(ns);
+                    break;
+                case UpstreamNetworkMonitor.EVENT_ON_LOST:
+                    removeUpstreamPrefixes(ns);
+                    break;
+            }
 
             if (ns == null || !pertainsToCurrentUpstream(ns)) {
                 // TODO: In future, this is where upstream evaluation and selection
@@ -2190,6 +2209,11 @@
         mOffloadController.dump(pw);
         pw.decreaseIndent();
 
+        pw.println("Private address coordinator:");
+        pw.increaseIndent();
+        mPrivateAddressCoordinator.dump(pw);
+        pw.decreaseIndent();
+
         pw.println("Log:");
         pw.increaseIndent();
         if (argsContain(args, "--short")) {
@@ -2231,6 +2255,11 @@
             public void dhcpLeasesChanged() {
                 updateConnectedClients(null /* wifiClients */);
             }
+
+            @Override
+            public void requestEnableTethering(int tetheringType, boolean enabled) {
+                enableTetheringInternal(tetheringType, enabled, null);
+            }
         };
     }
 
@@ -2314,7 +2343,8 @@
         final TetherState tetherState = new TetherState(
                 new IpServer(iface, mLooper, interfaceType, mLog, mNetd,
                              makeControlCallback(), mConfig.enableLegacyDhcpServer,
-                             mConfig.enableBpfOffload, mDeps.getIpServerDependencies()));
+                             mConfig.enableBpfOffload, mPrivateAddressCoordinator,
+                             mDeps.getIpServerDependencies()));
         mTetherStates.put(iface, tetherState);
         tetherState.ipServer.start();
     }
