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

Commit b3d2aaaf authored by Erik Kline's avatar Erik Kline Committed by android-build-merger
Browse files

Merge "Program offload-exempt local prefixes into the HAL" into oc-dr1-dev

am: aa7b8b53

Change-Id: Iaf80e584df458010741401fc1a19e7f6e21923c1
parents c2a76d16 aa7b8b53
Loading
Loading
Loading
Loading
+46 −24
Original line number Original line Diff line number Diff line
@@ -57,6 +57,7 @@ import android.net.NetworkRequest;
import android.net.NetworkState;
import android.net.NetworkState;
import android.net.NetworkUtils;
import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.net.RouteInfo;
import android.net.util.PrefixUtils;
import android.net.util.SharedLog;
import android.net.util.SharedLog;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Binder;
@@ -219,7 +220,7 @@ public class Tethering extends BaseNetworkObserver {
                mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
                mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
        mForwardedDownstreams = new HashSet<>();
        mForwardedDownstreams = new HashSet<>();
        mSimChange = new SimChangeListener(
        mSimChange = new SimChangeListener(
                mContext, mTetherMasterSM.getHandler(), () -> reevaluateSimCardProvisioning());
                mContext, smHandler, () -> reevaluateSimCardProvisioning());


        mStateReceiver = new StateReceiver();
        mStateReceiver = new StateReceiver();
        IntentFilter filter = new IntentFilter();
        IntentFilter filter = new IntentFilter();
@@ -227,13 +228,13 @@ public class Tethering extends BaseNetworkObserver {
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
        mContext.registerReceiver(mStateReceiver, filter, null, mTetherMasterSM.getHandler());
        mContext.registerReceiver(mStateReceiver, filter, null, smHandler);


        filter = new IntentFilter();
        filter = new IntentFilter();
        filter.addAction(Intent.ACTION_MEDIA_SHARED);
        filter.addAction(Intent.ACTION_MEDIA_SHARED);
        filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
        filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
        filter.addDataScheme("file");
        filter.addDataScheme("file");
        mContext.registerReceiver(mStateReceiver, filter, null, mTetherMasterSM.getHandler());
        mContext.registerReceiver(mStateReceiver, filter, null, smHandler);


        // load device config info
        // load device config info
        updateConfiguration();
        updateConfiguration();
@@ -1142,12 +1143,6 @@ public class Tethering extends BaseNetworkObserver {
        }
        }
    }
    }


    private void startOffloadController() {
        mOffloadController.start();
        mOffloadController.updateExemptPrefixes(
                mUpstreamNetworkMonitor.getOffloadExemptPrefixes());
    }

    class TetherMasterSM extends StateMachine {
    class TetherMasterSM extends StateMachine {
        private static final int BASE_MASTER                    = Protocol.BASE_TETHERING;
        private static final int BASE_MASTER                    = Protocol.BASE_TETHERING;
        // an interface SM has requested Tethering/Local Hotspot
        // an interface SM has requested Tethering/Local Hotspot
@@ -1165,14 +1160,14 @@ public class Tethering extends BaseNetworkObserver {
        static final int CMD_CLEAR_ERROR                        = BASE_MASTER + 6;
        static final int CMD_CLEAR_ERROR                        = BASE_MASTER + 6;
        static final int EVENT_IFACE_UPDATE_LINKPROPERTIES      = BASE_MASTER + 7;
        static final int EVENT_IFACE_UPDATE_LINKPROPERTIES      = BASE_MASTER + 7;


        private State mInitialState;
        private final State mInitialState;
        private State mTetherModeAliveState;
        private final State mTetherModeAliveState;


        private State mSetIpForwardingEnabledErrorState;
        private final State mSetIpForwardingEnabledErrorState;
        private State mSetIpForwardingDisabledErrorState;
        private final State mSetIpForwardingDisabledErrorState;
        private State mStartTetheringErrorState;
        private final State mStartTetheringErrorState;
        private State mStopTetheringErrorState;
        private final State mStopTetheringErrorState;
        private State mSetDnsForwardersErrorState;
        private final State mSetDnsForwardersErrorState;


        // This list is a little subtle.  It contains all the interfaces that currently are
        // This list is a little subtle.  It contains all the interfaces that currently are
        // requesting tethering, regardless of whether these interfaces are still members of
        // requesting tethering, regardless of whether these interfaces are still members of
@@ -1212,9 +1207,33 @@ public class Tethering extends BaseNetworkObserver {


            mNotifyList = new ArrayList<>();
            mNotifyList = new ArrayList<>();
            mIPv6TetheringCoordinator = new IPv6TetheringCoordinator(mNotifyList, mLog);
            mIPv6TetheringCoordinator = new IPv6TetheringCoordinator(mNotifyList, mLog);

            setInitialState(mInitialState);
            setInitialState(mInitialState);
        }
        }


        private void startOffloadController() {
            mOffloadController.start();
            sendOffloadExemptPrefixes();
        }

        private void sendOffloadExemptPrefixes() {
            sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes());
        }

        private void sendOffloadExemptPrefixes(Set<IpPrefix> localPrefixes) {
            // Add in well-known minimum set.
            PrefixUtils.addNonForwardablePrefixes(localPrefixes);
            // Add tragically hardcoded prefixes.
            localPrefixes.add(PrefixUtils.DEFAULT_WIFI_P2P_PREFIX);

            // Add prefixes for all downstreams, regardless of IP serving mode.
            for (TetherInterfaceStateMachine tism : mNotifyList) {
                localPrefixes.addAll(PrefixUtils.localPrefixesFrom(tism.linkProperties()));
            }

            mOffloadController.setLocalPrefixes(localPrefixes);
        }

        class InitialState extends State {
        class InitialState extends State {
            @Override
            @Override
            public boolean processMessage(Message message) {
            public boolean processMessage(Message message) {
@@ -1422,8 +1441,8 @@ public class Tethering extends BaseNetworkObserver {
        }
        }


        private void handleUpstreamNetworkMonitorCallback(int arg1, Object o) {
        private void handleUpstreamNetworkMonitorCallback(int arg1, Object o) {
            if (arg1 == UpstreamNetworkMonitor.NOTIFY_EXEMPT_PREFIXES) {
            if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) {
                mOffloadController.updateExemptPrefixes((Set<IpPrefix>) o);
                sendOffloadExemptPrefixes((Set<IpPrefix>) o);
                return;
                return;
            }
            }


@@ -1573,6 +1592,9 @@ public class Tethering extends BaseNetworkObserver {
                            mOffloadController.notifyDownstreamLinkProperties(newLp);
                            mOffloadController.notifyDownstreamLinkProperties(newLp);
                        } else {
                        } else {
                            mOffloadController.removeDownstreamInterface(newLp.getInterfaceName());
                            mOffloadController.removeDownstreamInterface(newLp.getInterfaceName());
                            // Another interface might be in local-only hotspot mode;
                            // resend all local prefixes to the OffloadController.
                            sendOffloadExemptPrefixes();
                        }
                        }
                        break;
                        break;
                    }
                    }
+55 −8
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;


import android.content.ContentResolver;
import android.content.ContentResolver;
import android.net.IpPrefix;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.LinkProperties;
import android.net.RouteInfo;
import android.net.RouteInfo;
import android.net.util.SharedLog;
import android.net.util.SharedLog;
@@ -27,8 +28,11 @@ import android.os.Handler;
import android.provider.Settings;
import android.provider.Settings;


import java.net.Inet4Address;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.Set;


/**
/**
@@ -47,7 +51,13 @@ public class OffloadController {
    private boolean mConfigInitialized;
    private boolean mConfigInitialized;
    private boolean mControlInitialized;
    private boolean mControlInitialized;
    private LinkProperties mUpstreamLinkProperties;
    private LinkProperties mUpstreamLinkProperties;
    // The complete set of offload-exempt prefixes passed in via Tethering from
    // all upstream and downstream sources.
    private Set<IpPrefix> mExemptPrefixes;
    private Set<IpPrefix> mExemptPrefixes;
    // A strictly "smaller" set of prefixes, wherein offload-approved prefixes
    // (e.g. downstream on-link prefixes) have been removed and replaced with
    // prefixes representing only the locally-assigned IP addresses.
    private Set<String> mLastLocalPrefixStrs;


    public OffloadController(Handler h, OffloadHardwareInterface hwi,
    public OffloadController(Handler h, OffloadHardwareInterface hwi,
            ContentResolver contentResolver, SharedLog log) {
            ContentResolver contentResolver, SharedLog log) {
@@ -55,6 +65,8 @@ public class OffloadController {
        mHwInterface = hwi;
        mHwInterface = hwi;
        mContentResolver = contentResolver;
        mContentResolver = contentResolver;
        mLog = log.forSubComponent(TAG);
        mLog = log.forSubComponent(TAG);
        mExemptPrefixes = new HashSet<>();
        mLastLocalPrefixStrs = new HashSet<>();
    }
    }


    public void start() {
    public void start() {
@@ -134,25 +146,22 @@ public class OffloadController {
    }
    }


    public void setUpstreamLinkProperties(LinkProperties lp) {
    public void setUpstreamLinkProperties(LinkProperties lp) {
        if (!started()) return;
        if (!started() || Objects.equals(mUpstreamLinkProperties, lp)) return;


        mUpstreamLinkProperties = (lp != null) ? new LinkProperties(lp) : null;
        mUpstreamLinkProperties = (lp != null) ? new LinkProperties(lp) : null;
        // TODO: examine return code and decide what to do if programming
        // TODO: examine return code and decide what to do if programming
        // upstream parameters fails (probably just wait for a subsequent
        // upstream parameters fails (probably just wait for a subsequent
        // onOffloadEvent() callback to tell us offload is available again and
        // onOffloadEvent() callback to tell us offload is available again and
        // then reapply all state).
        // then reapply all state).
        computeAndPushLocalPrefixes();
        pushUpstreamParameters();
        pushUpstreamParameters();
    }
    }


    public void updateExemptPrefixes(Set<IpPrefix> exemptPrefixes) {
    public void setLocalPrefixes(Set<IpPrefix> localPrefixes) {
        if (!started()) return;
        if (!started()) return;


        mExemptPrefixes = exemptPrefixes;
        mExemptPrefixes = localPrefixes;
        // TODO:
        computeAndPushLocalPrefixes();
        //     - add IP addresses from all downstream link properties
        //     - add routes from all non-tethering downstream link properties
        //     - remove any 64share prefixes
        //     - push this to the HAL
    }
    }


    public void notifyDownstreamLinkProperties(LinkProperties lp) {
    public void notifyDownstreamLinkProperties(LinkProperties lp) {
@@ -215,4 +224,42 @@ public class OffloadController {
        return mHwInterface.setUpstreamParameters(
        return mHwInterface.setUpstreamParameters(
                iface, v4addr, v4gateway, (v6gateways.isEmpty() ? null : v6gateways));
                iface, v4addr, v4gateway, (v6gateways.isEmpty() ? null : v6gateways));
    }
    }

    private boolean computeAndPushLocalPrefixes() {
        final Set<String> localPrefixStrs = computeLocalPrefixStrings(
                mExemptPrefixes, mUpstreamLinkProperties);
        if (mLastLocalPrefixStrs.equals(localPrefixStrs)) return true;

        mLastLocalPrefixStrs = localPrefixStrs;
        return mHwInterface.setLocalPrefixes(new ArrayList<>(localPrefixStrs));
    }

    // TODO: Factor in downstream LinkProperties once that information is available.
    private static Set<String> computeLocalPrefixStrings(
            Set<IpPrefix> localPrefixes, LinkProperties upstreamLinkProperties) {
        // Create an editable copy.
        final Set<IpPrefix> prefixSet = new HashSet<>(localPrefixes);

        // TODO: If a downstream interface (not currently passed in) is reusing
        // the /64 of the upstream (64share) then:
        //
        //     [a] remove that /64 from the local prefixes
        //     [b] add in /128s for IP addresses on the downstream interface
        //     [c] add in /128s for IP addresses on the upstream interface
        //
        // Until downstream information is available here, simply add /128s from
        // the upstream network; they'll just be redundant with their /64.
        if (upstreamLinkProperties != null) {
            for (LinkAddress linkAddr : upstreamLinkProperties.getLinkAddresses()) {
                if (!linkAddr.isGlobalPreferred()) continue;
                final InetAddress ip = linkAddr.getAddress();
                if (!(ip instanceof Inet6Address)) continue;
                prefixSet.add(new IpPrefix(ip, 128));
            }
        }

        final HashSet<String> localPrefixStrs = new HashSet<>();
        for (IpPrefix pfx : prefixSet) localPrefixStrs.add(pfx.toString());
        return localPrefixStrs;
    }
}
}
+20 −0
Original line number Original line Diff line number Diff line
@@ -168,6 +168,26 @@ public class OffloadHardwareInterface {
        return stats;
        return stats;
    }
    }


    public boolean setLocalPrefixes(ArrayList<String> localPrefixes) {
        final String logmsg = String.format("setLocalPrefixes([%s])",
                String.join(",", localPrefixes));

        final CbResults results = new CbResults();
        try {
            mOffloadControl.setLocalPrefixes(localPrefixes,
                    (boolean success, String errMsg) -> {
                        results.success = success;
                        results.errMsg = errMsg;
                    });
        } catch (RemoteException e) {
            record(logmsg, e);
            return false;
        }

        record(logmsg, results);
        return results.success;
    }

    public boolean setUpstreamParameters(
    public boolean setUpstreamParameters(
            String iface, String v4addr, String v4gateway, ArrayList<String> v6gws) {
            String iface, String v4addr, String v4gateway, ArrayList<String> v6gws) {
        iface = (iface != null) ? iface : NO_INTERFACE_NAME;
        iface = (iface != null) ? iface : NO_INTERFACE_NAME;
+2 −0
Original line number Original line Diff line number Diff line
@@ -161,6 +161,8 @@ public class TetherInterfaceStateMachine extends StateMachine {


    public int lastError() { return mLastError; }
    public int lastError() { return mLastError; }


    public LinkProperties linkProperties() { return new LinkProperties(mLinkProperties); }

    public void stop() { sendMessage(CMD_INTERFACE_DOWN); }
    public void stop() { sendMessage(CMD_INTERFACE_DOWN); }


    public void unwanted() { sendMessage(CMD_TETHER_UNREQUESTED); }
    public void unwanted() { sendMessage(CMD_TETHER_UNREQUESTED); }
+17 −41
Original line number Original line Diff line number Diff line
@@ -34,6 +34,7 @@ import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.NetworkRequest;
import android.net.NetworkState;
import android.net.NetworkState;
import android.net.util.NetworkConstants;
import android.net.util.NetworkConstants;
import android.net.util.PrefixUtils;
import android.net.util.SharedLog;
import android.net.util.SharedLog;
import android.util.Log;
import android.util.Log;


@@ -72,16 +73,11 @@ public class UpstreamNetworkMonitor {
    private static final boolean DBG = false;
    private static final boolean DBG = false;
    private static final boolean VDBG = false;
    private static final boolean VDBG = false;


    private static final IpPrefix[] MINIMUM_LOCAL_PREFIXES_SET = {
            prefix("127.0.0.0/8"), prefix("169.254.0.0/16"),
            prefix("::/3"), prefix("fe80::/64"), prefix("fc00::/7"), prefix("ff00::/8"),
    };

    public static final int EVENT_ON_AVAILABLE      = 1;
    public static final int EVENT_ON_AVAILABLE      = 1;
    public static final int EVENT_ON_CAPABILITIES   = 2;
    public static final int EVENT_ON_CAPABILITIES   = 2;
    public static final int EVENT_ON_LINKPROPERTIES = 3;
    public static final int EVENT_ON_LINKPROPERTIES = 3;
    public static final int EVENT_ON_LOST           = 4;
    public static final int EVENT_ON_LOST           = 4;
    public static final int NOTIFY_EXEMPT_PREFIXES  = 10;
    public static final int NOTIFY_LOCAL_PREFIXES   = 10;


    private static final int CALLBACK_LISTEN_ALL = 1;
    private static final int CALLBACK_LISTEN_ALL = 1;
    private static final int CALLBACK_TRACK_DEFAULT = 2;
    private static final int CALLBACK_TRACK_DEFAULT = 2;
@@ -93,7 +89,7 @@ public class UpstreamNetworkMonitor {
    private final Handler mHandler;
    private final Handler mHandler;
    private final int mWhat;
    private final int mWhat;
    private final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>();
    private final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>();
    private HashSet<IpPrefix> mOffloadExemptPrefixes;
    private HashSet<IpPrefix> mLocalPrefixes;
    private ConnectivityManager mCM;
    private ConnectivityManager mCM;
    private NetworkCallback mListenAllCallback;
    private NetworkCallback mListenAllCallback;
    private NetworkCallback mDefaultNetworkCallback;
    private NetworkCallback mDefaultNetworkCallback;
@@ -107,7 +103,7 @@ public class UpstreamNetworkMonitor {
        mHandler = mTarget.getHandler();
        mHandler = mTarget.getHandler();
        mLog = log.forSubComponent(TAG);
        mLog = log.forSubComponent(TAG);
        mWhat = what;
        mWhat = what;
        mOffloadExemptPrefixes = allOffloadExemptPrefixes(mNetworkMap.values());
        mLocalPrefixes = new HashSet<>();
    }
    }


    @VisibleForTesting
    @VisibleForTesting
@@ -223,8 +219,8 @@ public class UpstreamNetworkMonitor {
        return typeStatePair.ns;
        return typeStatePair.ns;
    }
    }


    public Set<IpPrefix> getOffloadExemptPrefixes() {
    public Set<IpPrefix> getLocalPrefixes() {
        return (Set<IpPrefix>) mOffloadExemptPrefixes.clone();
        return (Set<IpPrefix>) mLocalPrefixes.clone();
    }
    }


    private void handleAvailable(int callbackType, Network network) {
    private void handleAvailable(int callbackType, Network network) {
@@ -360,11 +356,11 @@ public class UpstreamNetworkMonitor {
        notifyTarget(EVENT_ON_LOST, mNetworkMap.remove(network));
        notifyTarget(EVENT_ON_LOST, mNetworkMap.remove(network));
    }
    }


    private void recomputeOffloadExemptPrefixes() {
    private void recomputeLocalPrefixes() {
        final HashSet<IpPrefix> exemptPrefixes = allOffloadExemptPrefixes(mNetworkMap.values());
        final HashSet<IpPrefix> localPrefixes = allLocalPrefixes(mNetworkMap.values());
        if (!mOffloadExemptPrefixes.equals(exemptPrefixes)) {
        if (!mLocalPrefixes.equals(localPrefixes)) {
            mOffloadExemptPrefixes = exemptPrefixes;
            mLocalPrefixes = localPrefixes;
            notifyTarget(NOTIFY_EXEMPT_PREFIXES, exemptPrefixes.clone());
            notifyTarget(NOTIFY_LOCAL_PREFIXES, localPrefixes.clone());
        }
        }
    }
    }


@@ -402,7 +398,7 @@ public class UpstreamNetworkMonitor {
        @Override
        @Override
        public void onLinkPropertiesChanged(Network network, LinkProperties newLp) {
        public void onLinkPropertiesChanged(Network network, LinkProperties newLp) {
            handleLinkProp(network, newLp);
            handleLinkProp(network, newLp);
            recomputeOffloadExemptPrefixes();
            recomputeLocalPrefixes();
        }
        }


        // TODO: Handle onNetworkSuspended();
        // TODO: Handle onNetworkSuspended();
@@ -411,7 +407,7 @@ public class UpstreamNetworkMonitor {
        @Override
        @Override
        public void onLost(Network network) {
        public void onLost(Network network) {
            handleLost(mCallbackType, network);
            handleLost(mCallbackType, network);
            recomputeOffloadExemptPrefixes();
            recomputeLocalPrefixes();
        }
        }
    }
    }


@@ -460,35 +456,15 @@ public class UpstreamNetworkMonitor {
        return result;
        return result;
    }
    }


    private static HashSet<IpPrefix> allOffloadExemptPrefixes(Iterable<NetworkState> netStates) {
    private static HashSet<IpPrefix> allLocalPrefixes(Iterable<NetworkState> netStates) {
        final HashSet<IpPrefix> prefixSet = new HashSet<>();
        final HashSet<IpPrefix> prefixSet = new HashSet<>();


        addDefaultLocalPrefixes(prefixSet);

        for (NetworkState ns : netStates) {
        for (NetworkState ns : netStates) {
            addOffloadExemptPrefixes(prefixSet, ns.linkProperties);
            final LinkProperties lp = ns.linkProperties;
            if (lp == null) continue;
            prefixSet.addAll(PrefixUtils.localPrefixesFrom(lp));
        }
        }


        return prefixSet;
        return prefixSet;
    }
    }

    private static void addDefaultLocalPrefixes(Set<IpPrefix> prefixSet) {
        Collections.addAll(prefixSet, MINIMUM_LOCAL_PREFIXES_SET);
    }

    private static void addOffloadExemptPrefixes(Set<IpPrefix> prefixSet, LinkProperties lp) {
        if (lp == null) return;

        for (LinkAddress linkAddr : lp.getAllLinkAddresses()) {
            prefixSet.add(new IpPrefix(linkAddr.getAddress(), linkAddr.getPrefixLength()));
        }

        // TODO: Consider adding other non-default routes associated with this
        // network. Traffic to these destinations should perhaps not go through
        // the Internet (upstream).
    }

    private static IpPrefix prefix(String prefixStr) {
        return new IpPrefix(prefixStr);
    }
}
}
Loading