Start using IP tool for advanced routing.

bug:5495862
bug:5396842
Change-Id: I5e31b352b14a4dc746cacce4d61cf8d9ad7382a0
This commit is contained in:
Robert Greenwalt
2011-11-02 14:37:19 -07:00
parent 274518a279
commit 49c75d3db9

View File

@@ -171,6 +171,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private static final int ENABLED = 1; private static final int ENABLED = 1;
private static final int DISABLED = 0; private static final int DISABLED = 0;
private static final boolean ADD = true;
private static final boolean REMOVE = false;
private static final boolean TO_DEFAULT_TABLE = true;
private static final boolean TO_SECONDARY_TABLE = false;
// Share the event space with NetworkStateTracker (which can't see this // Share the event space with NetworkStateTracker (which can't see this
// internal class but sends us events). If you change these, change // internal class but sends us events). If you change these, change
// NetworkStateTracker.java too. // NetworkStateTracker.java too.
@@ -501,7 +507,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b); INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b);
mTethering = new Tethering(mContext, nmService, statsService, mHandler.getLooper()); mTethering = new Tethering(mContext, nmService, statsService, this, mHandler.getLooper());
mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 || mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
mTethering.getTetherableWifiRegexs().length != 0 || mTethering.getTetherableWifiRegexs().length != 0 ||
mTethering.getTetherableBluetoothRegexs().length != 0) && mTethering.getTetherableBluetoothRegexs().length != 0) &&
@@ -1146,23 +1152,24 @@ public class ConnectivityService extends IConnectivityManager.Stub {
return false; return false;
} }
private boolean addRoute(LinkProperties p, RouteInfo r) { private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) {
return modifyRoute(p.getInterfaceName(), p, r, 0, true); return modifyRoute(p.getInterfaceName(), p, r, 0, ADD, toDefaultTable);
} }
private boolean removeRoute(LinkProperties p, RouteInfo r) { private boolean removeRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) {
return modifyRoute(p.getInterfaceName(), p, r, 0, false); return modifyRoute(p.getInterfaceName(), p, r, 0, REMOVE, toDefaultTable);
} }
private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) { private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) {
return modifyRouteToAddress(lp, addr, true); return modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE);
} }
private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) { private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) {
return modifyRouteToAddress(lp, addr, false); return modifyRouteToAddress(lp, addr, REMOVE, TO_DEFAULT_TABLE);
} }
private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd) { private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd,
boolean toDefaultTable) {
RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr); RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr);
if (bestRoute == null) { if (bestRoute == null) {
bestRoute = RouteInfo.makeHostRoute(addr); bestRoute = RouteInfo.makeHostRoute(addr);
@@ -1176,15 +1183,15 @@ public class ConnectivityService extends IConnectivityManager.Stub {
bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway()); bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway());
} }
} }
return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd); return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd, toDefaultTable);
} }
private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount, private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount,
boolean doAdd) { boolean doAdd, boolean toDefaultTable) {
if ((ifaceName == null) || (lp == null) || (r == null)) return false; if ((ifaceName == null) || (lp == null) || (r == null)) return false;
if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) { if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
loge("Error adding route - too much recursion"); loge("Error modifying route - too much recursion");
return false; return false;
} }
@@ -1199,14 +1206,18 @@ public class ConnectivityService extends IConnectivityManager.Stub {
// route to it's gateway // route to it's gateway
bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway()); bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway());
} }
modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd); modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd, toDefaultTable);
} }
} }
if (doAdd) { if (doAdd) {
if (VDBG) log("Adding " + r + " for interface " + ifaceName); if (VDBG) log("Adding " + r + " for interface " + ifaceName);
mAddedRoutes.add(r);
try { try {
mNetd.addRoute(ifaceName, r); if (toDefaultTable) {
mAddedRoutes.add(r); // only track default table - only one apps can effect
mNetd.addRoute(ifaceName, r);
} else {
mNetd.addSecondaryRoute(ifaceName, r);
}
} catch (Exception e) { } catch (Exception e) {
// never crash - catch them all // never crash - catch them all
if (VDBG) loge("Exception trying to add a route: " + e); if (VDBG) loge("Exception trying to add a route: " + e);
@@ -1215,18 +1226,29 @@ public class ConnectivityService extends IConnectivityManager.Stub {
} else { } else {
// if we remove this one and there are no more like it, then refcount==0 and // if we remove this one and there are no more like it, then refcount==0 and
// we can remove it from the table // we can remove it from the table
mAddedRoutes.remove(r); if (toDefaultTable) {
if (mAddedRoutes.contains(r) == false) { mAddedRoutes.remove(r);
if (mAddedRoutes.contains(r) == false) {
if (VDBG) log("Removing " + r + " for interface " + ifaceName);
try {
mNetd.removeRoute(ifaceName, r);
} catch (Exception e) {
// never crash - catch them all
if (VDBG) loge("Exception trying to remove a route: " + e);
return false;
}
} else {
if (VDBG) log("not removing " + r + " as it's still in use");
}
} else {
if (VDBG) log("Removing " + r + " for interface " + ifaceName); if (VDBG) log("Removing " + r + " for interface " + ifaceName);
try { try {
mNetd.removeRoute(ifaceName, r); mNetd.removeSecondaryRoute(ifaceName, r);
} catch (Exception e) { } catch (Exception e) {
// never crash - catch them all // never crash - catch them all
if (VDBG) loge("Exception trying to remove a route: " + e); if (VDBG) loge("Exception trying to remove a route: " + e);
return false; return false;
} }
} else {
if (VDBG) log("not removing " + r + " as it's still in use");
} }
} }
return true; return true;
@@ -1862,14 +1884,21 @@ public class ConnectivityService extends IConnectivityManager.Stub {
for (RouteInfo r : routeDiff.removed) { for (RouteInfo r : routeDiff.removed) {
if (isLinkDefault || ! r.isDefaultRoute()) { if (isLinkDefault || ! r.isDefaultRoute()) {
removeRoute(curLp, r); removeRoute(curLp, r, TO_DEFAULT_TABLE);
}
if (isLinkDefault == false) {
// remove from a secondary route table
removeRoute(curLp, r, TO_SECONDARY_TABLE);
} }
} }
for (RouteInfo r : routeDiff.added) { for (RouteInfo r : routeDiff.added) {
if (isLinkDefault || ! r.isDefaultRoute()) { if (isLinkDefault || ! r.isDefaultRoute()) {
addRoute(newLp, r); addRoute(newLp, r, TO_DEFAULT_TABLE);
} else { } else {
// add to a secondary route table
addRoute(newLp, r, TO_SECONDARY_TABLE);
// many radios add a default route even when we don't want one. // many radios add a default route even when we don't want one.
// remove the default route unless somebody else has asked for it // remove the default route unless somebody else has asked for it
String ifaceName = newLp.getInterfaceName(); String ifaceName = newLp.getInterfaceName();
@@ -2450,12 +2479,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1); int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(), boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0); Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0);
// Short term disabling of Tethering if DUN is required.
// TODO - fix multi-connection tethering using policy-base routing
int[] upstreamConnTypes = mTethering.getUpstreamIfaceTypes();
for (int i : upstreamConnTypes) {
if (i == ConnectivityManager.TYPE_MOBILE_DUN) return false;
}
return tetherEnabledInSettings && mTetheringConfigValid; return tetherEnabledInSettings && mTetheringConfigValid;
} }