diff --git a/service-t/src/com/android/server/ethernet/EthernetConfigStore.java b/service-t/src/com/android/server/ethernet/EthernetConfigStore.java
index 676bc99..6445603 100644
--- a/service-t/src/com/android/server/ethernet/EthernetConfigStore.java
+++ b/service-t/src/com/android/server/ethernet/EthernetConfigStore.java
@@ -17,11 +17,8 @@
 package com.android.server.ethernet;
 
 import android.net.IpConfiguration;
-import android.net.IpConfiguration.IpAssignment;
-import android.net.IpConfiguration.ProxySettings;
 import android.os.Environment;
-import android.util.Log;
-import android.util.SparseArray;
+import android.util.ArrayMap;
 
 import com.android.server.net.IpConfigStore;
 
@@ -29,34 +26,60 @@
 /**
  * This class provides an API to store and manage Ethernet network configuration.
  */
-public class EthernetConfigStore extends IpConfigStore {
-    private static final String TAG = "EthernetConfigStore";
-
+public class EthernetConfigStore {
     private static final String ipConfigFile = Environment.getDataDirectory() +
             "/misc/ethernet/ipconfig.txt";
 
+    private IpConfigStore mStore = new IpConfigStore();
+    private ArrayMap<String, IpConfiguration> mIpConfigurations;
+    private IpConfiguration mIpConfigurationForDefaultInterface;
+    private final Object mSync = new Object();
+
     public EthernetConfigStore() {
+        mIpConfigurations = new ArrayMap<>(0);
     }
 
-    public IpConfiguration readIpAndProxyConfigurations() {
-        SparseArray<IpConfiguration> networks = readIpAndProxyConfigurations(ipConfigFile);
+    public void read() {
+        synchronized (mSync) {
+            ArrayMap<String, IpConfiguration> configs =
+                    IpConfigStore.readIpConfigurations(ipConfigFile);
 
-        if (networks.size() == 0) {
-            Log.w(TAG, "No Ethernet configuration found. Using default.");
-            return new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null);
+            // This configuration may exist in old file versions when there was only a single active
+            // Ethernet interface.
+            if (configs.containsKey("0")) {
+                mIpConfigurationForDefaultInterface = configs.remove("0");
+            }
+
+            mIpConfigurations = configs;
         }
-
-        if (networks.size() > 1) {
-            // Currently we only support a single Ethernet interface.
-            Log.w(TAG, "Multiple Ethernet configurations detected. Only reading first one.");
-        }
-
-        return networks.valueAt(0);
     }
 
-    public void writeIpAndProxyConfigurations(IpConfiguration config) {
-        SparseArray<IpConfiguration> networks = new SparseArray<IpConfiguration>();
-        networks.put(0, config);
-        writeIpAndProxyConfigurations(ipConfigFile, networks);
+    public void write(String iface, IpConfiguration config) {
+        boolean modified;
+
+        synchronized (mSync) {
+            if (config == null) {
+                modified = mIpConfigurations.remove(iface) != null;
+            } else {
+                IpConfiguration oldConfig = mIpConfigurations.put(iface, config);
+                modified = !config.equals(oldConfig);
+            }
+
+            if (modified) {
+                mStore.writeIpConfigurations(ipConfigFile, mIpConfigurations);
+            }
+        }
+    }
+
+    public ArrayMap<String, IpConfiguration> getIpConfigurations() {
+        synchronized (mSync) {
+            return new ArrayMap<>(mIpConfigurations);
+        }
+    }
+
+    public IpConfiguration getIpConfigurationForDefaultInterface() {
+        synchronized (mSync) {
+            return new IpConfiguration(mIpConfigurationForDefaultInterface);
+        }
     }
 }
diff --git a/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java b/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
index 2e5d09e..29464b7 100644
--- a/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
+++ b/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
@@ -16,12 +16,9 @@
 
 package com.android.server.ethernet;
 
+import static android.net.ConnectivityManager.TYPE_ETHERNET;
+
 import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.DhcpResults;
-import android.net.EthernetManager;
-import android.net.IEthernetServiceListener;
-import android.net.InterfaceConfiguration;
 import android.net.IpConfiguration;
 import android.net.IpConfiguration.IpAssignment;
 import android.net.IpConfiguration.ProxySettings;
@@ -31,292 +28,215 @@
 import android.net.NetworkFactory;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
-import android.net.StaticIpConfiguration;
-import android.net.ip.IpManager;
-import android.net.ip.IpManager.ProvisioningConfiguration;
+import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
+import android.net.StringNetworkSpecifier;
+import android.net.ip.IpClient;
+import android.net.ip.IpClient.ProvisioningConfiguration;
 import android.os.Handler;
-import android.os.IBinder;
-import android.os.INetworkManagementService;
-import android.os.Looper;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.net.BaseNetworkObserver;
 
 import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * Manages connectivity for an Ethernet interface.
+ * {@link NetworkFactory} that represents Ethernet networks.
  *
- * Ethernet Interfaces may be present at boot time or appear after boot (e.g.,
- * for Ethernet adapters connected over USB). This class currently supports
- * only one interface. When an interface appears on the system (or is present
- * at boot time) this class will start tracking it and bring it up, and will
- * attempt to connect when requested. Any other interfaces that subsequently
- * appear will be ignored until the tracked interface disappears. Only
- * interfaces whose names match the <code>config_ethernet_iface_regex</code>
- * regular expression are tracked.
- *
- * This class reports a static network score of 70 when it is tracking an
- * interface and that interface's link is up, and a score of 0 otherwise.
- *
- * @hide
+ * This class reports a static network score of 70 when it is tracking an interface and that
+ * interface's link is up, and a score of 0 otherwise.
  */
-class EthernetNetworkFactory {
+public class EthernetNetworkFactory extends NetworkFactory {
+    private final static String TAG = EthernetNetworkFactory.class.getSimpleName();
+    final static boolean DBG = true;
+
+    private final static int NETWORK_SCORE = 70;
     private static final String NETWORK_TYPE = "Ethernet";
-    private static final String TAG = "EthernetNetworkFactory";
-    private static final int NETWORK_SCORE = 70;
-    private static final boolean DBG = true;
 
-    /** Tracks interface changes. Called from NetworkManagementService. */
-    private InterfaceObserver mInterfaceObserver;
+    private final ConcurrentHashMap<String, NetworkInterfaceState> mTrackingInterfaces =
+            new ConcurrentHashMap<>();
+    private final Handler mHandler;
+    private final Context mContext;
 
-    /** For static IP configuration */
-    private EthernetManager mEthernetManager;
+    public EthernetNetworkFactory(Handler handler, Context context, NetworkCapabilities filter) {
+        super(handler.getLooper(), context, NETWORK_TYPE, filter);
 
-    /** To set link state and configure IP addresses. */
-    private INetworkManagementService mNMService;
+        mHandler = handler;
+        mContext = context;
 
-    /** All code runs here, including start(). */
-    private Handler mHandler;
-
-    /* To communicate with ConnectivityManager */
-    private NetworkCapabilities mNetworkCapabilities;
-    private NetworkAgent mNetworkAgent;
-    private LocalNetworkFactory mFactory;
-    private Context mContext;
-
-    /** Product-dependent regular expression of interface names we track. */
-    private static String mIfaceMatch = "";
-
-    /** To notify Ethernet status. */
-    private final RemoteCallbackList<IEthernetServiceListener> mListeners;
-
-    /** Data members. All accesses to these must be on the handler thread. */
-    private String mIface = "";
-    private String mHwAddr;
-    private boolean mLinkUp;
-    private NetworkInfo mNetworkInfo;
-    private LinkProperties mLinkProperties;
-    private IpManager mIpManager;
-    private boolean mNetworkRequested = false;
-
-    EthernetNetworkFactory(RemoteCallbackList<IEthernetServiceListener> listeners) {
-        initNetworkCapabilities();
-        clearInfo();
-        mListeners = listeners;
+        setScoreFilter(NETWORK_SCORE);
     }
 
-    private class LocalNetworkFactory extends NetworkFactory {
-        LocalNetworkFactory(String name, Context context, Looper looper) {
-            super(looper, context, name, new NetworkCapabilities());
+    @Override
+    public boolean acceptRequest(NetworkRequest request, int score) {
+        if (DBG) {
+            Log.d(TAG, "acceptRequest, request: " + request + ", score: " + score);
         }
 
-        protected void startNetwork() {
-            if (!mNetworkRequested) {
-                mNetworkRequested = true;
-                maybeStartIpManager();
-            }
+        return networkForRequest(request) != null;
+    }
+
+    @Override
+    protected void needNetworkFor(NetworkRequest networkRequest, int score) {
+        NetworkInterfaceState network = networkForRequest(networkRequest);
+
+        if (network == null) {
+            Log.e(TAG, "needNetworkFor, failed to get a network for " + networkRequest);
+            return;
         }
 
-        protected void stopNetwork() {
-            mNetworkRequested = false;
-            stopIpManager();
+        if (++network.refCount == 1) {
+            network.start();
         }
     }
 
-    private void clearInfo() {
-        mLinkProperties = new LinkProperties();
-        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");
-        mNetworkInfo.setExtraInfo(mHwAddr);
-        mNetworkInfo.setIsAvailable(isTrackingInterface());
-    }
+    @Override
+    protected void releaseNetworkFor(NetworkRequest networkRequest) {
+        NetworkInterfaceState network = networkForRequest(networkRequest);
+        if (network == null) {
+            Log.e(TAG, "needNetworkFor, failed to get a network for " + networkRequest);
+            return;
+        }
 
-    private void stopIpManager() {
-        if (mIpManager != null) {
-            mIpManager.shutdown();
-            mIpManager = null;
+        if (--network.refCount == 1) {
+            network.stop();
         }
-        // ConnectivityService will only forget our NetworkAgent if we send it a NetworkInfo object
-        // with a state of DISCONNECTED or SUSPENDED. So we can't simply clear our NetworkInfo here:
-        // that sets the state to IDLE, and ConnectivityService will still think we're connected.
-        //
-        mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
-        if (mNetworkAgent != null) {
-            updateAgent();
-            mNetworkAgent = null;
-        }
-        clearInfo();
     }
 
     /**
-     * Updates interface state variables.
-     * Called on link state changes or on startup.
+     * Returns an array of available interface names. The array is sorted: unrestricted interfaces
+     * goes first, then sorted by name.
      */
-    private void updateInterfaceState(String iface, boolean up) {
-        if (!mIface.equals(iface)) {
+    String[] getAvailableInterfaces(boolean includeRestricted) {
+        return mTrackingInterfaces.values()
+                .stream()
+                .filter(iface -> !iface.isRestricted() || includeRestricted)
+                .sorted((iface1, iface2) -> {
+                    int r = Boolean.compare(iface1.isRestricted(), iface2.isRestricted());
+                    return r == 0 ? iface1.name.compareTo(iface2.name) : r;
+                })
+                .map(iface -> iface.name)
+                .toArray(String[]::new);
+    }
+
+    void addInterface(String ifaceName, String hwAddress, NetworkCapabilities capabilities,
+             IpConfiguration ipConfiguration) {
+        if (mTrackingInterfaces.containsKey(ifaceName)) {
+            Log.e(TAG, "Interface with name " + ifaceName + " already exists.");
             return;
         }
-        Log.d(TAG, "updateInterface: " + iface + " link " + (up ? "up" : "down"));
 
-        mLinkUp = up;
-        if (up) {
-            maybeStartIpManager();
+        if (DBG) {
+            Log.d(TAG, "addInterface, iface: " + ifaceName + ", capabilities: " + capabilities);
+        }
+
+        NetworkInterfaceState iface = new NetworkInterfaceState(
+                ifaceName, hwAddress, mHandler, mContext, capabilities);
+        iface.setIpConfig(ipConfiguration);
+        mTrackingInterfaces.put(ifaceName, iface);
+
+        updateCapabilityFilter();
+    }
+
+    private void updateCapabilityFilter() {
+        NetworkCapabilities capabilitiesFilter = new NetworkCapabilities();
+        capabilitiesFilter.clearAll();
+
+        for (NetworkInterfaceState iface:  mTrackingInterfaces.values()) {
+            capabilitiesFilter.combineCapabilities(iface.mCapabilities);
+        }
+
+        if (DBG) Log.d(TAG, "updateCapabilityFilter: " + capabilitiesFilter);
+        setCapabilityFilter(capabilitiesFilter);
+    }
+
+    void removeInterface(String interfaceName) {
+        NetworkInterfaceState iface = mTrackingInterfaces.remove(interfaceName);
+        if (iface != null) {
+            iface.stop();
+        }
+
+        updateCapabilityFilter();
+    }
+
+    /** Returns true if state has been modified */
+    boolean updateInterfaceLinkState(String ifaceName, boolean up) {
+        if (!mTrackingInterfaces.containsKey(ifaceName)) {
+            return false;
+        }
+
+        if (DBG) {
+            Log.d(TAG, "updateInterfaceLinkState, iface: " + ifaceName + ", up: " + up);
+        }
+
+        NetworkInterfaceState iface = mTrackingInterfaces.get(ifaceName);
+        return iface.updateLinkState(up);
+    }
+
+    boolean hasInterface(String interfacName) {
+        return mTrackingInterfaces.containsKey(interfacName);
+    }
+
+    void updateIpConfiguration(String iface, IpConfiguration ipConfiguration) {
+        NetworkInterfaceState network = mTrackingInterfaces.get(iface);
+        if (network != null) {
+            network.setIpConfig(ipConfiguration);
+        }
+    }
+
+    private NetworkInterfaceState networkForRequest(NetworkRequest request) {
+        String requestedIface = null;
+
+        NetworkSpecifier specifier = request.networkCapabilities.getNetworkSpecifier();
+        if (specifier instanceof StringNetworkSpecifier) {
+            requestedIface = ((StringNetworkSpecifier) specifier).specifier;
+        }
+
+        NetworkInterfaceState network = null;
+        if (!TextUtils.isEmpty(requestedIface)) {
+            NetworkInterfaceState n = mTrackingInterfaces.get(requestedIface);
+            if (n != null && n.statisified(request.networkCapabilities)) {
+                network = n;
+            }
         } else {
-            stopIpManager();
-        }
-    }
-
-    private class InterfaceObserver extends BaseNetworkObserver {
-        @Override
-        public void interfaceLinkStateChanged(String iface, boolean up) {
-            mHandler.post(() -> {
-                updateInterfaceState(iface, up);
-            });
-        }
-
-        @Override
-        public void interfaceAdded(String iface) {
-            mHandler.post(() -> {
-                maybeTrackInterface(iface);
-            });
-        }
-
-        @Override
-        public void interfaceRemoved(String iface) {
-            mHandler.post(() -> {
-                if (stopTrackingInterface(iface)) {
-                    trackFirstAvailableInterface();
+            for (NetworkInterfaceState n : mTrackingInterfaces.values()) {
+                if (n.statisified(request.networkCapabilities)) {
+                    network = n;
+                    break;
                 }
-            });
-        }
-    }
-
-    private void setInterfaceUp(String iface) {
-        // Bring up the interface so we get link status indications.
-        try {
-            mNMService.setInterfaceUp(iface);
-            String hwAddr = null;
-            InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
-
-            if (config == null) {
-                Log.e(TAG, "Null interface config for " + iface + ". Bailing out.");
-                return;
             }
-
-            if (!isTrackingInterface()) {
-                setInterfaceInfo(iface, config.getHardwareAddress());
-                mNetworkInfo.setIsAvailable(true);
-                mNetworkInfo.setExtraInfo(mHwAddr);
-            } else {
-                Log.e(TAG, "Interface unexpectedly changed from " + iface + " to " + mIface);
-                mNMService.setInterfaceDown(iface);
-            }
-        } catch (RemoteException | IllegalStateException e) {
-            // Either the system is crashing or the interface has disappeared. Just ignore the
-            // error; we haven't modified any state because we only do that if our calls succeed.
-            Log.e(TAG, "Error upping interface " + mIface + ": " + e);
         }
-    }
 
-    private boolean maybeTrackInterface(String iface) {
-        // If we don't already have an interface, and if this interface matches
-        // our regex, start tracking it.
-        if (!iface.matches(mIfaceMatch) || isTrackingInterface())
-            return false;
-
-        Log.d(TAG, "Started tracking interface " + iface);
-        setInterfaceUp(iface);
-        return true;
-    }
-
-    private boolean stopTrackingInterface(String iface) {
-        if (!iface.equals(mIface))
-            return false;
-
-        Log.d(TAG, "Stopped tracking interface " + iface);
-        setInterfaceInfo("", null);
-        stopIpManager();
-        return true;
-    }
-
-    public void updateAgent() {
-        if (mNetworkAgent == null) return;
         if (DBG) {
-            Log.i(TAG, "Updating mNetworkAgent with: " +
-                  mNetworkCapabilities + ", " +
-                  mNetworkInfo + ", " +
-                  mLinkProperties);
-        }
-        mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
-        mNetworkAgent.sendNetworkInfo(mNetworkInfo);
-        mNetworkAgent.sendLinkProperties(mLinkProperties);
-        // never set the network score below 0.
-        mNetworkAgent.sendNetworkScore(mLinkUp? NETWORK_SCORE : 0);
-    }
-
-    void onIpLayerStarted(LinkProperties linkProperties) {
-        if (mNetworkAgent != null) {
-            Log.e(TAG, "Already have a NetworkAgent - aborting new request");
-            stopIpManager();
-            return;
-        }
-        mLinkProperties = linkProperties;
-        mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);
-
-        // Create our NetworkAgent.
-        mNetworkAgent = new NetworkAgent(mHandler.getLooper(), mContext,
-                NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,
-                NETWORK_SCORE) {
-            public void unwanted() {
-                if (this == mNetworkAgent) {
-                    stopIpManager();
-                } else if (mNetworkAgent != null) {
-                    Log.d(TAG, "Ignoring unwanted as we have a more modern " +
-                            "instance");
-                }  // Otherwise, we've already called stopIpManager.
-            }
-        };
-    }
-
-    void onIpLayerStopped(LinkProperties linkProperties) {
-        // This cannot happen due to provisioning timeout, because our timeout is 0. It can only
-        // happen if we're provisioned and we lose provisioning.
-        stopIpManager();
-        maybeStartIpManager();
-    }
-
-    void updateLinkProperties(LinkProperties linkProperties) {
-        mLinkProperties = linkProperties;
-        if (mNetworkAgent != null) {
-            mNetworkAgent.sendLinkProperties(linkProperties);
-        }
-    }
-
-    public void maybeStartIpManager() {
-        if (mNetworkRequested && mIpManager == null && isTrackingInterface()) {
-            startIpManager();
-        }
-    }
-
-    public void startIpManager() {
-        if (DBG) {
-            Log.d(TAG, String.format("starting IpManager(%s): mNetworkInfo=%s", mIface,
-                    mNetworkInfo));
+            Log.i(TAG, "networkForRequest, request: " + request + ", network: " + network);
         }
 
-        IpConfiguration config = mEthernetManager.getConfiguration();
+        return network;
+    }
 
-        mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
-        IpManager.Callback ipmCallback = new IpManager.Callback() {
+    private static class NetworkInterfaceState {
+        final String name;
+
+        private final String mHwAddress;
+        private final NetworkCapabilities mCapabilities;
+        private final Handler mHandler;
+        private final Context mContext;
+        private final NetworkInfo mNetworkInfo;
+
+        private static String sTcpBufferSizes = null;  // Lazy initialized.
+
+        private boolean mLinkUp;
+        private LinkProperties mLinkProperties = new LinkProperties();
+
+        private IpClient mIpClient;
+        private NetworkAgent mNetworkAgent;
+        private IpConfiguration mIpConfig;
+
+        long refCount = 0;
+
+        private final IpClient.Callback mIpClientCallback = new IpClient.Callback() {
             @Override
             public void onProvisioningSuccess(LinkProperties newLp) {
                 mHandler.post(() -> onIpLayerStarted(newLp));
@@ -333,178 +253,191 @@
             }
         };
 
-        stopIpManager();
-        mIpManager = new IpManager(mContext, mIface, ipmCallback);
+        NetworkInterfaceState(String ifaceName, String hwAddress, Handler handler, Context context,
+                NetworkCapabilities capabilities) {
+            name = ifaceName;
+            mCapabilities = capabilities;
+            mHandler = handler;
+            mContext = context;
 
-        if (config.getProxySettings() == ProxySettings.STATIC ||
-                config.getProxySettings() == ProxySettings.PAC) {
-            mIpManager.setHttpProxy(config.getHttpProxy());
+            mHwAddress = hwAddress;
+            mNetworkInfo = new NetworkInfo(TYPE_ETHERNET, 0, NETWORK_TYPE, "");
+            mNetworkInfo.setExtraInfo(mHwAddress);
+            mNetworkInfo.setIsAvailable(true);
         }
 
-        final String tcpBufferSizes = mContext.getResources().getString(
-                com.android.internal.R.string.config_ethernet_tcp_buffers);
-        if (!TextUtils.isEmpty(tcpBufferSizes)) {
-            mIpManager.setTcpBufferSizes(tcpBufferSizes);
+        void setIpConfig(IpConfiguration ipConfig) {
+
+            this.mIpConfig = ipConfig;
         }
 
-        final ProvisioningConfiguration provisioningConfiguration;
-        if (config.getIpAssignment() == IpAssignment.STATIC) {
-            provisioningConfiguration = IpManager.buildProvisioningConfiguration()
-                    .withStaticConfiguration(config.getStaticIpConfiguration())
-                    .build();
-        } else {
-            provisioningConfiguration = mIpManager.buildProvisioningConfiguration()
-                    .withProvisioningTimeoutMs(0)
-                    .build();
+        boolean statisified(NetworkCapabilities requestedCapabilities) {
+            return requestedCapabilities.satisfiedByNetworkCapabilities(mCapabilities);
         }
 
-        mIpManager.startProvisioning(provisioningConfiguration);
-    }
-
-    /**
-     * Begin monitoring connectivity
-     */
-    public void start(Context context, Handler handler) {
-        mHandler = handler;
-
-        // The services we use.
-        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
-        mNMService = INetworkManagementService.Stub.asInterface(b);
-        mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);
-
-        // Interface match regex.
-        mIfaceMatch = context.getResources().getString(
-                com.android.internal.R.string.config_ethernet_iface_regex);
-
-        // Create and register our NetworkFactory.
-        mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, mHandler.getLooper());
-        mFactory.setCapabilityFilter(mNetworkCapabilities);
-        mFactory.setScoreFilter(NETWORK_SCORE);
-        mFactory.register();
-
-        mContext = context;
-
-        // Start tracking interface change events.
-        mInterfaceObserver = new InterfaceObserver();
-        try {
-            mNMService.registerObserver(mInterfaceObserver);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Could not register InterfaceObserver " + e);
+        boolean isRestricted() {
+            return mCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
         }
 
-        // If an Ethernet interface is already connected, start tracking that.
-        // Otherwise, the first Ethernet interface to appear will be tracked.
-        mHandler.post(() -> trackFirstAvailableInterface());
-    }
+        private void start() {
+            if (DBG) {
+                Log.d(TAG, String.format("starting IpClient(%s): mNetworkInfo=%s", name,
+                        mNetworkInfo));
+            }
+            if (mIpClient != null) stop();
 
-    public void trackFirstAvailableInterface() {
-        try {
-            final String[] ifaces = mNMService.listInterfaces();
-            for (String iface : ifaces) {
-                if (maybeTrackInterface(iface)) {
-                    // We have our interface. Track it.
-                    // Note: if the interface already has link (e.g., if we crashed and got
-                    // restarted while it was running), we need to fake a link up notification so we
-                    // start configuring it.
-                    if (mNMService.getInterfaceConfig(iface).hasFlag("running")) {
-                        updateInterfaceState(iface, true);
-                    }
-                    break;
+            mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddress);
+
+            mIpClient = new IpClient(mContext, name, mIpClientCallback);
+
+            if (sTcpBufferSizes == null) {
+                sTcpBufferSizes = mContext.getResources().getString(
+                        com.android.internal.R.string.config_ethernet_tcp_buffers);
+            }
+            provisionIpClient(mIpClient, mIpConfig, sTcpBufferSizes);
+        }
+
+        void onIpLayerStarted(LinkProperties linkProperties) {
+            if (mNetworkAgent != null) {
+                Log.e(TAG, "Already have a NetworkAgent - aborting new request");
+                stop();
+                return;
+            }
+            mLinkProperties = linkProperties;
+            mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddress);
+            mNetworkInfo.setIsAvailable(true);
+
+            // Create our NetworkAgent.
+            mNetworkAgent = new NetworkAgent(mHandler.getLooper(), mContext,
+                    NETWORK_TYPE, mNetworkInfo, mCapabilities, mLinkProperties,
+                    NETWORK_SCORE) {
+                public void unwanted() {
+                    if (this == mNetworkAgent) {
+                        stop();
+                    } else if (mNetworkAgent != null) {
+                        Log.d(TAG, "Ignoring unwanted as we have a more modern " +
+                                "instance");
+                    }  // Otherwise, we've already called stop.
                 }
+            };
+        }
+
+        void onIpLayerStopped(LinkProperties linkProperties) {
+            // This cannot happen due to provisioning timeout, because our timeout is 0. It can only
+            // happen if we're provisioned and we lose provisioning.
+            start();
+        }
+
+        void updateLinkProperties(LinkProperties linkProperties) {
+            mLinkProperties = linkProperties;
+            if (mNetworkAgent != null) {
+                mNetworkAgent.sendLinkProperties(linkProperties);
             }
-        } catch (RemoteException|IllegalStateException e) {
-            Log.e(TAG, "Could not get list of interfaces " + e);
+        }
+
+        /** Returns true if state has been modified */
+        boolean updateLinkState(boolean up) {
+            if (mLinkUp == up) return false;
+
+            mLinkUp = up;
+            if (up) {
+                start();
+            } else {
+                stop();
+            }
+
+            return true;
+        }
+
+        void stop() {
+            if (mIpClient != null) {
+                mIpClient.shutdown();
+                mIpClient = null;
+            }
+            // ConnectivityService will only forget our NetworkAgent if we send it a NetworkInfo object
+            // with a state of DISCONNECTED or SUSPENDED. So we can't simply clear our NetworkInfo here:
+            // that sets the state to IDLE, and ConnectivityService will still think we're connected.
+            //
+            mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddress);
+            if (mNetworkAgent != null) {
+                updateAgent();
+                mNetworkAgent = null;
+            }
+            clear();
+        }
+
+        private void updateAgent() {
+            if (mNetworkAgent == null) return;
+            if (DBG) {
+                Log.i(TAG, "Updating mNetworkAgent with: " +
+                        mCapabilities + ", " +
+                        mNetworkInfo + ", " +
+                        mLinkProperties);
+            }
+            mNetworkAgent.sendNetworkCapabilities(mCapabilities);
+            mNetworkAgent.sendNetworkInfo(mNetworkInfo);
+            mNetworkAgent.sendLinkProperties(mLinkProperties);
+            // never set the network score below 0.
+            mNetworkAgent.sendNetworkScore(mLinkUp? NETWORK_SCORE : 0);
+        }
+
+        private void clear() {
+            mLinkProperties.clear();
+            mNetworkInfo.setDetailedState(DetailedState.IDLE, null, null);
+            mNetworkInfo.setIsAvailable(false);
+        }
+
+        private static void provisionIpClient(IpClient ipClient, IpConfiguration config,
+                String tcpBufferSizes) {
+            if (config.getProxySettings() == ProxySettings.STATIC ||
+                    config.getProxySettings() == ProxySettings.PAC) {
+                ipClient.setHttpProxy(config.getHttpProxy());
+            }
+
+            if (!TextUtils.isEmpty(tcpBufferSizes)) {
+                ipClient.setTcpBufferSizes(tcpBufferSizes);
+            }
+
+            final ProvisioningConfiguration provisioningConfiguration;
+            if (config.getIpAssignment() == IpAssignment.STATIC) {
+                provisioningConfiguration = IpClient.buildProvisioningConfiguration()
+                        .withStaticConfiguration(config.getStaticIpConfiguration())
+                        .build();
+            } else {
+                provisioningConfiguration = IpClient.buildProvisioningConfiguration()
+                        .withProvisioningTimeoutMs(0)
+                        .build();
+            }
+
+            ipClient.startProvisioning(provisioningConfiguration);
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "{ "
+                    + "iface: " + name + ", "
+                    + "up: " + mLinkUp + ", "
+                    + "hwAddress: " + mHwAddress + ", "
+                    + "networkInfo: " + mNetworkInfo + ", "
+                    + "networkAgent: " + mNetworkAgent + ", "
+                    + "ipClient: " + mIpClient + ","
+                    + "linkProperties: " + mLinkProperties
+                    + "}";
         }
     }
 
-    public void stop() {
-        stopIpManager();
-        setInterfaceInfo("", null);
-        mFactory.unregister();
-    }
-
-    private void initNetworkCapabilities() {
-        mNetworkCapabilities = new NetworkCapabilities();
-        mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET);
-        mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
-        mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
-        mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);
-        mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-        // We have no useful data on bandwidth. Say 100M up and 100M down. :-(
-        mNetworkCapabilities.setLinkUpstreamBandwidthKbps(100 * 1000);
-        mNetworkCapabilities.setLinkDownstreamBandwidthKbps(100 * 1000);
-    }
-
-    public boolean isTrackingInterface() {
-        return !TextUtils.isEmpty(mIface);
-    }
-
-    /**
-     * Set interface information and notify listeners if availability is changed.
-     */
-    private void setInterfaceInfo(String iface, String hwAddr) {
-        boolean oldAvailable = isTrackingInterface();
-        mIface = iface;
-        mHwAddr = hwAddr;
-        boolean available = isTrackingInterface();
-
-        mNetworkInfo.setExtraInfo(mHwAddr);
-        mNetworkInfo.setIsAvailable(available);
-
-        if (oldAvailable != available) {
-            int n = mListeners.beginBroadcast();
-            for (int i = 0; i < n; i++) {
-                try {
-                    mListeners.getBroadcastItem(i).onAvailabilityChanged(available);
-                } catch (RemoteException e) {
-                    // Do nothing here.
-                }
-            }
-            mListeners.finishBroadcast();
-        }
-    }
-
-    private void postAndWaitForRunnable(Runnable r) throws InterruptedException {
-        CountDownLatch latch = new CountDownLatch(1);
-        mHandler.post(() -> {
-            try {
-                r.run();
-            } finally {
-                latch.countDown();
-            }
-        });
-        latch.await();
-    }
-
-
     void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) {
-        try {
-            postAndWaitForRunnable(() -> {
-                pw.println("Network Requested: " + mNetworkRequested);
-                if (isTrackingInterface()) {
-                    pw.println("Tracking interface: " + mIface);
-                    pw.increaseIndent();
-                    pw.println("MAC address: " + mHwAddr);
-                    pw.println("Link state: " + (mLinkUp ? "up" : "down"));
-                    pw.decreaseIndent();
-                } else {
-                    pw.println("Not tracking any interface");
-                }
-
-                pw.println();
-                pw.println("NetworkInfo: " + mNetworkInfo);
-                pw.println("LinkProperties: " + mLinkProperties);
-                pw.println("NetworkAgent: " + mNetworkAgent);
-                if (mIpManager != null) {
-                    pw.println("IpManager:");
-                    pw.increaseIndent();
-                    mIpManager.dump(fd, pw, args);
-                    pw.decreaseIndent();
-                }
-            });
-        } catch (InterruptedException e) {
-            throw new IllegalStateException("dump() interrupted");
+        super.dump(fd, pw, args);
+        pw.println(getClass().getSimpleName());
+        pw.println("Tracking interfaces:");
+        pw.increaseIndent();
+        for (String iface: mTrackingInterfaces.keySet()) {
+            NetworkInterfaceState ifaceState = mTrackingInterfaces.get(iface);
+            pw.println(iface + ":" + ifaceState);
+            pw.increaseIndent();
+            ifaceState.mIpClient.dump(fd, pw, args);
+            pw.decreaseIndent();
         }
+        pw.decreaseIndent();
     }
 }
diff --git a/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java b/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
index 42996d6..d5beec1 100644
--- a/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
+++ b/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
@@ -21,14 +21,10 @@
 import android.net.IEthernetManager;
 import android.net.IEthernetServiceListener;
 import android.net.IpConfiguration;
-import android.net.IpConfiguration.IpAssignment;
-import android.net.IpConfiguration.ProxySettings;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.os.RemoteCallbackList;
 import android.os.RemoteException;
-import android.provider.Settings;
 import android.util.Log;
 import android.util.PrintWriterPrinter;
 
@@ -41,31 +37,18 @@
 /**
  * EthernetServiceImpl handles remote Ethernet operation requests by implementing
  * the IEthernetManager interface.
- *
- * @hide
  */
 public class EthernetServiceImpl extends IEthernetManager.Stub {
     private static final String TAG = "EthernetServiceImpl";
 
     private final Context mContext;
-    private final EthernetConfigStore mEthernetConfigStore;
     private final AtomicBoolean mStarted = new AtomicBoolean(false);
-    private IpConfiguration mIpConfiguration;
 
     private Handler mHandler;
-    private final EthernetNetworkFactory mTracker;
-    private final RemoteCallbackList<IEthernetServiceListener> mListeners =
-            new RemoteCallbackList<IEthernetServiceListener>();
+    private EthernetTracker mTracker;
 
     public EthernetServiceImpl(Context context) {
         mContext = context;
-        Log.i(TAG, "Creating EthernetConfigStore");
-        mEthernetConfigStore = new EthernetConfigStore();
-        mIpConfiguration = mEthernetConfigStore.readIpAndProxyConfigurations();
-
-        Log.i(TAG, "Read stored IP configuration: " + mIpConfiguration);
-
-        mTracker = new EthernetNetworkFactory(mListeners);
     }
 
     private void enforceAccessPermission() {
@@ -80,6 +63,18 @@
                 "ConnectivityService");
     }
 
+    private void enforceUseRestrictedNetworksPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS,
+                "ConnectivityService");
+    }
+
+    private boolean checkUseRestrictedNetworksPermission() {
+        return mContext.checkCallingOrSelfPermission(
+                android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS)
+                == PackageManager.PERMISSION_GRANTED;
+    }
+
     public void start() {
         Log.i(TAG, "Starting Ethernet service");
 
@@ -87,60 +82,68 @@
         handlerThread.start();
         mHandler = new Handler(handlerThread.getLooper());
 
-        mTracker.start(mContext, mHandler);
+        mTracker = new EthernetTracker(mContext, mHandler);
+        mTracker.start();
 
         mStarted.set(true);
     }
 
+    @Override
+    public String[] getAvailableInterfaces() throws RemoteException {
+        return mTracker.getInterfaces(checkUseRestrictedNetworksPermission());
+    }
+
     /**
      * Get Ethernet configuration
      * @return the Ethernet Configuration, contained in {@link IpConfiguration}.
      */
     @Override
-    public IpConfiguration getConfiguration() {
+    public IpConfiguration getConfiguration(String iface) {
         enforceAccessPermission();
 
-        synchronized (mIpConfiguration) {
-            return new IpConfiguration(mIpConfiguration);
+        if (mTracker.isRestrictedInterface(iface)) {
+            enforceUseRestrictedNetworksPermission();
         }
+
+        return new IpConfiguration(mTracker.getIpConfiguration(iface));
     }
 
     /**
      * Set Ethernet configuration
      */
     @Override
-    public void setConfiguration(IpConfiguration config) {
+    public void setConfiguration(String iface, IpConfiguration config) {
         if (!mStarted.get()) {
             Log.w(TAG, "System isn't ready enough to change ethernet configuration");
         }
 
         enforceConnectivityInternalPermission();
 
-        synchronized (mIpConfiguration) {
-            mEthernetConfigStore.writeIpAndProxyConfigurations(config);
-
-            // TODO: this does not check proxy settings, gateways, etc.
-            // Fix this by making IpConfiguration a complete representation of static configuration.
-            if (!config.equals(mIpConfiguration)) {
-                mIpConfiguration = new IpConfiguration(config);
-                mTracker.stop();
-                mTracker.start(mContext, mHandler);
-            }
+        if (mTracker.isRestrictedInterface(iface)) {
+            enforceUseRestrictedNetworksPermission();
         }
+
+        // TODO: this does not check proxy settings, gateways, etc.
+        // Fix this by making IpConfiguration a complete representation of static configuration.
+        mTracker.updateIpConfiguration(iface, new IpConfiguration(config));
     }
 
     /**
-     * Indicates whether the system currently has one or more
-     * Ethernet interfaces.
+     * Indicates whether given interface is available.
      */
     @Override
-    public boolean isAvailable() {
+    public boolean isAvailable(String iface) {
         enforceAccessPermission();
-        return mTracker.isTrackingInterface();
+
+        if (mTracker.isRestrictedInterface(iface)) {
+            enforceUseRestrictedNetworksPermission();
+        }
+
+        return mTracker.isTrackingInterface(iface);
     }
 
     /**
-     * Addes a listener.
+     * Adds a listener.
      * @param listener A {@link IEthernetServiceListener} to add.
      */
     public void addListener(IEthernetServiceListener listener) {
@@ -148,7 +151,7 @@
             throw new IllegalArgumentException("listener must not be null");
         }
         enforceAccessPermission();
-        mListeners.register(listener);
+        mTracker.addListener(listener, checkUseRestrictedNetworksPermission());
     }
 
     /**
@@ -160,7 +163,7 @@
             throw new IllegalArgumentException("listener must not be null");
         }
         enforceAccessPermission();
-        mListeners.unregister(listener);
+        mTracker.removeListener(listener);
     }
 
     @Override
@@ -179,12 +182,6 @@
         mTracker.dump(fd, pw, args);
         pw.decreaseIndent();
 
-        pw.println();
-        pw.println("Stored Ethernet configuration: ");
-        pw.increaseIndent();
-        pw.println(mIpConfiguration);
-        pw.decreaseIndent();
-
         pw.println("Handler:");
         pw.increaseIndent();
         mHandler.dump(new PrintWriterPrinter(pw), "EthernetServiceImpl");
diff --git a/service-t/src/com/android/server/ethernet/EthernetTracker.java b/service-t/src/com/android/server/ethernet/EthernetTracker.java
new file mode 100644
index 0000000..7f893e0
--- /dev/null
+++ b/service-t/src/com/android/server/ethernet/EthernetTracker.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2018 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.server.ethernet;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.net.IEthernetServiceListener;
+import android.net.InterfaceConfiguration;
+import android.net.IpConfiguration;
+import android.net.IpConfiguration.IpAssignment;
+import android.net.IpConfiguration.ProxySettings;
+import android.net.LinkAddress;
+import android.net.NetworkCapabilities;
+import android.net.StaticIpConfiguration;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.INetworkManagementService;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.net.BaseNetworkObserver;
+
+import java.io.FileDescriptor;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Tracks Ethernet interfaces and manages interface configurations.
+ *
+ * <p>Interfaces may have different {@link android.net.NetworkCapabilities}. This mapping is defined
+ * in {@code config_ethernet_interfaces}. Notably, some interfaces could be marked as restricted by
+ * not specifying {@link android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED} flag.
+ * Interfaces could have associated {@link android.net.IpConfiguration}.
+ * Ethernet Interfaces may be present at boot time or appear after boot (e.g., for Ethernet adapters
+ * connected over USB). This class supports multiple interfaces. When an interface appears on the
+ * system (or is present at boot time) this class will start tracking it and bring it up. Only
+ * interfaces whose names match the {@code config_ethernet_iface_regex} regular expression are
+ * tracked.
+ *
+ * <p>All public or package private methods must be thread-safe unless stated otherwise.
+ */
+final class EthernetTracker {
+    private final static String TAG = EthernetTracker.class.getSimpleName();
+    private final static boolean DBG = EthernetNetworkFactory.DBG;
+
+    /** Product-dependent regular expression of interface names we track. */
+    private final String mIfaceMatch;
+
+    /** Mapping between {iface name | mac address} -> {NetworkCapabilities} */
+    private final ConcurrentHashMap<String, NetworkCapabilities> mNetworkCapabilities =
+            new ConcurrentHashMap<>();
+    private final ConcurrentHashMap<String, IpConfiguration> mIpConfigurations =
+            new ConcurrentHashMap<>();
+
+    private final INetworkManagementService mNMService;
+    private final Handler mHandler;
+    private final EthernetNetworkFactory mFactory;
+    private final EthernetConfigStore mConfigStore;
+
+    private final RemoteCallbackList<IEthernetServiceListener> mListeners =
+            new RemoteCallbackList<>();
+
+    private volatile IpConfiguration mIpConfigForDefaultInterface;
+
+    EthernetTracker(Context context, Handler handler) {
+        mHandler = handler;
+
+        // The services we use.
+        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+        mNMService = INetworkManagementService.Stub.asInterface(b);
+
+        // Interface match regex.
+        mIfaceMatch = context.getResources().getString(
+                com.android.internal.R.string.config_ethernet_iface_regex);
+
+        // Read default Ethernet interface configuration from resources
+        final String[] interfaceConfigs = context.getResources().getStringArray(
+                com.android.internal.R.array.config_ethernet_interfaces);
+        for (String strConfig : interfaceConfigs) {
+            parseEthernetConfig(strConfig);
+        }
+
+        mConfigStore = new EthernetConfigStore();
+
+        NetworkCapabilities nc = createNetworkCapabilities(true /* clear default capabilities */);
+        mFactory = new EthernetNetworkFactory(handler, context, nc);
+        mFactory.register();
+    }
+
+    void start() {
+        mConfigStore.read();
+
+        // Default interface is just the first one we want to track.
+        mIpConfigForDefaultInterface = mConfigStore.getIpConfigurationForDefaultInterface();
+        final ArrayMap<String, IpConfiguration> configs = mConfigStore.getIpConfigurations();
+        for (int i = 0; i < configs.size(); i++) {
+            mIpConfigurations.put(configs.keyAt(i), configs.valueAt(i));
+        }
+
+        try {
+            mNMService.registerObserver(new InterfaceObserver());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Could not register InterfaceObserver " + e);
+        }
+
+        mHandler.post(this::trackAvailableInterfaces);
+    }
+
+    void updateIpConfiguration(String iface, IpConfiguration ipConfiguration) {
+        if (DBG) {
+            Log.i(TAG, "updateIpConfiguration, iface: " + iface + ", cfg: " + ipConfiguration);
+        }
+
+        mConfigStore.write(iface, ipConfiguration);
+        mIpConfigurations.put(iface, ipConfiguration);
+
+        mHandler.post(() -> mFactory.updateIpConfiguration(iface, ipConfiguration));
+    }
+
+    IpConfiguration getIpConfiguration(String iface) {
+        return mIpConfigurations.get(iface);
+    }
+
+    boolean isTrackingInterface(String iface) {
+        return mFactory.hasInterface(iface);
+    }
+
+    String[] getInterfaces(boolean includeRestricted) {
+        return mFactory.getAvailableInterfaces(includeRestricted);
+    }
+
+    /**
+     * Returns true if given interface was configured as restricted (doesn't have
+     * NET_CAPABILITY_NOT_RESTRICTED) capability. Otherwise, returns false.
+     */
+    boolean isRestrictedInterface(String iface) {
+        final NetworkCapabilities nc = mNetworkCapabilities.get(iface);
+        return nc != null && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+    }
+
+    void addListener(IEthernetServiceListener listener, boolean canUseRestrictedNetworks) {
+        mListeners.register(listener, new ListenerInfo(canUseRestrictedNetworks));
+    }
+
+    void removeListener(IEthernetServiceListener listener) {
+        mListeners.unregister(listener);
+    }
+
+    private void removeInterface(String iface) {
+        mFactory.removeInterface(iface);
+    }
+
+    private void addInterface(String iface) {
+        InterfaceConfiguration config = null;
+        // Bring up the interface so we get link status indications.
+        try {
+            mNMService.setInterfaceUp(iface);
+            config = mNMService.getInterfaceConfig(iface);
+        } catch (RemoteException | IllegalStateException e) {
+            // Either the system is crashing or the interface has disappeared. Just ignore the
+            // error; we haven't modified any state because we only do that if our calls succeed.
+            Log.e(TAG, "Error upping interface " + iface, e);
+        }
+
+        if (config == null) {
+            Log.e(TAG, "Null interface config for " + iface + ". Bailing out.");
+            return;
+        }
+
+        final String hwAddress = config.getHardwareAddress();
+
+        NetworkCapabilities nc = mNetworkCapabilities.get(iface);
+        if (nc == null) {
+            // Try to resolve using mac address
+            nc = mNetworkCapabilities.get(hwAddress);
+            if (nc == null) {
+                nc = createDefaultNetworkCapabilities();
+            }
+        }
+        IpConfiguration ipConfiguration = mIpConfigurations.get(iface);
+        if (ipConfiguration == null) {
+            ipConfiguration = createDefaultIpConfiguration();
+        }
+
+        Log.d(TAG, "Started tracking interface " + iface);
+        mFactory.addInterface(iface, hwAddress, nc, ipConfiguration);
+
+        // Note: if the interface already has link (e.g., if we crashed and got
+        // restarted while it was running), we need to fake a link up notification so we
+        // start configuring it.
+        if (config.hasFlag("running")) {
+            updateInterfaceState(iface, true);
+        }
+    }
+
+    private void updateInterfaceState(String iface, boolean up) {
+        boolean modified = mFactory.updateInterfaceLinkState(iface, up);
+        if (modified) {
+            boolean restricted = isRestrictedInterface(iface);
+            int n = mListeners.beginBroadcast();
+            for (int i = 0; i < n; i++) {
+                try {
+                    if (restricted) {
+                        ListenerInfo listenerInfo = (ListenerInfo) mListeners.getBroadcastCookie(i);
+                        if (!listenerInfo.canUseRestrictedNetworks) {
+                            continue;
+                        }
+                    }
+                    mListeners.getBroadcastItem(i).onAvailabilityChanged(iface, up);
+                } catch (RemoteException e) {
+                    // Do nothing here.
+                }
+            }
+            mListeners.finishBroadcast();
+        }
+    }
+
+    private void maybeTrackInterface(String iface) {
+        if (DBG) Log.i(TAG, "maybeTrackInterface " + iface);
+        // If we don't already track this interface, and if this interface matches
+        // our regex, start tracking it.
+        if (!iface.matches(mIfaceMatch) || mFactory.hasInterface(iface)) {
+            return;
+        }
+
+        if (mIpConfigForDefaultInterface != null) {
+            updateIpConfiguration(iface, mIpConfigForDefaultInterface);
+            mIpConfigForDefaultInterface = null;
+        }
+
+        addInterface(iface);
+    }
+
+    private void trackAvailableInterfaces() {
+        try {
+            final String[] ifaces = mNMService.listInterfaces();
+            for (String iface : ifaces) {
+                maybeTrackInterface(iface);
+            }
+        } catch (RemoteException | IllegalStateException e) {
+            Log.e(TAG, "Could not get list of interfaces " + e);
+        }
+    }
+
+
+    private class InterfaceObserver extends BaseNetworkObserver {
+
+        @Override
+        public void interfaceLinkStateChanged(String iface, boolean up) {
+            if (DBG) {
+                Log.i(TAG, "interfaceLinkStateChanged, iface: " + iface + ", up: " + up);
+            }
+            mHandler.post(() -> updateInterfaceState(iface, up));
+        }
+
+        @Override
+        public void interfaceAdded(String iface) {
+            mHandler.post(() -> maybeTrackInterface(iface));
+        }
+
+        @Override
+        public void interfaceRemoved(String iface) {
+            mHandler.post(() -> removeInterface(iface));
+        }
+    }
+
+    private static class ListenerInfo {
+
+        boolean canUseRestrictedNetworks = false;
+
+        ListenerInfo(boolean canUseRestrictedNetworks) {
+            this.canUseRestrictedNetworks = canUseRestrictedNetworks;
+        }
+    }
+
+    private void parseEthernetConfig(String configString) {
+        String[] tokens = configString.split(";");
+        String name = tokens[0];
+        String capabilities = tokens.length > 1 ? tokens[1] : null;
+        NetworkCapabilities nc = createNetworkCapabilities(
+                !TextUtils.isEmpty(capabilities)  /* clear default capabilities */, capabilities);
+        mNetworkCapabilities.put(name, nc);
+
+        if (tokens.length > 2 && !TextUtils.isEmpty(tokens[2])) {
+            IpConfiguration ipConfig = createStaticIpConfiguration(tokens[2]);
+            mIpConfigurations.put(name, ipConfig);
+        }
+    }
+
+    private static NetworkCapabilities createDefaultNetworkCapabilities() {
+        NetworkCapabilities nc = createNetworkCapabilities(false /* clear default capabilities */);
+        nc.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+        nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
+
+        return nc;
+    }
+
+    private static NetworkCapabilities createNetworkCapabilities(boolean clearDefaultCapabilities) {
+        return createNetworkCapabilities(clearDefaultCapabilities, null);
+    }
+
+    private static NetworkCapabilities createNetworkCapabilities(
+            boolean clearDefaultCapabilities, @Nullable String commaSeparatedCapabilities) {
+
+        NetworkCapabilities nc = new NetworkCapabilities();
+        if (clearDefaultCapabilities) {
+            nc.clearAll();  // Remove default capabilities.
+        }
+        nc.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET);
+        nc.setLinkUpstreamBandwidthKbps(100 * 1000);
+        nc.setLinkDownstreamBandwidthKbps(100 * 1000);
+
+        if (!TextUtils.isEmpty(commaSeparatedCapabilities)) {
+            for (String strNetworkCapability : commaSeparatedCapabilities.split(",")) {
+                if (!TextUtils.isEmpty(strNetworkCapability)) {
+                    nc.addCapability(Integer.valueOf(strNetworkCapability));
+                }
+            }
+        }
+
+        return nc;
+    }
+
+    private static IpConfiguration createStaticIpConfiguration(String strIpAddress) {
+        StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
+        staticIpConfiguration.ipAddress = new LinkAddress(strIpAddress);
+        return new IpConfiguration(
+                IpAssignment.STATIC, ProxySettings.NONE, staticIpConfiguration, null);
+    }
+
+    private static IpConfiguration createDefaultIpConfiguration() {
+        return new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null);
+    }
+
+    private void postAndWaitForRunnable(Runnable r) {
+        mHandler.runWithScissors(r, 2000L /* timeout */);
+    }
+
+    void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) {
+        postAndWaitForRunnable(() -> {
+            pw.println(getClass().getSimpleName());
+            pw.println("Ethernet interface name filter: " + mIfaceMatch);
+            pw.println("Listeners: " + mListeners.getRegisteredCallbackCount());
+            pw.println("IP Configurations:");
+            pw.increaseIndent();
+            for (String iface : mIpConfigurations.keySet()) {
+                pw.println(iface + ": " + mIpConfigurations.get(iface));
+            }
+            pw.decreaseIndent();
+            pw.println();
+
+            pw.println("Network Capabilities:");
+            pw.increaseIndent();
+            for (String iface : mNetworkCapabilities.keySet()) {
+                pw.println(iface + ": " + mNetworkCapabilities.get(iface));
+            }
+            pw.decreaseIndent();
+            pw.println();
+
+            mFactory.dump(fd, pw, args);
+        });
+    }
+}
