Convert return error code in XfrmController to Status
Bug: 62056515
Test: runtest -x tests/netd_integration_test.cpp
Change-Id: I70022ba00f76776c3de05b7df33ce2be840d75ce
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index ceaa2a3..ff07c49 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -152,6 +152,7 @@
}
}
+// TODO: Need to consider a way to refer to the sSycalls instance
inline Syscalls& getSyscallInstance() { return netdutils::sSyscalls.get(); }
#else
@@ -177,35 +178,37 @@
};
public:
- virtual bool open() {
+ netdutils::Status open() override {
mSock = openNetlinkSocket(NETLINK_XFRM);
- if (mSock <= 0) {
+ if (mSock < 0) {
ALOGW("Could not get a new socket, line=%d", __LINE__);
- return false;
+ return netdutils::statusFromErrno(-mSock, "Could not open netlink socket");
}
- return true;
+ return netdutils::status::ok;
}
- static int validateResponse(NetlinkResponse response, size_t len) {
+ static netdutils::Status validateResponse(NetlinkResponse response, size_t len) {
if (len < sizeof(nlmsghdr)) {
ALOGW("Invalid response message received over netlink");
- return -EBADMSG;
+ return netdutils::statusFromErrno(EBADMSG, "Invalid message");
}
switch (response.hdr.nlmsg_type) {
case NLMSG_NOOP:
case NLMSG_DONE:
- return 0;
+ return netdutils::status::ok;
case NLMSG_OVERRUN:
ALOGD("Netlink request overran kernel buffer");
- return -EBADMSG;
+ return netdutils::statusFromErrno(EBADMSG, "Kernel buffer overrun");
case NLMSG_ERROR:
if (len < sizeof(NetlinkResponse::_err_)) {
ALOGD("Netlink message received malformed error response");
- return -EBADMSG;
+ return netdutils::statusFromErrno(EBADMSG, "Malformed error response");
}
- return response.err.err.error; // Netlink errors are negative errno.
+ return netdutils::statusFromErrno(
+ -response.err.err.error,
+ "Error netlink message"); // Netlink errors are negative errno.
case XFRM_MSG_NEWSA:
break;
}
@@ -213,15 +216,15 @@
if (response.hdr.nlmsg_type < XFRM_MSG_BASE /*== NLMSG_MIN_TYPE*/ ||
response.hdr.nlmsg_type > XFRM_MSG_MAX) {
ALOGD("Netlink message responded with an out-of-range message ID");
- return -EBADMSG;
+ return netdutils::statusFromErrno(EBADMSG, "Invalid message ID");
}
// TODO Add more message validation here
- return 0;
+ return netdutils::status::ok;
}
- virtual int sendMessage(uint16_t nlMsgType, uint16_t nlMsgFlags, uint16_t nlMsgSeqNum,
- std::vector<iovec>* iovecs) const {
+ netdutils::Status sendMessage(uint16_t nlMsgType, uint16_t nlMsgFlags, uint16_t nlMsgSeqNum,
+ std::vector<iovec>* iovecs) const override {
nlmsghdr nlMsg = {
.nlmsg_type = nlMsgType, .nlmsg_flags = nlMsgFlags, .nlmsg_seq = nlMsgSeqNum,
};
@@ -239,12 +242,12 @@
StatusOr<size_t> writeResult = getSyscallInstance().writev(mSock, *iovecs);
if (!isOk(writeResult)) {
ALOGE("netlink socket writev failed (%s)", toString(writeResult).c_str());
- return -writeResult.status().code();
+ return writeResult;
}
if (nlMsg.nlmsg_len != writeResult.value()) {
ALOGE("Invalid netlink message length sent %d", static_cast<int>(writeResult.value()));
- return -EBADMSG;
+ return netdutils::statusFromErrno(EBADMSG, "Invalid message length");
}
NetlinkResponse response = {};
@@ -253,20 +256,22 @@
getSyscallInstance().read(Fd(mSock), netdutils::makeSlice(response));
if (!isOk(readResult)) {
ALOGE("netlink response error (%s)", toString(readResult).c_str());
- return -readResult.status().code();
+ return readResult;
}
LOG_HEX("netlink msg resp", reinterpret_cast<char*>(readResult.value().base()),
readResult.value().size());
- int retNum = validateResponse(response, readResult.value().size());
- if (retNum < 0)
- ALOGE("netlink response contains error (%s)", strerror(-retNum));
- return retNum;
+ Status validateStatus = validateResponse(response, readResult.value().size());
+ if (!isOk(validateStatus)) {
+ ALOGE("netlink response contains error (%s)", toString(validateStatus).c_str());
+ }
+
+ return validateStatus;
}
};
-int convertToXfrmAddr(const std::string& strAddr, xfrm_address_t* xfrmAddr) {
+StatusOr<int> convertToXfrmAddr(const std::string& strAddr, xfrm_address_t* xfrmAddr) {
if (strAddr.length() == 0) {
memset(xfrmAddr, 0, sizeof(*xfrmAddr));
return AF_UNSPEC;
@@ -277,7 +282,7 @@
} else if (inet_pton(AF_INET, strAddr.c_str(), reinterpret_cast<void*>(xfrmAddr))) {
return AF_INET;
} else {
- return -EAFNOSUPPORT;
+ return netdutils::statusFromErrno(EAFNOSUPPORT, "Invalid address family");
}
}
@@ -333,10 +338,10 @@
//
XfrmController::XfrmController(void) {}
-int XfrmController::ipSecAllocateSpi(int32_t transformId, int32_t direction,
- const std::string& localAddress,
- const std::string& remoteAddress, int32_t inSpi,
- int32_t* outSpi) {
+netdutils::Status XfrmController::ipSecAllocateSpi(int32_t transformId, int32_t direction,
+ const std::string& localAddress,
+ const std::string& remoteAddress, int32_t inSpi,
+ int32_t* outSpi) {
ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("transformId=%d", transformId);
ALOGD("direction=%d", direction);
@@ -345,25 +350,28 @@
ALOGD("inSpi=%0.8x", inSpi);
XfrmSaInfo saInfo{};
- int ret;
- if ((ret = fillXfrmSaId(direction, localAddress, remoteAddress, INVALID_SPI, &saInfo)) < 0) {
+ netdutils::Status ret =
+ fillXfrmSaId(direction, localAddress, remoteAddress, INVALID_SPI, &saInfo);
+ if (!isOk(ret)) {
return ret;
}
XfrmSocketImpl sock;
- if (!sock.open()) {
+ netdutils::Status socketStatus = sock.open();
+ if (!isOk(socketStatus)) {
ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
- return -1; // TODO: return right error; for whatever reason the sock
- // failed to open
+ return socketStatus;
}
int minSpi = RAND_SPI_MIN, maxSpi = RAND_SPI_MAX;
if (inSpi)
minSpi = maxSpi = inSpi;
+
ret = allocateSpi(saInfo, minSpi, maxSpi, reinterpret_cast<uint32_t*>(outSpi), sock);
- if (ret < 0) {
+ if (!isOk(ret)) {
+ // TODO: May want to return a new Status with a modified status string
ALOGD("Failed to Allocate an SPI, line=%d", __LINE__);
*outSpi = INVALID_SPI;
}
@@ -371,7 +379,7 @@
return ret;
}
-int XfrmController::ipSecAddSecurityAssociation(
+netdutils::Status XfrmController::ipSecAddSecurityAssociation(
int32_t transformId, int32_t mode, int32_t direction, const std::string& localAddress,
const std::string& remoteAddress, int64_t underlyingNetworkHandle, int32_t spi,
const std::string& authAlgo, const std::vector<uint8_t>& authKey, int32_t authTruncBits,
@@ -396,9 +404,8 @@
ALOGD("encapRemotePort=%d", encapRemotePort);
XfrmSaInfo saInfo{};
- int ret;
-
- if ((ret = fillXfrmSaId(direction, localAddress, remoteAddress, spi, &saInfo)) < 0) {
+ netdutils::Status ret = fillXfrmSaId(direction, localAddress, remoteAddress, spi, &saInfo);
+ if (!isOk(ret)) {
return ret;
}
@@ -419,21 +426,21 @@
saInfo.mode = static_cast<XfrmMode>(mode);
break;
default:
- return -EINVAL;
+ return netdutils::statusFromErrno(EINVAL, "Invalid xfrm mode");
}
XfrmSocketImpl sock;
- if (!sock.open()) {
+ netdutils::Status socketStatus = sock.open();
+ if (!isOk(socketStatus)) {
ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
- return -1; // TODO: return right error; for whatever reason the sock
- // failed to open
+ return socketStatus;
}
switch (static_cast<XfrmEncapType>(encapType)) {
case XfrmEncapType::ESPINUDP:
case XfrmEncapType::ESPINUDP_NON_IKE:
if (saInfo.addrFamily != AF_INET) {
- return -EAFNOSUPPORT;
+ return netdutils::statusFromErrno(EAFNOSUPPORT, "IPv6 encap not supported");
}
switch (saInfo.direction) {
case XfrmDirection::IN:
@@ -445,28 +452,29 @@
saInfo.encap.dstPort = encapRemotePort;
break;
default:
- return -EINVAL;
+ return netdutils::statusFromErrno(EINVAL, "Invalid direction");
}
// fall through
case XfrmEncapType::NONE:
saInfo.encap.type = static_cast<XfrmEncapType>(encapType);
break;
default:
- return -EINVAL;
+ return netdutils::statusFromErrno(EINVAL, "Invalid encap type");
}
ret = createTransportModeSecurityAssociation(saInfo, sock);
- if (ret < 0) {
+ if (!isOk(ret)) {
ALOGD("Failed creating a Security Association, line=%d", __LINE__);
- return ret; // something went wrong creating the SA
}
- return 0;
+ return ret;
}
-int XfrmController::ipSecDeleteSecurityAssociation(int32_t transformId, int32_t direction,
- const std::string& localAddress,
- const std::string& remoteAddress, int32_t spi) {
+netdutils::Status XfrmController::ipSecDeleteSecurityAssociation(int32_t transformId,
+ int32_t direction,
+ const std::string& localAddress,
+ const std::string& remoteAddress,
+ int32_t spi) {
ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("transformId=%d", transformId);
ALOGD("direction=%d", direction);
@@ -475,47 +483,48 @@
ALOGD("spi=%0.8x", spi);
XfrmSaId saId;
- int ret;
-
- if ((ret = fillXfrmSaId(direction, localAddress, remoteAddress, spi, &saId)) < 0) {
+ netdutils::Status ret = fillXfrmSaId(direction, localAddress, remoteAddress, spi, &saId);
+ if (!isOk(ret)) {
return ret;
}
XfrmSocketImpl sock;
- if (!sock.open()) {
+ netdutils::Status socketStatus = sock.open();
+ if (!isOk(socketStatus)) {
ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
- return -1; // TODO: return right error; for whatever reason the sock
- // failed to open
+ return socketStatus;
}
ret = deleteSecurityAssociation(saId, sock);
- if (ret < 0) {
+ if (!isOk(ret)) {
ALOGD("Failed to delete Security Association, line=%d", __LINE__);
- return ret; // something went wrong deleting the SA
}
return ret;
}
-int XfrmController::fillXfrmSaId(int32_t direction, const std::string& localAddress,
- const std::string& remoteAddress, int32_t spi, XfrmSaId* xfrmId) {
+netdutils::Status XfrmController::fillXfrmSaId(int32_t direction, const std::string& localAddress,
+ const std::string& remoteAddress, int32_t spi,
+ XfrmSaId* xfrmId) {
xfrm_address_t localXfrmAddr{}, remoteXfrmAddr{};
- int addrFamilyLocal, addrFamilyRemote;
+ StatusOr<int> addrFamilyLocal, addrFamilyRemote;
addrFamilyRemote = convertToXfrmAddr(remoteAddress, &remoteXfrmAddr);
addrFamilyLocal = convertToXfrmAddr(localAddress, &localXfrmAddr);
- if (addrFamilyRemote < 0 || addrFamilyLocal < 0) {
- return -EINVAL;
+ if (!isOk(addrFamilyRemote) || !isOk(addrFamilyLocal)) {
+ return netdutils::statusFromErrno(EINVAL,
+ "Invalid address " + localAddress + "/" + remoteAddress);
}
- if (addrFamilyRemote == AF_UNSPEC ||
- (addrFamilyLocal != AF_UNSPEC && addrFamilyLocal != addrFamilyRemote)) {
- ALOGD("Invalid or Mismatched Address Families, %d != %d, line=%d", addrFamilyLocal,
- addrFamilyRemote, __LINE__);
- return -EINVAL;
+ if (addrFamilyRemote.value() == AF_UNSPEC ||
+ (addrFamilyLocal.value() != AF_UNSPEC &&
+ addrFamilyLocal.value() != addrFamilyRemote.value())) {
+ ALOGD("Invalid or Mismatched Address Families, %d != %d, line=%d", addrFamilyLocal.value(),
+ addrFamilyRemote.value(), __LINE__);
+ return netdutils::statusFromErrno(EINVAL, "Invalid or mismatched address families");
}
- xfrmId->addrFamily = addrFamilyRemote;
+ xfrmId->addrFamily = addrFamilyRemote.value();
xfrmId->spi = htonl(spi);
@@ -533,16 +542,14 @@
default:
ALOGD("Invalid XFRM direction, line=%d", __LINE__);
// Invalid direction for Transport mode transform: time to bail
- return -EINVAL;
+ return netdutils::statusFromErrno(EINVAL, "Invalid direction");
}
- return 0;
+ return netdutils::status::ok;
}
-int XfrmController::ipSecApplyTransportModeTransform(const android::base::unique_fd& socket,
- int32_t transformId, int32_t direction,
- const std::string& localAddress,
- const std::string& remoteAddress,
- int32_t spi) {
+netdutils::Status XfrmController::ipSecApplyTransportModeTransform(
+ const android::base::unique_fd& socket, int32_t transformId, int32_t direction,
+ const std::string& localAddress, const std::string& remoteAddress, int32_t spi) {
ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("transformId=%d", transformId);
ALOGD("direction=%d", direction);
@@ -552,12 +559,10 @@
struct sockaddr_storage saddr;
- int err;
-
StatusOr<sockaddr_storage> ret = getSyscallInstance().getsockname<sockaddr_storage>(Fd(socket));
if (!isOk(ret)) {
ALOGE("Failed to get socket info in %s", __FUNCTION__);
- return -ret.status().code();
+ return ret;
}
saddr = ret.value();
@@ -567,16 +572,17 @@
saInfo.direction = static_cast<XfrmDirection>(direction);
saInfo.spi = spi;
- if ((err = fillXfrmSaId(direction, localAddress, remoteAddress, spi, &saInfo)) < 0) {
+ netdutils::Status status = fillXfrmSaId(direction, localAddress, remoteAddress, spi, &saInfo);
+ if (!isOk(status)) {
ALOGE("Couldn't build SA ID %s", __FUNCTION__);
- return -err;
+ return status;
}
if (saInfo.addrFamily != saddr.ss_family) {
ALOGE("Transform address family(%d) differs from socket address "
"family(%d)!",
saInfo.addrFamily, saddr.ss_family);
- return -EINVAL;
+ return netdutils::statusFromErrno(EINVAL, "Mismatched address family");
}
struct {
@@ -600,19 +606,21 @@
sockLayer = SOL_IPV6;
break;
default:
- return -EAFNOSUPPORT;
+ return netdutils::statusFromErrno(EAFNOSUPPORT, "Invalid address family");
}
- Status status = getSyscallInstance().setsockopt(Fd(socket), sockLayer, sockOpt, policy);
+ status = getSyscallInstance().setsockopt(Fd(socket), sockLayer, sockOpt, policy);
if (!isOk(status)) {
ALOGE("Error setting socket option for XFRM! (%s)", toString(status).c_str());
}
- return -status.code();
+
+ return status;
}
-int XfrmController::ipSecRemoveTransportModeTransform(const android::base::unique_fd& socket) {
+netdutils::Status
+XfrmController::ipSecRemoveTransportModeTransform(const android::base::unique_fd& socket) {
(void)socket;
- return 0;
+ return netdutils::status::ok;
}
void XfrmController::fillTransportModeSelector(const XfrmSaInfo& record, xfrm_selector* selector) {
@@ -622,8 +630,8 @@
selector->ifindex = record.netId; // TODO : still need to sort this out
}
-int XfrmController::createTransportModeSecurityAssociation(const XfrmSaInfo& record,
- const XfrmSocket& sock) {
+netdutils::Status XfrmController::createTransportModeSecurityAssociation(const XfrmSaInfo& record,
+ const XfrmSocket& sock) {
xfrm_usersa_info usersa{};
nlattr_algo_crypt crypt{};
nlattr_algo_auth auth{};
@@ -725,7 +733,8 @@
return sizeof(*said);
}
-int XfrmController::deleteSecurityAssociation(const XfrmSaId& record, const XfrmSocket& sock) {
+netdutils::Status XfrmController::deleteSecurityAssociation(const XfrmSaId& record,
+ const XfrmSocket& sock) {
xfrm_usersa_id said{};
enum { NLMSG_HDR, USERSAID, USERSAID_PAD };
@@ -743,8 +752,9 @@
return sock.sendMessage(XFRM_MSG_DELSA, NETLINK_REQUEST_FLAGS, 0, &iov);
}
-int XfrmController::allocateSpi(const XfrmSaInfo& record, uint32_t minSpi, uint32_t maxSpi,
- uint32_t* outSpi, const XfrmSocket& sock) {
+netdutils::Status XfrmController::allocateSpi(const XfrmSaInfo& record, uint32_t minSpi,
+ uint32_t maxSpi, uint32_t* outSpi,
+ const XfrmSocket& sock) {
xfrm_userspi_info spiInfo{};
enum { NLMSG_HDR, USERSAID, USERSAID_PAD };
@@ -764,22 +774,23 @@
iov[USERSAID_PAD].iov_len = NLMSG_ALIGN(len) - len;
RandomSpi spiGen = RandomSpi(minSpi, maxSpi);
- int spi, ret;
+ int spi;
+ netdutils::Status ret;
while ((spi = spiGen.next()) != INVALID_SPI) {
spiInfo.min = spi;
spiInfo.max = spi;
ret = sock.sendMessage(XFRM_MSG_ALLOCSPI, NETLINK_REQUEST_FLAGS, 0, &iov);
/* If the SPI is in use, we'll get ENOENT */
- if (ret == -ENOENT)
+ if (netdutils::equalToErrno(ret, ENOENT))
continue;
- if (ret == 0) {
+ if (isOk(ret)) {
*outSpi = spi;
ALOGD("Allocated an SPI: %x", *outSpi);
} else {
*outSpi = INVALID_SPI;
- ALOGE("SPI Allocation Failed with error %d", ret);
+ ALOGE("SPI Allocation Failed with error %d", ret.code());
}
return ret;