Framework changes for 464xlat.
1. Add a Nat464Xlat service that ConnectivityService can use to start and stop clat. When clat is started, the service waits for the clat interface to come up and then calls ConnectivityService to add the appropriate routes. 2. Make ConnectivityService start clat when an IPv6-only mobile interface is connected. We only support clat on mobile for now. 3. Make tethering use the interface that has the IPv4 default route insted of using the base interface of the LinkProperties. This allows us to tether to a stacked interface, which is needed for tethering with 464xlat. Bug: 8276725 Change-Id: I24480af69ee280f504399062638af0836a56268e
This commit is contained in:
@@ -96,6 +96,7 @@ import com.android.internal.telephony.Phone;
|
|||||||
import com.android.internal.telephony.PhoneConstants;
|
import com.android.internal.telephony.PhoneConstants;
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
import com.android.server.am.BatteryStatsService;
|
import com.android.server.am.BatteryStatsService;
|
||||||
|
import com.android.server.connectivity.Nat464Xlat;
|
||||||
import com.android.server.connectivity.Tethering;
|
import com.android.server.connectivity.Tethering;
|
||||||
import com.android.server.connectivity.Vpn;
|
import com.android.server.connectivity.Vpn;
|
||||||
import com.android.server.net.BaseNetworkObserver;
|
import com.android.server.net.BaseNetworkObserver;
|
||||||
@@ -154,6 +155,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
private boolean mLockdownEnabled;
|
private boolean mLockdownEnabled;
|
||||||
private LockdownVpnTracker mLockdownTracker;
|
private LockdownVpnTracker mLockdownTracker;
|
||||||
|
|
||||||
|
private Nat464Xlat mClat;
|
||||||
|
|
||||||
/** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
|
/** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
|
||||||
private Object mRulesLock = new Object();
|
private Object mRulesLock = new Object();
|
||||||
/** Currently active network rules by UID. */
|
/** Currently active network rules by UID. */
|
||||||
@@ -544,9 +547,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
mVpn = new Vpn(mContext, mVpnCallback, mNetd);
|
mVpn = new Vpn(mContext, mVpnCallback, mNetd);
|
||||||
mVpn.startMonitoring(mContext, mTrackerHandler);
|
mVpn.startMonitoring(mContext, mTrackerHandler);
|
||||||
|
|
||||||
|
mClat = new Nat464Xlat(mContext, mNetd, this, mTrackerHandler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mNetd.registerObserver(mTethering);
|
mNetd.registerObserver(mTethering);
|
||||||
mNetd.registerObserver(mDataActivityObserver);
|
mNetd.registerObserver(mDataActivityObserver);
|
||||||
|
mNetd.registerObserver(mClat);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
loge("Error registering observer :" + e);
|
loge("Error registering observer :" + e);
|
||||||
}
|
}
|
||||||
@@ -2276,6 +2282,17 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update 464xlat state.
|
||||||
|
// TODO: Move to handleConnect()
|
||||||
|
NetworkStateTracker tracker = mNetTrackers[netType];
|
||||||
|
if (mClat.requiresClat(netType, tracker)) {
|
||||||
|
if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
|
||||||
|
mClat.startClat(tracker);
|
||||||
|
} else {
|
||||||
|
mClat.stopClat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Temporary notifying upstread change to Tethering.
|
// TODO: Temporary notifying upstread change to Tethering.
|
||||||
// @see bug/4455071
|
// @see bug/4455071
|
||||||
/** Notify TetheringService if interface name has been changed. */
|
/** Notify TetheringService if interface name has been changed. */
|
||||||
|
|||||||
189
services/java/com/android/server/connectivity/Nat464Xlat.java
Normal file
189
services/java/com/android/server/connectivity/Nat464Xlat.java
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.server.connectivity;
|
||||||
|
|
||||||
|
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||||
|
|
||||||
|
import java.net.Inet4Address;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.IConnectivityManager;
|
||||||
|
import android.net.InterfaceConfiguration;
|
||||||
|
import android.net.LinkAddress;
|
||||||
|
import android.net.LinkProperties;
|
||||||
|
import android.net.NetworkStateTracker;
|
||||||
|
import android.net.NetworkUtils;
|
||||||
|
import android.net.RouteInfo;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.INetworkManagementService;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.util.Slog;
|
||||||
|
|
||||||
|
import com.android.server.net.BaseNetworkObserver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*
|
||||||
|
* Class to manage a 464xlat CLAT daemon.
|
||||||
|
*/
|
||||||
|
public class Nat464Xlat extends BaseNetworkObserver {
|
||||||
|
private Context mContext;
|
||||||
|
private INetworkManagementService mNMService;
|
||||||
|
private IConnectivityManager mConnService;
|
||||||
|
private NetworkStateTracker mTracker;
|
||||||
|
private Handler mHandler;
|
||||||
|
|
||||||
|
// Whether we started clatd and expect it to be running.
|
||||||
|
private boolean mIsStarted;
|
||||||
|
// Whether the clatd interface exists (i.e., clatd is running).
|
||||||
|
private boolean mIsRunning;
|
||||||
|
// The LinkProperties of the clat interface.
|
||||||
|
private LinkProperties mLP;
|
||||||
|
|
||||||
|
// This must match the interface name in clatd.conf.
|
||||||
|
private static final String CLAT_INTERFACE_NAME = "clat4";
|
||||||
|
|
||||||
|
private static final String TAG = "Nat464Xlat";
|
||||||
|
|
||||||
|
public Nat464Xlat(Context context, INetworkManagementService nmService,
|
||||||
|
IConnectivityManager connService, Handler handler) {
|
||||||
|
mContext = context;
|
||||||
|
mNMService = nmService;
|
||||||
|
mConnService = connService;
|
||||||
|
mHandler = handler;
|
||||||
|
|
||||||
|
mIsStarted = false;
|
||||||
|
mIsRunning = false;
|
||||||
|
mLP = new LinkProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether an interface requires clat.
|
||||||
|
* @param netType the network type (one of the
|
||||||
|
* android.net.ConnectivityManager.TYPE_* constants)
|
||||||
|
* @param tracker the NetworkStateTracker corresponding to the network type.
|
||||||
|
* @return true if the interface requires clat, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean requiresClat(int netType, NetworkStateTracker tracker) {
|
||||||
|
LinkProperties lp = tracker.getLinkProperties();
|
||||||
|
// Only support clat on mobile for now.
|
||||||
|
Slog.d(TAG, "requiresClat: netType=" + netType + ", hasIPv4Address=" +
|
||||||
|
lp.hasIPv4Address());
|
||||||
|
return netType == TYPE_MOBILE && !lp.hasIPv4Address();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the clat daemon.
|
||||||
|
* @param lp The link properties of the interface to start clatd on.
|
||||||
|
*/
|
||||||
|
public void startClat(NetworkStateTracker tracker) {
|
||||||
|
if (mIsStarted) {
|
||||||
|
Slog.e(TAG, "startClat: already started");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mTracker = tracker;
|
||||||
|
LinkProperties lp = mTracker.getLinkProperties();
|
||||||
|
String iface = lp.getInterfaceName();
|
||||||
|
Slog.i(TAG, "Starting clatd on " + iface + ", lp=" + lp);
|
||||||
|
try {
|
||||||
|
mNMService.startClatd(iface);
|
||||||
|
} catch(RemoteException e) {
|
||||||
|
Slog.e(TAG, "Error starting clat daemon: " + e);
|
||||||
|
}
|
||||||
|
mIsStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the clat daemon.
|
||||||
|
*/
|
||||||
|
public void stopClat() {
|
||||||
|
if (mIsStarted) {
|
||||||
|
Slog.i(TAG, "Stopping clatd");
|
||||||
|
try {
|
||||||
|
mNMService.stopClatd();
|
||||||
|
} catch(RemoteException e) {
|
||||||
|
Slog.e(TAG, "Error stopping clat daemon: " + e);
|
||||||
|
}
|
||||||
|
mIsStarted = false;
|
||||||
|
mIsRunning = false;
|
||||||
|
mTracker = null;
|
||||||
|
mLP.clear();
|
||||||
|
} else {
|
||||||
|
Slog.e(TAG, "stopClat: already stopped");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStarted() {
|
||||||
|
return mIsStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRunning() {
|
||||||
|
return mIsRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void interfaceAdded(String iface) {
|
||||||
|
if (iface.equals(CLAT_INTERFACE_NAME)) {
|
||||||
|
Slog.i(TAG, "interface " + CLAT_INTERFACE_NAME +
|
||||||
|
" added, mIsRunning = " + mIsRunning + " -> true");
|
||||||
|
mIsRunning = true;
|
||||||
|
|
||||||
|
// Get the network configuration of the clat interface, store it
|
||||||
|
// in our link properties, and stack it on top of the interface
|
||||||
|
// it's running on.
|
||||||
|
try {
|
||||||
|
InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
|
||||||
|
mLP.clear();
|
||||||
|
mLP.setInterfaceName(iface);
|
||||||
|
RouteInfo ipv4Default = new RouteInfo(new LinkAddress(Inet4Address.ANY, 0), null,
|
||||||
|
iface);
|
||||||
|
mLP.addRoute(ipv4Default);
|
||||||
|
mLP.addLinkAddress(config.getLinkAddress());
|
||||||
|
mTracker.addStackedLink(mLP);
|
||||||
|
Slog.i(TAG, "Adding stacked link. tracker LP: " +
|
||||||
|
mTracker.getLinkProperties());
|
||||||
|
} catch(RemoteException e) {
|
||||||
|
Slog.e(TAG, "Error getting link properties: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inform ConnectivityService that things have changed.
|
||||||
|
Message msg = mHandler.obtainMessage(
|
||||||
|
NetworkStateTracker.EVENT_CONFIGURATION_CHANGED,
|
||||||
|
mTracker.getNetworkInfo());
|
||||||
|
Slog.i(TAG, "sending message to ConnectivityService: " + msg);
|
||||||
|
msg.sendToTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void interfaceRemoved(String iface) {
|
||||||
|
if (iface == CLAT_INTERFACE_NAME) {
|
||||||
|
if (mIsRunning) {
|
||||||
|
NetworkUtils.resetConnections(
|
||||||
|
CLAT_INTERFACE_NAME,
|
||||||
|
NetworkUtils.RESET_IPV4_ADDRESSES);
|
||||||
|
}
|
||||||
|
Slog.i(TAG, "interface " + CLAT_INTERFACE_NAME +
|
||||||
|
" removed, mIsRunning = " + mIsRunning + " -> false");
|
||||||
|
mIsRunning = false;
|
||||||
|
mTracker.removeStackedLink(mLP);
|
||||||
|
mLP.clear();
|
||||||
|
Slog.i(TAG, "mLP = " + mLP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user