Add XFRM-I support to IpSecService
This change adds support for XFRM-I to all IpSecService netd calls. Fallback logic is in netd, and thus both VTI and XFRM-I parameters are always passed down to IpSecService. Bug: 78589502 Test: All java, CTS tests passing Change-Id: Ie4186f0ad7e50763b21831f6fa411b5ee436de78
This commit is contained in:
@@ -69,6 +69,9 @@ public final class IpSecConfig implements Parcelable {
|
|||||||
private int mMarkValue;
|
private int mMarkValue;
|
||||||
private int mMarkMask;
|
private int mMarkMask;
|
||||||
|
|
||||||
|
// XFRM interface id
|
||||||
|
private int mXfrmInterfaceId;
|
||||||
|
|
||||||
/** Set the mode for this IPsec transform */
|
/** Set the mode for this IPsec transform */
|
||||||
public void setMode(int mode) {
|
public void setMode(int mode) {
|
||||||
mMode = mode;
|
mMode = mode;
|
||||||
@@ -145,6 +148,10 @@ public final class IpSecConfig implements Parcelable {
|
|||||||
mMarkMask = mask;
|
mMarkMask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setXfrmInterfaceId(int xfrmInterfaceId) {
|
||||||
|
mXfrmInterfaceId = xfrmInterfaceId;
|
||||||
|
}
|
||||||
|
|
||||||
// Transport or Tunnel
|
// Transport or Tunnel
|
||||||
public int getMode() {
|
public int getMode() {
|
||||||
return mMode;
|
return mMode;
|
||||||
@@ -202,6 +209,10 @@ public final class IpSecConfig implements Parcelable {
|
|||||||
return mMarkMask;
|
return mMarkMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getXfrmInterfaceId() {
|
||||||
|
return mXfrmInterfaceId;
|
||||||
|
}
|
||||||
|
|
||||||
// Parcelable Methods
|
// Parcelable Methods
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -225,6 +236,7 @@ public final class IpSecConfig implements Parcelable {
|
|||||||
out.writeInt(mNattKeepaliveInterval);
|
out.writeInt(mNattKeepaliveInterval);
|
||||||
out.writeInt(mMarkValue);
|
out.writeInt(mMarkValue);
|
||||||
out.writeInt(mMarkMask);
|
out.writeInt(mMarkMask);
|
||||||
|
out.writeInt(mXfrmInterfaceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -247,6 +259,7 @@ public final class IpSecConfig implements Parcelable {
|
|||||||
mNattKeepaliveInterval = c.mNattKeepaliveInterval;
|
mNattKeepaliveInterval = c.mNattKeepaliveInterval;
|
||||||
mMarkValue = c.mMarkValue;
|
mMarkValue = c.mMarkValue;
|
||||||
mMarkMask = c.mMarkMask;
|
mMarkMask = c.mMarkMask;
|
||||||
|
mXfrmInterfaceId = c.mXfrmInterfaceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IpSecConfig(Parcel in) {
|
private IpSecConfig(Parcel in) {
|
||||||
@@ -267,6 +280,7 @@ public final class IpSecConfig implements Parcelable {
|
|||||||
mNattKeepaliveInterval = in.readInt();
|
mNattKeepaliveInterval = in.readInt();
|
||||||
mMarkValue = in.readInt();
|
mMarkValue = in.readInt();
|
||||||
mMarkMask = in.readInt();
|
mMarkMask = in.readInt();
|
||||||
|
mXfrmInterfaceId = in.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -301,6 +315,8 @@ public final class IpSecConfig implements Parcelable {
|
|||||||
.append(mMarkValue)
|
.append(mMarkValue)
|
||||||
.append(", mMarkMask=")
|
.append(", mMarkMask=")
|
||||||
.append(mMarkMask)
|
.append(mMarkMask)
|
||||||
|
.append(", mXfrmInterfaceId=")
|
||||||
|
.append(mXfrmInterfaceId)
|
||||||
.append("}");
|
.append("}");
|
||||||
|
|
||||||
return strBuilder.toString();
|
return strBuilder.toString();
|
||||||
@@ -332,10 +348,10 @@ public final class IpSecConfig implements Parcelable {
|
|||||||
&& lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
|
&& lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
|
||||||
&& lhs.mSpiResourceId == rhs.mSpiResourceId
|
&& lhs.mSpiResourceId == rhs.mSpiResourceId
|
||||||
&& IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption)
|
&& IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption)
|
||||||
&& IpSecAlgorithm.equals(
|
&& IpSecAlgorithm.equals(lhs.mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
|
||||||
lhs.mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
|
|
||||||
&& IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication)
|
&& IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication)
|
||||||
&& lhs.mMarkValue == rhs.mMarkValue
|
&& lhs.mMarkValue == rhs.mMarkValue
|
||||||
&& lhs.mMarkMask == rhs.mMarkMask);
|
&& lhs.mMarkMask == rhs.mMarkMask
|
||||||
|
&& lhs.mXfrmInterfaceId == rhs.mXfrmInterfaceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -622,7 +622,8 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
mConfig.getDestinationAddress(),
|
mConfig.getDestinationAddress(),
|
||||||
spi,
|
spi,
|
||||||
mConfig.getMarkValue(),
|
mConfig.getMarkValue(),
|
||||||
mConfig.getMarkMask());
|
mConfig.getMarkMask(),
|
||||||
|
mConfig.getXfrmInterfaceId());
|
||||||
} catch (RemoteException | ServiceSpecificException e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
Log.e(TAG, "Failed to delete SA with ID: " + mResourceId, e);
|
Log.e(TAG, "Failed to delete SA with ID: " + mResourceId, e);
|
||||||
}
|
}
|
||||||
@@ -684,7 +685,8 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
mSrvConfig
|
mSrvConfig
|
||||||
.getNetdInstance()
|
.getNetdInstance()
|
||||||
.ipSecDeleteSecurityAssociation(
|
.ipSecDeleteSecurityAssociation(
|
||||||
uid, mSourceAddress, mDestinationAddress, mSpi, 0, 0);
|
uid, mSourceAddress, mDestinationAddress, mSpi, 0 /* mark */,
|
||||||
|
0 /* mask */, 0 /* if_id */);
|
||||||
}
|
}
|
||||||
} catch (ServiceSpecificException | RemoteException e) {
|
} catch (ServiceSpecificException | RemoteException e) {
|
||||||
Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e);
|
Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e);
|
||||||
@@ -796,6 +798,8 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
private final int mIkey;
|
private final int mIkey;
|
||||||
private final int mOkey;
|
private final int mOkey;
|
||||||
|
|
||||||
|
private final int mIfId;
|
||||||
|
|
||||||
TunnelInterfaceRecord(
|
TunnelInterfaceRecord(
|
||||||
int resourceId,
|
int resourceId,
|
||||||
String interfaceName,
|
String interfaceName,
|
||||||
@@ -803,7 +807,8 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
String localAddr,
|
String localAddr,
|
||||||
String remoteAddr,
|
String remoteAddr,
|
||||||
int ikey,
|
int ikey,
|
||||||
int okey) {
|
int okey,
|
||||||
|
int intfId) {
|
||||||
super(resourceId);
|
super(resourceId);
|
||||||
|
|
||||||
mInterfaceName = interfaceName;
|
mInterfaceName = interfaceName;
|
||||||
@@ -812,6 +817,7 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
mRemoteAddress = remoteAddr;
|
mRemoteAddress = remoteAddr;
|
||||||
mIkey = ikey;
|
mIkey = ikey;
|
||||||
mOkey = okey;
|
mOkey = okey;
|
||||||
|
mIfId = intfId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** always guarded by IpSecService#this */
|
/** always guarded by IpSecService#this */
|
||||||
@@ -822,7 +828,7 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
// Delete global policies
|
// Delete global policies
|
||||||
try {
|
try {
|
||||||
final INetd netd = mSrvConfig.getNetdInstance();
|
final INetd netd = mSrvConfig.getNetdInstance();
|
||||||
netd.removeVirtualTunnelInterface(mInterfaceName);
|
netd.ipSecRemoveTunnelInterface(mInterfaceName);
|
||||||
|
|
||||||
for (int selAddrFamily : ADDRESS_FAMILIES) {
|
for (int selAddrFamily : ADDRESS_FAMILIES) {
|
||||||
netd.ipSecDeleteSecurityPolicy(
|
netd.ipSecDeleteSecurityPolicy(
|
||||||
@@ -830,13 +836,15 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
selAddrFamily,
|
selAddrFamily,
|
||||||
IpSecManager.DIRECTION_OUT,
|
IpSecManager.DIRECTION_OUT,
|
||||||
mOkey,
|
mOkey,
|
||||||
0xffffffff);
|
0xffffffff,
|
||||||
|
mIfId);
|
||||||
netd.ipSecDeleteSecurityPolicy(
|
netd.ipSecDeleteSecurityPolicy(
|
||||||
uid,
|
uid,
|
||||||
selAddrFamily,
|
selAddrFamily,
|
||||||
IpSecManager.DIRECTION_IN,
|
IpSecManager.DIRECTION_IN,
|
||||||
mIkey,
|
mIkey,
|
||||||
0xffffffff);
|
0xffffffff,
|
||||||
|
mIfId);
|
||||||
}
|
}
|
||||||
} catch (ServiceSpecificException | RemoteException e) {
|
} catch (ServiceSpecificException | RemoteException e) {
|
||||||
Log.e(
|
Log.e(
|
||||||
@@ -878,6 +886,10 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
return mOkey;
|
return mOkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getIfId() {
|
||||||
|
return mIfId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ResourceTracker getResourceTracker() {
|
protected ResourceTracker getResourceTracker() {
|
||||||
return getUserRecord().mTunnelQuotaTracker;
|
return getUserRecord().mTunnelQuotaTracker;
|
||||||
@@ -1287,7 +1299,7 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
// Add inbound/outbound global policies
|
// Add inbound/outbound global policies
|
||||||
// (use reqid = 0)
|
// (use reqid = 0)
|
||||||
final INetd netd = mSrvConfig.getNetdInstance();
|
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) {
|
for (int selAddrFamily : ADDRESS_FAMILIES) {
|
||||||
// Always send down correct local/remote addresses for template.
|
// Always send down correct local/remote addresses for template.
|
||||||
@@ -1299,7 +1311,8 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
remoteAddr,
|
remoteAddr,
|
||||||
0,
|
0,
|
||||||
okey,
|
okey,
|
||||||
0xffffffff);
|
0xffffffff,
|
||||||
|
resourceId);
|
||||||
netd.ipSecAddSecurityPolicy(
|
netd.ipSecAddSecurityPolicy(
|
||||||
callerUid,
|
callerUid,
|
||||||
selAddrFamily,
|
selAddrFamily,
|
||||||
@@ -1308,7 +1321,8 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
localAddr,
|
localAddr,
|
||||||
0,
|
0,
|
||||||
ikey,
|
ikey,
|
||||||
0xffffffff);
|
0xffffffff,
|
||||||
|
resourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
userRecord.mTunnelInterfaceRecords.put(
|
userRecord.mTunnelInterfaceRecords.put(
|
||||||
@@ -1321,7 +1335,8 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
localAddr,
|
localAddr,
|
||||||
remoteAddr,
|
remoteAddr,
|
||||||
ikey,
|
ikey,
|
||||||
okey),
|
okey,
|
||||||
|
resourceId),
|
||||||
binder));
|
binder));
|
||||||
return new IpSecTunnelInterfaceResponse(IpSecManager.Status.OK, resourceId, intfName);
|
return new IpSecTunnelInterfaceResponse(IpSecManager.Status.OK, resourceId, intfName);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -1588,7 +1603,8 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
(authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0,
|
(authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0,
|
||||||
encapType,
|
encapType,
|
||||||
encapLocalPort,
|
encapLocalPort,
|
||||||
encapRemotePort);
|
encapRemotePort,
|
||||||
|
c.getXfrmInterfaceId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1744,6 +1760,11 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
: tunnelInterfaceInfo.getIkey();
|
: tunnelInterfaceInfo.getIkey();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 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
|
// 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 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).
|
// and SPs have matching marks (as VTI are meant to be built).
|
||||||
@@ -1757,20 +1778,25 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
// Set output mark via underlying network (output only)
|
// Set output mark via underlying network (output only)
|
||||||
c.setNetwork(tunnelInterfaceInfo.getUnderlyingNetwork());
|
c.setNetwork(tunnelInterfaceInfo.getUnderlyingNetwork());
|
||||||
|
|
||||||
// If outbound, also add SPI to the policy.
|
// Set outbound SPI only. We want inbound to use any valid SA (old, new) on rekeys,
|
||||||
for (int selAddrFamily : ADDRESS_FAMILIES) {
|
// but want to guarantee outbound packets are sent over the new SA.
|
||||||
mSrvConfig
|
spi = transformInfo.getSpiRecord().getSpi();
|
||||||
.getNetdInstance()
|
}
|
||||||
.ipSecUpdateSecurityPolicy(
|
|
||||||
callingUid,
|
// Always update the policy with the relevant XFRM_IF_ID
|
||||||
selAddrFamily,
|
for (int selAddrFamily : ADDRESS_FAMILIES) {
|
||||||
direction,
|
mSrvConfig
|
||||||
tunnelInterfaceInfo.getLocalAddress(),
|
.getNetdInstance()
|
||||||
tunnelInterfaceInfo.getRemoteAddress(),
|
.ipSecUpdateSecurityPolicy(
|
||||||
transformInfo.getSpiRecord().getSpi(),
|
callingUid,
|
||||||
mark, // Must always set policy mark; ikey/okey for VTIs
|
selAddrFamily,
|
||||||
0xffffffff);
|
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)
|
// Update SA with tunnel mark (ikey or okey based on direction)
|
||||||
|
|||||||
Reference in New Issue
Block a user