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

Commit 6e29bf00 authored by Erik Kline's avatar Erik Kline
Browse files

Support tethering IPv6 toward the first requested downstream.

We no longer tether toward wifi only, but rather implement 64share toward
the current, oldest (first requested) active downstream.

Additionally, explicitly ban IPv6 tethering toward Bluetooth until
PAN support is figured out.

Bug: 30298058
Change-Id: Ib705b69eae767ec50131d09d26168d9e041e4bc0
parent f5e51cf7
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -1616,6 +1616,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
                        if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
                        if (mNotifyList.indexOf(who) < 0) {
                            mNotifyList.add(who);
                            mIPv6TetheringCoordinator.addActiveDownstream(who);
                        }
                        transitionTo(mTetherModeAliveState);
                        break;
@@ -1623,6 +1624,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
                        who = (TetherInterfaceStateMachine)message.obj;
                        if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
                        mNotifyList.remove(who);
                        mIPv6TetheringCoordinator.removeActiveDownstream(who);
                        break;
                    default:
                        retValue = false;
@@ -1661,17 +1663,19 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
                maybeLogMessage(this, message.what);
                boolean retValue = true;
                switch (message.what) {
                    case CMD_TETHER_MODE_REQUESTED:
                    case CMD_TETHER_MODE_REQUESTED: {
                        TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
                        if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
                        if (mNotifyList.indexOf(who) < 0) {
                            mNotifyList.add(who);
                            mIPv6TetheringCoordinator.addActiveDownstream(who);
                        }
                        who.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED,
                                mCurrentUpstreamIface);
                        break;
                    case CMD_TETHER_MODE_UNREQUESTED:
                        who = (TetherInterfaceStateMachine)message.obj;
                    }
                    case CMD_TETHER_MODE_UNREQUESTED: {
                        TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
                        if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
                        if (mNotifyList.remove(who)) {
                            if (DBG) Log.d(TAG, "TetherModeAlive removing notifyee " + who);
@@ -1689,7 +1693,9 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
                        } else {
                           Log.e(TAG, "TetherModeAliveState UNREQUESTED has unknown who: " + who);
                        }
                        mIPv6TetheringCoordinator.removeActiveDownstream(who);
                        break;
                    }
                    case CMD_UPSTREAM_CHANGED:
                        // need to try DUN immediately if Wifi goes down
                        mTryCell = true;
+40 −14
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.util.Log;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.LinkedList;


/**
@@ -45,10 +46,28 @@ public class IPv6TetheringCoordinator {
    private static final boolean VDBG = false;

    private final ArrayList<TetherInterfaceStateMachine> mNotifyList;
    private final LinkedList<TetherInterfaceStateMachine> mActiveDownstreams;
    private NetworkState mUpstreamNetworkState;

    public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList) {
        mNotifyList = notifyList;
        mActiveDownstreams = new LinkedList<>();
    }

    public void addActiveDownstream(TetherInterfaceStateMachine downstream) {
        if (mActiveDownstreams.indexOf(downstream) == -1) {
            // Adding a new downstream appends it to the list. Adding a
            // downstream a second time without first removing it has no effect.
            mActiveDownstreams.offer(downstream);
            updateIPv6TetheringInterfaces();
        }
    }

    public void removeActiveDownstream(TetherInterfaceStateMachine downstream) {
        stopIPv6TetheringOn(downstream);
        if (mActiveDownstreams.remove(downstream)) {
            updateIPv6TetheringInterfaces();
        }
    }

    public void updateUpstreamNetworkState(NetworkState ns) {
@@ -72,8 +91,7 @@ public class IPv6TetheringCoordinator {

    private void stopIPv6TetheringOnAllInterfaces() {
        for (TetherInterfaceStateMachine sm : mNotifyList) {
            sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE,
                    0, 0, null);
            stopIPv6TetheringOn(sm);
        }
    }

@@ -98,28 +116,32 @@ public class IPv6TetheringCoordinator {

    private void updateIPv6TetheringInterfaces() {
        for (TetherInterfaceStateMachine sm : mNotifyList) {
            final LinkProperties lp = getInterfaceIPv6LinkProperties(sm.interfaceType());
            final LinkProperties lp = getInterfaceIPv6LinkProperties(sm);
            sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, lp);
            break;
        }
    }

    private LinkProperties getInterfaceIPv6LinkProperties(int interfaceType) {
    private LinkProperties getInterfaceIPv6LinkProperties(TetherInterfaceStateMachine sm) {
        if (mUpstreamNetworkState == null) return null;

        if (sm.interfaceType() == ConnectivityManager.TETHERING_BLUETOOTH) {
            // TODO: Figure out IPv6 support on PAN interfaces.
            return null;
        }

        // NOTE: Here, in future, we would have policies to decide how to divvy
        // up the available dedicated prefixes among downstream interfaces.
        // At this time we have no such mechanism--we only support tethering
        // IPv6 toward Wi-Fi interfaces.
        // IPv6 toward the oldest (first requested) active downstream.

        switch (interfaceType) {
            case ConnectivityManager.TETHERING_WIFI:
        final TetherInterfaceStateMachine currentActive = mActiveDownstreams.peek();
        if (currentActive != null && currentActive == sm) {
            final LinkProperties lp = getIPv6OnlyLinkProperties(
                    mUpstreamNetworkState.linkProperties);
            if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) {
                return lp;
            }
                break;
        }

        return null;
@@ -250,4 +272,8 @@ public class IPv6TetheringCoordinator {
                ns.networkCapabilities,
                ns.linkProperties);
    }

    private static void stopIPv6TetheringOn(TetherInterfaceStateMachine sm) {
        sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
    }
}