From 35e36db1d726f5741e7d8d83d2556e1417642be9 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 26 Feb 2015 01:25:36 +0900 Subject: [PATCH] Separate NAT from forwarding. Bug: 19500693 Change-Id: I39878644e21d51def1c31d1857e815f473ef0938 --- .../android/os/INetworkManagementService.aidl | 12 +++++++++++ .../server/NetworkManagementService.java | 21 +++++++++++++++++++ .../server/connectivity/Tethering.java | 11 ++++++++++ 3 files changed, 44 insertions(+) diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 5d5d2b384e040..154a5a59bf78f 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -177,6 +177,18 @@ interface INetworkManagementService */ String[] getDnsForwarders(); + /** + * Enables unidirectional packet forwarding from {@code fromIface} to + * {@code toIface}. + */ + void startInterfaceForwarding(String fromIface, String toIface); + + /** + * Disables unidirectional packet forwarding from {@code fromIface} to + * {@code toIface}. + */ + void stopInterfaceForwarding(String fromIface, String toIface); + /** * Enables Network Address Translation between two interfaces. * The address and netmask of the external interface is used for diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 6719aa6f5707c..8c56c8c5f0574 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -1259,6 +1259,27 @@ public class NetworkManagementService extends INetworkManagementService.Stub return filtered; } + private void modifyInterfaceForward(boolean add, String fromIface, String toIface) { + final Command cmd = new Command("ipfwd", add ? "add" : "remove", fromIface, toIface); + try { + mConnector.execute(cmd); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + } + + @Override + public void startInterfaceForwarding(String fromIface, String toIface) { + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + modifyInterfaceForward(true, fromIface, toIface); + } + + @Override + public void stopInterfaceForwarding(String fromIface, String toIface) { + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + modifyInterfaceForward(false, fromIface, toIface); + } + private void modifyNat(String action, String internalInterface, String externalInterface) throws SocketException { final Command cmd = new Command("nat", action, internalInterface, externalInterface); diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 9566f9396d182..5ff7022647fc5 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -980,6 +980,12 @@ public class Tethering extends BaseNetworkObserver { } catch (Exception e) { if (VDBG) Log.e(TAG, "Exception in forceUpdate: " + e.toString()); } + try { + mNMService.stopInterfaceForwarding(mIfaceName, mMyUpstreamIfaceName); + } catch (Exception e) { + if (VDBG) Log.e( + TAG, "Exception in removeInterfaceForward: " + e.toString()); + } try { mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName); } catch (Exception e) { @@ -1033,8 +1039,13 @@ public class Tethering extends BaseNetworkObserver { if (newUpstreamIfaceName != null) { try { mNMService.enableNat(mIfaceName, newUpstreamIfaceName); + mNMService.startInterfaceForwarding(mIfaceName, + newUpstreamIfaceName); } catch (Exception e) { Log.e(TAG, "Exception enabling Nat: " + e.toString()); + try { + mNMService.disableNat(mIfaceName, newUpstreamIfaceName); + } catch (Exception ee) {} try { mNMService.untetherInterface(mIfaceName); } catch (Exception ee) {}