Update underlying network of IpSecTunnelInterface

Bug: 169855650
Test: atest IpSecManagerTunnelTest
Change-Id: I6d1b8d0e49f89c67ddc2caf4ba63fb0b1eb062c0
This commit is contained in:
Yan Yan
2020-09-29 23:38:00 -07:00
parent 5e1ec81e2f
commit a2f3b49f10
3 changed files with 90 additions and 4 deletions

View File

@@ -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