/*
 *
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <random>
#include <string>
#include <vector>

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>

#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <linux/in.h>
#include <linux/ipsec.h>
#include <linux/netlink.h>
#include <linux/xfrm.h>

#define LOG_TAG "XfrmController"
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <android/net/INetd.h>
#include <cutils/properties.h>
#include <log/log.h>
#include <log/log_properties.h>
#include "Fwmark.h"
#include "InterfaceController.h"
#include "NetdConstants.h"
#include "NetlinkCommands.h"
#include "Permission.h"
#include "XfrmController.h"
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "android-base/unique_fd.h"
#include "netdutils/DumpWriter.h"
#include "netdutils/Fd.h"
#include "netdutils/Slice.h"
#include "netdutils/Syscalls.h"

using android::net::INetd;
using android::netdutils::DumpWriter;
using android::netdutils::Fd;
using android::netdutils::ScopedIndent;
using android::netdutils::Slice;
using android::netdutils::Status;
using android::netdutils::StatusOr;
using android::netdutils::Syscalls;

namespace android {
namespace net {

// Exposed for testing
constexpr uint32_t ALGO_MASK_AUTH_ALL = ~0;
// Exposed for testing
constexpr uint32_t ALGO_MASK_CRYPT_ALL = ~0;
// Exposed for testing
constexpr uint32_t ALGO_MASK_AEAD_ALL = ~0;
// Exposed for testing
constexpr uint8_t REPLAY_WINDOW_SIZE = 4;

namespace {

constexpr uint32_t RAND_SPI_MIN = 256;
constexpr uint32_t RAND_SPI_MAX = 0xFFFFFFFE;

constexpr uint32_t INVALID_SPI = 0;
constexpr const char* INFO_KIND_VTI = "vti";
constexpr const char* INFO_KIND_VTI6 = "vti6";
constexpr const char* INFO_KIND_XFRMI = "xfrm";
constexpr int INFO_KIND_MAX_LEN = 8;
constexpr int LOOPBACK_IFINDEX = 1;

bool mIsXfrmIntfSupported = false;

static inline bool isEngBuild() {
    static const std::string sBuildType = android::base::GetProperty("ro.build.type", "user");
    return sBuildType == "eng";
}

#define XFRM_MSG_TRANS(x)                                                                          \
    case x:                                                                                        \
        return #x;

const char* xfrmMsgTypeToString(uint16_t msg) {
    switch (msg) {
        XFRM_MSG_TRANS(XFRM_MSG_NEWSA)
        XFRM_MSG_TRANS(XFRM_MSG_DELSA)
        XFRM_MSG_TRANS(XFRM_MSG_GETSA)
        XFRM_MSG_TRANS(XFRM_MSG_NEWPOLICY)
        XFRM_MSG_TRANS(XFRM_MSG_DELPOLICY)
        XFRM_MSG_TRANS(XFRM_MSG_GETPOLICY)
        XFRM_MSG_TRANS(XFRM_MSG_ALLOCSPI)
        XFRM_MSG_TRANS(XFRM_MSG_ACQUIRE)
        XFRM_MSG_TRANS(XFRM_MSG_EXPIRE)
        XFRM_MSG_TRANS(XFRM_MSG_UPDPOLICY)
        XFRM_MSG_TRANS(XFRM_MSG_UPDSA)
        XFRM_MSG_TRANS(XFRM_MSG_POLEXPIRE)
        XFRM_MSG_TRANS(XFRM_MSG_FLUSHSA)
        XFRM_MSG_TRANS(XFRM_MSG_FLUSHPOLICY)
        XFRM_MSG_TRANS(XFRM_MSG_NEWAE)
        XFRM_MSG_TRANS(XFRM_MSG_GETAE)
        XFRM_MSG_TRANS(XFRM_MSG_REPORT)
        XFRM_MSG_TRANS(XFRM_MSG_MIGRATE)
        XFRM_MSG_TRANS(XFRM_MSG_NEWSADINFO)
        XFRM_MSG_TRANS(XFRM_MSG_GETSADINFO)
        XFRM_MSG_TRANS(XFRM_MSG_GETSPDINFO)
        XFRM_MSG_TRANS(XFRM_MSG_NEWSPDINFO)
        XFRM_MSG_TRANS(XFRM_MSG_MAPPING)
        default:
            return "XFRM_MSG UNKNOWN";
    }
}

// actually const but cannot be declared as such for reasons
uint8_t kPadBytesArray[] = {0, 0, 0};
void* kPadBytes = static_cast<void*>(kPadBytesArray);

#define LOG_HEX(__desc16__, __buf__, __len__)                                                      \
    do {                                                                                           \
        if (isEngBuild()) {                                                                        \
            logHex(__desc16__, __buf__, __len__);                                                  \
        }                                                                                          \
    } while (0)

#define LOG_IOV(__iov__)                                                                           \
    do {                                                                                           \
        if (isEngBuild()) {                                                                        \
            logIov(__iov__);                                                                       \
        }                                                                                          \
    } while (0)

void logHex(const char* desc16, const char* buf, size_t len) {
    char* printBuf = new char[len * 2 + 1 + 26]; // len->ascii, +newline, +prefix strlen
    int offset = 0;
    if (desc16) {
        sprintf(printBuf, "{%-16s}", desc16);
        offset += 18; // prefix string length
    }
    sprintf(printBuf + offset, "[%4.4u]: ", (len > 9999) ? 9999 : (unsigned)len);
    offset += 8;

    for (uint32_t j = 0; j < (uint32_t)len; j++) {
        sprintf(&printBuf[j * 2 + offset], "%0.2x", (unsigned char)buf[j]);
    }
    ALOGD("%s", printBuf);
    delete[] printBuf;
}

void logIov(const std::vector<iovec>& iov) {
    for (const iovec& row : iov) {
        logHex(nullptr, reinterpret_cast<char*>(row.iov_base), row.iov_len);
    }
}

size_t fillNlAttr(__u16 nlaType, size_t valueSize, nlattr* nlAttr) {
    size_t dataLen = valueSize;
    int padLength = NLMSG_ALIGN(dataLen) - dataLen;
    nlAttr->nla_len = (__u16)(dataLen + sizeof(nlattr));
    nlAttr->nla_type = nlaType;
    return padLength;
}

size_t fillNlAttrIpAddress(__u16 nlaType, int family, const std::string& value, nlattr* nlAttr,
                           Slice ipAddress) {
    inet_pton(family, value.c_str(), ipAddress.base());
    return fillNlAttr(nlaType, (family == AF_INET) ? sizeof(in_addr) : sizeof(in6_addr), nlAttr);
}

size_t fillNlAttrU32(__u16 nlaType, uint32_t value, XfrmController::nlattr_payload_u32* nlAttr) {
    nlAttr->value = value;
    return fillNlAttr(nlaType, sizeof(value), &nlAttr->hdr);
}

// returns the address family, placing the string in the provided buffer
StatusOr<uint16_t> convertStringAddress(const std::string& addr, uint8_t* buffer) {
    if (inet_pton(AF_INET, addr.c_str(), buffer) == 1) {
        return AF_INET;
    } else if (inet_pton(AF_INET6, addr.c_str(), buffer) == 1) {
        return AF_INET6;
    } else {
        return Status(EAFNOSUPPORT);
    }
}

// TODO: Need to consider a way to refer to the sSycalls instance
inline Syscalls& getSyscallInstance() { return netdutils::sSyscalls.get(); }

class XfrmSocketImpl : public XfrmSocket {
private:
    static constexpr int NLMSG_DEFAULTSIZE = 8192;

    union NetlinkResponse {
        nlmsghdr hdr;
        struct _err_ {
            nlmsghdr hdr;
            nlmsgerr err;
        } err;

        struct _buf_ {
            nlmsghdr hdr;
            char buf[NLMSG_DEFAULTSIZE];
        } buf;
    };

public:
    netdutils::Status open() override {
        mSock = openNetlinkSocket(NETLINK_XFRM);
        if (mSock < 0) {
            ALOGW("Could not get a new socket, line=%d", __LINE__);
            return netdutils::statusFromErrno(-mSock, "Could not open netlink socket");
        }

        return netdutils::status::ok;
    }

    static netdutils::Status validateResponse(NetlinkResponse response, size_t len) {
        if (len < sizeof(nlmsghdr)) {
            ALOGW("Invalid response message received over netlink");
            return netdutils::statusFromErrno(EBADMSG, "Invalid message");
        }

        switch (response.hdr.nlmsg_type) {
            case NLMSG_NOOP:
            case NLMSG_DONE:
                return netdutils::status::ok;
            case NLMSG_OVERRUN:
                ALOGD("Netlink request overran kernel buffer");
                return netdutils::statusFromErrno(EBADMSG, "Kernel buffer overrun");
            case NLMSG_ERROR:
                if (len < sizeof(NetlinkResponse::_err_)) {
                    ALOGD("Netlink message received malformed error response");
                    return netdutils::statusFromErrno(EBADMSG, "Malformed error response");
                }
                return netdutils::statusFromErrno(
                    -response.err.err.error,
                    "Error netlink message"); // Netlink errors are negative errno.
            case XFRM_MSG_NEWSA:
                break;
        }

        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 netdutils::statusFromErrno(EBADMSG, "Invalid message ID");
        }

        // TODO Add more message validation here
        return netdutils::status::ok;
    }

    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,
        };

        (*iovecs)[0].iov_base = &nlMsg;
        (*iovecs)[0].iov_len = NLMSG_HDRLEN;
        for (const iovec& iov : *iovecs) {
            nlMsg.nlmsg_len += iov.iov_len;
        }

        ALOGD("Sending Netlink XFRM Message: %s", xfrmMsgTypeToString(nlMsgType));
        LOG_IOV(*iovecs);

        StatusOr<size_t> writeResult = getSyscallInstance().writev(mSock, *iovecs);
        if (!isOk(writeResult)) {
            ALOGE("netlink socket writev failed (%s)", toString(writeResult).c_str());
            return writeResult;
        }

        if (nlMsg.nlmsg_len != writeResult.value()) {
            ALOGE("Invalid netlink message length sent %d", static_cast<int>(writeResult.value()));
            return netdutils::statusFromErrno(EBADMSG, "Invalid message length");
        }

        NetlinkResponse response = {};

        StatusOr<Slice> readResult =
            getSyscallInstance().read(Fd(mSock), netdutils::makeSlice(response));
        if (!isOk(readResult)) {
            ALOGE("netlink response error (%s)", toString(readResult).c_str());
            return readResult;
        }

        LOG_HEX("netlink msg resp", reinterpret_cast<char*>(readResult.value().base()),
                readResult.value().size());

        Status validateStatus = validateResponse(response, readResult.value().size());
        if (!isOk(validateStatus)) {
            ALOGE("netlink response contains error (%s)", toString(validateStatus).c_str());
        }

        return validateStatus;
    }
};

StatusOr<int> convertToXfrmAddr(const std::string& strAddr, xfrm_address_t* xfrmAddr) {
    if (strAddr.length() == 0) {
        memset(xfrmAddr, 0, sizeof(*xfrmAddr));
        return AF_UNSPEC;
    }

    if (inet_pton(AF_INET6, strAddr.c_str(), reinterpret_cast<void*>(xfrmAddr))) {
        return AF_INET6;
    } else if (inet_pton(AF_INET, strAddr.c_str(), reinterpret_cast<void*>(xfrmAddr))) {
        return AF_INET;
    } else {
        return netdutils::statusFromErrno(EAFNOSUPPORT, "Invalid address family");
    }
}

void fillXfrmNlaHdr(nlattr* hdr, uint16_t type, uint16_t len) {
    hdr->nla_type = type;
    hdr->nla_len = len;
}

void fillXfrmCurLifetimeDefaults(xfrm_lifetime_cur* cur) {
    memset(reinterpret_cast<char*>(cur), 0, sizeof(*cur));
}
void fillXfrmLifetimeDefaults(xfrm_lifetime_cfg* cfg) {
    cfg->soft_byte_limit = XFRM_INF;
    cfg->hard_byte_limit = XFRM_INF;
    cfg->soft_packet_limit = XFRM_INF;
    cfg->hard_packet_limit = XFRM_INF;
}

/*
 * Allocate SPIs within an (inclusive) range of min-max.
 * returns 0 (INVALID_SPI) once the entire range has been parsed.
 */
class RandomSpi {
public:
    RandomSpi(int min, int max) : mMin(min) {
        // Re-seeding should be safe because the seed itself is
        // sufficiently random and we don't need secure random
        std::mt19937 rnd = std::mt19937(std::random_device()());
        mNext = std::uniform_int_distribution<>(1, INT_MAX)(rnd);
        mSize = max - min + 1;
        mCount = mSize;
    }

    uint32_t next() {
        if (!mCount)
            return 0;
        mCount--;
        return (mNext++ % mSize) + mMin;
    }

private:
    uint32_t mNext;
    uint32_t mSize;
    uint32_t mMin;
    uint32_t mCount;
};

} // namespace

//
// Begin XfrmController Impl
//
//
XfrmController::XfrmController(void) {}

// Test-only constructor allowing override of XFRM Interface support checks
XfrmController::XfrmController(bool xfrmIntfSupport) {
    mIsXfrmIntfSupported = xfrmIntfSupport;
}

netdutils::Status XfrmController::Init() {
    RETURN_IF_NOT_OK(flushInterfaces());
    mIsXfrmIntfSupported = isXfrmIntfSupported();

    XfrmSocketImpl sock;
    RETURN_IF_NOT_OK(sock.open());
    RETURN_IF_NOT_OK(flushSaDb(sock));
    return flushPolicyDb(sock);
}

netdutils::Status XfrmController::flushInterfaces() {
    const auto& ifaces = InterfaceController::getIfaceNames();
    RETURN_IF_NOT_OK(ifaces);
    const String8 ifPrefix8 = String8(INetd::IPSEC_INTERFACE_PREFIX().string());

    for (const std::string& iface : ifaces.value()) {
        netdutils::Status status;
        // Look for the reserved interface prefix, which must be in the name at position 0
        if (android::base::StartsWith(iface.c_str(), ifPrefix8.c_str())) {
            RETURN_IF_NOT_OK(ipSecRemoveTunnelInterface(iface));
        }
    }
    return netdutils::status::ok;
}

netdutils::Status XfrmController::flushSaDb(const XfrmSocket& s) {
    struct xfrm_usersa_flush flushUserSa = {.proto = IPSEC_PROTO_ANY};

    std::vector<iovec> iov = {{nullptr, 0}, // reserved for the eventual addition of a NLMSG_HDR
                              {&flushUserSa, sizeof(flushUserSa)}, // xfrm_usersa_flush structure
                              {kPadBytes, NLMSG_ALIGN(sizeof(flushUserSa)) - sizeof(flushUserSa)}};

    return s.sendMessage(XFRM_MSG_FLUSHSA, NETLINK_REQUEST_FLAGS, 0, &iov);
}

netdutils::Status XfrmController::flushPolicyDb(const XfrmSocket& s) {
    std::vector<iovec> iov = {{nullptr, 0}}; // reserved for the eventual addition of a NLMSG_HDR
    return s.sendMessage(XFRM_MSG_FLUSHPOLICY, NETLINK_REQUEST_FLAGS, 0, &iov);
}

bool XfrmController::isXfrmIntfSupported() {
    const char* IPSEC_TEST_INTF_NAME = "ipsec_test";
    const int32_t XFRM_TEST_IF_ID = 0xFFFF;

    bool errored = false;
    errored |=
            ipSecAddXfrmInterface(IPSEC_TEST_INTF_NAME, XFRM_TEST_IF_ID, NETLINK_ROUTE_CREATE_FLAGS)
                    .code();
    errored |= ipSecRemoveTunnelInterface(IPSEC_TEST_INTF_NAME).code();
    return !errored;
}

netdutils::Status XfrmController::ipSecSetEncapSocketOwner(int socketFd, int newUid,
                                                           uid_t callerUid) {
    ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);

    const int fd = socketFd;
    struct stat info;
    if (fstat(fd, &info)) {
        return netdutils::statusFromErrno(errno, "Failed to stat socket file descriptor");
    }
    if (info.st_uid != callerUid) {
        return netdutils::statusFromErrno(EPERM, "fchown disabled for non-owner calls");
    }
    if (S_ISSOCK(info.st_mode) == 0) {
        return netdutils::statusFromErrno(EINVAL, "File descriptor was not a socket");
    }

    int optval;
    socklen_t optlen = sizeof(optval);
    netdutils::Status status =
            getSyscallInstance().getsockopt(Fd(fd), IPPROTO_UDP, UDP_ENCAP, &optval, &optlen);
    if (status != netdutils::status::ok) {
        return status;
    }
    if (optval != UDP_ENCAP_ESPINUDP && optval != UDP_ENCAP_ESPINUDP_NON_IKE) {
        return netdutils::statusFromErrno(EINVAL, "Socket did not have UDP-encap sockopt set");
    }
    if (fchown(fd, newUid, -1)) {
        return netdutils::statusFromErrno(errno, "Failed to fchown socket file descriptor");
    }

    return netdutils::status::ok;
}

netdutils::Status XfrmController::ipSecAllocateSpi(int32_t transformId,
                                                   const std::string& sourceAddress,
                                                   const std::string& destinationAddress,
                                                   int32_t inSpi, int32_t* outSpi) {
    ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
    ALOGD("transformId=%d", transformId);
    ALOGD("sourceAddress=%s", sourceAddress.c_str());
    ALOGD("destinationAddress=%s", destinationAddress.c_str());
    ALOGD("inSpi=%0.8x", inSpi);

    XfrmSaInfo saInfo{};
    netdutils::Status ret = fillXfrmCommonInfo(sourceAddress, destinationAddress, INVALID_SPI, 0, 0,
                                               transformId, 0, &saInfo);
    if (!isOk(ret)) {
        return ret;
    }

    XfrmSocketImpl sock;
    netdutils::Status socketStatus = sock.open();
    if (!isOk(socketStatus)) {
        ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
        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 (!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;
    }

    return ret;
}

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 xfrmInterfaceId) {
    ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
    ALOGD("transformId=%d", transformId);
    ALOGD("mode=%d", mode);
    ALOGD("sourceAddress=%s", sourceAddress.c_str());
    ALOGD("destinationAddress=%s", destinationAddress.c_str());
    ALOGD("underlyingNetworkId=%d", underlyingNetId);
    ALOGD("spi=%0.8x", spi);
    ALOGD("markValue=%x", markValue);
    ALOGD("markMask=%x", markMask);
    ALOGD("authAlgo=%s", authAlgo.c_str());
    ALOGD("authTruncBits=%d", authTruncBits);
    ALOGD("cryptAlgo=%s", cryptAlgo.c_str());
    ALOGD("cryptTruncBits=%d,", cryptTruncBits);
    ALOGD("aeadAlgo=%s", aeadAlgo.c_str());
    ALOGD("aeadIcvBits=%d,", aeadIcvBits);
    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, xfrmInterfaceId, &saInfo);
    if (!isOk(ret)) {
        return ret;
    }

    saInfo.auth = XfrmAlgo{
        .name = authAlgo, .key = authKey, .truncLenBits = static_cast<uint16_t>(authTruncBits)};

    saInfo.crypt = XfrmAlgo{
        .name = cryptAlgo, .key = cryptKey, .truncLenBits = static_cast<uint16_t>(cryptTruncBits)};

    saInfo.aead = XfrmAlgo{
        .name = aeadAlgo, .key = aeadKey, .truncLenBits = static_cast<uint16_t>(aeadIcvBits)};

    switch (static_cast<XfrmMode>(mode)) {
        case XfrmMode::TRANSPORT:
        case XfrmMode::TUNNEL:
            saInfo.mode = static_cast<XfrmMode>(mode);
            break;
        default:
            return netdutils::statusFromErrno(EINVAL, "Invalid xfrm mode");
    }

    XfrmSocketImpl sock;
    netdutils::Status socketStatus = sock.open();
    if (!isOk(socketStatus)) {
        ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
        return socketStatus;
    }

    switch (static_cast<XfrmEncapType>(encapType)) {
        case XfrmEncapType::ESPINUDP:
        case XfrmEncapType::ESPINUDP_NON_IKE:
            if (saInfo.addrFamily != AF_INET) {
                return netdutils::statusFromErrno(EAFNOSUPPORT, "IPv6 encap not supported");
            }
            // The ports are not used on input SAs, so this is OK to be wrong when
            // direction is ultimately input.
            saInfo.encap.srcPort = encapLocalPort;
            saInfo.encap.dstPort = encapRemotePort;
            [[fallthrough]];
        case XfrmEncapType::NONE:
            saInfo.encap.type = static_cast<XfrmEncapType>(encapType);
            break;
        default:
            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__);
    }

    return ret;
}

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 xfrmInterfaceId) {
    ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
    ALOGD("transformId=%d", transformId);
    ALOGD("sourceAddress=%s", sourceAddress.c_str());
    ALOGD("destinationAddress=%s", destinationAddress.c_str());
    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, xfrmInterfaceId, &saInfo);
    if (!isOk(ret)) {
        return ret;
    }

    XfrmSocketImpl sock;
    netdutils::Status socketStatus = sock.open();
    if (!isOk(socketStatus)) {
        ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
        return socketStatus;
    }

    ret = deleteSecurityAssociation(saInfo, sock);
    if (!isOk(ret)) {
        ALOGD("Failed to delete Security Association, line=%d", __LINE__);
    }

    return ret;
}

netdutils::Status XfrmController::fillXfrmCommonInfo(const std::string& sourceAddress,
                                                     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{};
    StatusOr<int> sourceFamily, destFamily;
    sourceFamily = convertToXfrmAddr(sourceAddress, &sourceXfrmAddr);
    destFamily = convertToXfrmAddr(destinationAddress, &destXfrmAddr);
    if (!isOk(sourceFamily) || !isOk(destFamily)) {
        return netdutils::statusFromErrno(EINVAL, "Invalid address " + sourceAddress + "/" +
                                                      destinationAddress);
    }

    if (destFamily.value() == AF_UNSPEC ||
        (sourceFamily.value() != AF_UNSPEC && sourceFamily.value() != destFamily.value())) {
        ALOGD("Invalid or Mismatched Address Families, %d != %d, line=%d", sourceFamily.value(),
              destFamily.value(), __LINE__);
        return netdutils::statusFromErrno(EINVAL, "Invalid or mismatched address families");
    }

    info->addrFamily = destFamily.value();

    info->dstAddr = destXfrmAddr;
    info->srcAddr = sourceXfrmAddr;

    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);

    if (mIsXfrmIntfSupported) {
        info->xfrm_if_id = xfrmInterfaceId;
    } else {
        info->mark.v = markValue;
        info->mark.m = markMask;
    }

    return netdutils::status::ok;
}

netdutils::Status XfrmController::ipSecApplyTransportModeTransform(
        int socketFd, int32_t transformId, int32_t direction, const std::string& sourceAddress,
        const std::string& destinationAddress, int32_t spi) {
    ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
    ALOGD("transformId=%d", transformId);
    ALOGD("direction=%d", direction);
    ALOGD("sourceAddress=%s", sourceAddress.c_str());
    ALOGD("destinationAddress=%s", destinationAddress.c_str());
    ALOGD("spi=%0.8x", spi);

    StatusOr<sockaddr_storage> ret =
            getSyscallInstance().getsockname<sockaddr_storage>(Fd(socketFd));
    if (!isOk(ret)) {
        ALOGE("Failed to get socket info in %s", __FUNCTION__);
        return ret;
    }
    struct sockaddr_storage saddr = ret.value();

    XfrmSpInfo 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;
    }

    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, spInfo.addrFamily);
        return netdutils::statusFromErrno(EINVAL, "Mismatched address family");
    }

    struct {
        xfrm_userpolicy_info info;
        xfrm_user_tmpl tmpl;
    } policy{};

    fillUserSpInfo(spInfo, static_cast<XfrmDirection>(direction), &policy.info);
    fillUserTemplate(spInfo, &policy.tmpl);

    LOG_HEX("XfrmUserPolicy", reinterpret_cast<char*>(&policy), sizeof(policy));

    int sockOpt, sockLayer;
    switch (saddr.ss_family) {
        case AF_INET:
            sockOpt = IP_XFRM_POLICY;
            sockLayer = SOL_IP;
            break;
        case AF_INET6:
            sockOpt = IPV6_XFRM_POLICY;
            sockLayer = SOL_IPV6;
            break;
        default:
            return netdutils::statusFromErrno(EAFNOSUPPORT, "Invalid address family");
    }

    status = getSyscallInstance().setsockopt(Fd(socketFd), sockLayer, sockOpt, policy);
    if (!isOk(status)) {
        ALOGE("Error setting socket option for XFRM! (%s)", toString(status).c_str());
    }

    return status;
}

netdutils::Status XfrmController::ipSecRemoveTransportModeTransform(int socketFd) {
    ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);

    StatusOr<sockaddr_storage> ret =
            getSyscallInstance().getsockname<sockaddr_storage>(Fd(socketFd));
    if (!isOk(ret)) {
        ALOGE("Failed to get socket info in %s! (%s)", __FUNCTION__, toString(ret).c_str());
        return ret;
    }

    int sockOpt, sockLayer;
    switch (ret.value().ss_family) {
        case AF_INET:
            sockOpt = IP_XFRM_POLICY;
            sockLayer = SOL_IP;
            break;
        case AF_INET6:
            sockOpt = IPV6_XFRM_POLICY;
            sockLayer = SOL_IPV6;
            break;
        default:
            return netdutils::statusFromErrno(EAFNOSUPPORT, "Invalid address family");
    }

    // Kernel will delete the security policy on this socket for both direction
    // if optval is set to NULL and optlen is set to 0.
    netdutils::Status status =
            getSyscallInstance().setsockopt(Fd(socketFd), sockLayer, sockOpt, nullptr, 0);
    if (!isOk(status)) {
        ALOGE("Error removing socket option for XFRM! (%s)", toString(status).c_str());
    }

    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, int32_t xfrmInterfaceId) {
    return processSecurityPolicy(transformId, selAddrFamily, direction, tmplSrcAddress,
                                 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 xfrmInterfaceId) {
    return processSecurityPolicy(transformId, selAddrFamily, direction, tmplSrcAddress,
                                 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 xfrmInterfaceId) {
    return processSecurityPolicy(transformId, selAddrFamily, direction, "", "", 0, markValue,
                                 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 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);
    ALOGD("direction=%d", direction);
    ALOGD("tmplSrcAddress=%s", tmplSrcAddress.c_str());
    ALOGD("tmplDstAddress=%s", tmplDstAddress.c_str());
    ALOGD("spi=%0.8x", spi);
    ALOGD("markValue=%d", markValue);
    ALOGD("markMask=%d", markMask);
    ALOGD("msgType=%d", msgType);
    ALOGD("xfrmInterfaceId=%d", xfrmInterfaceId);

    XfrmSpInfo spInfo{};
    spInfo.mode = XfrmMode::TUNNEL;

    XfrmSocketImpl sock;
    RETURN_IF_NOT_OK(sock.open());

    // 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_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, xfrmInterfaceId, &spInfo));

        return updateTunnelModeSecurityPolicy(spInfo, sock, static_cast<XfrmDirection>(direction),
                                              msgType);
    }
}

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
}

netdutils::Status XfrmController::updateSecurityAssociation(const XfrmSaInfo& record,
                                                            const XfrmSocket& sock) {
    xfrm_usersa_info usersa{};
    nlattr_algo_crypt crypt{};
    nlattr_algo_auth auth{};
    nlattr_algo_aead aead{};
    nlattr_xfrm_mark xfrmmark{};
    nlattr_xfrm_output_mark xfrmoutputmark{};
    nlattr_encap_tmpl encap{};
    nlattr_xfrm_interface_id xfrm_if_id{};

    enum {
        NLMSG_HDR,
        USERSA,
        USERSA_PAD,
        CRYPT,
        CRYPT_PAD,
        AUTH,
        AUTH_PAD,
        AEAD,
        AEAD_PAD,
        MARK,
        MARK_PAD,
        OUTPUT_MARK,
        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
            {&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())) {
        return netdutils::statusFromErrno(EINVAL, "Invalid xfrm algo selection; AEAD is mutually "
                                                  "exclusive with both Authentication and "
                                                  "Encryption");
    }

    if (record.aead.key.size() > MAX_KEY_LENGTH || record.auth.key.size() > MAX_KEY_LENGTH ||
        record.crypt.key.size() > MAX_KEY_LENGTH) {
        return netdutils::statusFromErrno(EINVAL, "Key length invalid; exceeds MAX_KEY_LENGTH");
    }

    if (record.mode != XfrmMode::TUNNEL &&
        (record.xfrm_if_id != 0 || record.netId != 0 || record.mark.v != 0 || record.mark.m != 0)) {
        return netdutils::statusFromErrno(EINVAL,
                                          "xfrm_if_id, mark and netid parameters invalid "
                                          "for non tunnel-mode transform");
    } else if (record.mode == XfrmMode::TUNNEL && !mIsXfrmIntfSupported && record.xfrm_if_id != 0) {
        return netdutils::statusFromErrno(EINVAL, "xfrm_if_id set for VTI Security Association");
    }

    int len;
    len = iov[USERSA].iov_len = fillUserSaInfo(record, &usersa);
    iov[USERSA_PAD].iov_len = NLMSG_ALIGN(len) - len;

    len = iov[CRYPT].iov_len = fillNlAttrXfrmAlgoEnc(record.crypt, &crypt);
    iov[CRYPT_PAD].iov_len = NLA_ALIGN(len) - len;

    len = iov[AUTH].iov_len = fillNlAttrXfrmAlgoAuth(record.auth, &auth);
    iov[AUTH_PAD].iov_len = NLA_ALIGN(len) - len;

    len = iov[AEAD].iov_len = fillNlAttrXfrmAlgoAead(record.aead, &aead);
    iov[AEAD_PAD].iov_len = NLA_ALIGN(len) - len;

    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;

    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);
}

int XfrmController::fillNlAttrXfrmAlgoEnc(const XfrmAlgo& inAlgo, nlattr_algo_crypt* algo) {
    if (inAlgo.name.empty()) { // Do not fill anything if algorithm not provided
        return 0;
    }

    int len = NLA_HDRLEN + sizeof(xfrm_algo);
    // Kernel always changes last char to null terminator; no safety checks needed.
    strncpy(algo->crypt.alg_name, inAlgo.name.c_str(), sizeof(algo->crypt.alg_name));
    algo->crypt.alg_key_len = inAlgo.key.size() * 8; // bits
    memcpy(algo->key, &inAlgo.key[0], inAlgo.key.size());
    len += inAlgo.key.size();
    fillXfrmNlaHdr(&algo->hdr, XFRMA_ALG_CRYPT, len);
    return len;
}

int XfrmController::fillNlAttrXfrmAlgoAuth(const XfrmAlgo& inAlgo, nlattr_algo_auth* algo) {
    if (inAlgo.name.empty()) { // Do not fill anything if algorithm not provided
        return 0;
    }

    int len = NLA_HDRLEN + sizeof(xfrm_algo_auth);
    // Kernel always changes last char to null terminator; no safety checks needed.
    strncpy(algo->auth.alg_name, inAlgo.name.c_str(), sizeof(algo->auth.alg_name));
    algo->auth.alg_key_len = inAlgo.key.size() * 8; // bits

    // This is the extra field for ALG_AUTH_TRUNC
    algo->auth.alg_trunc_len = inAlgo.truncLenBits;

    memcpy(algo->key, &inAlgo.key[0], inAlgo.key.size());
    len += inAlgo.key.size();

    fillXfrmNlaHdr(&algo->hdr, XFRMA_ALG_AUTH_TRUNC, len);
    return len;
}

int XfrmController::fillNlAttrXfrmAlgoAead(const XfrmAlgo& inAlgo, nlattr_algo_aead* algo) {
    if (inAlgo.name.empty()) { // Do not fill anything if algorithm not provided
        return 0;
    }

    int len = NLA_HDRLEN + sizeof(xfrm_algo_aead);
    // Kernel always changes last char to null terminator; no safety checks needed.
    strncpy(algo->aead.alg_name, inAlgo.name.c_str(), sizeof(algo->aead.alg_name));
    algo->aead.alg_key_len = inAlgo.key.size() * 8; // bits

    // This is the extra field for ALG_AEAD. ICV length is the same as truncation length
    // for any AEAD algorithm.
    algo->aead.alg_icv_len = inAlgo.truncLenBits;

    memcpy(algo->key, &inAlgo.key[0], inAlgo.key.size());
    len += inAlgo.key.size();

    fillXfrmNlaHdr(&algo->hdr, XFRMA_ALG_AEAD, len);
    return len;
}

int XfrmController::fillNlAttrXfrmEncapTmpl(const XfrmSaInfo& record, nlattr_encap_tmpl* tmpl) {
    if (record.encap.type == XfrmEncapType::NONE) {
        return 0;
    }

    int len = NLA_HDRLEN + sizeof(xfrm_encap_tmpl);
    tmpl->tmpl.encap_type = static_cast<uint16_t>(record.encap.type);
    tmpl->tmpl.encap_sport = htons(record.encap.srcPort);
    tmpl->tmpl.encap_dport = htons(record.encap.dstPort);
    fillXfrmNlaHdr(&tmpl->hdr, XFRMA_ENCAP, len);
    return len;
}

int XfrmController::fillUserSaInfo(const XfrmSaInfo& record, xfrm_usersa_info* usersa) {
    // 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;
    usersa->id.daddr = record.dstAddr;

    usersa->saddr = record.srcAddr;

    fillXfrmLifetimeDefaults(&usersa->lft);
    fillXfrmCurLifetimeDefaults(&usersa->curlft);
    memset(&usersa->stats, 0, sizeof(usersa->stats)); // leave stats zeroed out
    usersa->reqid = record.transformId;
    usersa->family = record.addrFamily;
    usersa->mode = static_cast<uint8_t>(record.mode);
    usersa->replay_window = REPLAY_WINDOW_SIZE;

    if (record.mode == XfrmMode::TRANSPORT) {
        usersa->flags = 0; // TODO: should we actually set flags, XFRM_SA_XFLAG_DONT_ENCAP_DSCP?
    } else {
        usersa->flags = XFRM_STATE_AF_UNSPEC;
    }

    return sizeof(*usersa);
}

int XfrmController::fillUserSaId(const XfrmCommonInfo& record, xfrm_usersa_id* said) {
    said->daddr = record.dstAddr;
    said->spi = record.spi;
    said->family = record.addrFamily;
    said->proto = IPPROTO_ESP;

    return sizeof(*said);
}

netdutils::Status XfrmController::deleteSecurityAssociation(const XfrmCommonInfo& record,
                                                            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, 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
            {&xfrm_if_id, 0},  // adjust size if interface ID is present
            {kPadBytes, 0},    // up to NLATTR_ALIGNTO pad bytes
    };

    int len;
    len = iov[USERSAID].iov_len = fillUserSaId(record, &said);
    iov[USERSAID_PAD].iov_len = NLMSG_ALIGN(len) - len;

    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);
}

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 };

    std::vector<iovec> iov = {
        {nullptr, 0},      // reserved for the eventual addition of a NLMSG_HDR
        {&spiInfo, 0},  // main userspi_info struct
        {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
    };

    int len;
    if (fillUserSaInfo(record, &spiInfo.info) == 0) {
        ALOGE("Failed to fill transport SA Info");
    }

    len = iov[USERSAID].iov_len = sizeof(spiInfo);
    iov[USERSAID_PAD].iov_len = NLMSG_ALIGN(len) - len;

    RandomSpi spiGen = RandomSpi(minSpi, maxSpi);
    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 (netdutils::equalToErrno(ret, ENOENT))
            continue;

        if (isOk(ret)) {
            *outSpi = spi;
            ALOGD("Allocated an SPI: %x", *outSpi);
        } else {
            *outSpi = INVALID_SPI;
            ALOGE("SPI Allocation Failed with error %d", ret.code());
        }

        return ret;
    }

    // Should always be -ENOENT if we get here
    return ret;
}

netdutils::Status XfrmController::updateTunnelModeSecurityPolicy(const XfrmSpInfo& record,
                                                                 const XfrmSocket& sock,
                                                                 XfrmDirection direction,
                                                                 uint16_t msgType) {
    xfrm_userpolicy_info userpolicy{};
    nlattr_user_tmpl usertmpl{};
    nlattr_xfrm_mark xfrmmark{};
    nlattr_xfrm_interface_id xfrm_if_id{};

    enum {
        NLMSG_HDR,
        USERPOLICY,
        USERPOLICY_PAD,
        USERTMPL,
        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
            {&xfrm_if_id, 0},  // adjust size if interface ID is present
            {kPadBytes, 0},    // up to NLATTR_ALIGNTO pad bytes
    };

    int len;
    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);
    iov[USERTMPL_PAD].iov_len = NLA_ALIGN(len) - len;

    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);
}

netdutils::Status XfrmController::deleteTunnelModeSecurityPolicy(const XfrmSpInfo& record,
                                                                 const XfrmSocket& sock,
                                                                 XfrmDirection direction) {
    xfrm_userpolicy_id policyid{};
    nlattr_xfrm_mark xfrmmark{};
    nlattr_xfrm_interface_id xfrm_if_id{};

    enum {
        NLMSG_HDR,
        USERPOLICYID,
        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
            {&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);
    iov[USERPOLICYID_PAD].iov_len = NLMSG_ALIGN(len) - len;

    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);
}

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
     * xfrm_user.c:verify_newpolicy_info() */
    usersp->index = 0;
    usersp->dir = static_cast<uint8_t>(direction);
    usersp->action = XFRM_POLICY_ALLOW;
    usersp->flags = XFRM_POLICY_LOCALOK;
    usersp->share = XFRM_SHARE_UNIQUE;
    return sizeof(*usersp);
}

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;

    tmpl->family = record.addrFamily;
    tmpl->saddr = record.srcAddr;
    tmpl->reqid = record.transformId;
    tmpl->mode = static_cast<uint8_t>(record.mode);
    tmpl->share = XFRM_SHARE_UNIQUE;
    tmpl->optional = 0; // if this is true, then a failed state lookup will be considered OK:
                        // http://lxr.free-electrons.com/source/net/xfrm/xfrm_policy.c#L1492
    tmpl->aalgos = ALGO_MASK_AUTH_ALL;  // TODO: if there's a bitmask somewhere of
                                        // algos, we should find it and apply it.
                                        // I can't find one.
    tmpl->ealgos = ALGO_MASK_CRYPT_ALL; // TODO: if there's a bitmask somewhere...
    return sizeof(xfrm_user_tmpl*);
}

int XfrmController::fillNlAttrUserTemplate(const XfrmSpInfo& record, nlattr_user_tmpl* tmpl) {
    fillUserTemplate(record, &tmpl->tmpl);

    int len = NLA_HDRLEN + sizeof(xfrm_user_tmpl);
    fillXfrmNlaHdr(&tmpl->hdr, XFRMA_TMPL, len);
    return len;
}

int XfrmController::fillNlAttrXfrmMark(const XfrmCommonInfo& record, nlattr_xfrm_mark* mark) {
    // Do not set if we were not given a mark
    if (record.mark.v == 0 && record.mark.m == 0) {
        return 0;
    }

    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);
    fillXfrmNlaHdr(&mark->hdr, XFRMA_MARK, len);
    return len;
}

// This function sets the output mark (or set-mark in newer kernels) to that of the underlying
// Network's netid. This allows outbound IPsec Tunnel mode packets to be correctly directed to a
// preselected underlying Network. Packet as marked as protected from VPNs and have a network
// explicitly selected to prevent interference or routing loops. Also set permission flag to
// PERMISSION_SYSTEM to ensure we can use background/restricted networks. Permission to use
// restricted networks is checked in IpSecService.
int XfrmController::fillNlAttrXfrmOutputMark(const __u32 underlyingNetId,
                                             nlattr_xfrm_output_mark* output_mark) {
    // Do not set if we were not given an output mark
    if (underlyingNetId == 0) {
        return 0;
    }

    Fwmark fwmark;
    fwmark.netId = underlyingNetId;

    // TODO: Rework this to more accurately follow the underlying network
    fwmark.permission = PERMISSION_SYSTEM;
    fwmark.explicitlySelected = true;
    fwmark.protectedFromVpn = true;
    output_mark->outputMark = fwmark.intValue;

    int len = NLA_HDRLEN + sizeof(__u32);
    fillXfrmNlaHdr(&output_mark->hdr, XFRMA_OUTPUT_MARK, len);
    return len;
}

int XfrmController::fillNlAttrXfrmIntfId(const uint32_t intfIdValue,
                                         nlattr_xfrm_interface_id* intf_id) {
    // Do not set if we were not given an interface id
    if (intfIdValue == 0) {
        return 0;
    }

    intf_id->if_id = intfIdValue;
    int len = NLA_HDRLEN + sizeof(__u32);
    fillXfrmNlaHdr(&intf_id->hdr, XFRMA_IF_ID, len);
    return len;
}

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.selAddrFamily, &usersp->sel);
    usersp->dir = static_cast<uint8_t>(direction);
    return sizeof(*usersp);
}

netdutils::Status XfrmController::ipSecAddTunnelInterface(const std::string& deviceName,
                                                          const std::string& localAddress,
                                                          const std::string& remoteAddress,
                                                          int32_t ikey, int32_t okey,
                                                          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;

    if (mIsXfrmIntfSupported) {
        return ipSecAddXfrmInterface(deviceName, interfaceId, flags);
    } else {
        return ipSecAddVirtualTunnelInterface(deviceName, localAddress, remoteAddress, ikey, okey,
                                              flags);
    }
}

netdutils::Status XfrmController::ipSecAddXfrmInterface(const std::string& deviceName,
                                                        int32_t interfaceId, uint16_t flags) {
    ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);

    if (deviceName.empty()) {
        return netdutils::statusFromErrno(EINVAL, "XFRM Interface deviceName empty");
    }

    ifinfomsg ifInfoMsg{};

    struct XfrmIntfCreateReq {
        nlattr ifNameNla;
        char ifName[IFNAMSIZ];  // Already aligned

        nlattr linkInfoNla;
        struct LinkInfo {
            nlattr infoKindNla;
            char infoKind[INFO_KIND_MAX_LEN];  // Already aligned

            nlattr infoDataNla;
            struct InfoData {
                nlattr xfrmLinkNla;
                uint32_t xfrmLink;

                nlattr xfrmIfIdNla;
                uint32_t xfrmIfId;
            } infoData;  // Already aligned

        } linkInfo;  // Already aligned
    } xfrmIntfCreateReq{
            .ifNameNla =
                    {
                            .nla_len = RTA_LENGTH(IFNAMSIZ),
                            .nla_type = IFLA_IFNAME,
                    },
            // Update .ifName via strlcpy

            .linkInfoNla =
                    {
                            .nla_len = RTA_LENGTH(sizeof(XfrmIntfCreateReq::LinkInfo)),
                            .nla_type = IFLA_LINKINFO,
                    },
            .linkInfo = {.infoKindNla =
                                 {
                                         .nla_len = RTA_LENGTH(INFO_KIND_MAX_LEN),
                                         .nla_type = IFLA_INFO_KIND,
                                 },
                         // Update .infoKind via strlcpy

                         .infoDataNla =
                                 {
                                         .nla_len = RTA_LENGTH(
                                                 sizeof(XfrmIntfCreateReq::LinkInfo::InfoData)),
                                         .nla_type = IFLA_INFO_DATA,
                                 },
                         .infoData = {
                                 .xfrmLinkNla =
                                         {
                                                 .nla_len = RTA_LENGTH(sizeof(uint32_t)),
                                                 .nla_type = IFLA_XFRM_LINK,
                                         },
                                 //   Always use LOOPBACK_IFINDEX, since we use output marks for
                                 //   route lookup instead. The use case of having a Network with
                                 //   loopback in it is unsupported in tunnel mode.
                                 .xfrmLink = static_cast<uint32_t>(LOOPBACK_IFINDEX),

                                 .xfrmIfIdNla =
                                         {
                                                 .nla_len = RTA_LENGTH(sizeof(uint32_t)),
                                                 .nla_type = IFLA_XFRM_IF_ID,
                                         },
                                 .xfrmIfId = static_cast<uint32_t>(interfaceId),
                         }}};

    strlcpy(xfrmIntfCreateReq.ifName, deviceName.c_str(), IFNAMSIZ);
    strlcpy(xfrmIntfCreateReq.linkInfo.infoKind, INFO_KIND_XFRMI, INFO_KIND_MAX_LEN);

    iovec iov[] = {
            {NULL, 0},  // reserved for the eventual addition of a NLMSG_HDR
            {&ifInfoMsg, sizeof(ifInfoMsg)},

            {&xfrmIntfCreateReq, sizeof(xfrmIntfCreateReq)},
    };

    // sendNetlinkRequest returns -errno
    int ret = -sendNetlinkRequest(RTM_NEWLINK, flags, iov, ARRAY_SIZE(iov), nullptr);
    return netdutils::statusFromErrno(ret, "Add/update xfrm interface");
}

netdutils::Status XfrmController::ipSecAddVirtualTunnelInterface(const std::string& deviceName,
                                                                 const std::string& localAddress,
                                                                 const std::string& remoteAddress,
                                                                 int32_t ikey, int32_t okey,
                                                                 uint16_t flags) {
    ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);

    if (deviceName.empty() || localAddress.empty() || remoteAddress.empty()) {
        return netdutils::statusFromErrno(EINVAL, "Required VTI creation parameter not provided");
    }

    uint8_t PADDING_BUFFER[] = {0, 0, 0, 0};

    // Find address family.
    uint8_t remAddr[sizeof(in6_addr)];

    StatusOr<uint16_t> statusOrRemoteFam = convertStringAddress(remoteAddress, remAddr);
    RETURN_IF_NOT_OK(statusOrRemoteFam);

    uint8_t locAddr[sizeof(in6_addr)];
    StatusOr<uint16_t> statusOrLocalFam = convertStringAddress(localAddress, locAddr);
    RETURN_IF_NOT_OK(statusOrLocalFam);

    if (statusOrLocalFam.value() != statusOrRemoteFam.value()) {
        return netdutils::statusFromErrno(EINVAL, "Local and remote address families do not match");
    }

    uint16_t family = statusOrLocalFam.value();

    ifinfomsg ifInfoMsg{};

    // Construct IFLA_IFNAME
    nlattr iflaIfName;
    char iflaIfNameStrValue[deviceName.length() + 1];
    size_t iflaIfNameLength =
        strlcpy(iflaIfNameStrValue, deviceName.c_str(), sizeof(iflaIfNameStrValue));
    size_t iflaIfNamePad = fillNlAttr(IFLA_IFNAME, iflaIfNameLength, &iflaIfName);

    // Construct IFLA_INFO_KIND
    // Constants "vti6" and "vti" enable the kernel to call different code paths,
    // (ip_tunnel.c, ip6_tunnel), based on the family.
    const std::string infoKindValue = (family == AF_INET6) ? INFO_KIND_VTI6 : INFO_KIND_VTI;
    nlattr iflaIfInfoKind;
    char infoKindValueStrValue[infoKindValue.length() + 1];
    size_t iflaIfInfoKindLength =
        strlcpy(infoKindValueStrValue, infoKindValue.c_str(), sizeof(infoKindValueStrValue));
    size_t iflaIfInfoKindPad = fillNlAttr(IFLA_INFO_KIND, iflaIfInfoKindLength, &iflaIfInfoKind);

    // Construct IFLA_VTI_LOCAL
    nlattr iflaVtiLocal;
    uint8_t binaryLocalAddress[sizeof(in6_addr)];
    size_t iflaVtiLocalPad =
        fillNlAttrIpAddress(IFLA_VTI_LOCAL, family, localAddress, &iflaVtiLocal,
                            netdutils::makeSlice(binaryLocalAddress));

    // Construct IFLA_VTI_REMOTE
    nlattr iflaVtiRemote;
    uint8_t binaryRemoteAddress[sizeof(in6_addr)];
    size_t iflaVtiRemotePad =
        fillNlAttrIpAddress(IFLA_VTI_REMOTE, family, remoteAddress, &iflaVtiRemote,
                            netdutils::makeSlice(binaryRemoteAddress));

    // Construct IFLA_VTI_OKEY
    nlattr_payload_u32 iflaVtiIKey;
    size_t iflaVtiIKeyPad = fillNlAttrU32(IFLA_VTI_IKEY, htonl(ikey), &iflaVtiIKey);

    // Construct IFLA_VTI_IKEY
    nlattr_payload_u32 iflaVtiOKey;
    size_t iflaVtiOKeyPad = fillNlAttrU32(IFLA_VTI_OKEY, htonl(okey), &iflaVtiOKey);

    int iflaInfoDataPayloadLength = iflaVtiLocal.nla_len + iflaVtiLocalPad + iflaVtiRemote.nla_len +
                                    iflaVtiRemotePad + iflaVtiIKey.hdr.nla_len + iflaVtiIKeyPad +
                                    iflaVtiOKey.hdr.nla_len + iflaVtiOKeyPad;

    // Construct IFLA_INFO_DATA
    nlattr iflaInfoData;
    size_t iflaInfoDataPad = fillNlAttr(IFLA_INFO_DATA, iflaInfoDataPayloadLength, &iflaInfoData);

    // Construct IFLA_LINKINFO
    nlattr iflaLinkInfo;
    size_t iflaLinkInfoPad = fillNlAttr(IFLA_LINKINFO,
                                        iflaInfoData.nla_len + iflaInfoDataPad +
                                            iflaIfInfoKind.nla_len + iflaIfInfoKindPad,
                                        &iflaLinkInfo);

    iovec iov[] = {
            {nullptr, 0},
            {&ifInfoMsg, sizeof(ifInfoMsg)},

            {&iflaIfName, sizeof(iflaIfName)},
            {iflaIfNameStrValue, iflaIfNameLength},
            {&PADDING_BUFFER, iflaIfNamePad},

            {&iflaLinkInfo, sizeof(iflaLinkInfo)},

            {&iflaIfInfoKind, sizeof(iflaIfInfoKind)},
            {infoKindValueStrValue, iflaIfInfoKindLength},
            {&PADDING_BUFFER, iflaIfInfoKindPad},

            {&iflaInfoData, sizeof(iflaInfoData)},

            {&iflaVtiLocal, sizeof(iflaVtiLocal)},
            {&binaryLocalAddress, (family == AF_INET) ? sizeof(in_addr) : sizeof(in6_addr)},
            {&PADDING_BUFFER, iflaVtiLocalPad},

            {&iflaVtiRemote, sizeof(iflaVtiRemote)},
            {&binaryRemoteAddress, (family == AF_INET) ? sizeof(in_addr) : sizeof(in6_addr)},
            {&PADDING_BUFFER, iflaVtiRemotePad},

            {&iflaVtiIKey, iflaVtiIKey.hdr.nla_len},
            {&PADDING_BUFFER, iflaVtiIKeyPad},

            {&iflaVtiOKey, iflaVtiOKey.hdr.nla_len},
            {&PADDING_BUFFER, iflaVtiOKeyPad},

            {&PADDING_BUFFER, iflaInfoDataPad},

            {&PADDING_BUFFER, iflaLinkInfoPad},
    };

    // sendNetlinkRequest returns -errno
    int ret = -1 * sendNetlinkRequest(RTM_NEWLINK, flags, iov, ARRAY_SIZE(iov), nullptr);
    return netdutils::statusFromErrno(ret, "Failed to add/update virtual tunnel interface");
}

netdutils::Status XfrmController::ipSecRemoveTunnelInterface(const std::string& deviceName) {
    ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
    ALOGD("deviceName=%s", deviceName.c_str());

    if (deviceName.empty()) {
        return netdutils::statusFromErrno(EINVAL, "Required parameter not provided");
    }

    uint8_t PADDING_BUFFER[] = {0, 0, 0, 0};

    ifinfomsg ifInfoMsg{};
    nlattr iflaIfName;
    char iflaIfNameStrValue[deviceName.length() + 1];
    size_t iflaIfNameLength =
        strlcpy(iflaIfNameStrValue, deviceName.c_str(), sizeof(iflaIfNameStrValue));
    size_t iflaIfNamePad = fillNlAttr(IFLA_IFNAME, iflaIfNameLength, &iflaIfName);

    iovec iov[] = {
        {nullptr, 0},
        {&ifInfoMsg, sizeof(ifInfoMsg)},

        {&iflaIfName, sizeof(iflaIfName)},
        {iflaIfNameStrValue, iflaIfNameLength},
        {&PADDING_BUFFER, iflaIfNamePad},
    };

    uint16_t action = RTM_DELLINK;
    uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;

    // sendNetlinkRequest returns -errno
    int ret = -1 * sendNetlinkRequest(action, flags, iov, ARRAY_SIZE(iov), nullptr);
    return netdutils::statusFromErrno(ret, "Error in deleting IpSec interface " + deviceName);
}

void XfrmController::dump(DumpWriter& dw) {
    ScopedIndent indentForXfrmController(dw);
    dw.println("XfrmController");

    ScopedIndent indentForXfrmISupport(dw);
    dw.println("XFRM-I support: %d", mIsXfrmIntfSupported);
}

} // namespace net
} // namespace android
