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

Commit 083cbd73 authored by Mark Chien's avatar Mark Chien Committed by android-build-merger
Browse files

Merge "[Tether09] Use INetd to call netd directly"

am: a3e62b2c

Change-Id: I031f9967a85ff1e6060ab926b7a9cbfed214750b
parents 088c30b5 a3e62b2c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ java_defaults {
    srcs: [
        "src/**/*.java",
        ":framework-tethering-shared-srcs",
        ":net-module-utils-srcs",
        ":tethering-module-utils-srcs",
        ":services-tethering-shared-srcs",
    ],
    static_libs: [
+86 −102
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.net.ConnectivityManager;
import android.net.INetd;
import android.net.INetworkStackStatusCallback;
import android.net.INetworkStatsService;
import android.net.InterfaceConfiguration;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -38,11 +37,11 @@ import android.net.dhcp.DhcpServingParamsParcel;
import android.net.dhcp.DhcpServingParamsParcelExt;
import android.net.dhcp.IDhcpServer;
import android.net.ip.RouterAdvertisementDaemon.RaParams;
import android.net.shared.NetdUtils;
import android.net.shared.RouteUtils;
import android.net.util.InterfaceParams;
import android.net.util.InterfaceSet;
import android.net.util.NetdService;
import android.net.util.SharedLog;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
@@ -144,10 +143,6 @@ public class IpServer extends StateMachine {
            return InterfaceParams.getByName(ifName);
        }

        public INetd getNetdService() {
            return NetdService.getInstance();
        }

        /** Create a DhcpServer instance to be used by IpServer. */
        public abstract void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
                DhcpServerCallbacks cb);
@@ -180,7 +175,6 @@ public class IpServer extends StateMachine {
    private final State mUnavailableState;

    private final SharedLog mLog;
    private final INetworkManagementService mNMService;
    private final INetd mNetd;
    private final INetworkStatsService mStatsService;
    private final Callback mCallback;
@@ -210,15 +204,15 @@ public class IpServer extends StateMachine {
    private int mDhcpServerStartIndex = 0;
    private IDhcpServer mDhcpServer;
    private RaParams mLastRaParams;
    private LinkAddress mIpv4Address;

    public IpServer(
            String ifaceName, Looper looper, int interfaceType, SharedLog log,
            INetworkManagementService nMService, INetworkStatsService statsService,
            Callback callback, boolean usingLegacyDhcp, Dependencies deps) {
            INetd netd, INetworkStatsService statsService, Callback callback,
            boolean usingLegacyDhcp, Dependencies deps) {
        super(ifaceName, looper);
        mLog = log.forSubComponent(ifaceName);
        mNMService = nMService;
        mNetd = deps.getNetdService();
        mNetd = netd;
        mStatsService = statsService;
        mCallback = callback;
        mInterfaceCtrl = new InterfaceController(ifaceName, mNetd, mLog);
@@ -347,7 +341,7 @@ public class IpServer extends StateMachine {
                        }
                    });
                } catch (RemoteException e) {
                    e.rethrowFromSystemServer();
                    throw new IllegalStateException(e);
                }
            });
        }
@@ -395,7 +389,8 @@ public class IpServer extends StateMachine {
                });
                mDhcpServer = null;
            } catch (RemoteException e) {
                e.rethrowFromSystemServer();
                mLog.e("Error stopping DHCP", e);
                // Not much more we can do here
            }
        }
    }
@@ -414,85 +409,69 @@ public class IpServer extends StateMachine {
        // NOTE: All of configureIPv4() will be refactored out of existence
        // into calls to InterfaceController, shared with startIPv4().
        mInterfaceCtrl.clearIPv4Address();
        mIpv4Address = null;
    }

    // TODO: Refactor this in terms of calls to InterfaceController.
    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;
        final Inet4Address srvAddr;
        int prefixLen = 0;
        try {
            if (mInterfaceType == ConnectivityManager.TETHERING_USB) {
            ipAsString = USB_NEAR_IFACE_ADDR;
                srvAddr = (Inet4Address) parseNumericAddress(USB_NEAR_IFACE_ADDR);
                prefixLen = USB_PREFIX_LENGTH;
            } else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {
            ipAsString = getRandomWifiIPv4Address();
                srvAddr = (Inet4Address) parseNumericAddress(getRandomWifiIPv4Address());
                prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH;
            } else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI_P2P) {
            ipAsString = WIFI_P2P_IFACE_ADDR;
                srvAddr = (Inet4Address) parseNumericAddress(WIFI_P2P_IFACE_ADDR);
                prefixLen = WIFI_P2P_IFACE_PREFIX_LENGTH;
            } else {
                // BT configures the interface elsewhere: only start DHCP.
            final Inet4Address srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR);
                // TODO: make all tethering types behave the same way, and delete the bluetooth
                // code that calls into NetworkManagementService directly.
                srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR);
                mIpv4Address = new LinkAddress(srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
                return configureDhcp(enabled, srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
            }

        final LinkAddress linkAddr;
        try {
            final InterfaceConfiguration ifcg = mNMService.getInterfaceConfig(mIfaceName);
            if (ifcg == null) {
                mLog.e("Received null interface config");
            mIpv4Address = new LinkAddress(srvAddr, prefixLen);
        } catch (IllegalArgumentException e) {
            mLog.e("Error selecting ipv4 address", e);
            if (!enabled) stopDhcp();
            return false;
        }

            InetAddress addr = parseNumericAddress(ipAsString);
            linkAddr = new LinkAddress(addr, prefixLen);
            ifcg.setLinkAddress(linkAddr);
        final Boolean setIfaceUp;
        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
            // state.
                ifcg.ignoreInterfaceUpDownStatus();
            } else {
                if (enabled) {
                    ifcg.setInterfaceUp();
            setIfaceUp = null;
        } else {
                    ifcg.setInterfaceDown();
            setIfaceUp = enabled;
        }
            }
            ifcg.clearFlag("running");

            // TODO: this may throw if the interface is already gone. Do proper handling and
            // simplify the DHCP server start/stop.
            mNMService.setInterfaceConfig(mIfaceName, ifcg);

            if (!configureDhcp(enabled, (Inet4Address) addr, prefixLen)) {
        if (!mInterfaceCtrl.setInterfaceConfiguration(mIpv4Address, setIfaceUp)) {
            mLog.e("Error configuring interface");
            if (!enabled) stopDhcp();
            return false;
        }
        } catch (Exception e) {
            mLog.e("Error configuring interface " + e);
            if (!enabled) {
                try {
                    // Calling stopDhcp several times is fine
                    stopDhcp();
                } catch (Exception dhcpError) {
                    mLog.e("Error stopping DHCP", dhcpError);
                }
            }

        if (!configureDhcp(enabled, srvAddr, prefixLen)) {
            return false;
        }

        // Directly-connected route.
        final IpPrefix ipv4Prefix = new IpPrefix(linkAddr.getAddress(),
                linkAddr.getPrefixLength());
        final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(),
                mIpv4Address.getPrefixLength());
        final RouteInfo route = new RouteInfo(ipv4Prefix, null, null, RTN_UNICAST);
        if (enabled) {
            mLinkProperties.addLinkAddress(linkAddr);
            mLinkProperties.addLinkAddress(mIpv4Address);
            mLinkProperties.addRoute(route);
        } else {
            mLinkProperties.removeLinkAddress(linkAddr);
            mLinkProperties.removeLinkAddress(mIpv4Address);
            mLinkProperties.removeRoute(route);
        }
        return true;
@@ -584,15 +563,13 @@ public class IpServer extends StateMachine {
        if (!deprecatedPrefixes.isEmpty()) {
            final ArrayList<RouteInfo> toBeRemoved =
                    getLocalRoutesFor(mIfaceName, deprecatedPrefixes);
            try {
                final int removalFailures = mNMService.removeRoutesFromLocalNetwork(toBeRemoved);
            // Remove routes from local network.
            final int removalFailures = RouteUtils.removeRoutesFromLocalNetwork(
                    mNetd, toBeRemoved);
            if (removalFailures > 0) {
                mLog.e(String.format("Failed to remove %d IPv6 routes from local table.",
                        removalFailures));
            }
            } catch (RemoteException e) {
                mLog.e("Failed to remove IPv6 routes from local table: " + e);
            }

            for (RouteInfo route : toBeRemoved) mLinkProperties.removeRoute(route);
        }
@@ -608,14 +585,19 @@ public class IpServer extends StateMachine {
                final ArrayList<RouteInfo> toBeAdded =
                        getLocalRoutesFor(mIfaceName, addedPrefixes);
                try {
                    // It's safe to call addInterfaceToLocalNetwork() even if
                    // the interface is already in the local_network. Note also
                    // that adding routes that already exist does not cause an
                    // error (EEXIST is silently ignored).
                    mNMService.addInterfaceToLocalNetwork(mIfaceName, toBeAdded);
                } catch (Exception e) {
                    // It's safe to call networkAddInterface() even if
                    // the interface is already in the local_network.
                    mNetd.networkAddInterface(INetd.LOCAL_NET_ID, mIfaceName);
                    try {
                        // Add routes from local network. Note that adding routes that
                        // already exist does not cause an error (EEXIST is silently ignored).
                        RouteUtils.addRoutesToLocalNetwork(mNetd, mIfaceName, toBeAdded);
                    } catch (IllegalStateException e) {
                        mLog.e("Failed to add IPv6 routes to local table: " + e);
                    }
                } catch (ServiceSpecificException | RemoteException e) {
                    mLog.e("Failed to add " + mIfaceName + " to local table: ", e);
                }

                for (RouteInfo route : toBeAdded) mLinkProperties.addRoute(route);
            }
@@ -762,8 +744,10 @@ public class IpServer extends StateMachine {
            }

            try {
                mNMService.tetherInterface(mIfaceName);
            } catch (Exception e) {
                final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(),
                        mIpv4Address.getPrefixLength());
                NetdUtils.tetherInterface(mNetd, mIfaceName, ipv4Prefix);
            } catch (RemoteException | ServiceSpecificException e) {
                mLog.e("Error Tethering: " + e);
                mLastError = ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR;
                return;
@@ -784,8 +768,8 @@ public class IpServer extends StateMachine {
            stopIPv6();

            try {
                mNMService.untetherInterface(mIfaceName);
            } catch (Exception e) {
                NetdUtils.untetherInterface(mNetd, mIfaceName);
            } catch (RemoteException | ServiceSpecificException e) {
                mLastError = ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
                mLog.e("Failed to untether interface: " + e);
            }
@@ -901,17 +885,17 @@ public class IpServer extends StateMachine {
                // About to tear down NAT; gather remaining statistics.
                mStatsService.forceUpdate();
            } catch (Exception e) {
                if (VDBG) Log.e(TAG, "Exception in forceUpdate: " + e.toString());
                mLog.e("Exception in forceUpdate: " + e.toString());
            }
            try {
                mNMService.stopInterfaceForwarding(mIfaceName, upstreamIface);
            } catch (Exception e) {
                if (VDBG) Log.e(TAG, "Exception in removeInterfaceForward: " + e.toString());
                mNetd.ipfwdRemoveInterfaceForward(mIfaceName, upstreamIface);
            } catch (RemoteException | ServiceSpecificException e) {
                mLog.e("Exception in ipfwdRemoveInterfaceForward: " + e.toString());
            }
            try {
                mNMService.disableNat(mIfaceName, upstreamIface);
            } catch (Exception e) {
                if (VDBG) Log.e(TAG, "Exception in disableNat: " + e.toString());
                mNetd.tetherRemoveForward(mIfaceName, upstreamIface);
            } catch (RemoteException | ServiceSpecificException e) {
                mLog.e("Exception in disableNat: " + e.toString());
            }
        }

@@ -947,10 +931,10 @@ public class IpServer extends StateMachine {

                    for (String ifname : added) {
                        try {
                            mNMService.enableNat(mIfaceName, ifname);
                            mNMService.startInterfaceForwarding(mIfaceName, ifname);
                        } catch (Exception e) {
                            mLog.e("Exception enabling NAT: " + e);
                            mNetd.tetherAddForward(mIfaceName, ifname);
                            mNetd.ipfwdAddInterfaceForward(mIfaceName, ifname);
                        } catch (RemoteException | ServiceSpecificException e) {
                            mLog.e("Exception enabling NAT: " + e.toString());
                            cleanupUpstream();
                            mLastError = ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR;
                            transitionTo(mInitialState);
+39 −37
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ import android.net.NetworkUtils;
import android.net.TetherStatesParcel;
import android.net.TetheringConfigurationParcel;
import android.net.ip.IpServer;
import android.net.shared.NetdUtils;
import android.net.util.BaseNetdUnsolicitedEventListener;
import android.net.util.InterfaceSet;
import android.net.util.PrefixUtils;
@@ -87,12 +88,12 @@ import android.net.wifi.p2p.WifiP2pManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceSpecificException;
import android.os.UserHandle;
import android.os.UserManager;
import android.telephony.PhoneStateListener;
@@ -102,6 +103,9 @@ import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
@@ -139,6 +143,8 @@ public class Tethering {
    };
    private static final SparseArray<String> sMagicDecoderRing =
            MessageUtils.findMessageNames(sMessageClasses);
    // Keep in sync with NETID_UNSET in system/netd/include/netid_client.h
    private static final int NETID_UNSET = 0;

    private static class TetherState {
        public final IpServer ipServer;
@@ -172,8 +178,6 @@ public class Tethering {
    private final Context mContext;
    private final ArrayMap<String, TetherState> mTetherStates;
    private final BroadcastReceiver mStateReceiver;
    // Stopship: replace mNMService before production.
    private final INetworkManagementService mNMService;
    private final INetworkStatsService mStatsService;
    private final INetworkPolicyManager mPolicyManager;
    private final Looper mLooper;
@@ -210,7 +214,6 @@ public class Tethering {
        mLog.mark("Tethering.constructed");
        mDeps = deps;
        mContext = mDeps.getContext();
        mNMService = mDeps.getINetworkManagementService();
        mStatsService = mDeps.getINetworkStatsService();
        mPolicyManager = mDeps.getINetworkPolicyManager();
        mNetd = mDeps.getINetd(mContext);
@@ -225,10 +228,9 @@ public class Tethering {

        mHandler = mTetherMasterSM.getHandler();
        mOffloadController = new OffloadController(mHandler,
                mDeps.getOffloadHardwareInterface(mHandler, mLog),
                mContext.getContentResolver(), mNMService,
                mLog);
        mUpstreamNetworkMonitor = deps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
                mDeps.getOffloadHardwareInterface(mHandler, mLog), mContext.getContentResolver(),
                mDeps.getINetworkManagementService(), mLog);
        mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
                TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
        mForwardedDownstreams = new HashSet<>();

@@ -421,7 +423,6 @@ public class Tethering {
        }
    }


    void interfaceRemoved(String iface) {
        if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
        synchronized (mPublicSync) {
@@ -1022,8 +1023,8 @@ public class Tethering {

        String[] ifaces = null;
        try {
            ifaces = mNMService.listInterfaces();
        } catch (Exception e) {
            ifaces = mNetd.interfaceGetList();
        } catch (RemoteException | ServiceSpecificException e) {
            Log.e(TAG, "Error listing Interfaces", e);
            return;
        }
@@ -1282,25 +1283,25 @@ public class Tethering {
        protected boolean turnOnMasterTetherSettings() {
            final TetheringConfiguration cfg = mConfig;
            try {
                mNMService.setIpForwardingEnabled(true);
            } catch (Exception e) {
                mNetd.ipfwdEnableForwarding(TAG);
            } catch (RemoteException | ServiceSpecificException e) {
                mLog.e(e);
                transitionTo(mSetIpForwardingEnabledErrorState);
                return false;
            }

            // TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
            // Legacy DHCP server is disabled if passed an empty ranges array
            final String[] dhcpRanges = cfg.enableLegacyDhcpServer
                    ? cfg.legacyDhcpRanges
                    : new String[0];
                    ? cfg.legacyDhcpRanges : new String[0];
            try {
                // TODO: Find a more accurate method name (startDHCPv4()?).
                mNMService.startTethering(dhcpRanges);
            } catch (Exception e) {
                NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
            } catch (RemoteException | ServiceSpecificException e) {
                try {
                    mNMService.stopTethering();
                    mNMService.startTethering(dhcpRanges);
                } catch (Exception ee) {
                    // Stop and retry.
                    mNetd.tetherStop();
                    NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
                } catch (RemoteException | ServiceSpecificException ee) {
                    mLog.e(ee);
                    transitionTo(mStartTetheringErrorState);
                    return false;
@@ -1312,15 +1313,15 @@ public class Tethering {

        protected boolean turnOffMasterTetherSettings() {
            try {
                mNMService.stopTethering();
            } catch (Exception e) {
                mNetd.tetherStop();
            } catch (RemoteException | ServiceSpecificException e) {
                mLog.e(e);
                transitionTo(mStopTetheringErrorState);
                return false;
            }
            try {
                mNMService.setIpForwardingEnabled(false);
            } catch (Exception e) {
                mNetd.ipfwdDisableForwarding(TAG);
            } catch (RemoteException | ServiceSpecificException e) {
                mLog.e(e);
                transitionTo(mSetIpForwardingDisabledErrorState);
                return false;
@@ -1390,12 +1391,13 @@ public class Tethering {
                // TODO: remove this invocation of NetworkUtils.makeStrings().
                dnsServers = NetworkUtils.makeStrings(dnses);
            }
            final int netId = (network != null) ? network.netId : NETID_UNSET;
            try {
                mNMService.setDnsForwarders(network, dnsServers);
                mNetd.tetherDnsSet(netId, dnsServers);
                mLog.log(String.format(
                        "SET DNS forwarders: network=%s dnsServers=%s",
                        network, Arrays.toString(dnsServers)));
            } catch (Exception e) {
            } catch (RemoteException | ServiceSpecificException e) {
                // TODO: Investigate how this can fail and what exactly
                // happens if/when such failures occur.
                mLog.e("setting DNS forwarders failed, " + e);
@@ -1698,8 +1700,8 @@ public class Tethering {
                Log.e(TAG, "Error in startTethering");
                notify(IpServer.CMD_START_TETHERING_ERROR);
                try {
                    mNMService.setIpForwardingEnabled(false);
                } catch (Exception e) { }
                    mNetd.ipfwdDisableForwarding(TAG);
                } catch (RemoteException | ServiceSpecificException e) { }
            }
        }

@@ -1709,8 +1711,8 @@ public class Tethering {
                Log.e(TAG, "Error in stopTethering");
                notify(IpServer.CMD_STOP_TETHERING_ERROR);
                try {
                    mNMService.setIpForwardingEnabled(false);
                } catch (Exception e) { }
                    mNetd.ipfwdDisableForwarding(TAG);
                } catch (RemoteException | ServiceSpecificException e) { }
            }
        }

@@ -1720,11 +1722,11 @@ public class Tethering {
                Log.e(TAG, "Error in setDnsForwarders");
                notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR);
                try {
                    mNMService.stopTethering();
                } catch (Exception e) { }
                    mNetd.tetherStop();
                } catch (RemoteException | ServiceSpecificException e) { }
                try {
                    mNMService.setIpForwardingEnabled(false);
                } catch (Exception e) { }
                    mNetd.ipfwdDisableForwarding(TAG);
                } catch (RemoteException | ServiceSpecificException e) { }
            }
        }

@@ -1884,7 +1886,7 @@ public class Tethering {
        }
    }

    void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
    void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
        // Binder.java closes the resource for us.
        @SuppressWarnings("resource")
        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
@@ -2065,7 +2067,7 @@ public class Tethering {

        mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
        final TetherState tetherState = new TetherState(
                new IpServer(iface, mLooper, interfaceType, mLog, mNMService, mStatsService,
                new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mStatsService,
                             makeControlCallback(), mConfig.enableLegacyDhcpServer,
                             mDeps.getIpServerDependencies()));
        mTetherStates.put(iface, tetherState);
+110 −80

File changed.

Preview size limit exceeded, changes collapsed.

+103 −106

File changed.

Preview size limit exceeded, changes collapsed.

Loading