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

#define LOG_TAG "Netd"
#include <cutils/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.
}

// 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.
#ifdef __clang__
#if __has_feature(address_sanitizer)
__attribute__((optnone))
#endif
#endif
WARN_UNUSED_RESULT int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen,
                                          const NetlinkDumpCallback *callback) {
    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;
    }

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

    int ret = 0;

    if (writev(sock, iov, iovlen) == -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;
}

WARN_UNUSED_RESULT 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[] = {
            { NULL,  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
