Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96cbbfca authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan Committed by Ricardo Cerqueira
Browse files

Tethering: IPV6 tethering support

- Added two APIs addUpstreamV6Interface and removeUpstreamV6Interface,
  required to pass the interfaces to use to the Router Advertisement
  Proxy.
- Added a dun entry to the networkAttributes value in
  res/values/config.xml. This is to allow tethering to work with the
  dunRequired property.
- Added dun to allowable tether upstream type.
- Enabled debug flags for debug logging inside framework components.
- Regardless of MOBILE_TYPE_DUN APN being available, if dun_required
  flag is not set, fall back to HIPRI as a preferred APN for the
  embedded data call.
- Debug logging was enabled by default which was causing security
  vulnerabilities. This patch disables debug logging.
- Added a NULL check for Network info in CMD_UPSTREAM_CHANGED
- Changed the exception type thrown from IllegalStateException to
  RemoteException whenever the IPv6 tethering rules fail to apply. The
  IllegalStateException is not caught by the caller causing the JVM
  to crash. By throwing RemoteException, the caller will catch and
  print and error message instead of crashing.

Conflicts:
        services/core/java/com/android/server/NetworkManagementService.java

CRs-fixed: 665103
Change-Id: Idb0971449473554bcd749d478563db7ba351d55d
parent 5661393b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -184,6 +184,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
     **/
+2 −0
Original line number Diff line number Diff line
@@ -191,6 +191,7 @@
        <item>"mobile,0,0,0,-1,true"</item>
        <item>"mobile_mms,2,0,2,60000,true"</item>
        <item>"mobile_supl,3,0,2,60000,true"</item>
        <item>"mobile_dun,4,0,2,60000,true"</item>
        <item>"mobile_hipri,5,0,3,60000,true"</item>
        <item>"mobile_fota,10,0,2,60000,true"</item>
        <item>"mobile_ims,11,0,2,60000,true"</item>
@@ -308,6 +309,7 @@
    <integer-array translatable="false" name="config_tether_upstream_types">
        <item>0</item>
        <item>1</item>
        <item>4</item>
        <item>5</item>
        <item>7</item>
        <item>9</item>
+34 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server;

import static android.Manifest.permission.ACCESS_NETWORK_STATE;
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.SHUTDOWN;
@@ -63,6 +64,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
@@ -70,6 +72,7 @@ import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
import java.util.List;

import com.android.internal.app.IBatteryStats;
import com.android.internal.net.NetworkStatsFactory;
@@ -138,6 +141,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
        public static final int TetheringStatsResult      = 221;
        public static final int DnsProxyQueryResult       = 222;
        public static final int ClatdStatusResult         = 223;
        public static final int V6RtrAdvResult            = 227;

        public static final int InterfaceChange           = 600;
        public static final int BandwidthControl          = 601;
@@ -814,6 +818,36 @@ public class NetworkManagementService extends INetworkManagementService.Stub
        }
    }

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

        Slog.d(TAG, "addUpstreamInterface("+ iface + ")");
        try {
            final Command cmd = new Command("tether", "interface", "add_upstream");
            cmd.appendArg(iface);
            mConnector.execute(cmd);
        } catch (NativeDaemonConnectorException e) {
            throw new RemoteException("Cannot add upstream interface");
        }
    }

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

        Slog.d(TAG, "removeUpstreamInterface(" + iface + ")");
        try {
            final Command cmd = new Command("tether", "interface", "remove_upstream");
            cmd.appendArg(iface);
            mConnector.execute(cmd);
        } catch (NativeDaemonConnectorException e) {
            throw new RemoteException("Cannot remove upstream interface");
        }
    }

    @Override
    public InterfaceConfiguration getInterfaceConfig(String iface) {
        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+82 −6
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
import android.net.INetworkStatsService;
import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
@@ -35,10 +36,12 @@ import android.net.NetworkInfo;
import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.os.Binder;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
@@ -553,7 +556,7 @@ public class Tethering extends BaseNetworkObserver {
                if (networkInfo != null &&
                        networkInfo.getDetailedState() != NetworkInfo.DetailedState.FAILED) {
                    if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION");
                    mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
                    mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED, networkInfo);
                }
            } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
                updateConfiguration();
@@ -699,12 +702,16 @@ public class Tethering extends BaseNetworkObserver {
                        mUpstreamIfaceTypes.add(HIPRI_TYPE);
                    }
                }
            }
                /* if DUN is still available, make that a priority */
                if (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
                    mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_DUN;
                } else {
                    mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_HIPRI;
                }
            } else {
                /* dun_required is not set, fall back to HIPRI in that case */
                mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_HIPRI;
            }
        }
    }

@@ -1312,7 +1319,54 @@ public class Tethering extends BaseNetworkObserver {
                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;

@@ -1327,10 +1381,21 @@ public class Tethering extends BaseNetworkObserver {
                    }

                    for (Integer netType : mUpstreamIfaceTypes) {
                        NetworkInfo info =
                                getConnectivityManager().getNetworkInfo(netType.intValue());
                        NetworkInfo info = null;
                        LinkProperties props = null;
                        boolean isV6Connected = false;
                        try {
                            info = cm.getNetworkInfo(netType.intValue());
                            if (info != null) {
                                props = cm.getLinkPropertiesForType(info.getType());
                                isV6Connected = isIpv6Connected(cm, props);
                            }
                        } catch (RemoteException e) { }
                        if ((info != null) && info.isConnected()) {
                            upType = netType.intValue();
                            if (isV6Connected) {
                                addUpstreamV6Interface(props.getInterfaceName());
                            }
                            break;
                        }
                    }
@@ -1510,8 +1575,19 @@ public class Tethering extends BaseNetworkObserver {
                    case CMD_UPSTREAM_CHANGED:
                        if(VDBG) Log.d(TAG, "CMD_UPSTREAM_CHANGED event received");
                        // need to try DUN immediately if Wifi goes down
                        NetworkInfo info = (NetworkInfo) message.obj;
                        mTryCell = !WAIT_FOR_NETWORK_TO_SETTLE;
                        chooseUpstreamType(mTryCell);
                        if ((info != null) && (!info.isConnected())) {
                            IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
                            IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
                            try {
                                LinkProperties props = cm.getLinkPropertiesForType(info.getType());
                                removeUpstreamV6Interface(props.getInterfaceName());
                            } catch(RemoteException e) {
                                Log.e(TAG, "Exception querying ConnectivityManager", e);
                            }
                        }
                        mTryCell = !mTryCell;
                        break;
                    case CMD_CELL_CONNECTION_RENEW: