Add NetworkManagement methods for netd uid binds

Add methods to NetworkManagementService for per uid routing and DNS and
for setting up fwmark tables for interfaces.

Change-Id: Icf2c4a46f7f422660031ef73b537745922286246
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 45524c8..30885856 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -344,6 +344,30 @@
     void setFirewallUidRule(int uid, boolean allow);
 
     /**
+     * Set all packets from users [uid_start,uid_end] to go through interface iface
+     * iface must already be set for marked forwarding by {@link setMarkedForwarding}
+     */
+    void setUidRangeRoute(String iface, int uid_start, int uid_end);
+
+    /**
+     * Clears the special routing rules for users [uid_start,uid_end]
+     */
+    void clearUidRangeRoute(String iface, int uid_start, int uid_end);
+
+    /**
+     * Setup an interface for routing packets marked by {@link setUidRangeRoute}
+     *
+     * This sets up a dedicated routing table for packets marked for {@code iface} and adds
+     * source-NAT rules so that the marked packets have the correct source address.
+     */
+    void setMarkedForwarding(String iface);
+
+    /**
+     * Removes marked forwarding for an interface
+     */
+    void clearMarkedForwarding(String iface);
+
+    /**
      * Set a process (pid) to use the name servers associated with the specified interface.
      */
     void setDnsInterfaceForPid(String iface, int pid);
@@ -354,6 +378,21 @@
     void clearDnsInterfaceForPid(int pid);
 
     /**
+    * Set a range of user ids to use the name servers associated with the specified interface.
+    */
+    void setDnsInterfaceForUidRange(String iface, int uid_start, int uid_end);
+
+    /**
+    * Clear a user range from being associated with an interface.
+    */
+    void clearDnsInterfaceForUidRange(int uid_start, int uid_end);
+
+    /**
+    * Clear the mappings from pid to Dns interface and from uid range to Dns interface.
+    */
+    void clearDnsInterfaceMaps();
+
+    /**
      * Start the clatd (464xlat) service
      */
     void startClatd(String interfaceName);
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 1622f0f..209df04 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -1378,6 +1378,79 @@
     }
 
     @Override
+    public void setUidRangeRoute(String iface, int uid_start, int uid_end) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("interface", "route",
+                    "uid", "add", iface, uid_start, uid_end);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearUidRangeRoute(String iface, int uid_start, int uid_end) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("interface", "route",
+                    "uid", "remove", iface, uid_start, uid_end);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void setMarkedForwarding(String iface) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("interface", "route", "fwmark", "add", iface);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearMarkedForwarding(String iface) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("interface", "route", "fwmark", "remove", iface);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void setDnsInterfaceForUidRange(String iface, int uid_start, int uid_end) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("resolver", "setifaceforuidrange", iface, uid_start, uid_end);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearDnsInterfaceForUidRange(int uid_start, int uid_end) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("resolver", "clearifaceforuidrange", uid_start, uid_end);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearDnsInterfaceMaps() {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("resolver", "clearifacemapping");
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+
+    @Override
     public void flushDefaultDnsCache() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {