Add XFRM-I support to XfrmController
This patch adds support for creating and managing XFRM interfaces,
adding xfrm_if_id parameters to all relevant netlink calls.
This is part of a patch set to enable XFRM-I support, with automatic
fallbacks to VTI in XfrmController (2/3)
Bug: 77856928
Test: Xfrm, Binder tests updated, passing
Change-Id: I09869e6a0000384c9c4d0aef1de4d5434c33374a
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index 7bcc392..7e1965b 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -759,46 +759,32 @@
}
binder::Status NetdNativeService::ipSecAddSecurityAssociation(
- int32_t transformId,
- int32_t mode,
- const std::string& sourceAddress,
- const std::string& destinationAddress,
- int32_t underlyingNetId,
- int32_t spi,
- int32_t markValue,
- int32_t markMask,
- const std::string& authAlgo, const std::vector<uint8_t>& authKey, int32_t authTruncBits,
- const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits,
- const std::string& aeadAlgo, const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits,
- int32_t encapType,
- int32_t encapLocalPort,
- int32_t encapRemotePort) {
+ int32_t transformId, int32_t mode, const std::string& sourceAddress,
+ const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi,
+ int32_t markValue, int32_t markMask, const std::string& authAlgo,
+ const std::vector<uint8_t>& authKey, int32_t authTruncBits, const std::string& cryptAlgo,
+ const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits, const std::string& aeadAlgo,
+ const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits, int32_t encapType,
+ int32_t encapLocalPort, int32_t encapRemotePort, int32_t interfaceId) {
// Necessary locking done in IpSecService and kernel
ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
gLog.log("ipSecAddSecurityAssociation()");
return asBinderStatus(gCtls->xfrmCtrl.ipSecAddSecurityAssociation(
transformId, mode, sourceAddress, destinationAddress, underlyingNetId, spi, markValue,
markMask, authAlgo, authKey, authTruncBits, cryptAlgo, cryptKey, cryptTruncBits,
- aeadAlgo, aeadKey, aeadIcvBits, encapType, encapLocalPort, encapRemotePort));
+ aeadAlgo, aeadKey, aeadIcvBits, encapType, encapLocalPort, encapRemotePort,
+ interfaceId));
}
binder::Status NetdNativeService::ipSecDeleteSecurityAssociation(
- int32_t transformId,
- const std::string& sourceAddress,
- const std::string& destinationAddress,
- int32_t spi,
- int32_t markValue,
- int32_t markMask) {
+ int32_t transformId, const std::string& sourceAddress,
+ const std::string& destinationAddress, int32_t spi, int32_t markValue, int32_t markMask,
+ int32_t interfaceId) {
// Necessary locking done in IpSecService and kernel
ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
gLog.log("ipSecDeleteSecurityAssociation()");
return asBinderStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityAssociation(
- transformId,
- sourceAddress,
- destinationAddress,
- spi,
- markValue,
- markMask));
+ transformId, sourceAddress, destinationAddress, spi, markValue, markMask, interfaceId));
}
binder::Status NetdNativeService::ipSecApplyTransportModeTransform(
@@ -834,51 +820,49 @@
const std::string& tmplSrcAddress,
const std::string& tmplDstAddress,
int32_t spi, int32_t markValue,
- int32_t markMask) {
+ int32_t markMask, int32_t interfaceId) {
// Necessary locking done in IpSecService and kernel
ENFORCE_PERMISSION(NETWORK_STACK);
gLog.log("ipSecAddSecurityPolicy()");
return asBinderStatus(gCtls->xfrmCtrl.ipSecAddSecurityPolicy(
transformId, selAddrFamily, direction, tmplSrcAddress, tmplDstAddress, spi, markValue,
- markMask));
+ markMask, interfaceId));
}
-binder::Status NetdNativeService::ipSecUpdateSecurityPolicy(int32_t transformId,
- int32_t selAddrFamily,
- int32_t direction,
- const std::string& tmplSrcAddress,
- const std::string& tmplDstAddress,
- int32_t spi, int32_t markValue,
- int32_t markMask) {
+binder::Status NetdNativeService::ipSecUpdateSecurityPolicy(
+ int32_t transformId, int32_t selAddrFamily, int32_t direction,
+ const std::string& tmplSrcAddress, const std::string& tmplDstAddress, int32_t spi,
+ int32_t markValue, int32_t markMask, int32_t interfaceId) {
// Necessary locking done in IpSecService and kernel
ENFORCE_PERMISSION(NETWORK_STACK);
gLog.log("ipSecAddSecurityPolicy()");
return asBinderStatus(gCtls->xfrmCtrl.ipSecUpdateSecurityPolicy(
transformId, selAddrFamily, direction, tmplSrcAddress, tmplDstAddress, spi, markValue,
- markMask));
+ markMask, interfaceId));
}
binder::Status NetdNativeService::ipSecDeleteSecurityPolicy(int32_t transformId,
int32_t selAddrFamily,
int32_t direction, int32_t markValue,
- int32_t markMask) {
+ int32_t markMask, int32_t interfaceId) {
// Necessary locking done in IpSecService and kernel
ENFORCE_PERMISSION(NETWORK_STACK);
gLog.log("ipSecAddSecurityPolicy()");
return asBinderStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityPolicy(
- transformId, selAddrFamily, direction, markValue, markMask));
+ transformId, selAddrFamily, direction, markValue, markMask, interfaceId));
}
binder::Status NetdNativeService::ipSecAddTunnelInterface(const std::string& deviceName,
const std::string& localAddress,
const std::string& remoteAddress,
- int32_t iKey, int32_t oKey) {
+ int32_t iKey, int32_t oKey,
+ int32_t interfaceId) {
// Necessary locking done in IpSecService and kernel
ENFORCE_PERMISSION(NETWORK_STACK);
auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
netdutils::Status result = gCtls->xfrmCtrl.ipSecAddTunnelInterface(
- deviceName, localAddress, remoteAddress, iKey, oKey, false);
+ deviceName, localAddress, remoteAddress, iKey, oKey, interfaceId, false);
RETURN_BINDER_STATUS_IF_NOT_OK(entry, result);
gLog.log(entry.returns(result).withAutomaticDuration());
@@ -888,13 +872,14 @@
binder::Status NetdNativeService::ipSecUpdateTunnelInterface(const std::string& deviceName,
const std::string& localAddress,
const std::string& remoteAddress,
- int32_t iKey, int32_t oKey) {
+ int32_t iKey, int32_t oKey,
+ int32_t interfaceId) {
// Necessary locking done in IpSecService and kernel
ENFORCE_PERMISSION(NETWORK_STACK);
auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
netdutils::Status result = gCtls->xfrmCtrl.ipSecAddTunnelInterface(
- deviceName, localAddress, remoteAddress, iKey, oKey, true);
+ deviceName, localAddress, remoteAddress, iKey, oKey, interfaceId, true);
RETURN_BINDER_STATUS_IF_NOT_OK(entry, result);
gLog.log(entry.returns(result).withAutomaticDuration());
diff --git a/server/NetdNativeService.h b/server/NetdNativeService.h
index dcac193..4b86f59 100644
--- a/server/NetdNativeService.h
+++ b/server/NetdNativeService.h
@@ -166,34 +166,20 @@
int32_t* outSpi);
binder::Status ipSecAddSecurityAssociation(
- int32_t transformId,
- int32_t mode,
- const std::string& sourceAddress,
- const std::string& destinationAddress,
- int32_t underlyingNetId,
- int32_t spi,
- int32_t markValue,
- int32_t markMask,
- const std::string& authAlgo,
- const std::vector<uint8_t>& authKey,
- int32_t authTruncBits,
- const std::string& cryptAlgo,
- const std::vector<uint8_t>& cryptKey,
- int32_t cryptTruncBits,
- const std::string& aeadAlgo,
- const std::vector<uint8_t>& aeadKey,
- int32_t aeadIcvBits,
- int32_t encapType,
- int32_t encapLocalPort,
- int32_t encapRemotePort);
+ int32_t transformId, int32_t mode, const std::string& sourceAddress,
+ const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi,
+ int32_t markValue, int32_t markMask, const std::string& authAlgo,
+ const std::vector<uint8_t>& authKey, int32_t authTruncBits,
+ const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey,
+ int32_t cryptTruncBits, const std::string& aeadAlgo,
+ const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits, int32_t encapType,
+ int32_t encapLocalPort, int32_t encapRemotePort, int32_t interfaceId);
- binder::Status ipSecDeleteSecurityAssociation(
- int32_t transformId,
- const std::string& sourceAddress,
- const std::string& destinationAddress,
- int32_t spi,
- int32_t markValue,
- int32_t markMask);
+ binder::Status ipSecDeleteSecurityAssociation(int32_t transformId,
+ const std::string& sourceAddress,
+ const std::string& destinationAddress,
+ int32_t spi, int32_t markValue, int32_t markMask,
+ int32_t interfaceId);
binder::Status ipSecApplyTransportModeTransform(
const android::base::unique_fd& socket,
@@ -209,28 +195,29 @@
binder::Status ipSecAddSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
int32_t direction, const std::string& tmplSrcAddress,
const std::string& tmplDstAddress, int32_t spi,
- int32_t markValue, int32_t markMask);
+ int32_t markValue, int32_t markMask, int32_t interfaceId);
binder::Status ipSecUpdateSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
int32_t direction, const std::string& tmplSrcAddress,
const std::string& tmplDstAddress, int32_t spi,
- int32_t markValue, int32_t markMask);
+ int32_t markValue, int32_t markMask,
+ int32_t interfaceId);
binder::Status ipSecDeleteSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
- int32_t direction, int32_t markValue,
- int32_t markMask);
+ int32_t direction, int32_t markValue, int32_t markMask,
+ int32_t interfaceId);
binder::Status trafficCheckBpfStatsEnable(bool* ret) override;
binder::Status ipSecAddTunnelInterface(const std::string& deviceName,
const std::string& localAddress,
const std::string& remoteAddress, int32_t iKey,
- int32_t oKey);
+ int32_t oKey, int32_t interfaceId);
binder::Status ipSecUpdateTunnelInterface(const std::string& deviceName,
const std::string& localAddress,
const std::string& remoteAddress, int32_t iKey,
- int32_t oKey);
+ int32_t oKey, int32_t interfaceId);
binder::Status ipSecRemoveTunnelInterface(const std::string& deviceName);
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index 18181e0..297a4b0 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -469,7 +469,7 @@
XfrmSaInfo saInfo{};
netdutils::Status ret = fillXfrmCommonInfo(sourceAddress, destinationAddress, INVALID_SPI, 0, 0,
- transformId, &saInfo);
+ transformId, 0, &saInfo);
if (!isOk(ret)) {
return ret;
}
@@ -497,12 +497,13 @@
}
netdutils::Status XfrmController::ipSecAddSecurityAssociation(
- int32_t transformId, int32_t mode, const std::string& sourceAddress,
- const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi, int32_t markValue,
- int32_t markMask, const std::string& authAlgo, const std::vector<uint8_t>& authKey,
- int32_t authTruncBits, const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey,
- int32_t cryptTruncBits, const std::string& aeadAlgo, const std::vector<uint8_t>& aeadKey,
- int32_t aeadIcvBits, int32_t encapType, int32_t encapLocalPort, int32_t encapRemotePort) {
+ int32_t transformId, int32_t mode, const std::string& sourceAddress,
+ const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi,
+ int32_t markValue, int32_t markMask, const std::string& authAlgo,
+ const std::vector<uint8_t>& authKey, int32_t authTruncBits, const std::string& cryptAlgo,
+ const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits, const std::string& aeadAlgo,
+ const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits, int32_t encapType,
+ int32_t encapLocalPort, int32_t encapRemotePort, int32_t xfrmInterfaceId) {
ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("transformId=%d", transformId);
ALOGD("mode=%d", mode);
@@ -521,10 +522,11 @@
ALOGD("encapType=%d", encapType);
ALOGD("encapLocalPort=%d", encapLocalPort);
ALOGD("encapRemotePort=%d", encapRemotePort);
+ ALOGD("xfrmInterfaceId=%d", xfrmInterfaceId);
XfrmSaInfo saInfo{};
netdutils::Status ret = fillXfrmCommonInfo(sourceAddress, destinationAddress, spi, markValue,
- markMask, transformId, &saInfo);
+ markMask, transformId, xfrmInterfaceId, &saInfo);
if (!isOk(ret)) {
return ret;
}
@@ -583,8 +585,9 @@
}
netdutils::Status XfrmController::ipSecDeleteSecurityAssociation(
- int32_t transformId, const std::string& sourceAddress, const std::string& destinationAddress,
- int32_t spi, int32_t markValue, int32_t markMask) {
+ int32_t transformId, const std::string& sourceAddress,
+ const std::string& destinationAddress, int32_t spi, int32_t markValue, int32_t markMask,
+ int32_t xfrmInterfaceId) {
ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("transformId=%d", transformId);
ALOGD("sourceAddress=%s", sourceAddress.c_str());
@@ -592,10 +595,11 @@
ALOGD("spi=%0.8x", spi);
ALOGD("markValue=%x", markValue);
ALOGD("markMask=%x", markMask);
+ ALOGD("xfrmInterfaceId=%d", xfrmInterfaceId);
XfrmSaInfo saInfo{};
netdutils::Status ret = fillXfrmCommonInfo(sourceAddress, destinationAddress, spi, markValue,
- markMask, transformId, &saInfo);
+ markMask, transformId, xfrmInterfaceId, &saInfo);
if (!isOk(ret)) {
return ret;
}
@@ -619,6 +623,7 @@
const std::string& destinationAddress,
int32_t spi, int32_t markValue,
int32_t markMask, int32_t transformId,
+ int32_t xfrmInterfaceId,
XfrmCommonInfo* info) {
// Use the addresses to determine the address family and do validation
xfrm_address_t sourceXfrmAddr{}, destXfrmAddr{};
@@ -642,16 +647,18 @@
info->dstAddr = destXfrmAddr;
info->srcAddr = sourceXfrmAddr;
- return fillXfrmCommonInfo(spi, markValue, markMask, transformId, info);
+ return fillXfrmCommonInfo(spi, markValue, markMask, transformId, xfrmInterfaceId, info);
}
netdutils::Status XfrmController::fillXfrmCommonInfo(int32_t spi, int32_t markValue,
int32_t markMask, int32_t transformId,
+ int32_t xfrmInterfaceId,
XfrmCommonInfo* info) {
info->transformId = transformId;
info->spi = htonl(spi);
info->mark.v = markValue;
info->mark.m = markMask;
+ info->xfrm_if_id = xfrmInterfaceId;
return netdutils::status::ok;
}
@@ -674,8 +681,8 @@
struct sockaddr_storage saddr = ret.value();
XfrmSpInfo spInfo{};
- netdutils::Status status =
- fillXfrmCommonInfo(sourceAddress, destinationAddress, spi, 0, 0, transformId, &spInfo);
+ netdutils::Status status = fillXfrmCommonInfo(sourceAddress, destinationAddress, spi, 0, 0,
+ transformId, 0, &spInfo);
if (!isOk(status)) {
ALOGE("Couldn't build SA ID %s", __FUNCTION__);
return status;
@@ -760,38 +767,37 @@
return status;
}
-netdutils::Status XfrmController::ipSecAddSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
- int32_t direction,
- const std::string& tmplSrcAddress,
- const std::string& tmplDstAddress,
- int32_t spi, int32_t markValue,
- int32_t markMask) {
+netdutils::Status XfrmController::ipSecAddSecurityPolicy(
+ int32_t transformId, int32_t selAddrFamily, int32_t direction,
+ const std::string& tmplSrcAddress, const std::string& tmplDstAddress, int32_t spi,
+ int32_t markValue, int32_t markMask, int32_t xfrmInterfaceId) {
return processSecurityPolicy(transformId, selAddrFamily, direction, tmplSrcAddress,
- tmplDstAddress, spi, markValue, markMask, XFRM_MSG_NEWPOLICY);
+ tmplDstAddress, spi, markValue, markMask, xfrmInterfaceId,
+ XFRM_MSG_NEWPOLICY);
}
netdutils::Status XfrmController::ipSecUpdateSecurityPolicy(
int32_t transformId, int32_t selAddrFamily, int32_t direction,
const std::string& tmplSrcAddress, const std::string& tmplDstAddress, int32_t spi,
- int32_t markValue, int32_t markMask) {
+ int32_t markValue, int32_t markMask, int32_t xfrmInterfaceId) {
return processSecurityPolicy(transformId, selAddrFamily, direction, tmplSrcAddress,
- tmplDstAddress, spi, markValue, markMask, XFRM_MSG_UPDPOLICY);
+ tmplDstAddress, spi, markValue, markMask, xfrmInterfaceId,
+ XFRM_MSG_UPDPOLICY);
}
netdutils::Status XfrmController::ipSecDeleteSecurityPolicy(int32_t transformId,
int32_t selAddrFamily,
int32_t direction, int32_t markValue,
- int32_t markMask) {
+ int32_t markMask,
+ int32_t xfrmInterfaceId) {
return processSecurityPolicy(transformId, selAddrFamily, direction, "", "", 0, markValue,
- markMask, XFRM_MSG_DELPOLICY);
+ markMask, xfrmInterfaceId, XFRM_MSG_DELPOLICY);
}
-netdutils::Status XfrmController::processSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
- int32_t direction,
- const std::string& tmplSrcAddress,
- const std::string& tmplDstAddress,
- int32_t spi, int32_t markValue,
- int32_t markMask, int32_t msgType) {
+netdutils::Status XfrmController::processSecurityPolicy(
+ int32_t transformId, int32_t selAddrFamily, int32_t direction,
+ const std::string& tmplSrcAddress, const std::string& tmplDstAddress, int32_t spi,
+ int32_t markValue, int32_t markMask, int32_t xfrmInterfaceId, int32_t msgType) {
ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("selAddrFamily=%s", selAddrFamily == AF_INET6 ? "AF_INET6" : "AF_INET");
ALOGD("transformId=%d", transformId);
@@ -802,6 +808,7 @@
ALOGD("markValue=%d", markValue);
ALOGD("markMask=%d", markMask);
ALOGD("msgType=%d", msgType);
+ ALOGD("xfrmInterfaceId=%d", xfrmInterfaceId);
XfrmSpInfo spInfo{};
spInfo.mode = XfrmMode::TUNNEL;
@@ -816,12 +823,13 @@
spInfo.selAddrFamily = selAddrFamily;
if (msgType == XFRM_MSG_DELPOLICY) {
- RETURN_IF_NOT_OK(fillXfrmCommonInfo(spi, markValue, markMask, transformId, &spInfo));
+ RETURN_IF_NOT_OK(fillXfrmCommonInfo(spi, markValue, markMask, transformId, xfrmInterfaceId,
+ &spInfo));
return deleteTunnelModeSecurityPolicy(spInfo, sock, static_cast<XfrmDirection>(direction));
} else {
RETURN_IF_NOT_OK(fillXfrmCommonInfo(tmplSrcAddress, tmplDstAddress, spi, markValue,
- markMask, transformId, &spInfo));
+ markMask, transformId, xfrmInterfaceId, &spInfo));
return updateTunnelModeSecurityPolicy(spInfo, sock, static_cast<XfrmDirection>(direction),
msgType);
@@ -843,6 +851,7 @@
nlattr_xfrm_mark xfrmmark{};
nlattr_xfrm_output_mark xfrmoutputmark{};
nlattr_encap_tmpl encap{};
+ nlattr_xfrm_interface_id xfrm_if_id{};
enum {
NLMSG_HDR,
@@ -860,24 +869,28 @@
OUTPUT_MARK_PAD,
ENCAP,
ENCAP_PAD,
+ INTF_ID,
+ INTF_ID_PAD,
};
std::vector<iovec> iov = {
- {nullptr, 0}, // reserved for the eventual addition of a NLMSG_HDR
- {&usersa, 0}, // main usersa_info struct
- {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
- {&crypt, 0}, // adjust size if crypt algo is present
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
- {&auth, 0}, // adjust size if auth algo is present
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
- {&aead, 0}, // adjust size if aead algo is present
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
- {&xfrmmark, 0}, // adjust size if xfrm mark is present
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
- {&xfrmoutputmark, 0}, // adjust size if xfrm output mark is present
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
- {&encap, 0}, // adjust size if encapsulating
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {nullptr, 0}, // reserved for the eventual addition of a NLMSG_HDR
+ {&usersa, 0}, // main usersa_info struct
+ {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
+ {&crypt, 0}, // adjust size if crypt algo is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {&auth, 0}, // adjust size if auth algo is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {&aead, 0}, // adjust size if aead algo is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {&xfrmmark, 0}, // adjust size if xfrm mark is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {&xfrmoutputmark, 0}, // adjust size if xfrm output mark is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {&encap, 0}, // adjust size if encapsulating
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {&xfrm_if_id, 0}, // adjust size if interface ID is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
};
if (!record.aead.name.empty() && (!record.auth.name.empty() || !record.crypt.name.empty())) {
@@ -891,6 +904,13 @@
return netdutils::statusFromErrno(EINVAL, "Key length invalid; exceeds MAX_KEY_LENGTH");
}
+ if (record.mode != XfrmMode::TUNNEL && record.xfrm_if_id != 0) {
+ // TODO: Also throw errors if output mark or mark supplied
+ return netdutils::statusFromErrno(EINVAL,
+ "xfrm_if_id parameter invalid for non "
+ "tunnel-mode transform");
+ }
+
int len;
len = iov[USERSA].iov_len = fillUserSaInfo(record, &usersa);
iov[USERSA_PAD].iov_len = NLMSG_ALIGN(len) - len;
@@ -913,6 +933,9 @@
len = iov[ENCAP].iov_len = fillNlAttrXfrmEncapTmpl(record, &encap);
iov[ENCAP_PAD].iov_len = NLA_ALIGN(len) - len;
+ len = iov[INTF_ID].iov_len = fillNlAttrXfrmIntfId(record.xfrm_if_id, &xfrm_if_id);
+ iov[INTF_ID_PAD].iov_len = NLA_ALIGN(len) - len;
+
return sock.sendMessage(XFRM_MSG_UPDSA, NETLINK_REQUEST_FLAGS, 0, &iov);
}
@@ -1026,15 +1049,18 @@
const XfrmSocket& sock) {
xfrm_usersa_id said{};
nlattr_xfrm_mark xfrmmark{};
+ nlattr_xfrm_interface_id xfrm_if_id{};
- enum { NLMSG_HDR, USERSAID, USERSAID_PAD, MARK, MARK_PAD };
+ enum { NLMSG_HDR, USERSAID, USERSAID_PAD, MARK, MARK_PAD, INTF_ID, INTF_ID_PAD };
std::vector<iovec> iov = {
- {nullptr, 0}, // reserved for the eventual addition of a NLMSG_HDR
- {&said, 0}, // main usersa_info struct
- {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
- {&xfrmmark, 0}, // adjust size if xfrm mark is present
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {nullptr, 0}, // reserved for the eventual addition of a NLMSG_HDR
+ {&said, 0}, // main usersa_info struct
+ {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
+ {&xfrmmark, 0}, // adjust size if xfrm mark is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {&xfrm_if_id, 0}, // adjust size if interface ID is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
};
int len;
@@ -1044,6 +1070,9 @@
len = iov[MARK].iov_len = fillNlAttrXfrmMark(record, &xfrmmark);
iov[MARK_PAD].iov_len = NLA_ALIGN(len) - len;
+ len = iov[INTF_ID].iov_len = fillNlAttrXfrmIntfId(record.xfrm_if_id, &xfrm_if_id);
+ iov[INTF_ID_PAD].iov_len = NLA_ALIGN(len) - len;
+
return sock.sendMessage(XFRM_MSG_DELSA, NETLINK_REQUEST_FLAGS, 0, &iov);
}
@@ -1102,6 +1131,7 @@
xfrm_userpolicy_info userpolicy{};
nlattr_user_tmpl usertmpl{};
nlattr_xfrm_mark xfrmmark{};
+ nlattr_xfrm_interface_id xfrm_if_id{};
enum {
NLMSG_HDR,
@@ -1111,16 +1141,20 @@
USERTMPL_PAD,
MARK,
MARK_PAD,
+ INTF_ID,
+ INTF_ID_PAD,
};
std::vector<iovec> iov = {
- {nullptr, 0}, // reserved for the eventual addition of a NLMSG_HDR
- {&userpolicy, 0}, // main xfrm_userpolicy_info struct
- {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
- {&usertmpl, 0}, // adjust size if xfrm_user_tmpl struct is present
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
- {&xfrmmark, 0}, // adjust size if xfrm mark is present
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {nullptr, 0}, // reserved for the eventual addition of a NLMSG_HDR
+ {&userpolicy, 0}, // main xfrm_userpolicy_info struct
+ {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
+ {&usertmpl, 0}, // adjust size if xfrm_user_tmpl struct is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {&xfrmmark, 0}, // adjust size if xfrm mark is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {&xfrm_if_id, 0}, // adjust size if interface ID is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
};
int len;
@@ -1133,6 +1167,9 @@
len = iov[MARK].iov_len = fillNlAttrXfrmMark(record, &xfrmmark);
iov[MARK_PAD].iov_len = NLA_ALIGN(len) - len;
+ len = iov[INTF_ID].iov_len = fillNlAttrXfrmIntfId(record.xfrm_if_id, &xfrm_if_id);
+ iov[INTF_ID_PAD].iov_len = NLA_ALIGN(len) - len;
+
return sock.sendMessage(msgType, NETLINK_REQUEST_FLAGS, 0, &iov);
}
@@ -1141,6 +1178,7 @@
XfrmDirection direction) {
xfrm_userpolicy_id policyid{};
nlattr_xfrm_mark xfrmmark{};
+ nlattr_xfrm_interface_id xfrm_if_id{};
enum {
NLMSG_HDR,
@@ -1148,14 +1186,18 @@
USERPOLICYID_PAD,
MARK,
MARK_PAD,
+ INTF_ID,
+ INTF_ID_PAD,
};
std::vector<iovec> iov = {
- {nullptr, 0}, // reserved for the eventual addition of a NLMSG_HDR
- {&policyid, 0}, // main xfrm_userpolicy_id struct
- {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
- {&xfrmmark, 0}, // adjust size if xfrm mark is present
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {nullptr, 0}, // reserved for the eventual addition of a NLMSG_HDR
+ {&policyid, 0}, // main xfrm_userpolicy_id struct
+ {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
+ {&xfrmmark, 0}, // adjust size if xfrm mark is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {&xfrm_if_id, 0}, // adjust size if interface ID is present
+ {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
};
int len = iov[USERPOLICYID].iov_len = fillUserPolicyId(record, direction, &policyid);
@@ -1164,6 +1206,9 @@
len = iov[MARK].iov_len = fillNlAttrXfrmMark(record, &xfrmmark);
iov[MARK_PAD].iov_len = NLA_ALIGN(len) - len;
+ len = iov[INTF_ID].iov_len = fillNlAttrXfrmIntfId(record.xfrm_if_id, &xfrm_if_id);
+ iov[INTF_ID_PAD].iov_len = NLA_ALIGN(len) - len;
+
return sock.sendMessage(XFRM_MSG_DELPOLICY, NETLINK_REQUEST_FLAGS, 0, &iov);
}
@@ -1268,13 +1313,14 @@
const std::string& localAddress,
const std::string& remoteAddress,
int32_t ikey, int32_t okey,
- bool isUpdate) {
+ int32_t interfaceId, bool isUpdate) {
ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("deviceName=%s", deviceName.c_str());
ALOGD("localAddress=%s", localAddress.c_str());
ALOGD("remoteAddress=%s", remoteAddress.c_str());
ALOGD("ikey=%0.8x", ikey);
ALOGD("okey=%0.8x", okey);
+ ALOGD("interfaceId=%0.8x", interfaceId);
ALOGD("isUpdate=%d", isUpdate);
uint16_t flags = isUpdate ? NETLINK_REQUEST_FLAGS : NETLINK_ROUTE_CREATE_FLAGS;
diff --git a/server/XfrmController.h b/server/XfrmController.h
index b2f0bff..9208f54 100644
--- a/server/XfrmController.h
+++ b/server/XfrmController.h
@@ -113,6 +113,7 @@
int transformId; // requestId
int spi;
xfrm_mark mark;
+ int xfrm_if_id;
};
struct XfrmSaInfo : XfrmCommonInfo {
@@ -144,19 +145,21 @@
int32_t* outSpi);
static netdutils::Status ipSecAddSecurityAssociation(
- int32_t transformId, int32_t mode, const std::string& sourceAddress,
- const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi,
- int32_t markValue, int32_t markMask, const std::string& authAlgo,
- const std::vector<uint8_t>& authKey, int32_t authTruncBits, const std::string& cryptAlgo,
- const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits, const std::string& aeadAlgo,
- const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits, int32_t encapType,
- int32_t encapLocalPort, int32_t encapRemotePort);
+ int32_t transformId, int32_t mode, const std::string& sourceAddress,
+ const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi,
+ int32_t markValue, int32_t markMask, const std::string& authAlgo,
+ const std::vector<uint8_t>& authKey, int32_t authTruncBits,
+ const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey,
+ int32_t cryptTruncBits, const std::string& aeadAlgo,
+ const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits, int32_t encapType,
+ int32_t encapLocalPort, int32_t encapRemotePort, int32_t xfrmInterfaceId);
static netdutils::Status ipSecDeleteSecurityAssociation(int32_t transformId,
const std::string& sourceAddress,
const std::string& destinationAddress,
int32_t spi, int32_t markValue,
- int32_t markMask);
+ int32_t markMask,
+ int32_t xfrmInterfaceId);
static netdutils::Status
ipSecApplyTransportModeTransform(const android::base::unique_fd& socket, int32_t transformId,
@@ -170,23 +173,25 @@
int32_t direction,
const std::string& tmplSrcAddress,
const std::string& tmplDstAddress, int32_t spi,
- int32_t markValue, int32_t markMask);
+ int32_t markValue, int32_t markMask,
+ int32_t xfrmInterfaceId);
static netdutils::Status ipSecUpdateSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
int32_t direction,
const std::string& tmplSrcAddress,
const std::string& tmplDstAddress,
int32_t spi, int32_t markValue,
- int32_t markMask);
+ int32_t markMask, int32_t xfrmInterfaceId);
static netdutils::Status ipSecDeleteSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
int32_t direction, int32_t markValue,
- int32_t markMask);
+ int32_t markMask, int32_t xfrmInterfaceId);
static netdutils::Status ipSecAddTunnelInterface(const std::string& deviceName,
const std::string& localAddress,
const std::string& remoteAddress, int32_t ikey,
- int32_t okey, bool isUpdate);
+ int32_t okey, int32_t interfaceId,
+ bool isUpdate);
static netdutils::Status ipSecRemoveTunnelInterface(const std::string& deviceName);
@@ -327,9 +332,11 @@
static netdutils::Status fillXfrmCommonInfo(const std::string& sourceAddress,
const std::string& destinationAddress, int32_t spi,
int32_t markValue, int32_t markMask,
- int32_t transformId, XfrmCommonInfo* info);
+ int32_t transformId, int32_t xfrmInterfaceId,
+ XfrmCommonInfo* info);
static netdutils::Status fillXfrmCommonInfo(int32_t spi, int32_t markValue, int32_t markMask,
- int32_t transformId, XfrmCommonInfo* info);
+ int32_t transformId, int32_t xfrmInterfaceId,
+ XfrmCommonInfo* info);
// Top level functions for managing a Transport Mode Transform
static netdutils::Status addTransportModeTransform(const XfrmSaInfo& record);
@@ -374,7 +381,7 @@
const std::string& tmplSrcAddress,
const std::string& tmplDstAddress, int32_t spi,
int32_t markValue, int32_t markMask,
- int32_t msgType);
+ int32_t xfrmInterfaceId, int32_t msgType);
static netdutils::Status updateTunnelModeSecurityPolicy(const XfrmSpInfo& record,
const XfrmSocket& sock,
XfrmDirection direction,
diff --git a/server/XfrmControllerTest.cpp b/server/XfrmControllerTest.cpp
index 5539dab..be819d8 100644
--- a/server/XfrmControllerTest.cpp
+++ b/server/XfrmControllerTest.cpp
@@ -103,7 +103,8 @@
static constexpr int DROID_SPI = 0xD1201D;
static constexpr size_t KEY_LENGTH = 32;
static constexpr int NLMSG_DEFAULTSIZE = 8192;
-static constexpr uint16_t TEST_XFRM_OUTPUT_MARK = 0x512;
+static constexpr uint32_t TEST_XFRM_UNDERLYING_NET = 0x512;
+static constexpr uint32_t TEST_XFRM_IF_ID = 0x1234;
static constexpr uint32_t TEST_XFRM_MARK = 0x123;
static constexpr uint32_t TEST_XFRM_MASK = 0xFFFFFFFF;
@@ -277,10 +278,16 @@
// Calculate the length of the expected netlink message.
size_t expectedMsgLength =
- NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_usersa_info)) +
- NLA_ALIGN(offsetof(XfrmController::nlattr_algo_crypt, key) + KEY_LENGTH) +
- NLA_ALIGN(offsetof(XfrmController::nlattr_algo_auth, key) + KEY_LENGTH) +
- NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark));
+ NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_usersa_info)) +
+ NLA_ALIGN(offsetof(XfrmController::nlattr_algo_crypt, key) + KEY_LENGTH) +
+ NLA_ALIGN(offsetof(XfrmController::nlattr_algo_auth, key) + KEY_LENGTH) +
+ NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark));
+
+ uint32_t testIfId = 0;
+ if (mode == XfrmMode::TUNNEL) {
+ expectedMsgLength += NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
+ testIfId = TEST_XFRM_IF_ID;
+ }
if (underlying_netid) {
expectedMsgLength += NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_output_mark));
@@ -294,12 +301,13 @@
XfrmController ctrl;
Status res = ctrl.ipSecAddSecurityAssociation(
- 1 /* resourceId */, static_cast<int>(mode), localAddr, remoteAddr,
- underlying_netid /* underlying netid */, DROID_SPI, TEST_XFRM_MARK /* mark */,
- TEST_XFRM_MASK /* mask */, "hmac(sha256)" /* auth algo */,
- authKey, 128 /* auth trunc length */, "cbc(aes)" /* encryption algo */,
- cryptKey, 0 /* crypt trunc length? */, "" /* AEAD algo */, {}, 0,
- static_cast<int>(XfrmEncapType::NONE), 0 /* local port */, 0 /* remote port */);
+ 1 /* resourceId */, static_cast<int>(mode), localAddr, remoteAddr,
+ underlying_netid /* underlying netid */, DROID_SPI, TEST_XFRM_MARK /* mark */,
+ TEST_XFRM_MASK /* mask */, "hmac(sha256)" /* auth algo */, authKey,
+ 128 /* auth trunc length */, "cbc(aes)" /* encryption algo */, cryptKey,
+ 0 /* crypt trunc length? */, "" /* AEAD algo */, {}, 0,
+ static_cast<int>(XfrmEncapType::NONE), 0 /* local port */, 0 /* remote port */,
+ testIfId /* xfrm_if_id */);
EXPECT_TRUE(isOk(res)) << res;
EXPECT_EQ(expectedMsgLength, nlMsgBuf.size());
@@ -334,8 +342,9 @@
XfrmController::nlattr_algo_auth authAlgo{};
XfrmController::nlattr_xfrm_mark mark{};
XfrmController::nlattr_xfrm_output_mark outputmark{};
- auto attrHandler = [&encryptAlgo, &authAlgo, &mark, &outputmark](const nlattr& attr,
- const Slice& attr_payload) {
+ XfrmController::nlattr_xfrm_interface_id xfrm_if_id{};
+ auto attrHandler = [&encryptAlgo, &authAlgo, &mark, &outputmark, &xfrm_if_id](
+ const nlattr& attr, const Slice& attr_payload) {
Slice buf = attr_payload;
if (attr.nla_type == XFRMA_ALG_CRYPT) {
encryptAlgo.hdr = attr;
@@ -353,6 +362,9 @@
} else if (attr.nla_type == XFRMA_OUTPUT_MARK) {
mark.hdr = attr;
netdutils::extract(buf, outputmark.outputMark);
+ } else if (attr.nla_type == XFRMA_IF_ID) {
+ xfrm_if_id.hdr = attr;
+ netdutils::extract(buf, xfrm_if_id.if_id);
} else {
FAIL() << "Unexpected nlattr type: " << attr.nla_type;
}
@@ -366,6 +378,8 @@
reinterpret_cast<void*>(&authAlgo.key), KEY_LENGTH));
EXPECT_EQ(TEST_XFRM_MARK, mark.mark.v);
EXPECT_EQ(TEST_XFRM_MASK, mark.mark.m);
+ EXPECT_EQ(testIfId, xfrm_if_id.if_id);
+
if (underlying_netid) {
Fwmark fwmark;
fwmark.intValue = outputmark.outputMark;
@@ -389,7 +403,7 @@
TEST_P(XfrmControllerParameterizedTest, TestTunnelModeIpSecAddSecurityAssociationWithOutputMark) {
const int version = GetParam();
testIpSecAddSecurityAssociation(version, mockSyscalls, XfrmMode::TUNNEL,
- TEST_XFRM_OUTPUT_MARK);
+ TEST_XFRM_UNDERLYING_NET);
}
TEST_F(XfrmControllerTest, TestIpSecAddSecurityAssociationIPv4Encap) {
@@ -403,9 +417,9 @@
XfrmController ctrl;
Status res = ctrl.ipSecAddSecurityAssociation(
- 1, static_cast<int>(XfrmMode::TRANSPORT),
- LOCALHOST_V6, TEST_ADDR_V6, 0, DROID_SPI, 0, 0, "hmac(sha256)", {}, 128, "cbc(aes)",
- {}, 0, "", {}, 0, static_cast<int>(XfrmEncapType::ESPINUDP_NON_IKE), 0, 0);
+ 1, static_cast<int>(XfrmMode::TRANSPORT), LOCALHOST_V6, TEST_ADDR_V6, 0, DROID_SPI, 0,
+ 0, "hmac(sha256)", {}, 128, "cbc(aes)", {}, 0, "", {}, 0,
+ static_cast<int>(XfrmEncapType::ESPINUDP_NON_IKE), 0, 0, 0);
EXPECT_FALSE(isOk(res)) << "IPv6 UDP encap not rejected";
}
@@ -508,7 +522,8 @@
Slice responseSlice = netdutils::makeSlice(response);
size_t expectedMsgLength = NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_usersa_id)) +
- NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark));
+ NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark)) +
+ NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
std::vector<uint8_t> nlMsgBuf;
EXPECT_CALL(mockSyscalls, writev(_, _))
@@ -518,7 +533,8 @@
XfrmController ctrl;
Status res = ctrl.ipSecDeleteSecurityAssociation(1 /* resourceId */, localAddr, remoteAddr,
- DROID_SPI, TEST_XFRM_MARK, TEST_XFRM_MASK);
+ DROID_SPI, TEST_XFRM_MARK, TEST_XFRM_MASK,
+ TEST_XFRM_IF_ID);
EXPECT_TRUE(isOk(res)) << res;
EXPECT_EQ(expectedMsgLength, nlMsgBuf.size());
@@ -526,11 +542,24 @@
Slice nlMsgSlice = netdutils::makeSlice(nlMsgBuf);
nlMsgSlice = netdutils::drop(nlMsgSlice, NLMSG_HDRLEN);
+ // Extract and check the usersa_id
xfrm_usersa_id said{};
netdutils::extract(nlMsgSlice, said);
-
+ nlMsgSlice = drop(nlMsgSlice, sizeof(xfrm_usersa_id));
EXPECT_EQ(htonl(DROID_SPI), said.spi);
expectAddressEquals(family, remoteAddr, said.daddr);
+
+ // Extract and check the mark.
+ XfrmController::nlattr_xfrm_mark mark{};
+ netdutils::extract(nlMsgSlice, mark);
+ nlMsgSlice = drop(nlMsgSlice, sizeof(XfrmController::nlattr_xfrm_mark));
+ EXPECT_EQ(TEST_XFRM_MARK, mark.mark.v);
+ EXPECT_EQ(TEST_XFRM_MASK, mark.mark.m);
+
+ // Extract and check the interface id.
+ XfrmController::nlattr_xfrm_interface_id xfrm_if_id{};
+ netdutils::extract(nlMsgSlice, xfrm_if_id);
+ EXPECT_EQ(TEST_XFRM_IF_ID, xfrm_if_id.if_id);
}
TEST_P(XfrmControllerParameterizedTest, TestIpSecAddSecurityPolicy) {
@@ -545,7 +574,8 @@
size_t expectedMsgLength = NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_userpolicy_info)) +
NLMSG_ALIGN(sizeof(XfrmController::nlattr_user_tmpl)) +
- NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark));
+ NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark)) +
+ NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
std::vector<uint8_t> nlMsgBuf;
EXPECT_CALL(mockSyscalls, writev(_, _))
@@ -556,7 +586,7 @@
XfrmController ctrl;
Status res = ctrl.ipSecAddSecurityPolicy(
1 /* resourceId */, family, static_cast<int>(XfrmDirection::OUT), localAddr, remoteAddr,
- 0 /* SPI */, TEST_XFRM_MARK, TEST_XFRM_MASK);
+ 0 /* SPI */, TEST_XFRM_MARK, TEST_XFRM_MASK, TEST_XFRM_IF_ID);
EXPECT_TRUE(isOk(res)) << res;
EXPECT_EQ(expectedMsgLength, nlMsgBuf.size());
@@ -578,7 +608,9 @@
// Extract and check the user tmpl and mark.
XfrmController::nlattr_user_tmpl usertmpl{};
XfrmController::nlattr_xfrm_mark mark{};
- auto attrHandler = [&usertmpl, &mark](const nlattr& attr, const Slice& attr_payload) {
+ XfrmController::nlattr_xfrm_interface_id xfrm_if_id{};
+ auto attrHandler = [&usertmpl, &mark, &xfrm_if_id](const nlattr& attr,
+ const Slice& attr_payload) {
Slice buf = attr_payload;
if (attr.nla_type == XFRMA_TMPL) {
usertmpl.hdr = attr;
@@ -586,6 +618,9 @@
} else if (attr.nla_type == XFRMA_MARK) {
mark.hdr = attr;
netdutils::extract(buf, mark.mark);
+ } else if (attr.nla_type == XFRMA_IF_ID) {
+ mark.hdr = attr;
+ netdutils::extract(buf, xfrm_if_id.if_id);
} else {
FAIL() << "Unexpected nlattr type: " << attr.nla_type;
}
@@ -595,7 +630,7 @@
expectAddressEquals(family, remoteAddr, usertmpl.tmpl.id.daddr);
EXPECT_EQ(TEST_XFRM_MARK, mark.mark.v);
EXPECT_EQ(TEST_XFRM_MASK, mark.mark.m);
-
+ EXPECT_EQ(TEST_XFRM_IF_ID, xfrm_if_id.if_id);
}
TEST_P(XfrmControllerParameterizedTest, TestIpSecUpdateSecurityPolicy) {
@@ -610,7 +645,8 @@
size_t expectedMsgLength = NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_userpolicy_info)) +
NLMSG_ALIGN(sizeof(XfrmController::nlattr_user_tmpl)) +
- NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark));
+ NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark)) +
+ NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
std::vector<uint8_t> nlMsgBuf;
EXPECT_CALL(mockSyscalls, writev(_, _))
@@ -621,7 +657,7 @@
XfrmController ctrl;
Status res = ctrl.ipSecUpdateSecurityPolicy(
1 /* resourceId */, family, static_cast<int>(XfrmDirection::OUT), localAddr, remoteAddr,
- 0 /* SPI */, 0 /* Mark */, 0 /* Mask */);
+ 0 /* SPI */, 0 /* Mark */, 0 /* Mask */, TEST_XFRM_IF_ID /* xfrm_if_id */);
EXPECT_TRUE(isOk(res)) << res;
EXPECT_EQ(expectedMsgLength, nlMsgBuf.size());
@@ -643,7 +679,8 @@
Slice responseSlice = netdutils::makeSlice(response);
size_t expectedMsgLength = NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_userpolicy_id)) +
- NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark));
+ NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark)) +
+ NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
std::vector<uint8_t> nlMsgBuf;
EXPECT_CALL(mockSyscalls, writev(_, _))
@@ -654,7 +691,7 @@
XfrmController ctrl;
Status res = ctrl.ipSecDeleteSecurityPolicy(1 /* resourceId */, family,
static_cast<int>(XfrmDirection::OUT),
- TEST_XFRM_MARK, TEST_XFRM_MASK);
+ TEST_XFRM_MARK, TEST_XFRM_MASK, TEST_XFRM_IF_ID);
EXPECT_TRUE(isOk(res)) << res;
EXPECT_EQ(expectedMsgLength, nlMsgBuf.size());
@@ -669,12 +706,18 @@
// Drop the user policy id.
nlMsgSlice = drop(nlMsgSlice, NLA_ALIGN(sizeof(xfrm_userpolicy_id)));
+
// Extract and check the mark.
XfrmController::nlattr_xfrm_mark mark{};
netdutils::extract(nlMsgSlice, mark);
+ nlMsgSlice = drop(nlMsgSlice, sizeof(XfrmController::nlattr_xfrm_mark));
EXPECT_EQ(TEST_XFRM_MARK, mark.mark.v);
EXPECT_EQ(TEST_XFRM_MASK, mark.mark.m);
+ // Extract and check the interface id.
+ XfrmController::nlattr_xfrm_interface_id xfrm_if_id{};
+ netdutils::extract(nlMsgSlice, xfrm_if_id);
+ EXPECT_EQ(TEST_XFRM_IF_ID, xfrm_if_id.if_id);
}
// TODO: Add tests for VTIs, ensuring that we are sending the correct data over netlink.
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
index ad631e4..48d064f 100644
--- a/server/binder/android/net/INetd.aidl
+++ b/server/binder/android/net/INetd.aidl
@@ -342,7 +342,7 @@
* @param mode either Transport or Tunnel mode
* @param sourceAddress InetAddress as string for the sending endpoint
* @param destinationAddress InetAddress as string for the receiving endpoint
- * @param underlyingNetId the netId of the network to which the SA is applied
+ * @param underlyingNetId the netId of the network to which the SA is applied.
* @param spi a 32-bit unique ID allocated to the user
* @param markValue a 32-bit unique ID chosen by the user
* @param markMask a 32-bit mask chosen by the user
@@ -359,6 +359,8 @@
* @param encapType encapsulation type used (if any) for the udp encap socket
* @param encapLocalPort the port number on the host to be used in encap packets
* @param encapRemotePort the port number of the remote to be used for encap packets
+ * @param interfaceId the identifier for the IPsec tunnel interface.
+ * Only accepted for tunnel mode SAs.
*/
void ipSecAddSecurityAssociation(
int transformId,
@@ -374,7 +376,8 @@
in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits,
int encapType,
int encapLocalPort,
- int encapRemotePort);
+ int encapRemotePort,
+ int interfaceId);
/**
* Delete a previously created security association identified by the provided parameters
@@ -385,6 +388,7 @@
* @param spi a requested 32-bit unique ID allocated to the user
* @param markValue a 32-bit unique ID chosen by the user
* @param markMask a 32-bit mask chosen by the user
+ * @param interfaceId the identifier for the IPsec tunnel interface.
*/
void ipSecDeleteSecurityAssociation(
int transformId,
@@ -392,7 +396,8 @@
in @utf8InCpp String destinationAddress,
int spi,
int markValue,
- int markMask);
+ int markMask,
+ int interfaceId);
/**
* Apply a previously created SA to a specified socket, starting IPsec on that socket
@@ -432,6 +437,7 @@
* @param spi a 32-bit unique ID allocated to the user
* @param markValue a 32-bit unique ID chosen by the user
* @param markMask a 32-bit mask chosen by the user
+ * @param interfaceId the identifier for the IPsec tunnel interface.
*/
void ipSecAddSecurityPolicy(
int transformId,
@@ -441,7 +447,8 @@
in @utf8InCpp String tmplDstAddress,
int spi,
int markValue,
- int markMask);
+ int markMask,
+ int interfaceId);
/**
* Updates an IPsec global policy.
@@ -454,6 +461,7 @@
* @param spi a 32-bit unique ID allocated to the user
* @param markValue a 32-bit unique ID chosen by the user
* @param markMask a 32-bit mask chosen by the user
+ * @param interfaceId the identifier for the IPsec tunnel interface.
*/
void ipSecUpdateSecurityPolicy(
int transformId,
@@ -463,7 +471,8 @@
in @utf8InCpp String tmplDstAddress,
int spi,
int markValue,
- int markMask);
+ int markMask,
+ int interfaceId);
/**
* Deletes an IPsec global policy.
@@ -476,13 +485,15 @@
* @param direction DIRECTION_IN or DIRECTION_OUT
* @param markValue a 32-bit unique ID chosen by the user
* @param markMask a 32-bit mask chosen by the user
+ * @param interfaceId the identifier for the IPsec tunnel interface.
*/
void ipSecDeleteSecurityPolicy(
int transformId,
int selAddrFamily,
int direction,
int markValue,
- int markMask);
+ int markMask,
+ int interfaceId);
// This could not be declared as @uft8InCpp; thus, when used in native code it must be
// converted from a UTF-16 string to an ASCII string.
@@ -496,13 +507,15 @@
* @param remoteAddress InetAddress as string for the remote endpoint
* @param iKey, to match Policies and SAs for input packets.
* @param oKey, to match Policies and SAs for output packets.
+ * @param interfaceId the identifier for the IPsec tunnel interface.
*/
void ipSecAddTunnelInterface(
in @utf8InCpp String deviceName,
in @utf8InCpp String localAddress,
in @utf8InCpp String remoteAddress,
int iKey,
- int oKey);
+ int oKey,
+ int interfaceId);
/**
* Update a IPsec Tunnel Interface.
@@ -512,13 +525,15 @@
* @param remoteAddress InetAddress as string for the remote endpoint
* @param iKey, to match Policies and SAs for input packets.
* @param oKey, to match Policies and SAs for output packets.
+ * @param interfaceId the identifier for the IPsec tunnel interface.
*/
void ipSecUpdateTunnelInterface(
in @utf8InCpp String deviceName,
in @utf8InCpp String localAddress,
in @utf8InCpp String remoteAddress,
int iKey,
- int oKey);
+ int oKey,
+ int interfaceId);
/**
* Removes a IPsec Tunnel Interface.