Add output mark to XfrmController
Adds the ability for XfrmController to set output marks, to allow
support for VTIs. This change uses the underlying networkId field
(renamed from underlyingNetwork), for which the System Server currently
passes the netid of the underlying Network.
Bug: 72392543
Test: All tests (CTS + unit tests) passing
Change-Id: I76fe052ecf0fc193f07713a2ea31a4ad58fc9ff9
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index f34a33b..25d3bad 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -414,7 +414,7 @@
netdutils::Status XfrmController::ipSecAddSecurityAssociation(
int32_t transformId, int32_t mode, const std::string& sourceAddress,
- const std::string& destinationAddress, int64_t underlyingNetworkHandle, int32_t spi,
+ 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,
@@ -425,7 +425,7 @@
ALOGD("mode=%d", mode);
ALOGD("sourceAddress=%s", sourceAddress.c_str());
ALOGD("destinationAddress=%s", destinationAddress.c_str());
- ALOGD("underlyingNetworkHandle=%" PRIx64, underlyingNetworkHandle);
+ ALOGD("underlyingNetworkId=%d", underlyingNetId);
ALOGD("spi=%0.8x", spi);
ALOGD("markValue=%x", markValue);
ALOGD("markMask=%x", markMask);
@@ -489,6 +489,8 @@
return netdutils::statusFromErrno(EINVAL, "Invalid encap type");
}
+ saInfo.netId = underlyingNetId;
+
ret = updateSecurityAssociation(saInfo, sock);
if (!isOk(ret)) {
ALOGD("Failed updating a Security Association, line=%d", __LINE__);
@@ -725,7 +727,6 @@
selector->family = record.addrFamily;
selector->proto = AF_UNSPEC; // TODO: do we need to match the protocol? it's
// possible via the socket
- selector->ifindex = record.netId; // TODO : still need to sort this out
}
netdutils::Status XfrmController::updateSecurityAssociation(const XfrmSaInfo& record,
@@ -735,6 +736,7 @@
nlattr_algo_auth auth{};
nlattr_algo_aead aead{};
nlattr_xfrm_mark xfrmmark{};
+ nlattr_xfrm_output_mark xfrmoutputmark{};
nlattr_encap_tmpl encap{};
enum {
@@ -749,24 +751,28 @@
AEAD_PAD,
MARK,
MARK_PAD,
+ OUTPUT_MARK,
+ OUTPUT_MARK_PAD,
ENCAP,
ENCAP_PAD,
};
std::vector<iovec> iov = {
- {NULL, 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
- {&encap, 0}, // adjust size if encapsulating
- {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
+ {NULL, 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
};
if (!record.aead.name.empty() && (!record.auth.name.empty() || !record.crypt.name.empty())) {
@@ -796,6 +802,9 @@
len = iov[MARK].iov_len = fillNlAttrXfrmMark(record, &xfrmmark);
iov[MARK_PAD].iov_len = NLA_ALIGN(len) - len;
+ len = iov[OUTPUT_MARK].iov_len = fillNlAttrXfrmOutputMark(record.netId, &xfrmoutputmark);
+ iov[OUTPUT_MARK_PAD].iov_len = NLA_ALIGN(len) - len;
+
len = iov[ENCAP].iov_len = fillNlAttrXfrmEncapTmpl(record, &encap);
iov[ENCAP_PAD].iov_len = NLA_ALIGN(len) - len;
@@ -1101,6 +1110,19 @@
return len;
}
+int XfrmController::fillNlAttrXfrmOutputMark(
+ const __u32 output_mark_value, nlattr_xfrm_output_mark* output_mark) {
+ // Do not set if we were not given an output mark
+ if (output_mark_value == 0) {
+ return 0;
+ }
+
+ output_mark->outputMark = output_mark_value;
+ int len = NLA_HDRLEN + sizeof(__u32);
+ fillXfrmNlaHdr(&output_mark->hdr, XFRMA_OUTPUT_MARK, len);
+ return len;
+}
+
int XfrmController::fillUserPolicyId(const XfrmSaInfo& record, XfrmDirection direction,
xfrm_userpolicy_id* usersp) {
// For DELPOLICY, when index is absent, selector is needed to match the policy