Start using IP tool for advanced routing.
bug:5495862
bug:5396842
Change-Id: I5e31b352b14a4dc746cacce4d61cf8d9ad7382a0
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index fb13b75..4c26dbb 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -59,7 +59,11 @@
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashSet;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
@@ -77,6 +81,9 @@
private static final int ADD = 1;
private static final int REMOVE = 2;
+ private static final String DEFAULT = "default";
+ private static final String SECONDARY = "secondary";
+
/**
* Name representing {@link #setGlobalAlert(long)} limit when delivered to
* {@link INetworkManagementEventObserver#limitReached(String, String)}.
@@ -500,15 +507,25 @@
public void addRoute(String interfaceName, RouteInfo route) {
mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
- modifyRoute(interfaceName, ADD, route);
+ modifyRoute(interfaceName, ADD, route, DEFAULT);
}
public void removeRoute(String interfaceName, RouteInfo route) {
mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
- modifyRoute(interfaceName, REMOVE, route);
+ modifyRoute(interfaceName, REMOVE, route, DEFAULT);
}
- private void modifyRoute(String interfaceName, int action, RouteInfo route) {
+ public void addSecondaryRoute(String interfaceName, RouteInfo route) {
+ mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
+ modifyRoute(interfaceName, ADD, route, SECONDARY);
+ }
+
+ public void removeSecondaryRoute(String interfaceName, RouteInfo route) {
+ mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
+ modifyRoute(interfaceName, REMOVE, route, SECONDARY);
+ }
+
+ private void modifyRoute(String interfaceName, int action, RouteInfo route, String type) {
ArrayList<String> rsp;
StringBuilder cmd;
@@ -516,12 +533,12 @@
switch (action) {
case ADD:
{
- cmd = new StringBuilder("interface route add " + interfaceName);
+ cmd = new StringBuilder("interface route add " + interfaceName + " " + type);
break;
}
case REMOVE:
{
- cmd = new StringBuilder("interface route remove " + interfaceName);
+ cmd = new StringBuilder("interface route remove " + interfaceName + " " + type);
break;
}
default:
@@ -828,14 +845,33 @@
}
}
+ private void modifyNat(String cmd, String internalInterface, String externalInterface)
+ throws SocketException {
+ cmd = String.format("nat %s %s %s", cmd, internalInterface, externalInterface);
+
+ NetworkInterface internalNetworkInterface =
+ NetworkInterface.getByName(internalInterface);
+ Collection<InterfaceAddress>interfaceAddresses =
+ internalNetworkInterface.getInterfaceAddresses();
+ cmd += " " + interfaceAddresses.size();
+ for (InterfaceAddress ia : interfaceAddresses) {
+ InetAddress addr = NetworkUtils.getNetworkPart(ia.getAddress(),
+ ia.getNetworkPrefixLength());
+ cmd = cmd + " " + addr.getHostAddress() + "/" + ia.getNetworkPrefixLength();
+ }
+
+ mConnector.doCommand(cmd);
+ }
+
public void enableNat(String internalInterface, String externalInterface)
throws IllegalStateException {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+ if (DBG) Log.d(TAG, "enableNat(" + internalInterface + ", " + externalInterface + ")");
try {
- mConnector.doCommand(
- String.format("nat enable %s %s", internalInterface, externalInterface));
- } catch (NativeDaemonConnectorException e) {
+ modifyNat("enable", internalInterface, externalInterface);
+ } catch (Exception e) {
+ Log.e(TAG, "enableNat got Exception " + e.toString());
throw new IllegalStateException(
"Unable to communicate to native daemon for enabling NAT interface");
}
@@ -845,10 +881,11 @@
throws IllegalStateException {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+ if (DBG) Log.d(TAG, "disableNat(" + internalInterface + ", " + externalInterface + ")");
try {
- mConnector.doCommand(
- String.format("nat disable %s %s", internalInterface, externalInterface));
- } catch (NativeDaemonConnectorException e) {
+ modifyNat("disable", internalInterface, externalInterface);
+ } catch (Exception e) {
+ Log.e(TAG, "disableNat got Exception " + e.toString());
throw new IllegalStateException(
"Unable to communicate to native daemon for disabling NAT interface");
}