Merge "Remove last NetworkStack usage of hidden APIs"
am: 16ec5d038c

Change-Id: I27c78d09938f672a4428a17436d5ed0541170d0d
diff --git a/Android.bp b/Android.bp
index 225f86de..0407c41 100644
--- a/Android.bp
+++ b/Android.bp
@@ -851,6 +851,7 @@
         "core/java/android/annotation/UnsupportedAppUsage.java",
         "core/java/android/net/DhcpResults.java",
         "core/java/android/util/LocalLog.java",
+        "core/java/com/android/internal/annotations/GuardedBy.java",
         "core/java/com/android/internal/annotations/VisibleForTesting.java",
         "core/java/com/android/internal/util/HexDump.java",
         "core/java/com/android/internal/util/IndentingPrintWriter.java",
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 6c291c2..6f9e65f 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.annotation.UnsupportedAppUsage;
+import android.net.shared.InetAddressUtils;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -73,19 +74,21 @@
     public StaticIpConfiguration toStaticIpConfiguration() {
         final StaticIpConfiguration s = new StaticIpConfiguration();
         // All these except dnsServers are immutable, so no need to make copies.
-        s.ipAddress = ipAddress;
-        s.gateway = gateway;
-        s.dnsServers.addAll(dnsServers);
-        s.domains = domains;
+        s.setIpAddress(ipAddress);
+        s.setGateway(gateway);
+        for (InetAddress addr : dnsServers) {
+            s.addDnsServer(addr);
+        }
+        s.setDomains(domains);
         return s;
     }
 
     public DhcpResults(StaticIpConfiguration source) {
         if (source != null) {
-            ipAddress = source.ipAddress;
-            gateway = source.gateway;
-            dnsServers.addAll(source.dnsServers);
-            domains = source.domains;
+            ipAddress = source.getIpAddress();
+            gateway = source.getGateway();
+            dnsServers.addAll(source.getDnsServers());
+            domains = source.getDomains();
         }
     }
 
@@ -177,7 +180,7 @@
         toStaticIpConfiguration().writeToParcel(dest, flags);
         dest.writeInt(leaseDuration);
         dest.writeInt(mtu);
-        NetworkUtils.parcelInetAddress(dest, serverAddress, flags);
+        InetAddressUtils.parcelInetAddress(dest, serverAddress, flags);
         dest.writeString(vendorInfo);
     }
 
@@ -191,7 +194,7 @@
         final DhcpResults dhcpResults = new DhcpResults(s);
         dhcpResults.leaseDuration = in.readInt();
         dhcpResults.mtu = in.readInt();
-        dhcpResults.serverAddress = (Inet4Address) NetworkUtils.unparcelInetAddress(in);
+        dhcpResults.serverAddress = (Inet4Address) InetAddressUtils.unparcelInetAddress(in);
         dhcpResults.vendorInfo = in.readString();
         return dhcpResults;
     }
@@ -200,7 +203,7 @@
     // Not part of the superclass because they're only used by the JNI iterface to the DHCP daemon.
     public boolean setIpAddress(String addrString, int prefixLength) {
         try {
-            Inet4Address addr = (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
+            Inet4Address addr = (Inet4Address) InetAddresses.parseNumericAddress(addrString);
             ipAddress = new LinkAddress(addr, prefixLength);
         } catch (IllegalArgumentException|ClassCastException e) {
             Log.e(TAG, "setIpAddress failed with addrString " + addrString + "/" + prefixLength);
@@ -211,7 +214,7 @@
 
     public boolean setGateway(String addrString) {
         try {
-            gateway = NetworkUtils.numericToInetAddress(addrString);
+            gateway = InetAddresses.parseNumericAddress(addrString);
         } catch (IllegalArgumentException e) {
             Log.e(TAG, "setGateway failed with addrString " + addrString);
             return true;
@@ -222,7 +225,7 @@
     public boolean addDns(String addrString) {
         if (TextUtils.isEmpty(addrString) == false) {
             try {
-                dnsServers.add(NetworkUtils.numericToInetAddress(addrString));
+                dnsServers.add(InetAddresses.parseNumericAddress(addrString));
             } catch (IllegalArgumentException e) {
                 Log.e(TAG, "addDns failed with addrString " + addrString);
                 return true;
diff --git a/core/java/android/net/INetworkStackConnector.aidl b/core/java/android/net/INetworkStackConnector.aidl
index 8b64f1c..e052488 100644
--- a/core/java/android/net/INetworkStackConnector.aidl
+++ b/core/java/android/net/INetworkStackConnector.aidl
@@ -16,6 +16,7 @@
 package android.net;
 
 import android.net.INetworkMonitorCallbacks;
+import android.net.NetworkParcelable;
 import android.net.dhcp.DhcpServingParamsParcel;
 import android.net.dhcp.IDhcpServerCallbacks;
 import android.net.ip.IIpClientCallbacks;
@@ -24,6 +25,7 @@
 oneway interface INetworkStackConnector {
     void makeDhcpServer(in String ifName, in DhcpServingParamsParcel params,
         in IDhcpServerCallbacks cb);
-    void makeNetworkMonitor(int netId, String name, in INetworkMonitorCallbacks cb);
+    void makeNetworkMonitor(in NetworkParcelable network, String name,
+        in INetworkMonitorCallbacks cb);
     void makeIpClient(in String ifName, in IIpClientCallbacks callbacks);
 }
\ No newline at end of file
diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java
index d277034..ac6bff0 100644
--- a/core/java/android/net/NetworkStack.java
+++ b/core/java/android/net/NetworkStack.java
@@ -104,10 +104,11 @@
      *
      * <p>The INetworkMonitor will be returned asynchronously through the provided callbacks.
      */
-    public void makeNetworkMonitor(Network network, String name, INetworkMonitorCallbacks cb) {
+    public void makeNetworkMonitor(
+            NetworkParcelable network, String name, INetworkMonitorCallbacks cb) {
         requestConnector(connector -> {
             try {
-                connector.makeNetworkMonitor(network.netId, name, cb);
+                connector.makeNetworkMonitor(network, name, cb);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 44170b5..07668a9 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -19,7 +19,6 @@
 import android.annotation.UnsupportedAppUsage;
 import android.net.shared.Inet4AddressUtils;
 import android.os.Build;
-import android.os.Parcel;
 import android.system.ErrnoException;
 import android.util.Log;
 import android.util.Pair;
@@ -247,32 +246,6 @@
     }
 
     /**
-     * Writes an InetAddress to a parcel. The address may be null. This is likely faster than
-     * calling writeSerializable.
-     */
-    protected static void parcelInetAddress(Parcel parcel, InetAddress address, int flags) {
-        byte[] addressArray = (address != null) ? address.getAddress() : null;
-        parcel.writeByteArray(addressArray);
-    }
-
-    /**
-     * Reads an InetAddress from a parcel. Returns null if the address that was written was null
-     * or if the data is invalid.
-     */
-    protected static InetAddress unparcelInetAddress(Parcel in) {
-        byte[] addressArray = in.createByteArray();
-        if (addressArray == null) {
-            return null;
-        }
-        try {
-            return InetAddress.getByAddress(addressArray);
-        } catch (UnknownHostException e) {
-            return null;
-        }
-    }
-
-
-    /**
      *  Masks a raw IP address byte array with the specified prefix length.
      */
     public static void maskRawAddress(byte[] array, int prefixLength) {
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 25bae3c..99cf3a9 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -19,6 +19,7 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
+import android.net.shared.InetAddressUtils;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -232,10 +233,10 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeParcelable(ipAddress, flags);
-        NetworkUtils.parcelInetAddress(dest, gateway, flags);
+        InetAddressUtils.parcelInetAddress(dest, gateway, flags);
         dest.writeInt(dnsServers.size());
         for (InetAddress dnsServer : dnsServers) {
-            NetworkUtils.parcelInetAddress(dest, dnsServer, flags);
+            InetAddressUtils.parcelInetAddress(dest, dnsServer, flags);
         }
         dest.writeString(domains);
     }
@@ -244,11 +245,11 @@
     public static StaticIpConfiguration readFromParcel(Parcel in) {
         final StaticIpConfiguration s = new StaticIpConfiguration();
         s.ipAddress = in.readParcelable(null);
-        s.gateway = NetworkUtils.unparcelInetAddress(in);
+        s.gateway = InetAddressUtils.unparcelInetAddress(in);
         s.dnsServers.clear();
         int size = in.readInt();
         for (int i = 0; i < size; i++) {
-            s.dnsServers.add(NetworkUtils.unparcelInetAddress(in));
+            s.dnsServers.add(InetAddressUtils.unparcelInetAddress(in));
         }
         s.domains = in.readString();
         return s;
diff --git a/core/java/android/net/metrics/DhcpClientEvent.java b/core/java/android/net/metrics/DhcpClientEvent.java
index 2a942ee..3008115 100644
--- a/core/java/android/net/metrics/DhcpClientEvent.java
+++ b/core/java/android/net/metrics/DhcpClientEvent.java
@@ -31,10 +31,6 @@
 public final class DhcpClientEvent implements IpConnectivityLog.Event {
 
     // Names for recording DhcpClient pseudo-state transitions.
-    /** {@hide} Represents transitions from DhcpInitState to DhcpBoundState */
-    public static final String INITIAL_BOUND = "InitialBoundState";
-    /** {@hide} Represents transitions from and to DhcpBoundState via DhcpRenewingState */
-    public static final String RENEWING_BOUND = "RenewingBoundState";
 
     /** @hide */
     public final String msg;
diff --git a/core/java/android/net/shared/FdEventsReader.java b/core/java/android/net/shared/FdEventsReader.java
index 5ccc560..bffbfb1 100644
--- a/core/java/android/net/shared/FdEventsReader.java
+++ b/core/java/android/net/shared/FdEventsReader.java
@@ -21,15 +21,15 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.net.util.SocketUtils;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.MessageQueue;
 import android.system.ErrnoException;
 import android.system.OsConstants;
 
-import libcore.io.IoUtils;
-
 import java.io.FileDescriptor;
+import java.io.IOException;
 
 
 /**
@@ -81,7 +81,10 @@
     private long mPacketsReceived;
 
     protected static void closeFd(FileDescriptor fd) {
-        IoUtils.closeQuietly(fd);
+        try {
+            SocketUtils.closeSocket(fd);
+        } catch (IOException ignored) {
+        }
     }
 
     protected FdEventsReader(@NonNull Handler h, @NonNull BufferType buffer) {
@@ -136,8 +139,8 @@
     }
 
     /**
-     * Subclasses MUST create the listening socket here, including setting
-     * all desired socket options, interface or address/port binding, etc.
+     * Subclasses MUST create the listening socket here, including setting all desired socket
+     * options, interface or address/port binding, etc. The socket MUST be created nonblocking.
      */
     @Nullable
     protected abstract FileDescriptor createFd();
@@ -181,10 +184,6 @@
 
         try {
             mFd = createFd();
-            if (mFd != null) {
-                // Force the socket to be non-blocking.
-                IoUtils.setBlocking(mFd, false);
-            }
         } catch (Exception e) {
             logError("Failed to create socket: ", e);
             closeFd(mFd);
diff --git a/core/java/android/net/shared/InetAddressUtils.java b/core/java/android/net/shared/InetAddressUtils.java
new file mode 100644
index 0000000..c9ee3a7
--- /dev/null
+++ b/core/java/android/net/shared/InetAddressUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 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.shared;
+
+import android.os.Parcel;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Collection of utilities to interact with {@link InetAddress}
+ * @hide
+ */
+public class InetAddressUtils {
+
+    /**
+     * Writes an InetAddress to a parcel. The address may be null. This is likely faster than
+     * calling writeSerializable.
+     * @hide
+     */
+    public static void parcelInetAddress(Parcel parcel, InetAddress address, int flags) {
+        byte[] addressArray = (address != null) ? address.getAddress() : null;
+        parcel.writeByteArray(addressArray);
+    }
+
+    /**
+     * Reads an InetAddress from a parcel. Returns null if the address that was written was null
+     * or if the data is invalid.
+     * @hide
+     */
+    public static InetAddress unparcelInetAddress(Parcel in) {
+        byte[] addressArray = in.createByteArray();
+        if (addressArray == null) {
+            return null;
+        }
+        try {
+            return InetAddress.getByAddress(addressArray);
+        } catch (UnknownHostException e) {
+            return null;
+        }
+    }
+
+    private InetAddressUtils() {}
+}
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index 9b0d896..46f76bb 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -25,7 +25,8 @@
         ":services-networkstack-shared-srcs",
     ],
     static_libs: [
-        "services-netlink-lib",
+        "netd_aidl_interface-java",
+        "networkstack-aidl-interfaces-java",
     ]
 }
 
diff --git a/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
index 08452bb..4fa7d64 100644
--- a/packages/NetworkStack/src/android/net/apf/ApfFilter.java
+++ b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
@@ -38,7 +38,6 @@
 import android.content.IntentFilter;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
-import android.net.NetworkUtils;
 import android.net.apf.ApfGenerator.IllegalInstructionException;
 import android.net.apf.ApfGenerator.Register;
 import android.net.ip.IpClient.IpClientCallbacksWrapper;
@@ -47,6 +46,8 @@
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.RaEvent;
 import android.net.util.InterfaceParams;
+import android.net.util.NetworkStackUtils;
+import android.net.util.SocketUtils;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.system.ErrnoException;
@@ -60,8 +61,6 @@
 import com.android.internal.util.HexDump;
 import com.android.internal.util.IndentingPrintWriter;
 
-import libcore.io.IoBridge;
-
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.net.Inet4Address;
@@ -200,10 +199,8 @@
 
         public void halt() {
             mStopped = true;
-            try {
-                // Interrupts the read() call the thread is blocked in.
-                IoBridge.closeAndSignalBlockedThreads(mSocket);
-            } catch (IOException ignored) {}
+            // Interrupts the read() call the thread is blocked in.
+            NetworkStackUtils.closeSocketQuietly(mSocket);
         }
 
         @Override
@@ -470,8 +467,8 @@
             socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6);
             SocketAddress addr = makePacketSocketAddress(
                     (short) ETH_P_IPV6, mInterfaceParams.index);
-            Os.bind(socket, addr);
-            NetworkUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat);
+            SocketUtils.bindSocket(socket, addr);
+            SocketUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat);
         } catch(SocketException|ErrnoException e) {
             Log.e(TAG, "Error starting filter", e);
             return;
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java b/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
index 12eecc0..b0e8da9 100644
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
+++ b/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
@@ -28,6 +28,7 @@
 import static android.net.dhcp.DhcpPacket.DHCP_VENDOR_INFO;
 import static android.net.dhcp.DhcpPacket.INADDR_ANY;
 import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
+import static android.net.util.NetworkStackUtils.closeSocketQuietly;
 import static android.net.util.SocketUtils.makePacketSocketAddress;
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_PACKET;
@@ -44,7 +45,6 @@
 
 import android.content.Context;
 import android.net.DhcpResults;
-import android.net.NetworkUtils;
 import android.net.TrafficStats;
 import android.net.ip.IpClient;
 import android.net.metrics.DhcpClientEvent;
@@ -66,8 +66,6 @@
 import com.android.internal.util.StateMachine;
 import com.android.internal.util.WakeupMessage;
 
-import libcore.io.IoBridge;
-
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.net.Inet4Address;
@@ -108,6 +106,12 @@
     private static final boolean MSG_DBG = false;
     private static final boolean PACKET_DBG = false;
 
+    // Metrics events: must be kept in sync with server-side aggregation code.
+    /** Represents transitions from DhcpInitState to DhcpBoundState */
+    private static final String EVENT_INITIAL_BOUND = "InitialBoundState";
+    /** Represents transitions from and to DhcpBoundState via DhcpRenewingState */
+    private static final String EVENT_RENEWING_BOUND = "RenewingBoundState";
+
     // Timers and timeouts.
     private static final int SECONDS = 1000;
     private static final int FIRST_TIMEOUT_MS   =   2 * SECONDS;
@@ -313,8 +317,8 @@
         try {
             mPacketSock = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IP);
             SocketAddress addr = makePacketSocketAddress((short) ETH_P_IP, mIface.index);
-            Os.bind(mPacketSock, addr);
-            NetworkUtils.attachDhcpFilter(mPacketSock);
+            SocketUtils.bindSocket(mPacketSock, addr);
+            SocketUtils.attachDhcpFilter(mPacketSock);
         } catch(SocketException|ErrnoException e) {
             Log.e(TAG, "Error creating packet socket", e);
             return false;
@@ -350,15 +354,9 @@
         }
     }
 
-    private static void closeQuietly(FileDescriptor fd) {
-        try {
-            IoBridge.closeAndSignalBlockedThreads(fd);
-        } catch (IOException ignored) {}
-    }
-
     private void closeSockets() {
-        closeQuietly(mUdpSock);
-        closeQuietly(mPacketSock);
+        closeSocketQuietly(mUdpSock);
+        closeSocketQuietly(mPacketSock);
     }
 
     class ReceiveThread extends Thread {
@@ -414,7 +412,8 @@
         try {
             if (encap == DhcpPacket.ENCAP_L2) {
                 if (DBG) Log.d(TAG, "Broadcasting " + description);
-                Os.sendto(mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr);
+                SocketUtils.sendTo(
+                        mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr);
             } else if (encap == DhcpPacket.ENCAP_BOOTP && to.equals(INADDR_BROADCAST)) {
                 if (DBG) Log.d(TAG, "Broadcasting " + description);
                 // We only send L3-encapped broadcasts in DhcpRebindingState,
@@ -928,9 +927,9 @@
         private void logTimeToBoundState() {
             long now = SystemClock.elapsedRealtime();
             if (mLastBoundExitTime > mLastInitEnterTime) {
-                logState(DhcpClientEvent.RENEWING_BOUND, (int)(now - mLastBoundExitTime));
+                logState(EVENT_RENEWING_BOUND, (int) (now - mLastBoundExitTime));
             } else {
-                logState(DhcpClientEvent.INITIAL_BOUND, (int)(now - mLastInitEnterTime));
+                logState(EVENT_INITIAL_BOUND, (int) (now - mLastInitEnterTime));
             }
         }
     }
@@ -1021,7 +1020,7 @@
 
             // We need to broadcast and possibly reconnect the socket to a
             // completely different server.
-            closeQuietly(mUdpSock);
+            closeSocketQuietly(mUdpSock);
             if (!initUdpSocket()) {
                 Log.e(TAG, "Failed to recreate UDP socket");
                 transitionTo(mDhcpInitState);
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java b/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java
index eac8d2a..96d1a28 100644
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java
+++ b/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java
@@ -64,7 +64,7 @@
     @Override
     protected int readPacket(@NonNull FileDescriptor fd, @NonNull Payload packetBuffer)
             throws Exception {
-        final InetSocketAddress addr = new InetSocketAddress();
+        final InetSocketAddress addr = new InetSocketAddress(0);
         final int read = Os.recvfrom(
                 fd, packetBuffer.mBytes, 0, packetBuffer.mBytes.length, 0 /* flags */, addr);
 
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
index beabd3e..cd993e9 100644
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
+++ b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
@@ -28,6 +28,7 @@
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.IPPROTO_UDP;
 import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_NONBLOCK;
 import static android.system.OsConstants.SOL_SOCKET;
 import static android.system.OsConstants.SO_BROADCAST;
 import static android.system.OsConstants.SO_REUSEADDR;
@@ -43,7 +44,6 @@
 import android.annotation.Nullable;
 import android.net.INetworkStackStatusCallback;
 import android.net.MacAddress;
-import android.net.NetworkUtils;
 import android.net.TrafficStats;
 import android.net.util.SharedLog;
 import android.net.util.SocketUtils;
@@ -207,7 +207,7 @@
         @Override
         public void addArpEntry(@NonNull Inet4Address ipv4Addr, @NonNull MacAddress ethAddr,
                 @NonNull String ifname, @NonNull FileDescriptor fd) throws IOException {
-            NetworkUtils.addArpEntry(ipv4Addr, ethAddr, ifname, fd);
+            SocketUtils.addArpEntry(ipv4Addr, ethAddr, ifname, fd);
         }
 
         @Override
@@ -630,7 +630,7 @@
             // TODO: have and use an API to set a socket tag without going through the thread tag
             final int oldTag = TrafficStats.getAndSetThreadStatsTag(TAG_SYSTEM_DHCP_SERVER);
             try {
-                mSocket = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+                mSocket = Os.socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
                 SocketUtils.bindSocketToInterface(mSocket, mIfName);
                 Os.setsockoptInt(mSocket, SOL_SOCKET, SO_REUSEADDR, 1);
                 Os.setsockoptInt(mSocket, SOL_SOCKET, SO_BROADCAST, 1);
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java
index 31ce95b..3cd2aa4 100644
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java
+++ b/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java
@@ -209,7 +209,7 @@
          * but it must always be set explicitly before building the {@link DhcpServingParams}.
          */
         public Builder setDefaultRouters(@NonNull Inet4Address... defaultRouters) {
-            return setDefaultRouters(new ArraySet<>(Arrays.asList(defaultRouters)));
+            return setDefaultRouters(makeArraySet(defaultRouters));
         }
 
         /**
@@ -239,7 +239,7 @@
          * building the {@link DhcpServingParams}.
          */
         public Builder setDnsServers(@NonNull Inet4Address... dnsServers) {
-            return setDnsServers(new ArraySet<>(Arrays.asList(dnsServers)));
+            return setDnsServers(makeArraySet(dnsServers));
         }
 
         /**
@@ -269,7 +269,7 @@
          * and do not need to be set here.
          */
         public Builder setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) {
-            return setExcludedAddrs(new ArraySet<>(Arrays.asList(excludedAddrs)));
+            return setExcludedAddrs(makeArraySet(excludedAddrs));
         }
 
         /**
@@ -368,4 +368,10 @@
     static IpPrefix makeIpPrefix(@NonNull LinkAddress addr) {
         return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
     }
+
+    private static <T> ArraySet<T> makeArraySet(T[] elements) {
+        final ArraySet<T> set = new ArraySet<>(elements.length);
+        set.addAll(Arrays.asList(elements));
+        return set;
+    }
 }
diff --git a/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java b/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java
index 385dd52..649257a 100644
--- a/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java
+++ b/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java
@@ -20,12 +20,13 @@
 import static android.system.OsConstants.AF_PACKET;
 import static android.system.OsConstants.ARPHRD_ETHER;
 import static android.system.OsConstants.ETH_P_ALL;
+import static android.system.OsConstants.SOCK_NONBLOCK;
 import static android.system.OsConstants.SOCK_RAW;
 
-import android.net.NetworkUtils;
 import android.net.util.ConnectivityPacketSummary;
 import android.net.util.InterfaceParams;
 import android.net.util.PacketReader;
+import android.net.util.SocketUtils;
 import android.os.Handler;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -33,7 +34,7 @@
 import android.util.LocalLog;
 import android.util.Log;
 
-import libcore.util.HexEncoding;
+import com.android.internal.util.HexDump;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -101,9 +102,10 @@
         protected FileDescriptor createFd() {
             FileDescriptor s = null;
             try {
-                s = Os.socket(AF_PACKET, SOCK_RAW, 0);
-                NetworkUtils.attachControlPacketFilter(s, ARPHRD_ETHER);
-                Os.bind(s, makePacketSocketAddress((short) ETH_P_ALL, mInterface.index));
+                s = Os.socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, 0);
+                SocketUtils.attachControlPacketFilter(s, ARPHRD_ETHER);
+                SocketUtils.bindSocket(
+                        s, makePacketSocketAddress((short) ETH_P_ALL, mInterface.index));
             } catch (ErrnoException | IOException e) {
                 logError("Failed to create packet tracking socket: ", e);
                 closeFd(s);
@@ -119,8 +121,7 @@
             if (summary == null) return;
 
             if (DBG) Log.d(mTag, summary);
-            addLogEntry(summary +
-                        "\n[" + new String(HexEncoding.encode(recvbuf, 0, length)) + "]");
+            addLogEntry(summary + "\n[" + HexDump.toHexString(recvbuf, 0, length) + "]");
         }
 
         @Override
diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
index 4315d34..12fe8c5 100644
--- a/packages/NetworkStack/src/android/net/ip/IpClient.java
+++ b/packages/NetworkStack/src/android/net/ip/IpClient.java
@@ -16,6 +16,7 @@
 
 package android.net.ip;
 
+import static android.net.RouteInfo.RTN_UNICAST;
 import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
 import static android.net.shared.LinkPropertiesParcelableUtil.fromStableParcelable;
 import static android.net.shared.LinkPropertiesParcelableUtil.toStableParcelable;
@@ -36,7 +37,6 @@
 import android.net.apf.ApfCapabilities;
 import android.net.apf.ApfFilter;
 import android.net.dhcp.DhcpClient;
-import android.net.ip.IIpClientCallbacks;
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.IpManagerEvent;
 import android.net.shared.InitialConfiguration;
@@ -52,7 +52,6 @@
 import android.util.Log;
 import android.util.SparseArray;
 
-import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IState;
 import com.android.internal.util.IndentingPrintWriter;
@@ -992,7 +991,7 @@
             // specified in the InitialConfiguration have been observed with Netlink.
             if (config.isProvisionedBy(newLp.getLinkAddresses(), null)) {
                 for (IpPrefix prefix : config.directlyConnectedRoutes) {
-                    newLp.addRoute(new RouteInfo(prefix, null, mInterfaceName));
+                    newLp.addRoute(new RouteInfo(prefix, null, mInterfaceName, RTN_UNICAST));
                 }
             }
             addAllReachableDnsServers(newLp, config.dnsServers);
@@ -1093,7 +1092,7 @@
         // If we have a StaticIpConfiguration attempt to apply it and
         // handle the result accordingly.
         if (mConfiguration.mStaticIpConfig != null) {
-            if (mInterfaceCtrl.setIPv4Address(mConfiguration.mStaticIpConfig.ipAddress)) {
+            if (mInterfaceCtrl.setIPv4Address(mConfiguration.mStaticIpConfig.getIpAddress())) {
                 handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
             } else {
                 return false;
@@ -1348,10 +1347,8 @@
             apfConfig.apfCapabilities = mConfiguration.mApfCapabilities;
             apfConfig.multicastFilter = mMulticastFiltering;
             // Get the Configuration for ApfFilter from Context
-            apfConfig.ieee802_3Filter =
-                    mContext.getResources().getBoolean(R.bool.config_apfDrop802_3Frames);
-            apfConfig.ethTypeBlackList =
-                    mContext.getResources().getIntArray(R.array.config_apfEthTypeBlackList);
+            apfConfig.ieee802_3Filter = ApfCapabilities.getApfDrop8023Frames(mContext);
+            apfConfig.ethTypeBlackList = ApfCapabilities.getApfEthTypeBlackList(mContext);
             mApfFilter = ApfFilter.maybeCreate(mContext, apfConfig, mInterfaceParams, mCallback);
             // TODO: investigate the effects of any multicast filtering racing/interfering with the
             // rest of this IP configuration startup.
diff --git a/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java b/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
index 2e6ff24..b29d617 100644
--- a/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
+++ b/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
@@ -20,6 +20,10 @@
 import static android.net.netlink.NetlinkConstants.hexify;
 import static android.net.netlink.NetlinkConstants.stringForNlMsgType;
 import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
+import static android.system.OsConstants.AF_NETLINK;
+import static android.system.OsConstants.NETLINK_ROUTE;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_NONBLOCK;
 
 import android.net.MacAddress;
 import android.net.netlink.NetlinkErrorMessage;
@@ -27,8 +31,10 @@
 import android.net.netlink.NetlinkSocket;
 import android.net.netlink.RtNetlinkNeighborMessage;
 import android.net.netlink.StructNdMsg;
+import android.net.util.NetworkStackUtils;
 import android.net.util.PacketReader;
 import android.net.util.SharedLog;
+import android.net.util.SocketUtils;
 import android.os.Handler;
 import android.os.SystemClock;
 import android.system.ErrnoException;
@@ -36,8 +42,6 @@
 import android.system.OsConstants;
 import android.util.Log;
 
-import libcore.io.IoUtils;
-
 import java.io.FileDescriptor;
 import java.net.InetAddress;
 import java.net.SocketAddress;
@@ -77,7 +81,7 @@
                 1, ip, StructNdMsg.NUD_PROBE, ifIndex, null);
 
         try {
-            NetlinkSocket.sendOneShotKernelMessage(OsConstants.NETLINK_ROUTE, msg);
+            NetlinkSocket.sendOneShotKernelMessage(NETLINK_ROUTE, msg);
         } catch (ErrnoException e) {
             Log.e(TAG, "Error " + msgSnippet + ": " + e);
             return -e.errno;
@@ -145,8 +149,8 @@
         FileDescriptor fd = null;
 
         try {
-            fd = NetlinkSocket.forProto(OsConstants.NETLINK_ROUTE);
-            Os.bind(fd, makeNetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH));
+            fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, NETLINK_ROUTE);
+            SocketUtils.bindSocket(fd, makeNetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH));
             NetlinkSocket.connectToKernel(fd);
 
             if (VDBG) {
@@ -155,7 +159,7 @@
             }
         } catch (ErrnoException|SocketException e) {
             logError("Failed to create rtnetlink socket", e);
-            IoUtils.closeQuietly(fd);
+            NetworkStackUtils.closeSocketQuietly(fd);
             return null;
         }
 
diff --git a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
index 6dcf0c0..98123a5 100644
--- a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
+++ b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
@@ -16,6 +16,9 @@
 
 package android.net.util;
 
+import java.io.FileDescriptor;
+import java.io.IOException;
+
 /**
  * Collection of utilities for the network stack.
  */
@@ -27,4 +30,14 @@
     public static <T> boolean isEmpty(T[] array) {
         return array == null || array.length == 0;
     }
+
+    /**
+     * Close a socket, ignoring any exception while closing.
+     */
+    public static void closeSocketQuietly(FileDescriptor fd) {
+        try {
+            SocketUtils.closeSocket(fd);
+        } catch (IOException ignored) {
+        }
+    }
 }
diff --git a/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java b/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java
index 4f55779..6fb4b0d 100644
--- a/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java
+++ b/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java
@@ -15,6 +15,8 @@
  */
 package com.android.server;
 
+import static android.net.RouteInfo.RTN_UNICAST;
+
 import android.annotation.NonNull;
 import android.net.INetd;
 import android.net.INetdUnsolicitedEventListener;
@@ -169,7 +171,7 @@
     public void onRouteChanged(boolean updated, String route, String gateway, String ifName) {
         final RouteInfo processRoute = new RouteInfo(new IpPrefix(route),
                 ("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway),
-                ifName);
+                ifName, RTN_UNICAST);
         if (updated) {
             invokeForAllObservers(o -> o.onRouteUpdated(processRoute));
         } else {
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
index 7405c47..cedcb84 100644
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
@@ -19,6 +19,7 @@
 import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
 import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
+import static android.net.shared.NetworkParcelableUtil.fromStableParcelable;
 
 import static com.android.server.util.PermissionUtil.checkDumpPermission;
 import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
@@ -34,7 +35,7 @@
 import android.net.INetworkMonitorCallbacks;
 import android.net.INetworkStackConnector;
 import android.net.Network;
-import android.net.NetworkRequest;
+import android.net.NetworkParcelable;
 import android.net.PrivateDnsConfigParcel;
 import android.net.dhcp.DhcpServer;
 import android.net.dhcp.DhcpServingParams;
@@ -150,13 +151,12 @@
         }
 
         @Override
-        public void makeNetworkMonitor(int netId, String name, INetworkMonitorCallbacks cb)
+        public void makeNetworkMonitor(
+                NetworkParcelable network, String name, INetworkMonitorCallbacks cb)
                 throws RemoteException {
-            final Network network = new Network(netId, false /* privateDnsBypass */);
-            final NetworkRequest defaultRequest = mCm.getDefaultRequest();
-            final SharedLog log = addValidationLogs(network, name);
-            final NetworkMonitor nm = new NetworkMonitor(
-                    mContext, cb, network, defaultRequest, log);
+            final Network parsedNetwork = fromStableParcelable(network);
+            final SharedLog log = addValidationLogs(parsedNetwork, name);
+            final NetworkMonitor nm = new NetworkMonitor(mContext, cb, parsedNetwork, log);
             cb.onNetworkMonitorCreated(new NetworkMonitorImpl(nm));
         }
 
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index 96eaa50..f21561f 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -47,7 +47,6 @@
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
 import android.net.ProxyInfo;
 import android.net.TrafficStats;
 import android.net.Uri;
@@ -310,14 +309,14 @@
     private long mLastProbeTime;
 
     public NetworkMonitor(Context context, INetworkMonitorCallbacks cb, Network network,
-            NetworkRequest defaultRequest, SharedLog validationLog) {
-        this(context, cb, network, defaultRequest, new IpConnectivityLog(), validationLog,
+            SharedLog validationLog) {
+        this(context, cb, network, new IpConnectivityLog(), validationLog,
                 Dependencies.DEFAULT);
     }
 
     @VisibleForTesting
     protected NetworkMonitor(Context context, INetworkMonitorCallbacks cb, Network network,
-            NetworkRequest defaultRequest, IpConnectivityLog logger, SharedLog validationLogs,
+            IpConnectivityLog logger, SharedLog validationLogs,
             Dependencies deps) {
         // Add suffix indicating which NetworkMonitor we're talking about.
         super(TAG + "/" + network.toString());
@@ -369,8 +368,7 @@
         // we can ever fetch them.
         // TODO: Delete ASAP.
         mLinkProperties = new LinkProperties();
-        mNetworkCapabilities = new NetworkCapabilities();
-        mNetworkCapabilities.clearAll();
+        mNetworkCapabilities = new NetworkCapabilities(null);
     }
 
     /**
diff --git a/packages/NetworkStack/tests/src/android/net/util/PacketReaderTest.java b/packages/NetworkStack/tests/src/android/net/util/PacketReaderTest.java
index dced743..6e11c40 100644
--- a/packages/NetworkStack/tests/src/android/net/util/PacketReaderTest.java
+++ b/packages/NetworkStack/tests/src/android/net/util/PacketReaderTest.java
@@ -17,7 +17,13 @@
 package android.net.util;
 
 import static android.net.util.PacketReader.DEFAULT_RECV_BUF_SIZE;
-import static android.system.OsConstants.*;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_NONBLOCK;
+import static android.system.OsConstants.SOL_SOCKET;
+import static android.system.OsConstants.SO_SNDTIMEO;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -31,10 +37,12 @@
 import android.system.Os;
 import android.system.StructTimeval;
 
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.UncheckedIOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.Inet6Address;
@@ -45,13 +53,6 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import org.junit.runner.RunWith;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import libcore.io.IoBridge;
-
 /**
  * Tests for PacketReader.
  *
@@ -80,7 +81,7 @@
         protected FileDescriptor createFd() {
             FileDescriptor s = null;
             try {
-                s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+                s = Os.socket(AF_INET6, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
                 Os.bind(s, LOOPBACK6, 0);
                 mLocalSockName = (InetSocketAddress) Os.getsockname(s);
                 Os.setsockoptTimeval(s, SOL_SOCKET, SO_SNDTIMEO, TIMEO);
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
index d31fa77..d11bb64 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -21,7 +21,6 @@
 import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_INVALID;
 import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_VALID;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
@@ -51,7 +50,6 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
-import android.net.NetworkRequest;
 import android.net.captiveportal.CaptivePortalProbeResult;
 import android.net.metrics.IpConnectivityLog;
 import android.net.util.SharedLog;
@@ -103,7 +101,6 @@
     private @Mock NetworkMonitor.Dependencies mDependencies;
     private @Mock INetworkMonitorCallbacks mCallbacks;
     private @Spy Network mNetwork = new Network(TEST_NETID);
-    private NetworkRequest mRequest;
 
     private static final int TEST_NETID = 4242;
 
@@ -178,10 +175,6 @@
                 InetAddresses.parseNumericAddress("192.168.0.0")
         }).when(mNetwork).getAllByName(any());
 
-        mRequest = new NetworkRequest.Builder()
-                .addCapability(NET_CAPABILITY_INTERNET)
-                .addCapability(NET_CAPABILITY_NOT_RESTRICTED)
-                .build();
         // Default values. Individual tests can override these.
         when(mCm.getLinkProperties(any())).thenReturn(TEST_LINKPROPERTIES);
         when(mCm.getNetworkCapabilities(any())).thenReturn(METERED_CAPABILITIES);
@@ -195,9 +188,9 @@
     private class WrappedNetworkMonitor extends NetworkMonitor {
         private long mProbeTime = 0;
 
-        WrappedNetworkMonitor(Context context, Network network, NetworkRequest defaultRequest,
-                IpConnectivityLog logger, Dependencies deps) {
-                super(context, mCallbacks, network, defaultRequest, logger,
+        WrappedNetworkMonitor(Context context, Network network, IpConnectivityLog logger,
+                Dependencies deps) {
+                super(context, mCallbacks, network, logger,
                         new SharedLog("test_nm"), deps);
         }
 
@@ -213,7 +206,7 @@
 
     private WrappedNetworkMonitor makeMeteredWrappedNetworkMonitor() {
         final WrappedNetworkMonitor nm = new WrappedNetworkMonitor(
-                mContext, mNetwork, mRequest, mLogger, mDependencies);
+                mContext, mNetwork, mLogger, mDependencies);
         when(mCm.getNetworkCapabilities(any())).thenReturn(METERED_CAPABILITIES);
         nm.start();
         waitForIdle(nm.getHandler());
@@ -222,7 +215,7 @@
 
     private WrappedNetworkMonitor makeNotMeteredWrappedNetworkMonitor() {
         final WrappedNetworkMonitor nm = new WrappedNetworkMonitor(
-                mContext, mNetwork, mRequest, mLogger, mDependencies);
+                mContext, mNetwork, mLogger, mDependencies);
         when(mCm.getNetworkCapabilities(any())).thenReturn(NOT_METERED_CAPABILITIES);
         nm.start();
         waitForIdle(nm.getHandler());
@@ -231,7 +224,7 @@
 
     private NetworkMonitor makeMonitor() {
         final NetworkMonitor nm = new NetworkMonitor(
-                mContext, mCallbacks, mNetwork, mRequest, mLogger, mValidationLogger,
+                mContext, mCallbacks, mNetwork, mLogger, mValidationLogger,
                 mDependencies);
         nm.start();
         waitForIdle(nm.getHandler());
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1519c17..c8e5d2b 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -40,6 +40,7 @@
 import static android.net.NetworkPolicyManager.uidRulesToString;
 import static android.net.NetworkStack.NETWORKSTACK_PACKAGE_NAME;
 import static android.net.shared.NetworkMonitorUtils.isValidationRequired;
+import static android.net.shared.NetworkParcelableUtil.toStableParcelable;
 import static android.os.Process.INVALID_UID;
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
@@ -98,10 +99,10 @@
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.NetworkEvent;
 import android.net.netlink.InetDiagMessage;
-import android.net.shared.NetdService;
 import android.net.shared.NetworkMonitorUtils;
 import android.net.shared.PrivateDnsConfig;
 import android.net.util.MultinetworkPolicyTracker;
+import android.net.util.NetdService;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -5012,8 +5013,8 @@
         if (DBG) log("registerNetworkAgent " + nai);
         final long token = Binder.clearCallingIdentity();
         try {
-            mContext.getSystemService(NetworkStack.class)
-                    .makeNetworkMonitor(nai.network, name, new NetworkMonitorCallbacks(nai));
+            mContext.getSystemService(NetworkStack.class).makeNetworkMonitor(
+                    toStableParcelable(nai.network), name, new NetworkMonitorCallbacks(nai));
         } finally {
             Binder.restoreCallingIdentity(token);
         }
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 371276f..126bf65 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -44,7 +44,7 @@
 import android.net.Network;
 import android.net.NetworkUtils;
 import android.net.TrafficStats;
-import android.net.shared.NetdService;
+import android.net.util.NetdService;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 8592491..da4df22 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -62,7 +62,7 @@
 import android.net.RouteInfo;
 import android.net.TetherStatsParcel;
 import android.net.UidRange;
-import android.net.shared.NetdService;
+import android.net.util.NetdService;
 import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.Handler;
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 30c7de5..638ec95 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -9,12 +9,6 @@
         "java/android/net/ip/InterfaceController.java", // TODO: move to NetworkStack with tethering
         "java/android/net/util/InterfaceParams.java", // TODO: move to NetworkStack with IpServer
         "java/android/net/shared/*.java",
-    ],
-}
-
-java_library {
-    name: "services-netlink-lib",
-    srcs: [
         "java/android/net/netlink/*.java",
-    ]
+    ],
 }
diff --git a/services/net/java/android/net/ip/InterfaceController.java b/services/net/java/android/net/ip/InterfaceController.java
index b3af67c..970bc9c 100644
--- a/services/net/java/android/net/ip/InterfaceController.java
+++ b/services/net/java/android/net/ip/InterfaceController.java
@@ -17,7 +17,6 @@
 package android.net.ip;
 
 import android.net.INetd;
-import android.net.InterfaceConfiguration;
 import android.net.InterfaceConfigurationParcel;
 import android.net.LinkAddress;
 import android.net.util.SharedLog;
@@ -49,14 +48,18 @@
         mLog = log;
     }
 
-    private boolean setInterfaceConfig(InterfaceConfiguration config) {
-        final InterfaceConfigurationParcel cfgParcel = config.toParcel(mIfName);
-
+    private boolean setInterfaceAddress(LinkAddress addr) {
+        final InterfaceConfigurationParcel ifConfig = new InterfaceConfigurationParcel();
+        ifConfig.ifName = mIfName;
+        ifConfig.ipv4Addr = addr.getAddress().getHostAddress();
+        ifConfig.prefixLength = addr.getPrefixLength();
+        ifConfig.hwAddr = "";
+        ifConfig.flags = new String[0];
         try {
-            mNetd.interfaceSetCfg(cfgParcel);
+            mNetd.interfaceSetCfg(ifConfig);
         } catch (RemoteException | ServiceSpecificException e) {
             logError("Setting IPv4 address to %s/%d failed: %s",
-                    cfgParcel.ipv4Addr, cfgParcel.prefixLength, e);
+                    ifConfig.ipv4Addr, ifConfig.prefixLength, e);
             return false;
         }
         return true;
@@ -69,18 +72,14 @@
         if (!(address.getAddress() instanceof Inet4Address)) {
             return false;
         }
-        final InterfaceConfiguration ifConfig = new InterfaceConfiguration();
-        ifConfig.setLinkAddress(address);
-        return setInterfaceConfig(ifConfig);
+        return setInterfaceAddress(address);
     }
 
     /**
      * Clear the IPv4Address of the interface.
      */
     public boolean clearIPv4Address() {
-        final InterfaceConfiguration ifConfig = new InterfaceConfiguration();
-        ifConfig.setLinkAddress(new LinkAddress("0.0.0.0/0"));
-        return setInterfaceConfig(ifConfig);
+        return setInterfaceAddress(new LinkAddress("0.0.0.0/0"));
     }
 
     private boolean setEnableIPv6(boolean enabled) {
diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java
index f7360f5..7910c9a 100644
--- a/services/net/java/android/net/ip/IpServer.java
+++ b/services/net/java/android/net/ip/IpServer.java
@@ -40,7 +40,7 @@
 import android.net.ip.RouterAdvertisementDaemon.RaParams;
 import android.net.util.InterfaceParams;
 import android.net.util.InterfaceSet;
-import android.net.shared.NetdService;
+import android.net.util.NetdService;
 import android.net.util.SharedLog;
 import android.os.INetworkManagementService;
 import android.os.Looper;
diff --git a/services/net/java/android/net/netlink/NetlinkSocket.java b/services/net/java/android/net/netlink/NetlinkSocket.java
index 2a98d90..16f72bd 100644
--- a/services/net/java/android/net/netlink/NetlinkSocket.java
+++ b/services/net/java/android/net/netlink/NetlinkSocket.java
@@ -27,14 +27,13 @@
 import static android.system.OsConstants.SO_RCVTIMEO;
 import static android.system.OsConstants.SO_SNDTIMEO;
 
+import android.net.util.SocketUtils;
 import android.system.ErrnoException;
 import android.system.Os;
-import android.system.StructTimeval;
 import android.util.Log;
 
-import libcore.io.IoUtils;
-
 import java.io.FileDescriptor;
+import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.net.SocketException;
 import java.nio.ByteBuffer;
@@ -95,7 +94,11 @@
             Log.e(TAG, errPrefix, e);
             throw new ErrnoException(errPrefix, EIO, e);
         } finally {
-            IoUtils.closeQuietly(fd);
+            try {
+                SocketUtils.closeSocket(fd);
+            } catch (IOException e) {
+                // Nothing we can do here
+            }
         }
     }
 
@@ -106,7 +109,7 @@
     }
 
     public static void connectToKernel(FileDescriptor fd) throws ErrnoException, SocketException {
-        Os.connect(fd, makeNetlinkSocketAddress(0, 0));
+        SocketUtils.connectSocket(fd, makeNetlinkSocketAddress(0, 0));
     }
 
     private static void checkTimeout(long timeoutMs) {
@@ -125,7 +128,7 @@
             throws ErrnoException, IllegalArgumentException, InterruptedIOException {
         checkTimeout(timeoutMs);
 
-        Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(timeoutMs));
+        SocketUtils.setSocketTimeValueOption(fd, SOL_SOCKET, SO_RCVTIMEO, timeoutMs);
 
         ByteBuffer byteBuffer = ByteBuffer.allocate(bufsize);
         int length = Os.read(fd, byteBuffer);
@@ -148,7 +151,7 @@
             FileDescriptor fd, byte[] bytes, int offset, int count, long timeoutMs)
             throws ErrnoException, IllegalArgumentException, InterruptedIOException {
         checkTimeout(timeoutMs);
-        Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(timeoutMs));
+        SocketUtils.setSocketTimeValueOption(fd, SOL_SOCKET, SO_SNDTIMEO, timeoutMs);
         return Os.write(fd, bytes, offset, count);
     }
 }
diff --git a/services/net/java/android/net/shared/InitialConfiguration.java b/services/net/java/android/net/shared/InitialConfiguration.java
index bc2373f..4ad7138 100644
--- a/services/net/java/android/net/shared/InitialConfiguration.java
+++ b/services/net/java/android/net/shared/InitialConfiguration.java
@@ -20,6 +20,7 @@
 import static android.net.shared.ParcelableUtil.toParcelableArray;
 import static android.text.TextUtils.join;
 
+import android.net.InetAddresses;
 import android.net.InitialConfigurationParcelable;
 import android.net.IpPrefix;
 import android.net.IpPrefixParcelable;
@@ -27,7 +28,7 @@
 import android.net.LinkAddressParcelable;
 import android.net.RouteInfo;
 
-import java.net.Inet6Address;
+import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.util.HashSet;
 import java.util.List;
@@ -43,6 +44,8 @@
     private static final int RFC6177_MIN_PREFIX_LENGTH = 48;
     private static final int RFC7421_PREFIX_LENGTH = 64;
 
+    public static final InetAddress INET6_ANY = InetAddresses.parseNumericAddress("::");
+
     /**
      * Create a InitialConfiguration that is a copy of the specified configuration.
      */
@@ -102,7 +105,7 @@
             return false;
         }
         // There no more than one IPv4 address
-        if (ipAddresses.stream().filter(LinkAddress::isIPv4).count() > 1) {
+        if (ipAddresses.stream().filter(InitialConfiguration::isIPv4).count() > 1) {
             return false;
         }
 
@@ -184,11 +187,11 @@
     }
 
     private static boolean isPrefixLengthCompliant(LinkAddress addr) {
-        return addr.isIPv4() || isCompliantIPv6PrefixLength(addr.getPrefixLength());
+        return isIPv4(addr) || isCompliantIPv6PrefixLength(addr.getPrefixLength());
     }
 
     private static boolean isPrefixLengthCompliant(IpPrefix prefix) {
-        return prefix.isIPv4() || isCompliantIPv6PrefixLength(prefix.getPrefixLength());
+        return isIPv4(prefix) || isCompliantIPv6PrefixLength(prefix.getPrefixLength());
     }
 
     private static boolean isCompliantIPv6PrefixLength(int prefixLength) {
@@ -196,8 +199,16 @@
                 && (prefixLength <= RFC7421_PREFIX_LENGTH);
     }
 
+    private static boolean isIPv4(IpPrefix prefix) {
+        return prefix.getAddress() instanceof Inet4Address;
+    }
+
+    private static boolean isIPv4(LinkAddress addr) {
+        return addr.getAddress() instanceof Inet4Address;
+    }
+
     private static boolean isIPv6DefaultRoute(IpPrefix prefix) {
-        return prefix.getAddress().equals(Inet6Address.ANY);
+        return prefix.getAddress().equals(INET6_ANY);
     }
 
     private static boolean isIPv6GUA(LinkAddress addr) {
diff --git a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
index 0007350..1f0525e 100644
--- a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
+++ b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
@@ -44,11 +44,11 @@
             @Nullable StaticIpConfiguration config) {
         if (config == null) return null;
         final StaticIpConfigurationParcelable p = new StaticIpConfigurationParcelable();
-        p.ipAddress = LinkPropertiesParcelableUtil.toStableParcelable(config.ipAddress);
-        p.gateway = parcelAddress(config.gateway);
+        p.ipAddress = LinkPropertiesParcelableUtil.toStableParcelable(config.getIpAddress());
+        p.gateway = parcelAddress(config.getGateway());
         p.dnsServers = toParcelableArray(
-                config.dnsServers, IpConfigurationParcelableUtil::parcelAddress, String.class);
-        p.domains = config.domains;
+                config.getDnsServers(), IpConfigurationParcelableUtil::parcelAddress, String.class);
+        p.domains = config.getDomains();
         return p;
     }
 
@@ -59,11 +59,13 @@
             @Nullable StaticIpConfigurationParcelable p) {
         if (p == null) return null;
         final StaticIpConfiguration config = new StaticIpConfiguration();
-        config.ipAddress = LinkPropertiesParcelableUtil.fromStableParcelable(p.ipAddress);
-        config.gateway = unparcelAddress(p.gateway);
-        config.dnsServers.addAll(fromParcelableArray(
-                p.dnsServers, IpConfigurationParcelableUtil::unparcelAddress));
-        config.domains = p.domains;
+        config.setIpAddress(LinkPropertiesParcelableUtil.fromStableParcelable(p.ipAddress));
+        config.setGateway(unparcelAddress(p.gateway));
+        for (InetAddress addr : fromParcelableArray(
+                p.dnsServers, IpConfigurationParcelableUtil::unparcelAddress)) {
+            config.addDnsServer(addr);
+        }
+        config.setDomains(p.domains);
         return config;
     }
 
diff --git a/services/net/java/android/net/shared/NetdService.java b/services/net/java/android/net/util/NetdService.java
similarity index 99%
rename from services/net/java/android/net/shared/NetdService.java
rename to services/net/java/android/net/util/NetdService.java
index f5ae725..d4cd5bd 100644
--- a/services/net/java/android/net/shared/NetdService.java
+++ b/services/net/java/android/net/util/NetdService.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.shared;
+package android.net.util;
 
 import android.content.Context;
 import android.net.INetd;
diff --git a/tests/net/java/android/net/ip/InterfaceControllerTest.java b/tests/net/java/android/net/ip/InterfaceControllerTest.java
new file mode 100644
index 0000000..d27a4f9
--- /dev/null
+++ b/tests/net/java/android/net/ip/InterfaceControllerTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 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 static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.net.INetd;
+import android.net.InetAddresses;
+import android.net.InterfaceConfigurationParcel;
+import android.net.LinkAddress;
+import android.net.util.SharedLog;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class InterfaceControllerTest {
+    private static final String TEST_IFACE = "testif";
+    private static final String TEST_IPV4_ADDR = "192.168.123.28";
+    private static final int TEST_PREFIXLENGTH = 31;
+
+    @Mock private INetd mNetd;
+    @Mock private SharedLog mLog;
+    @Captor private ArgumentCaptor<InterfaceConfigurationParcel> mConfigCaptor;
+
+    private InterfaceController mController;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mController = new InterfaceController(TEST_IFACE, mNetd, mLog);
+
+        doNothing().when(mNetd).interfaceSetCfg(mConfigCaptor.capture());
+    }
+
+    @Test
+    public void testSetIPv4Address() throws Exception {
+        mController.setIPv4Address(
+                new LinkAddress(InetAddresses.parseNumericAddress(TEST_IPV4_ADDR),
+                        TEST_PREFIXLENGTH));
+        verify(mNetd, times(1)).interfaceSetCfg(any());
+        final InterfaceConfigurationParcel parcel = mConfigCaptor.getValue();
+        assertEquals(TEST_IFACE, parcel.ifName);
+        assertEquals(TEST_IPV4_ADDR, parcel.ipv4Addr);
+        assertEquals(TEST_PREFIXLENGTH, parcel.prefixLength);
+        assertEquals("", parcel.hwAddr);
+        assertArrayEquals(new String[0], parcel.flags);
+    }
+
+    @Test
+    public void testClearIPv4Address() throws Exception {
+        mController.clearIPv4Address();
+        verify(mNetd, times(1)).interfaceSetCfg(any());
+        final InterfaceConfigurationParcel parcel = mConfigCaptor.getValue();
+        assertEquals(TEST_IFACE, parcel.ifName);
+        assertEquals("0.0.0.0", parcel.ipv4Addr);
+        assertEquals(0, parcel.prefixLength);
+        assertEquals("", parcel.hwAddr);
+        assertArrayEquals(new String[0], parcel.flags);
+    }
+}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 923c7dd..036c5dc 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -57,6 +57,7 @@
 import static android.net.NetworkPolicyManager.RULE_NONE;
 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.shared.NetworkParcelableUtil.fromStableParcelable;
 
 import static com.android.internal.util.TestUtils.waitForIdleHandler;
 import static com.android.internal.util.TestUtils.waitForIdleLooper;
@@ -119,6 +120,7 @@
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkMisc;
+import android.net.NetworkParcelable;
 import android.net.NetworkRequest;
 import android.net.NetworkSpecifier;
 import android.net.NetworkStack;
@@ -482,8 +484,8 @@
                 fail(e.getMessage());
             }
 
-            final ArgumentCaptor<Network> nmNetworkCaptor =
-                    ArgumentCaptor.forClass(Network.class);
+            final ArgumentCaptor<NetworkParcelable> nmNetworkCaptor =
+                    ArgumentCaptor.forClass(NetworkParcelable.class);
             final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor =
                     ArgumentCaptor.forClass(INetworkMonitorCallbacks.class);
             doNothing().when(mNetworkStack).makeNetworkMonitor(
@@ -523,7 +525,8 @@
                 }
             };
 
-            assertEquals(mNetworkAgent.netId, nmNetworkCaptor.getValue().netId);
+            assertEquals(
+                    mNetworkAgent.netId, fromStableParcelable(nmNetworkCaptor.getValue()).netId);
             mNmCallbacks = nmCbCaptor.getValue();
 
             try {