Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
frameworks/base: IPV6 tethering support
Added two APIs addUpstreamV6Interface and removeUpstreamV6Interface, required
to pass the interfaces to use to the Router Advertisement Proxy

Change-Id: Idabec4af913bd459ad211d7bd9aefcffdb70f09d
  • Loading branch information
Jaime Lopez committed Jan 13, 2012
1 parent d1a0a99 commit ceffdd2
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 2 deletions.
10 changes: 10 additions & 0 deletions core/java/android/os/INetworkManagementService.aidl
Expand Up @@ -219,6 +219,16 @@ interface INetworkManagementService
*/
void disableNat(String internalInterface, String externalInterface);

/**
* Add an upstream IPv6 interface
*/
void addUpstreamV6Interface(String iface);

/**
* Remove an upstream IPv6 interface
*/
void removeUpstreamV6Interface(String iface);

/**
** PPPD
**/
Expand Down
27 changes: 27 additions & 0 deletions services/java/com/android/server/NetworkManagementService.java
Expand Up @@ -46,6 +46,7 @@
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
import java.util.List;

import com.android.internal.net.NetworkStatsFactory;
import com.google.android.collect.Sets;
Expand Down Expand Up @@ -109,6 +110,7 @@ class NetdResponseCode {
public static final int InterfaceTxThrottleResult = 219;
public static final int QuotaCounterResult = 220;
public static final int TetheringStatsResult = 221;
public static final int V6RtrAdvResult = 223;

public static final int InterfaceChange = 600;
public static final int BandwidthControl = 601;
Expand Down Expand Up @@ -365,6 +367,31 @@ public String[] listInterfaces() throws IllegalStateException {
}
}

public void addUpstreamV6Interface(String iface) throws IllegalStateException {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");

Slog.d(TAG, "addUpstreamInterface("+ iface + ")");
try {
mConnector.doCommand("tether interface add_upstream " + iface);
} catch (NativeDaemonConnectorException e) {
throw new IllegalStateException("Cannot add upstream interface");
}
}

public void removeUpstreamV6Interface(String iface) throws IllegalStateException {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");

Slog.d(TAG, "removeUpstreamInterface(" + iface + ")");

try {
mConnector.doCommand("tether interface remove_upstream " + iface);
} catch (NativeDaemonConnectorException e) {
throw new IllegalStateException("Cannot remove upstream interface");
}
}

public InterfaceConfiguration getInterfaceConfig(String iface) throws IllegalStateException {
mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
String rsp;
Expand Down
79 changes: 77 additions & 2 deletions services/java/com/android/server/connectivity/Tethering.java
Expand Up @@ -500,7 +500,9 @@ public void onReceive(Context content, Intent intent) {
}
} else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION");
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
NetworkInfo info = (NetworkInfo)
intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED, info);
}
}
}
Expand Down Expand Up @@ -1269,7 +1271,54 @@ protected boolean turnOffMasterTetherSettings() {
return true;
}

protected void addUpstreamV6Interface(String iface) {
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);

Log.d(TAG, "adding v6 interface " + iface);
try {
service.addUpstreamV6Interface(iface);
} catch (RemoteException e) {
Log.e(TAG, "Unable to append v6 upstream interface");
}
}

protected void removeUpstreamV6Interface(String iface) {
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);

Log.d(TAG, "removing v6 interface " + iface);
try {
service.removeUpstreamV6Interface(iface);
} catch (RemoteException e) {
Log.e(TAG, "Unable to remove v6 upstream interface");
}
}


boolean isIpv6Connected(IConnectivityManager cm, LinkProperties linkProps) {
boolean ret = false;
Collection <InetAddress> addresses = null;

if (cm == null || linkProps == null) {
return false;
}
addresses = linkProps.getAddresses();
for (InetAddress addr: addresses) {
if (addr instanceof java.net.Inet6Address) {
java.net.Inet6Address i6addr = (java.net.Inet6Address) addr;
if (!i6addr.isAnyLocalAddress() && !i6addr.isLinkLocalAddress() &&
!i6addr.isLoopbackAddress() && !i6addr.isMulticastAddress()) {
ret = true;
break;
}
}
}
return ret;
}
protected void chooseUpstreamType(boolean tryCell) {
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
int upType = ConnectivityManager.TYPE_NONE;
String iface = null;

Expand All @@ -1283,13 +1332,28 @@ protected void chooseUpstreamType(boolean tryCell) {
}
}


if (VDBG) {
Log.d(TAG, "chooseUpstreamType has upstream iface types:");
for (Integer netType : mUpstreamIfaceTypes) {
Log.d(TAG, " " + netType);
}
}

for (Integer netType : mUpstreamIfaceTypes) {
NetworkInfo info = null;
LinkProperties props = null;
boolean isV6Connected = false;
try {
info = mConnService.getNetworkInfo(netType.intValue());
info = cm.getNetworkInfo(netType.intValue());
props = cm.getLinkProperties(info.getType());
isV6Connected = isIpv6Connected(cm, props);
} catch (RemoteException e) { }
if ((info != null) && info.isConnected()) {
upType = netType.intValue();
if (isV6Connected) {
addUpstreamV6Interface(props.getInterfaceName());
}
break;
}
}
Expand Down Expand Up @@ -1406,8 +1470,19 @@ public boolean processMessage(Message message) {
break;
case CMD_UPSTREAM_CHANGED:
// need to try DUN immediately if Wifi goes down
NetworkInfo info = (NetworkInfo) message.obj;
mTryCell = !WAIT_FOR_NETWORK_TO_SETTLE;
chooseUpstreamType(mTryCell);
if (!info.isConnected()) {
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
try {
LinkProperties props = cm.getLinkProperties(info.getType());
removeUpstreamV6Interface(props.getInterfaceName());
} catch(RemoteException e) {
Log.e(TAG, "Exception querying ConnectivityManager", e);
}
}
mTryCell = !mTryCell;
break;
case CMD_CELL_CONNECTION_RENEW:
Expand Down

0 comments on commit ceffdd2

Please sign in to comment.