Use independent address families for SP selector and template
This patch allows Security Policy selectors and templates to have
different address families, allowing for wildcard selectors, but
specified templates. This is required for IPsec tunnel mode to work
properly, as selectors match inner addresses (and thus must be dual
IPv4/IPv6), while templates match outer addresses.
Bug: 79384676
Test: CTS tests passing, ip xfrm monitor shows correct results
Change-Id: I60214e17f50f91deb1ffdc71158131d237d1e642
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index c8e0c7e..c0ca209 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -601,7 +601,8 @@
socket));
}
-binder::Status NetdNativeService::ipSecAddSecurityPolicy(int32_t transformId, int32_t direction,
+binder::Status NetdNativeService::ipSecAddSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
+ int32_t direction,
const std::string& tmplSrcAddress,
const std::string& tmplDstAddress,
int32_t spi, int32_t markValue,
@@ -610,10 +611,13 @@
ENFORCE_PERMISSION(NETWORK_STACK);
gLog.log("ipSecAddSecurityPolicy()");
return asBinderStatus(gCtls->xfrmCtrl.ipSecAddSecurityPolicy(
- transformId, direction, tmplSrcAddress, tmplDstAddress, spi, markValue, markMask));
+ transformId, selAddrFamily, direction, tmplSrcAddress, tmplDstAddress, spi, markValue,
+ markMask));
}
-binder::Status NetdNativeService::ipSecUpdateSecurityPolicy(int32_t transformId, int32_t direction,
+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,
@@ -622,18 +626,19 @@
ENFORCE_PERMISSION(NETWORK_STACK);
gLog.log("ipSecAddSecurityPolicy()");
return asBinderStatus(gCtls->xfrmCtrl.ipSecUpdateSecurityPolicy(
- transformId, direction, tmplSrcAddress, tmplDstAddress, spi, markValue, markMask));
+ transformId, selAddrFamily, direction, tmplSrcAddress, tmplDstAddress, spi, markValue,
+ markMask));
}
-binder::Status NetdNativeService::ipSecDeleteSecurityPolicy(int32_t transformId, int32_t direction,
- const std::string& tmplSrcAddress,
- const std::string& tmplDstAddress,
- int32_t markValue, int32_t markMask) {
+binder::Status NetdNativeService::ipSecDeleteSecurityPolicy(int32_t transformId,
+ int32_t selAddrFamily,
+ int32_t direction, int32_t markValue,
+ int32_t markMask) {
// Necessary locking done in IpSecService and kernel
ENFORCE_PERMISSION(NETWORK_STACK);
gLog.log("ipSecAddSecurityPolicy()");
return asBinderStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityPolicy(
- transformId, direction, tmplSrcAddress, tmplDstAddress, markValue, markMask));
+ transformId, selAddrFamily, direction, markValue, markMask));
}
binder::Status NetdNativeService::addVirtualTunnelInterface(
diff --git a/server/NetdNativeService.h b/server/NetdNativeService.h
index 2e77043..b34e363 100644
--- a/server/NetdNativeService.h
+++ b/server/NetdNativeService.h
@@ -151,19 +151,18 @@
binder::Status ipSecRemoveTransportModeTransform(
const android::base::unique_fd& socket);
- binder::Status ipSecAddSecurityPolicy(int32_t transformId, int32_t direction,
- const std::string& tmplSrcAddress,
+ 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);
- binder::Status ipSecUpdateSecurityPolicy(int32_t transformId, int32_t direction,
- const std::string& tmplSrcAddress,
+ 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);
- binder::Status ipSecDeleteSecurityPolicy(int32_t transformId, int32_t direction,
- const std::string& tmplSrcAddress,
- const std::string& tmplDstAddress, int32_t markValue,
+ binder::Status ipSecDeleteSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
+ int32_t direction, int32_t markValue,
int32_t markMask);
binder::Status trafficCheckBpfStatsEnable(bool* ret) override;
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index eae6928..f915814 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -464,8 +464,8 @@
ALOGD("inSpi=%0.8x", inSpi);
XfrmSaInfo saInfo{};
- netdutils::Status ret =
- fillXfrmId(sourceAddress, destinationAddress, INVALID_SPI, 0, 0, transformId, &saInfo);
+ netdutils::Status ret = fillXfrmCommonInfo(sourceAddress, destinationAddress, INVALID_SPI, 0, 0,
+ transformId, &saInfo);
if (!isOk(ret)) {
return ret;
}
@@ -519,8 +519,8 @@
ALOGD("encapRemotePort=%d", encapRemotePort);
XfrmSaInfo saInfo{};
- netdutils::Status ret = fillXfrmId(sourceAddress, destinationAddress, spi, markValue, markMask,
- transformId, &saInfo);
+ netdutils::Status ret = fillXfrmCommonInfo(sourceAddress, destinationAddress, spi, markValue,
+ markMask, transformId, &saInfo);
if (!isOk(ret)) {
return ret;
}
@@ -589,9 +589,9 @@
ALOGD("markValue=%x", markValue);
ALOGD("markMask=%x", markMask);
- XfrmId saId{};
- netdutils::Status ret =
- fillXfrmId(sourceAddress, destinationAddress, spi, markValue, markMask, transformId, &saId);
+ XfrmSaInfo saInfo{};
+ netdutils::Status ret = fillXfrmCommonInfo(sourceAddress, destinationAddress, spi, markValue,
+ markMask, transformId, &saInfo);
if (!isOk(ret)) {
return ret;
}
@@ -603,7 +603,7 @@
return socketStatus;
}
- ret = deleteSecurityAssociation(saId, sock);
+ ret = deleteSecurityAssociation(saInfo, sock);
if (!isOk(ret)) {
ALOGD("Failed to delete Security Association, line=%d", __LINE__);
}
@@ -611,16 +611,11 @@
return ret;
}
-netdutils::Status XfrmController::fillXfrmId(const std::string& sourceAddress,
- const std::string& destinationAddress, int32_t spi,
- int32_t markValue, int32_t markMask,
- int32_t transformId, XfrmId* xfrmId) {
- // Fill the straightforward fields first
- xfrmId->transformId = transformId;
- xfrmId->spi = htonl(spi);
- xfrmId->mark.v = markValue;
- xfrmId->mark.m = markMask;
-
+netdutils::Status XfrmController::fillXfrmCommonInfo(const std::string& sourceAddress,
+ const std::string& destinationAddress,
+ int32_t spi, int32_t markValue,
+ int32_t markMask, int32_t transformId,
+ XfrmCommonInfo* info) {
// Use the addresses to determine the address family and do validation
xfrm_address_t sourceXfrmAddr{}, destXfrmAddr{};
StatusOr<int> sourceFamily, destFamily;
@@ -638,10 +633,22 @@
return netdutils::statusFromErrno(EINVAL, "Invalid or mismatched address families");
}
- xfrmId->addrFamily = destFamily.value();
+ info->addrFamily = destFamily.value();
- xfrmId->dstAddr = destXfrmAddr;
- xfrmId->srcAddr = sourceXfrmAddr;
+ info->dstAddr = destXfrmAddr;
+ info->srcAddr = sourceXfrmAddr;
+
+ return fillXfrmCommonInfo(spi, markValue, markMask, transformId, info);
+}
+
+netdutils::Status XfrmController::fillXfrmCommonInfo(int32_t spi, int32_t markValue,
+ int32_t markMask, int32_t transformId,
+ XfrmCommonInfo* info) {
+ info->transformId = transformId;
+ info->spi = htonl(spi);
+ info->mark.v = markValue;
+ info->mark.m = markMask;
+
return netdutils::status::ok;
}
@@ -662,18 +669,23 @@
}
struct sockaddr_storage saddr = ret.value();
- XfrmSaInfo saInfo{};
+ XfrmSpInfo spInfo{};
netdutils::Status status =
- fillXfrmId(sourceAddress, destinationAddress, spi, 0, 0, transformId, &saInfo);
+ fillXfrmCommonInfo(sourceAddress, destinationAddress, spi, 0, 0, transformId, &spInfo);
if (!isOk(status)) {
ALOGE("Couldn't build SA ID %s", __FUNCTION__);
return status;
}
- if (saddr.ss_family == AF_INET && saInfo.addrFamily != AF_INET) {
+ spInfo.selAddrFamily = spInfo.addrFamily;
+
+ // Allow dual stack sockets. Dual stack sockets are guaranteed to never have an AF_INET source
+ // address; the source address would instead be an IPv4-mapped address. Thus, disallow AF_INET
+ // sockets with mismatched address families (All other cases are acceptable).
+ if (saddr.ss_family == AF_INET && spInfo.addrFamily != AF_INET) {
ALOGE("IPV4 socket address family(%d) should match IPV4 Transform "
"address family(%d)!",
- saddr.ss_family, saInfo.addrFamily);
+ saddr.ss_family, spInfo.addrFamily);
return netdutils::statusFromErrno(EINVAL, "Mismatched address family");
}
@@ -682,8 +694,8 @@
xfrm_user_tmpl tmpl;
} policy{};
- fillTransportModeUserSpInfo(saInfo, static_cast<XfrmDirection>(direction), &policy.info);
- fillUserTemplate(saInfo, &policy.tmpl);
+ fillUserSpInfo(spInfo, static_cast<XfrmDirection>(direction), &policy.info);
+ fillUserTemplate(spInfo, &policy.tmpl);
LOG_HEX("XfrmUserPolicy", reinterpret_cast<char*>(&policy), sizeof(policy));
@@ -744,38 +756,40 @@
return status;
}
-netdutils::Status XfrmController::ipSecAddSecurityPolicy(int32_t transformId, int32_t direction,
+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) {
- return processSecurityPolicy(transformId, direction, tmplSrcAddress, tmplDstAddress, spi,
- markValue, markMask, XFRM_MSG_NEWPOLICY);
+ return processSecurityPolicy(transformId, selAddrFamily, direction, tmplSrcAddress,
+ tmplDstAddress, spi, markValue, markMask, XFRM_MSG_NEWPOLICY);
}
-netdutils::Status XfrmController::ipSecUpdateSecurityPolicy(int32_t transformId, int32_t direction,
- const std::string& tmplSrcAddress,
- const std::string& tmplDstAddress,
- int32_t spi, int32_t markValue,
+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) {
+ return processSecurityPolicy(transformId, selAddrFamily, direction, tmplSrcAddress,
+ tmplDstAddress, spi, markValue, markMask, XFRM_MSG_UPDPOLICY);
+}
+
+netdutils::Status XfrmController::ipSecDeleteSecurityPolicy(int32_t transformId,
+ int32_t selAddrFamily,
+ int32_t direction, int32_t markValue,
int32_t markMask) {
- return processSecurityPolicy(transformId, direction, tmplSrcAddress, tmplDstAddress, spi,
- markValue, markMask, XFRM_MSG_UPDPOLICY);
+ return processSecurityPolicy(transformId, selAddrFamily, direction, "", "", 0, markValue,
+ markMask, XFRM_MSG_DELPOLICY);
}
-netdutils::Status XfrmController::ipSecDeleteSecurityPolicy(int32_t transformId, int32_t direction,
- const std::string& tmplSrcAddress,
- const std::string& tmplDstAddress,
- int32_t markValue, int32_t markMask) {
- return processSecurityPolicy(transformId, direction, tmplSrcAddress, tmplDstAddress, 0,
- markValue, markMask, XFRM_MSG_DELPOLICY);
-}
-
-netdutils::Status XfrmController::processSecurityPolicy(int32_t transformId, int32_t direction,
+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) {
ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
+ ALOGD("selAddrFamily=%s", selAddrFamily == AF_INET6 ? "AF_INET6" : "AF_INET");
ALOGD("transformId=%d", transformId);
ALOGD("direction=%d", direction);
ALOGD("tmplSrcAddress=%s", tmplSrcAddress.c_str());
@@ -785,25 +799,33 @@
ALOGD("markMask=%d", markMask);
ALOGD("msgType=%d", msgType);
- XfrmSaInfo saInfo{};
- saInfo.mode = XfrmMode::TUNNEL;
+ XfrmSpInfo spInfo{};
+ spInfo.mode = XfrmMode::TUNNEL;
XfrmSocketImpl sock;
RETURN_IF_NOT_OK(sock.open());
- RETURN_IF_NOT_OK(fillXfrmId(tmplSrcAddress, tmplDstAddress, spi, markValue, markMask,
- transformId, &saInfo));
+ // Set the correct address families. Tunnel mode policies use wildcard selectors, while
+ // templates have addresses set. These may be different address families. This method is called
+ // separately for IPv4 and IPv6 policies, and thus only need to map a single inner address
+ // family to the outer address families.
+ spInfo.selAddrFamily = selAddrFamily;
if (msgType == XFRM_MSG_DELPOLICY) {
- return deleteTunnelModeSecurityPolicy(saInfo, sock, static_cast<XfrmDirection>(direction));
+ RETURN_IF_NOT_OK(fillXfrmCommonInfo(spi, markValue, markMask, transformId, &spInfo));
+
+ return deleteTunnelModeSecurityPolicy(spInfo, sock, static_cast<XfrmDirection>(direction));
} else {
- return updateTunnelModeSecurityPolicy(saInfo, sock, static_cast<XfrmDirection>(direction),
+ RETURN_IF_NOT_OK(fillXfrmCommonInfo(tmplSrcAddress, tmplDstAddress, spi, markValue,
+ markMask, transformId, &spInfo));
+
+ return updateTunnelModeSecurityPolicy(spInfo, sock, static_cast<XfrmDirection>(direction),
msgType);
}
}
-void XfrmController::fillXfrmSelector(const XfrmSaInfo& record, xfrm_selector* selector) {
- selector->family = record.addrFamily;
+void XfrmController::fillXfrmSelector(const int selAddrFamily, xfrm_selector* selector) {
+ selector->family = selAddrFamily;
selector->proto = AF_UNSPEC; // TODO: do we need to match the protocol? it's
// possible via the socket
}
@@ -960,7 +982,9 @@
}
int XfrmController::fillUserSaInfo(const XfrmSaInfo& record, xfrm_usersa_info* usersa) {
- fillXfrmSelector(record, &usersa->sel);
+ // Use AF_UNSPEC for all SAs. In transport mode, kernel picks selector family based on
+ // usersa->family, while in tunnel mode, the XFRM_STATE_AF_UNSPEC flag allows dual-stack SAs.
+ fillXfrmSelector(AF_UNSPEC, &usersa->sel);
usersa->id.proto = IPPROTO_ESP;
usersa->id.spi = record.spi;
@@ -985,7 +1009,7 @@
return sizeof(*usersa);
}
-int XfrmController::fillUserSaId(const XfrmId& record, xfrm_usersa_id* said) {
+int XfrmController::fillUserSaId(const XfrmCommonInfo& record, xfrm_usersa_id* said) {
said->daddr = record.dstAddr;
said->spi = record.spi;
said->family = record.addrFamily;
@@ -994,7 +1018,7 @@
return sizeof(*said);
}
-netdutils::Status XfrmController::deleteSecurityAssociation(const XfrmId& record,
+netdutils::Status XfrmController::deleteSecurityAssociation(const XfrmCommonInfo& record,
const XfrmSocket& sock) {
xfrm_usersa_id said{};
nlattr_xfrm_mark xfrmmark{};
@@ -1067,7 +1091,7 @@
return ret;
}
-netdutils::Status XfrmController::updateTunnelModeSecurityPolicy(const XfrmSaInfo& record,
+netdutils::Status XfrmController::updateTunnelModeSecurityPolicy(const XfrmSpInfo& record,
const XfrmSocket& sock,
XfrmDirection direction,
uint16_t msgType) {
@@ -1096,7 +1120,7 @@
};
int len;
- len = iov[USERPOLICY].iov_len = fillTransportModeUserSpInfo(record, direction, &userpolicy);
+ len = iov[USERPOLICY].iov_len = fillUserSpInfo(record, direction, &userpolicy);
iov[USERPOLICY_PAD].iov_len = NLMSG_ALIGN(len) - len;
len = iov[USERTMPL].iov_len = fillNlAttrUserTemplate(record, &usertmpl);
@@ -1108,7 +1132,7 @@
return sock.sendMessage(msgType, NETLINK_REQUEST_FLAGS, 0, &iov);
}
-netdutils::Status XfrmController::deleteTunnelModeSecurityPolicy(const XfrmSaInfo& record,
+netdutils::Status XfrmController::deleteTunnelModeSecurityPolicy(const XfrmSpInfo& record,
const XfrmSocket& sock,
XfrmDirection direction) {
xfrm_userpolicy_id policyid{};
@@ -1139,9 +1163,9 @@
return sock.sendMessage(XFRM_MSG_DELPOLICY, NETLINK_REQUEST_FLAGS, 0, &iov);
}
-int XfrmController::fillTransportModeUserSpInfo(const XfrmSaInfo& record, XfrmDirection direction,
- xfrm_userpolicy_info* usersp) {
- fillXfrmSelector(record, &usersp->sel);
+int XfrmController::fillUserSpInfo(const XfrmSpInfo& record, XfrmDirection direction,
+ xfrm_userpolicy_info* usersp) {
+ fillXfrmSelector(record.selAddrFamily, &usersp->sel);
fillXfrmLifetimeDefaults(&usersp->lft);
fillXfrmCurLifetimeDefaults(&usersp->curlft);
/* if (index) index & 0x3 == dir -- must be true
@@ -1154,7 +1178,7 @@
return sizeof(*usersp);
}
-int XfrmController::fillUserTemplate(const XfrmSaInfo& record, xfrm_user_tmpl* tmpl) {
+int XfrmController::fillUserTemplate(const XfrmSpInfo& record, xfrm_user_tmpl* tmpl) {
tmpl->id.daddr = record.dstAddr;
tmpl->id.spi = record.spi;
tmpl->id.proto = IPPROTO_ESP;
@@ -1173,7 +1197,7 @@
return sizeof(xfrm_user_tmpl*);
}
-int XfrmController::fillNlAttrUserTemplate(const XfrmSaInfo& record, nlattr_user_tmpl* tmpl) {
+int XfrmController::fillNlAttrUserTemplate(const XfrmSpInfo& record, nlattr_user_tmpl* tmpl) {
fillUserTemplate(record, &tmpl->tmpl);
int len = NLA_HDRLEN + sizeof(xfrm_user_tmpl);
@@ -1181,7 +1205,7 @@
return len;
}
-int XfrmController::fillNlAttrXfrmMark(const XfrmId& record, nlattr_xfrm_mark* mark) {
+int XfrmController::fillNlAttrXfrmMark(const XfrmCommonInfo& record, nlattr_xfrm_mark* mark) {
mark->mark.v = record.mark.v; // set to 0 if it's not used
mark->mark.m = record.mark.m; // set to 0 if it's not used
int len = NLA_HDRLEN + sizeof(xfrm_mark);
@@ -1202,10 +1226,10 @@
return len;
}
-int XfrmController::fillUserPolicyId(const XfrmSaInfo& record, XfrmDirection direction,
+int XfrmController::fillUserPolicyId(const XfrmSpInfo& record, XfrmDirection direction,
xfrm_userpolicy_id* usersp) {
// For DELPOLICY, when index is absent, selector is needed to match the policy
- fillXfrmSelector(record, &usersp->sel);
+ fillXfrmSelector(record.selAddrFamily, &usersp->sel);
usersp->dir = static_cast<uint8_t>(direction);
return sizeof(*usersp);
}
diff --git a/server/XfrmController.h b/server/XfrmController.h
index 96a2fae..851f976 100644
--- a/server/XfrmController.h
+++ b/server/XfrmController.h
@@ -103,7 +103,7 @@
};
// minimally sufficient structure to match either an SA or a Policy
-struct XfrmId {
+struct XfrmCommonInfo {
xfrm_address_t dstAddr; // network order
xfrm_address_t srcAddr;
int addrFamily; // AF_INET or AF_INET6
@@ -112,7 +112,7 @@
xfrm_mark mark;
};
-struct XfrmSaInfo : XfrmId {
+struct XfrmSaInfo : XfrmCommonInfo {
XfrmAlgo auth;
XfrmAlgo crypt;
XfrmAlgo aead;
@@ -121,6 +121,12 @@
XfrmEncap encap;
};
+struct XfrmSpInfo : XfrmSaInfo {
+ // Address family in XfrmCommonInfo used for template/SA matching, need separate addrFamily
+ // for selectors
+ int selAddrFamily; // AF_INET or AF_INET6
+};
+
class XfrmController {
public:
XfrmController();
@@ -157,21 +163,22 @@
static netdutils::Status
ipSecRemoveTransportModeTransform(const android::base::unique_fd& socket);
- static netdutils::Status ipSecAddSecurityPolicy(int32_t transformId, int32_t direction,
+ static netdutils::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);
- static netdutils::Status ipSecUpdateSecurityPolicy(int32_t transformId, int32_t direction,
+ 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);
- static netdutils::Status ipSecDeleteSecurityPolicy(int32_t transformId, int32_t direction,
- const std::string& tmplSrcAddress,
- const std::string& tmplDstAddress,
- int32_t markValue, int32_t markMask);
+ static netdutils::Status ipSecDeleteSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
+ int32_t direction, int32_t markValue,
+ int32_t markMask);
static int addVirtualTunnelInterface(const std::string& deviceName,
const std::string& localAddress,
@@ -300,11 +307,13 @@
"is needed.");
#endif
- // helper function for filling in the XfrmId (and XfrmSaInfo) structure
- static netdutils::Status fillXfrmId(const std::string& sourceAddress,
- const std::string& destinationAddress, int32_t spi,
- int32_t markValue, int32_t markMask, int32_t transformId,
- XfrmId* xfrmId);
+ // helper functions for filling in the XfrmCommonInfo (and XfrmSaInfo) structure
+ 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);
+ static netdutils::Status fillXfrmCommonInfo(int32_t spi, int32_t markValue, int32_t markMask,
+ int32_t transformId, XfrmCommonInfo* info);
// Top level functions for managing a Transport Mode Transform
static netdutils::Status addTransportModeTransform(const XfrmSaInfo& record);
@@ -312,7 +321,7 @@
// TODO(messagerefactor): FACTOR OUT ALL MESSAGE BUILDING CODE BELOW HERE
// Shared between SA and SP
- static void fillXfrmSelector(const XfrmSaInfo& record, xfrm_selector* selector);
+ static void fillXfrmSelector(const int record, xfrm_selector* selector);
// Shared between Transport and Tunnel Mode
static int fillNlAttrXfrmAlgoEnc(const XfrmAlgo& in_algo, nlattr_algo_crypt* algo);
@@ -326,33 +335,34 @@
static int fillUserSaInfo(const XfrmSaInfo& record, xfrm_usersa_info* usersa);
// Functions for deleting a Transport Mode SA
- static netdutils::Status deleteSecurityAssociation(const XfrmId& record,
+ static netdutils::Status deleteSecurityAssociation(const XfrmCommonInfo& record,
const XfrmSocket& sock);
- static int fillUserSaId(const XfrmId& record, xfrm_usersa_id* said);
- static int fillUserTemplate(const XfrmSaInfo& record, xfrm_user_tmpl* tmpl);
+ static int fillUserSaId(const XfrmCommonInfo& record, xfrm_usersa_id* said);
+ static int fillUserTemplate(const XfrmSpInfo& record, xfrm_user_tmpl* tmpl);
- static int fillTransportModeUserSpInfo(const XfrmSaInfo& record, XfrmDirection direction,
- xfrm_userpolicy_info* usersp);
- static int fillNlAttrUserTemplate(const XfrmSaInfo& record, nlattr_user_tmpl* tmpl);
- static int fillUserPolicyId(const XfrmSaInfo& record, XfrmDirection direction,
+ static int fillUserSpInfo(const XfrmSpInfo& record, XfrmDirection direction,
+ xfrm_userpolicy_info* usersp);
+ static int fillNlAttrUserTemplate(const XfrmSpInfo& record, nlattr_user_tmpl* tmpl);
+ static int fillUserPolicyId(const XfrmSpInfo& record, XfrmDirection direction,
xfrm_userpolicy_id* policy_id);
- static int fillNlAttrXfrmMark(const XfrmId& record, nlattr_xfrm_mark* mark);
+ static int fillNlAttrXfrmMark(const XfrmCommonInfo& record, nlattr_xfrm_mark* mark);
static int fillNlAttrXfrmOutputMark(const __u32 output_mark_value,
nlattr_xfrm_output_mark* output_mark);
static netdutils::Status allocateSpi(const XfrmSaInfo& record, uint32_t minSpi, uint32_t maxSpi,
uint32_t* outSpi, const XfrmSocket& sock);
- static netdutils::Status processSecurityPolicy(int32_t transformId, int32_t direction,
+ static netdutils::Status 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);
- static netdutils::Status updateTunnelModeSecurityPolicy(const XfrmSaInfo& record,
+ static netdutils::Status updateTunnelModeSecurityPolicy(const XfrmSpInfo& record,
const XfrmSocket& sock,
XfrmDirection direction,
uint16_t msgType);
- static netdutils::Status deleteTunnelModeSecurityPolicy(const XfrmSaInfo& record,
+ static netdutils::Status deleteTunnelModeSecurityPolicy(const XfrmSpInfo& record,
const XfrmSocket& sock,
XfrmDirection direction);
static netdutils::Status flushInterfaces();
diff --git a/server/XfrmControllerTest.cpp b/server/XfrmControllerTest.cpp
index d868d9b..692f158 100644
--- a/server/XfrmControllerTest.cpp
+++ b/server/XfrmControllerTest.cpp
@@ -255,7 +255,7 @@
xfrm_userspi_info userspi{};
netdutils::extract(nlMsgSlice, userspi);
- EXPECT_EQ(family, userspi.info.sel.family);
+ EXPECT_EQ(AF_UNSPEC, userspi.info.sel.family);
expectAddressEquals(family, localAddr, userspi.info.saddr);
expectAddressEquals(family, remoteAddr, userspi.info.id.daddr);
@@ -551,8 +551,8 @@
XfrmController ctrl;
Status res = ctrl.ipSecAddSecurityPolicy(
- 1 /* resourceId */, static_cast<int>(XfrmDirection::OUT), localAddr, remoteAddr,
- 0 /* SPI */, TEST_XFRM_MARK, TEST_XFRM_MASK);
+ 1 /* resourceId */, family, static_cast<int>(XfrmDirection::OUT), localAddr, remoteAddr,
+ 0 /* SPI */, TEST_XFRM_MARK, TEST_XFRM_MASK);
EXPECT_TRUE(isOk(res)) << res;
EXPECT_EQ(expectedMsgLength, nlMsgBuf.size());
@@ -596,6 +596,7 @@
TEST_P(XfrmControllerParameterizedTest, TestIpSecUpdateSecurityPolicy) {
const int version = GetParam();
+ const int family = (version == 6) ? AF_INET6 : AF_INET;
const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
@@ -615,8 +616,8 @@
XfrmController ctrl;
Status res = ctrl.ipSecUpdateSecurityPolicy(
- 1 /* resourceId */, static_cast<int>(XfrmDirection::OUT), localAddr, remoteAddr,
- 0 /* SPI */, 0 /* Mark */, 0 /* Mask */);
+ 1 /* resourceId */, family, static_cast<int>(XfrmDirection::OUT), localAddr, remoteAddr,
+ 0 /* SPI */, 0 /* Mark */, 0 /* Mask */);
EXPECT_TRUE(isOk(res)) << res;
EXPECT_EQ(expectedMsgLength, nlMsgBuf.size());
@@ -629,6 +630,7 @@
TEST_P(XfrmControllerParameterizedTest, TestIpSecDeleteSecurityPolicy) {
const int version = GetParam();
+ const int family = (version == 6) ? AF_INET6 : AF_INET;
const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
@@ -646,9 +648,9 @@
.WillOnce(DoAll(SetArgSlice<1>(responseSlice), Return(responseSlice)));
XfrmController ctrl;
- Status res = ctrl.ipSecDeleteSecurityPolicy(
- 1 /* resourceId */, static_cast<int>(XfrmDirection::OUT), localAddr, remoteAddr,
- TEST_XFRM_MARK, TEST_XFRM_MASK);
+ Status res = ctrl.ipSecDeleteSecurityPolicy(1 /* resourceId */, family,
+ static_cast<int>(XfrmDirection::OUT),
+ TEST_XFRM_MARK, TEST_XFRM_MASK);
EXPECT_TRUE(isOk(res)) << res;
EXPECT_EQ(expectedMsgLength, nlMsgBuf.size());
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
index a98f0f7..3ed4f8c 100644
--- a/server/binder/android/net/INetd.aidl
+++ b/server/binder/android/net/INetd.aidl
@@ -432,6 +432,7 @@
* Adds an IPsec global policy.
*
* @param transformId a unique identifier for allocated resources
+ * @param selAddrFamily the address family identifier for the selector
* @param direction DIRECTION_IN or DIRECTION_OUT
* @param tmplSrcAddress InetAddress as string for the sending endpoint
* @param tmplDstAddress InetAddress as string for the receiving endpoint
@@ -441,6 +442,7 @@
*/
void ipSecAddSecurityPolicy(
int transformId,
+ int selAddrFamily,
int direction,
in @utf8InCpp String tmplSrcAddress,
in @utf8InCpp String tmplDstAddress,
@@ -452,6 +454,7 @@
* Updates an IPsec global policy.
*
* @param transformId a unique identifier for allocated resources
+ * @param selAddrFamily the address family identifier for the selector
* @param direction DIRECTION_IN or DIRECTION_OUT
* @param tmplSrcAddress InetAddress as string for the sending endpoint
* @param tmplDstAddress InetAddress as string for the receiving endpoint
@@ -461,6 +464,7 @@
*/
void ipSecUpdateSecurityPolicy(
int transformId,
+ int selAddrFamily,
int direction,
in @utf8InCpp String tmplSrcAddress,
in @utf8InCpp String tmplDstAddress,
@@ -471,18 +475,19 @@
/**
* Deletes an IPsec global policy.
*
+ * Deletion of global policies does not do any matching based on the templates, thus
+ * template source/destination addresses are not needed (as opposed to add/update).
+ *
* @param transformId a unique identifier for allocated resources
+ * @param selAddrFamily the address family identifier for the selector
* @param direction DIRECTION_IN or DIRECTION_OUT
- * @param tmplSrcAddress InetAddress as string for the sending endpoint
- * @param tmplDstAddress InetAddress as string for the receiving endpoint
* @param markValue a 32-bit unique ID chosen by the user
* @param markMask a 32-bit mask chosen by the user
*/
void ipSecDeleteSecurityPolicy(
int transformId,
+ int selAddrFamily,
int direction,
- in @utf8InCpp String tmplSrcAddress,
- in @utf8InCpp String tmplDstAddress,
int markValue,
int markMask);