Merge changes Ifc8ad902,I6d1b8d0e am: 8d659bb1ec am: 488687d11f am: e669fe43cd
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1453730 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I6f3235dd38e4c4912f986cbb27867ff14fe38e81
This commit is contained in:
@@ -58,6 +58,9 @@ interface IIpSecService
|
||||
in LinkAddress localAddr,
|
||||
in String callingPackage);
|
||||
|
||||
void setNetworkForTunnelInterface(
|
||||
int tunnelResourceId, in Network underlyingNetwork, in String callingPackage);
|
||||
|
||||
void deleteTunnelInterface(int resourceId, in String callingPackage);
|
||||
|
||||
IpSecTransformResponse createTransform(
|
||||
|
||||
@@ -782,6 +782,42 @@ public final class IpSecManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the underlying network for this IpSecTunnelInterface.
|
||||
*
|
||||
* <p>This new underlying network will be used for all transforms applied AFTER this call is
|
||||
* complete. Before new {@link IpSecTransform}(s) with matching addresses are applied to
|
||||
* this tunnel interface, traffic will still use the old SA, and be routed on the old
|
||||
* underlying network.
|
||||
*
|
||||
* <p>To migrate IPsec tunnel mode traffic, a caller should:
|
||||
*
|
||||
* <ol>
|
||||
* <li>Update the IpSecTunnelInterface’s underlying network.
|
||||
* <li>Apply {@link IpSecTransform}(s) with matching addresses to this
|
||||
* IpSecTunnelInterface.
|
||||
* </ol>
|
||||
*
|
||||
* @param underlyingNetwork the new {@link Network} that will carry traffic for this tunnel.
|
||||
* This network MUST never be the network exposing this IpSecTunnelInterface, otherwise
|
||||
* this method will throw an {@link IllegalArgumentException}.
|
||||
*/
|
||||
// TODO: b/169171001 Update the documentation when transform migration is supported.
|
||||
// The purpose of making updating network and applying transforms separate is to leave open
|
||||
// the possibility to support lossless migration procedures. To do that, Android platform
|
||||
// will need to support multiple inbound tunnel mode transforms, just like it can support
|
||||
// multiple transport mode transforms.
|
||||
@RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
|
||||
@RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
|
||||
public void setUnderlyingNetwork(@NonNull Network underlyingNetwork) throws IOException {
|
||||
try {
|
||||
mService.setNetworkForTunnelInterface(
|
||||
mResourceId, underlyingNetwork, mOpPackageName);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
private IpSecTunnelInterface(@NonNull Context ctx, @NonNull IIpSecService service,
|
||||
@NonNull InetAddress localAddress, @NonNull InetAddress remoteAddress,
|
||||
@NonNull Network underlyingNetwork)
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.annotation.NonNull;
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.IIpSecService;
|
||||
import android.net.INetd;
|
||||
import android.net.InetAddresses;
|
||||
@@ -41,6 +42,7 @@ import android.net.IpSecTransformResponse;
|
||||
import android.net.IpSecTunnelInterfaceResponse;
|
||||
import android.net.IpSecUdpEncapResponse;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.TrafficStats;
|
||||
import android.net.util.NetdService;
|
||||
@@ -797,9 +799,15 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private final class TunnelInterfaceRecord extends OwnedResourceRecord {
|
||||
/**
|
||||
* Tracks an tunnel interface, and manages cleanup paths.
|
||||
*
|
||||
* <p>This class is not thread-safe, and expects that that users of this class will ensure
|
||||
* synchronization and thread safety by holding the IpSecService.this instance lock
|
||||
*/
|
||||
@VisibleForTesting
|
||||
final class TunnelInterfaceRecord extends OwnedResourceRecord {
|
||||
private final String mInterfaceName;
|
||||
private final Network mUnderlyingNetwork;
|
||||
|
||||
// outer addresses
|
||||
private final String mLocalAddress;
|
||||
@@ -810,6 +818,8 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
|
||||
private final int mIfId;
|
||||
|
||||
private Network mUnderlyingNetwork;
|
||||
|
||||
TunnelInterfaceRecord(
|
||||
int resourceId,
|
||||
String interfaceName,
|
||||
@@ -870,14 +880,22 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
releaseNetId(mOkey);
|
||||
}
|
||||
|
||||
public String getInterfaceName() {
|
||||
return mInterfaceName;
|
||||
@GuardedBy("IpSecService.this")
|
||||
public void setUnderlyingNetwork(Network underlyingNetwork) {
|
||||
// When #applyTunnelModeTransform is called, this new underlying network will be used to
|
||||
// update the output mark of the input transform.
|
||||
mUnderlyingNetwork = underlyingNetwork;
|
||||
}
|
||||
|
||||
@GuardedBy("IpSecService.this")
|
||||
public Network getUnderlyingNetwork() {
|
||||
return mUnderlyingNetwork;
|
||||
}
|
||||
|
||||
public String getInterfaceName() {
|
||||
return mInterfaceName;
|
||||
}
|
||||
|
||||
/** Returns the local, outer address for the tunnelInterface */
|
||||
public String getLocalAddress() {
|
||||
return mLocalAddress;
|
||||
@@ -1429,6 +1447,34 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/** Set TunnelInterface to use a specific underlying network. */
|
||||
@Override
|
||||
public synchronized void setNetworkForTunnelInterface(
|
||||
int tunnelResourceId, Network underlyingNetwork, String callingPackage) {
|
||||
enforceTunnelFeatureAndPermissions(callingPackage);
|
||||
Objects.requireNonNull(underlyingNetwork, "No underlying network was specified");
|
||||
|
||||
final UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
|
||||
|
||||
// Get tunnelInterface record; if no such interface is found, will throw
|
||||
// IllegalArgumentException. userRecord.mTunnelInterfaceRecords is never null
|
||||
final TunnelInterfaceRecord tunnelInterfaceInfo =
|
||||
userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
|
||||
|
||||
final ConnectivityManager connectivityManager =
|
||||
mContext.getSystemService(ConnectivityManager.class);
|
||||
final LinkProperties lp = connectivityManager.getLinkProperties(underlyingNetwork);
|
||||
if (tunnelInterfaceInfo.getInterfaceName().equals(lp.getInterfaceName())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Underlying network cannot be the network being exposed by this tunnel");
|
||||
}
|
||||
|
||||
// It is meaningless to check if the network exists or is valid because the network might
|
||||
// disconnect at any time after it passes the check.
|
||||
|
||||
tunnelInterfaceInfo.setUnderlyingNetwork(underlyingNetwork);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a TunnelInterface that has been been allocated by and registered with the system
|
||||
* server
|
||||
|
||||
Reference in New Issue
Block a user