Merge changes from topic "xfrmi-support"
am: f928c1e4b9 Change-Id: I9b76a58ab9ebdb9abb01216e8b3916f1f52f9267
This commit is contained in:
@@ -65,10 +65,13 @@ public final class IpSecConfig implements Parcelable {
|
||||
// An interval, in seconds between the NattKeepalive packets
|
||||
private int mNattKeepaliveInterval;
|
||||
|
||||
// XFRM mark and mask
|
||||
// XFRM mark and mask; defaults to 0 (no mark/mask)
|
||||
private int mMarkValue;
|
||||
private int mMarkMask;
|
||||
|
||||
// XFRM interface id
|
||||
private int mXfrmInterfaceId;
|
||||
|
||||
/** Set the mode for this IPsec transform */
|
||||
public void setMode(int mode) {
|
||||
mMode = mode;
|
||||
@@ -125,14 +128,30 @@ public final class IpSecConfig implements Parcelable {
|
||||
mNattKeepaliveInterval = interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mark value
|
||||
*
|
||||
* <p>Internal (System server) use only. Marks passed in by users will be overwritten or
|
||||
* ignored.
|
||||
*/
|
||||
public void setMarkValue(int mark) {
|
||||
mMarkValue = mark;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mark mask
|
||||
*
|
||||
* <p>Internal (System server) use only. Marks passed in by users will be overwritten or
|
||||
* ignored.
|
||||
*/
|
||||
public void setMarkMask(int mask) {
|
||||
mMarkMask = mask;
|
||||
}
|
||||
|
||||
public void setXfrmInterfaceId(int xfrmInterfaceId) {
|
||||
mXfrmInterfaceId = xfrmInterfaceId;
|
||||
}
|
||||
|
||||
// Transport or Tunnel
|
||||
public int getMode() {
|
||||
return mMode;
|
||||
@@ -190,6 +209,10 @@ public final class IpSecConfig implements Parcelable {
|
||||
return mMarkMask;
|
||||
}
|
||||
|
||||
public int getXfrmInterfaceId() {
|
||||
return mXfrmInterfaceId;
|
||||
}
|
||||
|
||||
// Parcelable Methods
|
||||
|
||||
@Override
|
||||
@@ -213,6 +236,7 @@ public final class IpSecConfig implements Parcelable {
|
||||
out.writeInt(mNattKeepaliveInterval);
|
||||
out.writeInt(mMarkValue);
|
||||
out.writeInt(mMarkMask);
|
||||
out.writeInt(mXfrmInterfaceId);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -235,6 +259,7 @@ public final class IpSecConfig implements Parcelable {
|
||||
mNattKeepaliveInterval = c.mNattKeepaliveInterval;
|
||||
mMarkValue = c.mMarkValue;
|
||||
mMarkMask = c.mMarkMask;
|
||||
mXfrmInterfaceId = c.mXfrmInterfaceId;
|
||||
}
|
||||
|
||||
private IpSecConfig(Parcel in) {
|
||||
@@ -255,6 +280,7 @@ public final class IpSecConfig implements Parcelable {
|
||||
mNattKeepaliveInterval = in.readInt();
|
||||
mMarkValue = in.readInt();
|
||||
mMarkMask = in.readInt();
|
||||
mXfrmInterfaceId = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -289,6 +315,8 @@ public final class IpSecConfig implements Parcelable {
|
||||
.append(mMarkValue)
|
||||
.append(", mMarkMask=")
|
||||
.append(mMarkMask)
|
||||
.append(", mXfrmInterfaceId=")
|
||||
.append(mXfrmInterfaceId)
|
||||
.append("}");
|
||||
|
||||
return strBuilder.toString();
|
||||
@@ -320,10 +348,10 @@ public final class IpSecConfig implements Parcelable {
|
||||
&& lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
|
||||
&& lhs.mSpiResourceId == rhs.mSpiResourceId
|
||||
&& IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption)
|
||||
&& IpSecAlgorithm.equals(
|
||||
lhs.mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
|
||||
&& IpSecAlgorithm.equals(lhs.mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
|
||||
&& IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication)
|
||||
&& lhs.mMarkValue == rhs.mMarkValue
|
||||
&& lhs.mMarkMask == rhs.mMarkMask);
|
||||
&& lhs.mMarkMask == rhs.mMarkMask
|
||||
&& lhs.mXfrmInterfaceId == rhs.mXfrmInterfaceId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import static android.system.OsConstants.AF_UNSPEC;
|
||||
import static android.system.OsConstants.EINVAL;
|
||||
import static android.system.OsConstants.IPPROTO_UDP;
|
||||
import static android.system.OsConstants.SOCK_DGRAM;
|
||||
|
||||
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
@@ -62,6 +63,8 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
@@ -73,8 +76,6 @@ import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
/**
|
||||
* A service to manage multiple clients that want to access the IpSec API. The service is
|
||||
* responsible for maintaining a list of clients and managing the resources (and related quotas)
|
||||
@@ -621,7 +622,8 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
mConfig.getDestinationAddress(),
|
||||
spi,
|
||||
mConfig.getMarkValue(),
|
||||
mConfig.getMarkMask());
|
||||
mConfig.getMarkMask(),
|
||||
mConfig.getXfrmInterfaceId());
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
Log.e(TAG, "Failed to delete SA with ID: " + mResourceId, e);
|
||||
}
|
||||
@@ -683,7 +685,8 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
mSrvConfig
|
||||
.getNetdInstance()
|
||||
.ipSecDeleteSecurityAssociation(
|
||||
uid, mSourceAddress, mDestinationAddress, mSpi, 0, 0);
|
||||
uid, mSourceAddress, mDestinationAddress, mSpi, 0 /* mark */,
|
||||
0 /* mask */, 0 /* if_id */);
|
||||
}
|
||||
} catch (ServiceSpecificException | RemoteException e) {
|
||||
Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e);
|
||||
@@ -795,6 +798,8 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
private final int mIkey;
|
||||
private final int mOkey;
|
||||
|
||||
private final int mIfId;
|
||||
|
||||
TunnelInterfaceRecord(
|
||||
int resourceId,
|
||||
String interfaceName,
|
||||
@@ -802,7 +807,8 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
String localAddr,
|
||||
String remoteAddr,
|
||||
int ikey,
|
||||
int okey) {
|
||||
int okey,
|
||||
int intfId) {
|
||||
super(resourceId);
|
||||
|
||||
mInterfaceName = interfaceName;
|
||||
@@ -811,6 +817,7 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
mRemoteAddress = remoteAddr;
|
||||
mIkey = ikey;
|
||||
mOkey = okey;
|
||||
mIfId = intfId;
|
||||
}
|
||||
|
||||
/** always guarded by IpSecService#this */
|
||||
@@ -821,7 +828,7 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
// Delete global policies
|
||||
try {
|
||||
final INetd netd = mSrvConfig.getNetdInstance();
|
||||
netd.removeVirtualTunnelInterface(mInterfaceName);
|
||||
netd.ipSecRemoveTunnelInterface(mInterfaceName);
|
||||
|
||||
for (int selAddrFamily : ADDRESS_FAMILIES) {
|
||||
netd.ipSecDeleteSecurityPolicy(
|
||||
@@ -829,13 +836,15 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
selAddrFamily,
|
||||
IpSecManager.DIRECTION_OUT,
|
||||
mOkey,
|
||||
0xffffffff);
|
||||
0xffffffff,
|
||||
mIfId);
|
||||
netd.ipSecDeleteSecurityPolicy(
|
||||
uid,
|
||||
selAddrFamily,
|
||||
IpSecManager.DIRECTION_IN,
|
||||
mIkey,
|
||||
0xffffffff);
|
||||
0xffffffff,
|
||||
mIfId);
|
||||
}
|
||||
} catch (ServiceSpecificException | RemoteException e) {
|
||||
Log.e(
|
||||
@@ -877,6 +886,10 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
return mOkey;
|
||||
}
|
||||
|
||||
public int getIfId() {
|
||||
return mIfId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceTracker getResourceTracker() {
|
||||
return getUserRecord().mTunnelQuotaTracker;
|
||||
@@ -1286,7 +1299,7 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
// Add inbound/outbound global policies
|
||||
// (use reqid = 0)
|
||||
final INetd netd = mSrvConfig.getNetdInstance();
|
||||
netd.addVirtualTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey);
|
||||
netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
|
||||
|
||||
for (int selAddrFamily : ADDRESS_FAMILIES) {
|
||||
// Always send down correct local/remote addresses for template.
|
||||
@@ -1298,7 +1311,8 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
remoteAddr,
|
||||
0,
|
||||
okey,
|
||||
0xffffffff);
|
||||
0xffffffff,
|
||||
resourceId);
|
||||
netd.ipSecAddSecurityPolicy(
|
||||
callerUid,
|
||||
selAddrFamily,
|
||||
@@ -1307,7 +1321,8 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
localAddr,
|
||||
0,
|
||||
ikey,
|
||||
0xffffffff);
|
||||
0xffffffff,
|
||||
resourceId);
|
||||
}
|
||||
|
||||
userRecord.mTunnelInterfaceRecords.put(
|
||||
@@ -1320,7 +1335,8 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
localAddr,
|
||||
remoteAddr,
|
||||
ikey,
|
||||
okey),
|
||||
okey,
|
||||
resourceId),
|
||||
binder));
|
||||
return new IpSecTunnelInterfaceResponse(IpSecManager.Status.OK, resourceId, intfName);
|
||||
} catch (RemoteException e) {
|
||||
@@ -1523,6 +1539,9 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid IpSecTransform.mode: " + config.getMode());
|
||||
}
|
||||
|
||||
config.setMarkValue(0);
|
||||
config.setMarkMask(0);
|
||||
}
|
||||
|
||||
private static final String TUNNEL_OP = AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS;
|
||||
@@ -1584,7 +1603,8 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
(authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0,
|
||||
encapType,
|
||||
encapLocalPort,
|
||||
encapRemotePort);
|
||||
encapRemotePort,
|
||||
c.getXfrmInterfaceId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1740,27 +1760,48 @@ public class IpSecService extends IIpSecService.Stub {
|
||||
: tunnelInterfaceInfo.getIkey();
|
||||
|
||||
try {
|
||||
c.setMarkValue(mark);
|
||||
c.setMarkMask(0xffffffff);
|
||||
// Default to using the invalid SPI of 0 for inbound SAs. This allows policies to skip
|
||||
// SPI matching as part of the template resolution.
|
||||
int spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
|
||||
c.setXfrmInterfaceId(tunnelInterfaceInfo.getIfId());
|
||||
|
||||
// TODO: enable this when UPDSA supports updating marks. Adding kernel support upstream
|
||||
// (and backporting) would allow us to narrow the mark space, and ensure that the SA
|
||||
// and SPs have matching marks (as VTI are meant to be built).
|
||||
// Currently update does nothing with marks. Leave empty (defaulting to 0) to ensure the
|
||||
// config matches the actual allocated resources in the kernel.
|
||||
// All SAs will have zero marks (from creation time), and any policy that matches the
|
||||
// same src/dst could match these SAs. Non-IpSecService governed processes that
|
||||
// establish floating policies with the same src/dst may result in undefined
|
||||
// behavior. This is generally limited to vendor code due to the permissions
|
||||
// (CAP_NET_ADMIN) required.
|
||||
//
|
||||
// c.setMarkValue(mark);
|
||||
// c.setMarkMask(0xffffffff);
|
||||
|
||||
if (direction == IpSecManager.DIRECTION_OUT) {
|
||||
// Set output mark via underlying network (output only)
|
||||
c.setNetwork(tunnelInterfaceInfo.getUnderlyingNetwork());
|
||||
|
||||
// If outbound, also add SPI to the policy.
|
||||
for (int selAddrFamily : ADDRESS_FAMILIES) {
|
||||
mSrvConfig
|
||||
.getNetdInstance()
|
||||
.ipSecUpdateSecurityPolicy(
|
||||
callingUid,
|
||||
selAddrFamily,
|
||||
direction,
|
||||
tunnelInterfaceInfo.getLocalAddress(),
|
||||
tunnelInterfaceInfo.getRemoteAddress(),
|
||||
transformInfo.getSpiRecord().getSpi(),
|
||||
mark,
|
||||
0xffffffff);
|
||||
}
|
||||
// Set outbound SPI only. We want inbound to use any valid SA (old, new) on rekeys,
|
||||
// but want to guarantee outbound packets are sent over the new SA.
|
||||
spi = transformInfo.getSpiRecord().getSpi();
|
||||
}
|
||||
|
||||
// Always update the policy with the relevant XFRM_IF_ID
|
||||
for (int selAddrFamily : ADDRESS_FAMILIES) {
|
||||
mSrvConfig
|
||||
.getNetdInstance()
|
||||
.ipSecUpdateSecurityPolicy(
|
||||
callingUid,
|
||||
selAddrFamily,
|
||||
direction,
|
||||
transformInfo.getConfig().getSourceAddress(),
|
||||
transformInfo.getConfig().getDestinationAddress(),
|
||||
spi, // If outbound, also add SPI to the policy.
|
||||
mark, // Must always set policy mark; ikey/okey for VTIs
|
||||
0xffffffff,
|
||||
c.getXfrmInterfaceId());
|
||||
}
|
||||
|
||||
// Update SA with tunnel mark (ikey or okey based on direction)
|
||||
|
||||
Reference in New Issue
Block a user