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

Commit dd4d5820 authored by Erik Kline's avatar Erik Kline
Browse files

Make interface IP serving code set LinkProperties

Additionally, clean up awkward IPv6TetheringInterfaceServices
instantiation mechanics.  In future, this class will be absorbed
by TetherInterfaceStateMachine (prior to its renaming to IpServer).

Test: as follows
    - built
    - flashed
    - booted
    - runtest frameworks-net passes
Bug: 29337859
Bug: 32163131

Change-Id: Ib620e3df182f9f8e2c019aae1cd8981eb0b29376
parent b5c4e80e
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -1258,10 +1258,10 @@ public class Tethering extends BaseNetworkObserver {
                        sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
                    }
                }
                setUpstreamByType(ns);
                setUpstreamNetwork(ns);
            }

            protected void setUpstreamByType(NetworkState ns) {
            protected void setUpstreamNetwork(NetworkState ns) {
                String iface = null;
                if (ns != null && ns.linkProperties != null) {
                    // Find the interface with the default IPv4 route. It may be the
@@ -1786,7 +1786,9 @@ public class Tethering extends BaseNetworkObserver {
            }
        }

        mLog.log(String.format("OBSERVED LinkProperties update iface=%s state=%s", iface, state));
        mLog.log(String.format(
                "OBSERVED LinkProperties update iface=%s state=%s lp=%s",
                iface, IControlsTethering.getStateString(state), newLp));
        final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
        mTetherMasterSM.sendMessage(which, state, 0, newLp);
    }
+10 −0
Original line number Diff line number Diff line
@@ -33,6 +33,16 @@ public class IControlsTethering {
    public static final int STATE_TETHERED    = 2;
    public static final int STATE_LOCAL_ONLY  = 3;

    public static String getStateString(int state) {
        switch (state) {
            case STATE_UNAVAILABLE: return "UNAVAILABLE";
            case STATE_AVAILABLE:   return "AVAILABLE";
            case STATE_TETHERED:    return "TETHERED";
            case STATE_LOCAL_ONLY:  return "LOCAL_ONLY";
        }
        return "UNKNOWN: " + state;
    }

    /**
     * Notify that |who| has changed its tethering state.
     *
+3 −0
Original line number Diff line number Diff line
@@ -85,13 +85,16 @@ public class OffloadController {
            mLog.i("tethering offload control not supported");
            stop();
        }
        mLog.log("tethering offload started");
    }

    public void stop() {
        final boolean wasStarted = started();
        mUpstreamLinkProperties = null;
        mHwInterface.stopOffloadControl();
        mControlInitialized = false;
        mConfigInitialized = false;
        if (wasStarted) mLog.log("tethering offload stopped");
    }

    public void setUpstreamLinkProperties(LinkProperties lp) {
+76 −35
Original line number Diff line number Diff line
@@ -56,9 +56,10 @@ import java.util.Objects;
import java.util.Random;

/**
 * @hide
 * Provides the interface to IP-layer serving functionality for a given network
 * interface, e.g. for tethering or "local-only hotspot" mode.
 *
 * Tracks the eligibility of a given network interface for tethering.
 * @hide
 */
public class TetherInterfaceStateMachine extends StateMachine {
    private static final IpPrefix LINK_LOCAL_PREFIX = new IpPrefix("fe80::/64");
@@ -117,6 +118,12 @@ public class TetherInterfaceStateMachine extends StateMachine {
    private String mMyUpstreamIfaceName;  // may change over time
    private NetworkInterface mNetworkInterface;
    private byte[] mHwAddr;
    // TODO: De-duplicate this with mLinkProperties above. Currently, these link
    // properties are those selected by the IPv6TetheringCoordinator and relayed
    // to us. By comparison, mLinkProperties contains the addresses and directly
    // connected routes that have been formed from these properties iff. we have
    // succeeded in configuring them and are able to announce them within Router
    // Advertisements (otherwise, we do not add them to mLinkProperties at all).
    private LinkProperties mLastIPv6LinkProperties;
    private RouterAdvertisementDaemon mRaDaemon;
    private RaParams mLastRaParams;
@@ -133,7 +140,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
        mIfaceName = ifaceName;
        mInterfaceType = interfaceType;
        mLinkProperties = new LinkProperties();
        mLinkProperties.setInterfaceName(mIfaceName);
        resetLinkProperties();
        mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;

        mInitialState = new InitialState();
@@ -162,10 +169,15 @@ public class TetherInterfaceStateMachine extends StateMachine {
     * Internals.
     */

    // configured when we start tethering and unconfig'd on error or conclusion
    private boolean configureIfaceIp(boolean enabled) {
        if (VDBG) Log.d(TAG, "configureIfaceIp(" + enabled + ")");
    private boolean startIPv4() { return configureIPv4(true); }

    private void stopIPv4() { configureIPv4(false); }

    private boolean configureIPv4(boolean enabled) {
        if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")");

        // TODO: Replace this hard-coded information with dynamically selected
        // config passed down to us by a higher layer IP-coordinating element.
        String ipAsString = null;
        int prefixLen = 0;
        if (mInterfaceType == ConnectivityManager.TETHERING_USB) {
@@ -179,15 +191,20 @@ public class TetherInterfaceStateMachine extends StateMachine {
            return true;
        }

        InterfaceConfiguration ifcg = null;
        final LinkAddress linkAddr;
        try {
            ifcg = mNMService.getInterfaceConfig(mIfaceName);
            if (ifcg != null) {
            final InterfaceConfiguration ifcg = mNMService.getInterfaceConfig(mIfaceName);
            if (ifcg == null) {
                mLog.e("Received null interface config");
                return false;
            }

            InetAddress addr = NetworkUtils.numericToInetAddress(ipAsString);
                ifcg.setLinkAddress(new LinkAddress(addr, prefixLen));
            linkAddr = new LinkAddress(addr, prefixLen);
            ifcg.setLinkAddress(linkAddr);
            if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {
                // The WiFi stack has ownership of the interface up/down state.
                    // It is unclear whether the bluetooth or USB stacks will manage their own
                // It is unclear whether the Bluetooth or USB stacks will manage their own
                // state.
                ifcg.ignoreInterfaceUpDownStatus();
            } else {
@@ -199,12 +216,20 @@ public class TetherInterfaceStateMachine extends StateMachine {
            }
            ifcg.clearFlag("running");
            mNMService.setInterfaceConfig(mIfaceName, ifcg);
            }
        } catch (Exception e) {
            mLog.e("Error configuring interface " + e);
            return false;
        }

        // Directly-connected route.
        final RouteInfo route = new RouteInfo(linkAddr);
        if (enabled) {
            mLinkProperties.addLinkAddress(linkAddr);
            mLinkProperties.addRoute(route);
        } else {
            mLinkProperties.removeLinkAddress(linkAddr);
            mLinkProperties.removeRoute(route);
        }
        return true;
    }

@@ -294,7 +319,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
        mLastIPv6LinkProperties = v6only;
    }

    private void configureLocalRoutes(
    private void configureLocalIPv6Routes(
            HashSet<IpPrefix> deprecatedPrefixes, HashSet<IpPrefix> newPrefixes) {
        // [1] Remove the routes that are deprecated.
        if (!deprecatedPrefixes.isEmpty()) {
@@ -309,6 +334,8 @@ public class TetherInterfaceStateMachine extends StateMachine {
            } catch (RemoteException e) {
                mLog.e("Failed to remove IPv6 routes from local table: " + e);
            }

            for (RouteInfo route : toBeRemoved) mLinkProperties.removeRoute(route);
        }

        // [2] Add only the routes that have not previously been added.
@@ -340,11 +367,13 @@ public class TetherInterfaceStateMachine extends StateMachine {
                } catch (RemoteException e) {
                    mLog.e("Failed to add IPv6 routes to local table: " + e);
                }

                for (RouteInfo route : toBeAdded) mLinkProperties.addRoute(route);
            }
        }
    }

    private void configureLocalDns(
    private void configureLocalIPv6Dns(
            HashSet<Inet6Address> deprecatedDnses, HashSet<Inet6Address> newDnses) {
        final INetd netd = NetdService.getInstance();
        if (netd == null) {
@@ -362,6 +391,8 @@ public class TetherInterfaceStateMachine extends StateMachine {
                } catch (ServiceSpecificException | RemoteException e) {
                    mLog.e("Failed to remove local dns IP " + dnsString + ": " + e);
                }

                mLinkProperties.removeLinkAddress(new LinkAddress(dns, RFC7421_PREFIX_LENGTH));
            }
        }

@@ -380,6 +411,8 @@ public class TetherInterfaceStateMachine extends StateMachine {
                    mLog.e("Failed to add local dns IP " + dnsString + ": " + e);
                    newDnses.remove(dns);
                }

                mLinkProperties.addLinkAddress(new LinkAddress(dns, RFC7421_PREFIX_LENGTH));
            }
        }

@@ -396,10 +429,10 @@ public class TetherInterfaceStateMachine extends StateMachine {
            final RaParams deprecatedParams =
                    RaParams.getDeprecatedRaParams(mLastRaParams, newParams);

            configureLocalRoutes(deprecatedParams.prefixes,
            configureLocalIPv6Routes(deprecatedParams.prefixes,
                    (newParams != null) ? newParams.prefixes : null);

            configureLocalDns(deprecatedParams.dnses,
            configureLocalIPv6Dns(deprecatedParams.dnses,
                    (newParams != null) ? newParams.dnses : null);

            mRaDaemon.buildNewRa(deprecatedParams, newParams);
@@ -419,12 +452,19 @@ public class TetherInterfaceStateMachine extends StateMachine {
    private void sendInterfaceState(int newInterfaceState) {
        mTetherController.updateInterfaceState(
                TetherInterfaceStateMachine.this, newInterfaceState, mLastError);
        // TODO: Populate mLinkProperties correctly, and send more sensible
        // updates more frequently (not just here).
        sendLinkProperties();
    }

    private void sendLinkProperties() {
        mTetherController.updateLinkProperties(
                TetherInterfaceStateMachine.this, new LinkProperties(mLinkProperties));
    }

    private void resetLinkProperties() {
        mLinkProperties.clear();
        mLinkProperties.setInterfaceName(mIfaceName);
    }

    class InitialState extends State {
        @Override
        public void enter() {
@@ -464,7 +504,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
    class BaseServingState extends State {
        @Override
        public void enter() {
            if (!configureIfaceIp(true)) {
            if (!startIPv4()) {
                mLastError = ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR;
                return;
            }
@@ -498,7 +538,9 @@ public class TetherInterfaceStateMachine extends StateMachine {
                mLog.e("Failed to untether interface: " + e);
            }

            configureIfaceIp(false);
            stopIPv4();

            resetLinkProperties();
        }

        @Override
@@ -515,6 +557,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
                    break;
                case CMD_IPV6_TETHER_UPDATE:
                    updateUpstreamIPv6LinkProperties((LinkProperties) message.obj);
                    sendLinkProperties();
                    break;
                case CMD_IP_FORWARDING_ENABLE_ERROR:
                case CMD_IP_FORWARDING_DISABLE_ERROR:
@@ -625,7 +668,6 @@ public class TetherInterfaceStateMachine extends StateMachine {
            if (super.processMessage(message)) return true;

            maybeLogMessage(this, message.what);
            boolean retValue = true;
            switch (message.what) {
                case CMD_TETHER_REQUESTED:
                    mLog.e("CMD_TETHER_REQUESTED while already tethering.");
@@ -655,10 +697,9 @@ public class TetherInterfaceStateMachine extends StateMachine {
                    mMyUpstreamIfaceName = newUpstreamIfaceName;
                    break;
                default:
                    retValue = false;
                    break;
                    return false;
            }
            return retValue;
            return true;
        }
    }

+2 −1
Original line number Diff line number Diff line
@@ -62,7 +62,8 @@ public class OffloadControllerTest {
    @Mock private OffloadHardwareInterface mHardware;
    @Mock private ApplicationInfo mApplicationInfo;
    @Mock private Context mContext;
    final ArgumentCaptor<ArrayList> mStringArrayCaptor = ArgumentCaptor.forClass(ArrayList.class);
    private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
            ArgumentCaptor.forClass(ArrayList.class);
    private MockContentResolver mContentResolver;

    @Before public void setUp() throws Exception {
Loading