diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
new file mode 100644
index 0000000..87ac846
--- /dev/null
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2016 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 android.net.ip;
+
+import android.content.Context;
+import android.net.DhcpResults;
+import android.net.LinkProperties;
+import android.net.LinkProperties.ProvisioningChange;
+import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
+import android.os.INetworkManagementService;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+import com.android.server.net.NetlinkTracker;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+
+
+/**
+ * IpManager
+ *
+ * This class provides the interface to IP-layer provisioning and maintenance
+ * functionality that can be used by transport layers like Wi-Fi, Ethernet,
+ * et cetera.
+ *
+ * [ Lifetime ]
+ * IpManager is designed to be instantiated as soon as the interface name is
+ * known and can be as long-lived as the class containing it (i.e. declaring
+ * it "private final" is okay).
+ *
+ * @hide
+ */
+public class IpManager extends StateMachine {
+    private static final String TAG = IpManager.class.getSimpleName();
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false;
+
+    /**
+     * Callbacks for both configuration of IpManager and for handling
+     * events as desired.
+     */
+    public static class Callback {
+        /**
+         * Configuration callbacks.
+         *
+         * Override methods as desired in order to control which features
+         * IpManager will use at run time.
+         */
+
+        // An IpReachabilityMonitor will always be started, if only for logging.
+        // This method is checked before probing neighbors and before calling
+        // onProvisioningLost() (see below).
+        public boolean usingIpReachabilityMonitor() {
+            return false;
+        }
+
+        /**
+         * Event callbacks.
+         *
+         * Override methods as desired in order to handle event callbacks
+         * as IpManager invokes them.
+         */
+
+        // TODO: Kill with fire once DHCP and static configuration are moved
+        // out of WifiStateMachine.
+        public void onIPv4ProvisioningSuccess(DhcpResults dhcpResults, int reason) {}
+        public void onIPv4ProvisioningFailure(int reason) {}
+
+        public void onProvisioningSuccess(LinkProperties newLp) {}
+        public void onProvisioningFailure(LinkProperties newLp) {}
+
+        // Invoked on LinkProperties changes.
+        public void onLinkPropertiesChange(LinkProperties newLp) {}
+
+        // Called when the internal IpReachabilityMonitor (if enabled) has
+        // detected the loss of a critical number of required neighbors.
+        public void onReachabilityLost(String logMsg) {}
+    }
+
+    private static final int CMD_STOP = 1;
+    private static final int CMD_START = 2;
+    private static final int CMD_CONFIRM = 3;
+    private static final int CMD_UPDATE_DHCPV4_RESULTS = 4;
+    // Sent by NetlinkTracker to communicate netlink events.
+    private static final int EVENT_NETLINK_LINKPROPERTIES_CHANGED = 5;
+
+    private static final int MAX_LOG_RECORDS = 1000;
+
+    private final Object mLock = new Object();
+    private final State mStoppedState = new StoppedState();
+    private final State mStartedState = new StartedState();
+
+    private final Context mContext;
+    private final String mInterfaceName;
+    @VisibleForTesting
+    protected final Callback mCallback;
+    private final INetworkManagementService mNwService;
+    private final NetlinkTracker mNetlinkTracker;
+
+    private int mInterfaceIndex;
+
+    /**
+     * Non-final member variables accessed only from within our StateMachine.
+     */
+    private IpReachabilityMonitor mIpReachabilityMonitor;
+    private DhcpResults mDhcpResults;
+    private StaticIpConfiguration mStaticIpConfig;
+
+    /**
+     * Member variables accessed both from within the StateMachine thread
+     * and via accessors from other threads.
+     */
+    @GuardedBy("mLock")
+    private LinkProperties mLinkProperties;
+
+    public IpManager(Context context, String ifName, Callback callback)
+                throws IllegalArgumentException {
+        super(TAG + "." + ifName);
+
+        mContext = context;
+        mInterfaceName = ifName;
+
+        mCallback = callback;
+
+        mNwService = INetworkManagementService.Stub.asInterface(
+                ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
+
+        mNetlinkTracker = new NetlinkTracker(
+                mInterfaceName,
+                new NetlinkTracker.Callback() {
+                    @Override
+                    public void update() {
+                        sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED);
+                    }
+                });
+        try {
+            mNwService.registerObserver(mNetlinkTracker);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Couldn't register NetlinkTracker: " + e.toString());
+        }
+
+        resetLinkProperties();
+
+        // Super simple StateMachine.
+        addState(mStoppedState);
+        addState(mStartedState);
+        setInitialState(mStoppedState);
+        setLogRecSize(MAX_LOG_RECORDS);
+        super.start();
+    }
+
+    /**
+     * A special constructor for use in testing that bypasses some of the more
+     * complicated setup bits.
+     *
+     * TODO: Figure out how to delete this yet preserve testability.
+     */
+    @VisibleForTesting
+    protected IpManager(String ifName, Callback callback) {
+        super(TAG + ".test-" + ifName);
+        mInterfaceName = ifName;
+        mCallback = callback;
+
+        mContext = null;
+        mNwService = null;
+        mNetlinkTracker = null;
+    }
+
+    public void startProvisioning(StaticIpConfiguration staticIpConfig) {
+        getInterfaceIndex();
+
+        sendMessage(CMD_START, staticIpConfig);
+    }
+
+    public void startProvisioning() {
+        getInterfaceIndex();
+
+        sendMessage(CMD_START);
+    }
+
+    public void stop() {
+        sendMessage(CMD_STOP);
+    }
+
+    public void confirmConfiguration() {
+        sendMessage(CMD_CONFIRM);
+    }
+
+    public LinkProperties getLinkProperties() {
+        synchronized (mLock) {
+            return new LinkProperties(mLinkProperties);
+        }
+    }
+
+    // TODO: Kill with fire once DHCPv4/static config is moved into IpManager.
+    public void updateWithDhcpResults(DhcpResults dhcpResults, int reason) {
+        sendMessage(CMD_UPDATE_DHCPV4_RESULTS, reason, 0, dhcpResults);
+    }
+
+
+    /**
+     * Internals.
+     */
+
+    private void getInterfaceIndex() {
+        try {
+            mInterfaceIndex = NetworkInterface.getByName(mInterfaceName).getIndex();
+        } catch (SocketException | NullPointerException e) {
+            // TODO: throw new IllegalStateException.
+            Log.e(TAG, "ALERT: Failed to get interface index: ", e);
+        }
+    }
+
+    // This needs to be called with care to ensure that our LinkProperties
+    // are in sync with the actual LinkProperties of the interface. For example,
+    // we should only call this if we know for sure that there are no IP addresses
+    // assigned to the interface, etc.
+    private void resetLinkProperties() {
+        mNetlinkTracker.clearLinkProperties();
+        mDhcpResults = null;
+        mStaticIpConfig = null;
+
+        synchronized (mLock) {
+            mLinkProperties = new LinkProperties();
+            mLinkProperties.setInterfaceName(mInterfaceName);
+        }
+    }
+
+    private ProvisioningChange setLinkProperties(LinkProperties newLp) {
+        if (mIpReachabilityMonitor != null) {
+            mIpReachabilityMonitor.updateLinkProperties(newLp);
+        }
+
+        // TODO: Figure out whether and how to incorporate static configuration
+        // into the notion of provisioning.
+        ProvisioningChange delta;
+        synchronized (mLock) {
+            delta = LinkProperties.compareProvisioning(mLinkProperties, newLp);
+            mLinkProperties = new LinkProperties(newLp);
+        }
+
+        if (DBG) {
+            switch (delta) {
+                case GAINED_PROVISIONING:
+                case LOST_PROVISIONING:
+                    Log.d(TAG, "provisioning: " + delta);
+                    break;
+            }
+        }
+
+        return delta;
+    }
+
+    private LinkProperties assembleLinkProperties() {
+        // [1] Create a new LinkProperties object to populate.
+        LinkProperties newLp = new LinkProperties();
+        newLp.setInterfaceName(mInterfaceName);
+
+        // [2] Pull in data from netlink:
+        //         - IPv4 addresses
+        //         - IPv6 addresses
+        //         - IPv6 routes
+        //         - IPv6 DNS servers
+        LinkProperties netlinkLinkProperties = mNetlinkTracker.getLinkProperties();
+        newLp.setLinkAddresses(netlinkLinkProperties.getLinkAddresses());
+        for (RouteInfo route : netlinkLinkProperties.getRoutes()) {
+            newLp.addRoute(route);
+        }
+        for (InetAddress dns : netlinkLinkProperties.getDnsServers()) {
+            // Only add likely reachable DNS servers.
+            // TODO: investigate deleting this.
+            if (newLp.isReachable(dns)) {
+                newLp.addDnsServer(dns);
+            }
+        }
+
+        // [3] Add in data from DHCPv4, if available.
+        //
+        // mDhcpResults is never shared with any other owner so we don't have
+        // to worry about concurrent modification.
+        if (mDhcpResults != null) {
+            for (RouteInfo route : mDhcpResults.getRoutes(mInterfaceName)) {
+                newLp.addRoute(route);
+            }
+            for (InetAddress dns : mDhcpResults.dnsServers) {
+                // Only add likely reachable DNS servers.
+                // TODO: investigate deleting this.
+                if (newLp.isReachable(dns)) {
+                    newLp.addDnsServer(dns);
+                }
+            }
+            newLp.setDomains(mDhcpResults.domains);
+        }
+
+        if (VDBG) {
+            Log.d(TAG, "newLp{" + newLp + "}");
+        }
+
+        return newLp;
+    }
+
+    class StoppedState extends State {
+        @Override
+        public void enter() {
+            try {
+                mNwService.disableIpv6(mInterfaceName);
+                mNwService.clearInterfaceAddresses(mInterfaceName);
+            } catch (Exception e) {
+                Log.e(TAG, "Failed to clear addresses or disable IPv6" + e);
+            }
+
+            resetLinkProperties();
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_STOP:
+                    break;
+
+                case CMD_START:
+                    mStaticIpConfig = (StaticIpConfiguration) msg.obj;
+                    transitionTo(mStartedState);
+                    break;
+
+                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                    setLinkProperties(assembleLinkProperties());
+                    break;
+
+                default:
+                    return NOT_HANDLED;
+            }
+            return HANDLED;
+        }
+    }
+
+    class StartedState extends State {
+        @Override
+        public void enter() {
+            // Set privacy extensions.
+            try {
+                mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
+                mNwService.enableIpv6(mInterfaceName);
+            } catch (RemoteException re) {
+                Log.e(TAG, "Unable to change interface settings: " + re);
+            } catch (IllegalStateException ie) {
+                Log.e(TAG, "Unable to change interface settings: " + ie);
+            }
+
+            mIpReachabilityMonitor = new IpReachabilityMonitor(
+                    mContext,
+                    mInterfaceName,
+                    new IpReachabilityMonitor.Callback() {
+                        @Override
+                        public void notifyLost(InetAddress ip, String logMsg) {
+                            if (mCallback.usingIpReachabilityMonitor()) {
+                                mCallback.onReachabilityLost(logMsg);
+                            }
+                        }
+                    });
+
+            // TODO: Check mStaticIpConfig and handle accordingly.
+        }
+
+        @Override
+        public void exit() {
+            mIpReachabilityMonitor.stop();
+            mIpReachabilityMonitor = null;
+
+            resetLinkProperties();
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_STOP:
+                    transitionTo(mStoppedState);
+                    break;
+
+                case CMD_START:
+                    // TODO: Defer this message to be delivered after a state transition
+                    // to StoppedState.  That way, receiving CMD_START in StartedState
+                    // effects a restart.
+                    Log.e(TAG, "ALERT: START received in StartedState.");
+                    break;
+
+                case CMD_CONFIRM:
+                    if (mCallback.usingIpReachabilityMonitor()) {
+                        mIpReachabilityMonitor.probeAll();
+                    }
+                    break;
+
+                case CMD_UPDATE_DHCPV4_RESULTS:
+                    final DhcpResults dhcpResults = (DhcpResults) msg.obj;
+                    final int reason = msg.arg1;
+                    if (dhcpResults != null) {
+                        mDhcpResults = new DhcpResults(dhcpResults);
+                        setLinkProperties(assembleLinkProperties());
+                        mCallback.onIPv4ProvisioningSuccess(dhcpResults, reason);
+                    } else {
+                        mDhcpResults = null;
+                        setLinkProperties(assembleLinkProperties());
+                        mCallback.onIPv4ProvisioningFailure(reason);
+                    }
+                    break;
+
+                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                    final LinkProperties newLp = assembleLinkProperties();
+                    final ProvisioningChange delta = setLinkProperties(newLp);
+
+                    // NOTE: The only receiver of these callbacks currently
+                    // treats all three of them identically, namely it calls
+                    // IpManager#getLinkProperties() and makes its own determination.
+                    switch (delta) {
+                        case GAINED_PROVISIONING:
+                            mCallback.onProvisioningSuccess(newLp);
+                            break;
+
+                        case LOST_PROVISIONING:
+                            mCallback.onProvisioningFailure(newLp);
+                            break;
+
+                        default:
+                            // TODO: Only notify on STILL_PROVISIONED?
+                            mCallback.onLinkPropertiesChange(newLp);
+                            break;
+                    }
+
+                    break;
+
+                default:
+                    return NOT_HANDLED;
+            }
+            return HANDLED;
+        }
+
+    }
+}
