/*
 * 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 <errno.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

#define LOG_TAG "Netd"
#include <log/log.h>

#include "NetdConstants.h"
#include "NetlinkCommands.h"

namespace android {
namespace net {

int openNetlinkSocket(int protocol) {
    int sock = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, protocol);
    if (sock == -1) {
        return -errno;
    }
    if (connect(sock, reinterpret_cast<const sockaddr*>(&KERNEL_NLADDR),
                sizeof(KERNEL_NLADDR)) == -1) {
        return -errno;
    }
    return sock;
}

int recvNetlinkAck(int sock) {
    struct {
        nlmsghdr msg;
        nlmsgerr err;
    } response;

    int ret = recv(sock, &response, sizeof(response), 0);

    if (ret == -1) {
        ret = -errno;
        ALOGE("netlink recv failed (%s)", strerror(-ret));
        return ret;
    }

    if (ret != sizeof(response)) {
        ALOGE("bad netlink response message size (%d != %zu)", ret, sizeof(response));
        return -EBADMSG;
    }

    return response.err.error;  // Netlink errors are negative errno.
}

// Disable optimizations in ASan build.
// ASan reports an out-of-bounds 32-bit(!) access in the first loop of the function (over iov[]).
// TODO: verify if this bug is still present.
#ifdef __clang__
#if __has_feature(address_sanitizer)
#define OPTNONE [[clang::optnone]]
#endif
#endif

#ifndef OPTNONE
#define OPTNONE /* nop */
#endif

// Sends a netlink request and possibly expects an ack.
// |iov| is an array of struct iovec that contains the netlink message payload.
// The netlink header is generated by this function based on |action| and |flags|.
// Returns -errno if there was an error or if the kernel reported an error.
OPTNONE int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen,
                               const NetlinkDumpCallback* callback) {
    int sock = openNetlinkSocket(NETLINK_ROUTE);
    if (sock < 0) {
        return sock;
    }

    nlmsghdr nlmsg = {
        .nlmsg_type = action,
        .nlmsg_flags = flags,
    };
    iov[0].iov_base = &nlmsg;
    iov[0].iov_len = sizeof(nlmsg);
    for (int i = 0; i < iovlen; ++i) {
        nlmsg.nlmsg_len += iov[i].iov_len;
    }

    ssize_t writevRet = writev(sock, iov, iovlen);
    // Don't let pointers to the stack escape.
    iov[0] = {nullptr, 0};
    int ret = 0;
    if (writevRet == -1) {
        ret = -errno;
        ALOGE("netlink socket connect/writev failed (%s)", strerror(-ret));
        close(sock);
        return ret;
    }

    if (flags & NLM_F_ACK) {
        ret = recvNetlinkAck(sock);
    } else if ((flags & NLM_F_DUMP) && callback != nullptr) {
        ret = processNetlinkDump(sock, *callback);
    }

    close(sock);

    return ret;
}

int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen) {
    return sendNetlinkRequest(action, flags, iov, iovlen, nullptr);
}

int processNetlinkDump(int sock, const NetlinkDumpCallback& callback) {
    char buf[kNetlinkDumpBufferSize];

    ssize_t bytesread;
    do {
        bytesread = read(sock, buf, sizeof(buf));

        if (bytesread < 0) {
            return -errno;
        }

        uint32_t len = bytesread;
        for (nlmsghdr *nlh = reinterpret_cast<nlmsghdr *>(buf);
             NLMSG_OK(nlh, len);
             nlh = NLMSG_NEXT(nlh, len)) {
            switch (nlh->nlmsg_type) {
              case NLMSG_DONE:
                return 0;
              case NLMSG_ERROR: {
                nlmsgerr *err = reinterpret_cast<nlmsgerr *>(NLMSG_DATA(nlh));
                return err->error;
              }
              default:
                callback(nlh);
            }
        }
    } while (bytesread > 0);

    return 0;
}

int rtNetlinkFlush(uint16_t getAction, uint16_t deleteAction, const char* what,
                   const NetlinkDumpFilter& shouldDelete) {
    // RTM_GETxxx is always RTM_DELxxx + 1, see <linux/rtnetlink.h>.
    if (getAction != deleteAction + 1) {
        ALOGE("Unknown flush type getAction=%d deleteAction=%d", getAction, deleteAction);
        return -EINVAL;
    }

    int writeSock = openNetlinkSocket(NETLINK_ROUTE);
    if (writeSock < 0) {
        return writeSock;
    }

    NetlinkDumpCallback callback = [writeSock, deleteAction, shouldDelete, what] (nlmsghdr *nlh) {
        if (!shouldDelete(nlh)) return;

        nlh->nlmsg_type = deleteAction;
        nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
        if (write(writeSock, nlh, nlh->nlmsg_len) == -1) {
            ALOGE("Error writing flush request: %s", strerror(errno));
            return;
        }

        int ret = recvNetlinkAck(writeSock);
        // A flush works by dumping routes and deleting each route as it's returned, and it can
        // fail if something else deletes the route between the dump and the delete. This can
        // happen, for example, if an interface goes down while we're trying to flush its routes.
        // So ignore ENOENT.
        if (ret != 0 && ret != -ENOENT) {
            ALOGW("Flushing %s: %s", what, strerror(-ret));
        }
    };

    int ret = 0;
    for (const int family : { AF_INET, AF_INET6 }) {
        // struct fib_rule_hdr and struct rtmsg are functionally identical.
        rtmsg rule = {
            .rtm_family = static_cast<uint8_t>(family),
        };
        iovec iov[] = {
            { nullptr,  0 },
            { &rule, sizeof(rule) },
        };
        uint16_t flags = NETLINK_DUMP_FLAGS;

        if ((ret = sendNetlinkRequest(getAction, flags, iov, ARRAY_SIZE(iov), &callback)) != 0) {
            break;
        }
    }

    close(writeSock);

    return ret;
}

uint32_t getRtmU32Attribute(const nlmsghdr* nlh, int attribute) {
    uint32_t rta_len = RTM_PAYLOAD(nlh);
    rtmsg *msg = reinterpret_cast<rtmsg *>(NLMSG_DATA(nlh));
    rtattr *rta = reinterpret_cast<rtattr *> RTM_RTA(msg);
    for (; RTA_OK(rta, rta_len); rta = RTA_NEXT(rta, rta_len)) {
        if (rta->rta_type == attribute) {
            return *(static_cast<uint32_t *>(RTA_DATA(rta)));
        }
    }
    return 0;
}

}  // namespace net
}  // namespace android
