/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 * Copyright (c) 2012-2014 Cisco Systems
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include <linux/ip.h>
#include <netdb.h>
#include "net/net.h"
#include "clients.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
#include "qemu/sockets.h"
#include "qemu/iov.h"
#include "qemu/main-loop.h"


/* The buffer size needs to be investigated for optimum numbers and
 * optimum means of paging in on different systems. This size is
 * chosen to be sufficient to accommodate one packet with some headers
 */

#define BUFFER_ALIGN sysconf(_SC_PAGESIZE)
#define BUFFER_SIZE 2048
#define IOVSIZE 2
#define MAX_L2TPV3_MSGCNT 64
#define MAX_L2TPV3_IOVCNT (MAX_L2TPV3_MSGCNT * IOVSIZE)

/* Header set to 0x30000 signifies a data packet */

#define L2TPV3_DATA_PACKET 0x30000

/* IANA-assigned IP protocol ID for L2TPv3 */

#ifndef IPPROTO_L2TP
#define IPPROTO_L2TP 0x73
#endif

typedef struct NetL2TPV3State {
    NetClientState nc;
    int fd;

    /*
     * these are used for xmit - that happens packet a time
     * and for first sign of life packet (easier to parse that once)
     */

    uint8_t *header_buf;
    struct iovec *vec;

    /*
     * these are used for receive - try to "eat" up to 32 packets at a time
     */

    struct mmsghdr *msgvec;

    /*
     * peer address
     */

    struct sockaddr_storage *dgram_dst;
    uint32_t dst_size;

    /*
     * L2TPv3 parameters
     */

    uint64_t rx_cookie;
    uint64_t tx_cookie;
    uint32_t rx_session;
    uint32_t tx_session;
    uint32_t header_size;
    uint32_t counter;

    /*
    * DOS avoidance in error handling
    */

    bool header_mismatch;

    /*
     * Ring buffer handling
     */

    int queue_head;
    int queue_tail;
    int queue_depth;

    /*
     * Precomputed offsets
     */

    uint32_t offset;
    uint32_t cookie_offset;
    uint32_t counter_offset;
    uint32_t session_offset;

    /* Poll Control */

    bool read_poll;
    bool write_poll;

    /* Flags */

    bool ipv6;
    bool udp;
    bool has_counter;
    bool pin_counter;
    bool cookie;
    bool cookie_is_64;

} NetL2TPV3State;

static void net_l2tpv3_send(void *opaque);
static void l2tpv3_writable(void *opaque);

static void l2tpv3_update_fd_handler(NetL2TPV3State *s)
{
    qemu_set_fd_handler(s->fd,
                        s->read_poll ? net_l2tpv3_send : NULL,
                        s->write_poll ? l2tpv3_writable : NULL,
                        s);
}

static void l2tpv3_read_poll(NetL2TPV3State *s, bool enable)
{
    if (s->read_poll != enable) {
        s->read_poll = enable;
        l2tpv3_update_fd_handler(s);
    }
}

static void l2tpv3_write_poll(NetL2TPV3State *s, bool enable)
{
    if (s->write_poll != enable) {
        s->write_poll = enable;
        l2tpv3_update_fd_handler(s);
    }
}

static void l2tpv3_writable(void *opaque)
{
    NetL2TPV3State *s = opaque;
    l2tpv3_write_poll(s, false);
    qemu_flush_queued_packets(&s->nc);
}

static void l2tpv3_send_completed(NetClientState *nc, ssize_t len)
{
    NetL2TPV3State *s = DO_UPCAST(NetL2TPV3State, nc, nc);
    l2tpv3_read_poll(s, true);
}

static void l2tpv3_poll(NetClientState *nc, bool enable)
{
    NetL2TPV3State *s = DO_UPCAST(NetL2TPV3State, nc, nc);
    l2tpv3_write_poll(s, enable);
    l2tpv3_read_poll(s, enable);
}

static void l2tpv3_form_header(NetL2TPV3State *s)
{
    uint32_t *counter;

    if (s->udp) {
        stl_be_p((uint32_t *) s->header_buf, L2TPV3_DATA_PACKET);
    }
    stl_be_p(
            (uint32_t *) (s->header_buf + s->session_offset),
            s->tx_session
        );
    if (s->cookie) {
        if (s->cookie_is_64) {
            stq_be_p(
                (uint64_t *)(s->header_buf + s->cookie_offset),
                s->tx_cookie
            );
        } else {
            stl_be_p(
                (uint32_t *) (s->header_buf + s->cookie_offset),
                s->tx_cookie
            );
        }
    }
    if (s->has_counter) {
        counter = (uint32_t *)(s->header_buf + s->counter_offset);
        if (s->pin_counter) {
            *counter = 0;
        } else {
            stl_be_p(counter, ++s->counter);
        }
    }
}

static ssize_t net_l2tpv3_receive_dgram_iov(NetClientState *nc,
                    const struct iovec *iov,
                    int iovcnt)
{
    NetL2TPV3State *s = DO_UPCAST(NetL2TPV3State, nc, nc);

    struct msghdr message;
    int ret;

    if (iovcnt > MAX_L2TPV3_IOVCNT - 1) {
        error_report(
            "iovec too long %d > %d, change l2tpv3.h",
            iovcnt, MAX_L2TPV3_IOVCNT
        );
        return -1;
    }
    l2tpv3_form_header(s);
    memcpy(s->vec + 1, iov, iovcnt * sizeof(struct iovec));
    s->vec->iov_base = s->header_buf;
    s->vec->iov_len = s->offset;
    message.msg_name = s->dgram_dst;
    message.msg_namelen = s->dst_size;
    message.msg_iov = s->vec;
    message.msg_iovlen = iovcnt + 1;
    message.msg_control = NULL;
    message.msg_controllen = 0;
    message.msg_flags = 0;
    do {
        ret = sendmsg(s->fd, &message, 0);
    } while ((ret == -1) && (errno == EINTR));
    if (ret > 0) {
        ret -= s->offset;
    } else if (ret == 0) {
        /* belt and braces - should not occur on DGRAM
        * we should get an error and never a 0 send
        */
        ret = iov_size(iov, iovcnt);
    } else {
        /* signal upper layer that socket buffer is full */
        ret = -errno;
        if (ret == -EAGAIN || ret == -ENOBUFS) {
            l2tpv3_write_poll(s, true);
            ret = 0;
        }
    }
    return ret;
}

static ssize_t net_l2tpv3_receive_dgram(NetClientState *nc,
                    const uint8_t *buf,
                    size_t size)
{
    NetL2TPV3State *s = DO_UPCAST(NetL2TPV3State, nc, nc);

    struct iovec *vec;
    struct msghdr message;
    ssize_t ret = 0;

    l2tpv3_form_header(s);
    vec = s->vec;
    vec->iov_base = s->header_buf;
    vec->iov_len = s->offset;
    vec++;
    vec->iov_base = (void *) buf;
    vec->iov_len = size;
    message.msg_name = s->dgram_dst;
    message.msg_namelen = s->dst_size;
    message.msg_iov = s->vec;
    message.msg_iovlen = 2;
    message.msg_control = NULL;
    message.msg_controllen = 0;
    message.msg_flags = 0;
    do {
        ret = sendmsg(s->fd, &message, 0);
    } while ((ret == -1) && (errno == EINTR));
    if (ret > 0) {
        ret -= s->offset;
    } else if (ret == 0) {
        /* belt and braces - should not occur on DGRAM
        * we should get an error and never a 0 send
        */
        ret = size;
    } else {
        ret = -errno;
        if (ret == -EAGAIN || ret == -ENOBUFS) {
            /* signal upper layer that socket buffer is full */
            l2tpv3_write_poll(s, true);
            ret = 0;
        }
    }
    return ret;
}

static int l2tpv3_verify_header(NetL2TPV3State *s, uint8_t *buf)
{

    uint32_t *session;
    uint64_t cookie;

    if ((!s->udp) && (!s->ipv6)) {
        buf += sizeof(struct iphdr) /* fix for ipv4 raw */;
    }

    /* we do not do a strict check for "data" packets as per
    * the RFC spec because the pure IP spec does not have
    * that anyway.
    */

    if (s->cookie) {
        if (s->cookie_is_64) {
            cookie = ldq_be_p(buf + s->cookie_offset);
        } else {
            cookie = ldl_be_p(buf + s->cookie_offset) & 0xffffffffULL;
        }
        if (cookie != s->rx_cookie) {
            if (!s->header_mismatch) {
                error_report("unknown cookie id");
            }
            return -1;
        }
    }
    session = (uint32_t *) (buf + s->session_offset);
    if (ldl_be_p(session) != s->rx_session) {
        if (!s->header_mismatch) {
            error_report("session mismatch");
        }
        return -1;
    }
    return 0;
}

static void net_l2tpv3_process_queue(NetL2TPV3State *s)
{
    int size = 0;
    struct iovec *vec;
    bool bad_read;
    int data_size;
    struct mmsghdr *msgvec;

    /* go into ring mode only if there is a "pending" tail */
    if (s->queue_depth > 0) {
        do {
            msgvec = s->msgvec + s->queue_tail;
            if (msgvec->msg_len > 0) {
                data_size = msgvec->msg_len - s->header_size;
                vec = msgvec->msg_hdr.msg_iov;
                if ((data_size > 0) &&
                    (l2tpv3_verify_header(s, vec->iov_base) == 0)) {
                    vec++;
                    /* Use the legacy delivery for now, we will
                     * switch to using our own ring as a queueing mechanism
                     * at a later date
                     */
                    size = qemu_send_packet_async(
                            &s->nc,
                            vec->iov_base,
                            data_size,
                            l2tpv3_send_completed
                        );
                    if (size == 0) {
                        l2tpv3_read_poll(s, false);
                    }
                    bad_read = false;
                } else {
                    bad_read = true;
                    if (!s->header_mismatch) {
                        /* report error only once */
                        error_report("l2tpv3 header verification failed");
                        s->header_mismatch = true;
                    }
                }
            } else {
                bad_read = true;
            }
            s->queue_tail = (s->queue_tail + 1) % MAX_L2TPV3_MSGCNT;
            s->queue_depth--;
        } while (
                (s->queue_depth > 0) &&
                 qemu_can_send_packet(&s->nc) &&
                ((size > 0) || bad_read)
            );
    }
}

static void net_l2tpv3_send(void *opaque)
{
    NetL2TPV3State *s = opaque;
    int target_count, count;
    struct mmsghdr *msgvec;

    /* go into ring mode only if there is a "pending" tail */

    if (s->queue_depth) {

        /* The ring buffer we use has variable intake
         * count of how much we can read varies - adjust accordingly
         */

        target_count = MAX_L2TPV3_MSGCNT - s->queue_depth;

        /* Ensure we do not overrun the ring when we have
         * a lot of enqueued packets
         */

        if (s->queue_head + target_count > MAX_L2TPV3_MSGCNT) {
            target_count = MAX_L2TPV3_MSGCNT - s->queue_head;
        }
    } else {

        /* we do not have any pending packets - we can use
        * the whole message vector linearly instead of using
        * it as a ring
        */

        s->queue_head = 0;
        s->queue_tail = 0;
        target_count = MAX_L2TPV3_MSGCNT;
    }

    msgvec = s->msgvec + s->queue_head;
    if (target_count > 0) {
        do {
            count = recvmmsg(
                s->fd,
                msgvec,
                target_count, MSG_DONTWAIT, NULL);
        } while ((count == -1) && (errno == EINTR));
        if (count < 0) {
            /* Recv error - we still need to flush packets here,
             * (re)set queue head to current position
             */
            count = 0;
        }
        s->queue_head = (s->queue_head + count) % MAX_L2TPV3_MSGCNT;
        s->queue_depth += count;
    }
    net_l2tpv3_process_queue(s);
}

static void destroy_vector(struct mmsghdr *msgvec, int count, int iovcount)
{
    int i, j;
    struct iovec *iov;
    struct mmsghdr *cleanup = msgvec;
    if (cleanup) {
        for (i = 0; i < count; i++) {
            if (cleanup->msg_hdr.msg_iov) {
                iov = cleanup->msg_hdr.msg_iov;
                for (j = 0; j < iovcount; j++) {
                    g_free(iov->iov_base);
                    iov++;
                }
                g_free(cleanup->msg_hdr.msg_iov);
            }
            cleanup++;
        }
        g_free(msgvec);
    }
}

static struct mmsghdr *build_l2tpv3_vector(NetL2TPV3State *s, int count)
{
    int i;
    struct iovec *iov;
    struct mmsghdr *msgvec, *result;

    msgvec = g_new(struct mmsghdr, count);
    result = msgvec;
    for (i = 0; i < count ; i++) {
        msgvec->msg_hdr.msg_name = NULL;
        msgvec->msg_hdr.msg_namelen = 0;
        iov =  g_new(struct iovec, IOVSIZE);
        msgvec->msg_hdr.msg_iov = iov;
        iov->iov_base = g_malloc(s->header_size);
        iov->iov_len = s->header_size;
        iov++ ;
        iov->iov_base = qemu_memalign(BUFFER_ALIGN, BUFFER_SIZE);
        iov->iov_len = BUFFER_SIZE;
        msgvec->msg_hdr.msg_iovlen = 2;
        msgvec->msg_hdr.msg_control = NULL;
        msgvec->msg_hdr.msg_controllen = 0;
        msgvec->msg_hdr.msg_flags = 0;
        msgvec++;
    }
    return result;
}

static void net_l2tpv3_cleanup(NetClientState *nc)
{
    NetL2TPV3State *s = DO_UPCAST(NetL2TPV3State, nc, nc);
    qemu_purge_queued_packets(nc);
    l2tpv3_read_poll(s, false);
    l2tpv3_write_poll(s, false);
    if (s->fd >= 0) {
        close(s->fd);
    }
    destroy_vector(s->msgvec, MAX_L2TPV3_MSGCNT, IOVSIZE);
    g_free(s->vec);
    g_free(s->header_buf);
    g_free(s->dgram_dst);
}

static NetClientInfo net_l2tpv3_info = {
    .type = NET_CLIENT_DRIVER_L2TPV3,
    .size = sizeof(NetL2TPV3State),
    .receive = net_l2tpv3_receive_dgram,
    .receive_iov = net_l2tpv3_receive_dgram_iov,
    .poll = l2tpv3_poll,
    .cleanup = net_l2tpv3_cleanup,
};

int net_init_l2tpv3(const Netdev *netdev,
                    const char *name,
                    NetClientState *peer, Error **errp)
{
    const NetdevL2TPv3Options *l2tpv3;
    NetL2TPV3State *s;
    NetClientState *nc;
    int fd = -1, gairet;
    struct addrinfo hints;
    struct addrinfo *result = NULL;
    char *srcport, *dstport;

    nc = qemu_new_net_client(&net_l2tpv3_info, peer, "l2tpv3", name);

    s = DO_UPCAST(NetL2TPV3State, nc, nc);

    s->queue_head = 0;
    s->queue_tail = 0;
    s->header_mismatch = false;

    assert(netdev->type == NET_CLIENT_DRIVER_L2TPV3);
    l2tpv3 = &netdev->u.l2tpv3;

    if (l2tpv3->has_ipv6 && l2tpv3->ipv6) {
        s->ipv6 = l2tpv3->ipv6;
    } else {
        s->ipv6 = false;
    }

    if ((l2tpv3->has_offset) && (l2tpv3->offset > 256)) {
        error_setg(errp, "offset must be less than 256 bytes");
        goto outerr;
    }

    if (l2tpv3->has_rxcookie || l2tpv3->has_txcookie) {
        if (l2tpv3->has_rxcookie && l2tpv3->has_txcookie) {
            s->cookie = true;
        } else {
            error_setg(errp,
                       "require both 'rxcookie' and 'txcookie' or neither");
            goto outerr;
        }
    } else {
        s->cookie = false;
    }

    if (l2tpv3->has_cookie64 || l2tpv3->cookie64) {
        s->cookie_is_64  = true;
    } else {
        s->cookie_is_64  = false;
    }

    if (l2tpv3->has_udp && l2tpv3->udp) {
        s->udp = true;
        if (!(l2tpv3->has_srcport && l2tpv3->has_dstport)) {
            error_setg(errp, "need both src and dst port for udp");
            goto outerr;
        } else {
            srcport = l2tpv3->srcport;
            dstport = l2tpv3->dstport;
        }
    } else {
        s->udp = false;
        srcport = NULL;
        dstport = NULL;
    }


    s->offset = 4;
    s->session_offset = 0;
    s->cookie_offset = 4;
    s->counter_offset = 4;

    s->tx_session = l2tpv3->txsession;
    if (l2tpv3->has_rxsession) {
        s->rx_session = l2tpv3->rxsession;
    } else {
        s->rx_session = s->tx_session;
    }

    if (s->cookie) {
        s->rx_cookie = l2tpv3->rxcookie;
        s->tx_cookie = l2tpv3->txcookie;
        if (s->cookie_is_64 == true) {
            /* 64 bit cookie */
            s->offset += 8;
            s->counter_offset += 8;
        } else {
            /* 32 bit cookie */
            s->offset += 4;
            s->counter_offset += 4;
        }
    }

    memset(&hints, 0, sizeof(hints));

    if (s->ipv6) {
        hints.ai_family = AF_INET6;
    } else {
        hints.ai_family = AF_INET;
    }
    if (s->udp) {
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_protocol = 0;
        s->offset += 4;
        s->counter_offset += 4;
        s->session_offset += 4;
        s->cookie_offset += 4;
    } else {
        hints.ai_socktype = SOCK_RAW;
        hints.ai_protocol = IPPROTO_L2TP;
    }

    gairet = getaddrinfo(l2tpv3->src, srcport, &hints, &result);

    if ((gairet != 0) || (result == NULL)) {
        error_setg(errp, "could not resolve src, errno = %s",
                   gai_strerror(gairet));
        goto outerr;
    }
    fd = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (fd == -1) {
        fd = -errno;
        error_setg(errp, "socket creation failed, errno = %d",
                   -fd);
        goto outerr;
    }
    if (bind(fd, (struct sockaddr *) result->ai_addr, result->ai_addrlen)) {
        error_setg(errp, "could not bind socket err=%i", errno);
        goto outerr;
    }
    if (result) {
        freeaddrinfo(result);
    }

    memset(&hints, 0, sizeof(hints));

    if (s->ipv6) {
        hints.ai_family = AF_INET6;
    } else {
        hints.ai_family = AF_INET;
    }
    if (s->udp) {
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_protocol = 0;
    } else {
        hints.ai_socktype = SOCK_RAW;
        hints.ai_protocol = IPPROTO_L2TP;
    }

    result = NULL;
    gairet = getaddrinfo(l2tpv3->dst, dstport, &hints, &result);
    if ((gairet != 0) || (result == NULL)) {
        error_setg(errp, "could not resolve dst, error = %s",
                   gai_strerror(gairet));
        goto outerr;
    }

    s->dgram_dst = g_new0(struct sockaddr_storage, 1);
    memcpy(s->dgram_dst, result->ai_addr, result->ai_addrlen);
    s->dst_size = result->ai_addrlen;

    if (result) {
        freeaddrinfo(result);
    }

    if (l2tpv3->has_counter && l2tpv3->counter) {
        s->has_counter = true;
        s->offset += 4;
    } else {
        s->has_counter = false;
    }

    if (l2tpv3->has_pincounter && l2tpv3->pincounter) {
        s->has_counter = true;  /* pin counter implies that there is counter */
        s->pin_counter = true;
    } else {
        s->pin_counter = false;
    }

    if (l2tpv3->has_offset) {
        /* extra offset */
        s->offset += l2tpv3->offset;
    }

    if ((s->ipv6) || (s->udp)) {
        s->header_size = s->offset;
    } else {
        s->header_size = s->offset + sizeof(struct iphdr);
    }

    s->msgvec = build_l2tpv3_vector(s, MAX_L2TPV3_MSGCNT);
    s->vec = g_new(struct iovec, MAX_L2TPV3_IOVCNT);
    s->header_buf = g_malloc(s->header_size);

    qemu_set_nonblock(fd);

    s->fd = fd;
    s->counter = 0;

    l2tpv3_read_poll(s, true);

    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
             "l2tpv3: connected");
    return 0;
outerr:
    qemu_del_net_client(nc);
    if (fd >= 0) {
        close(fd);
    }
    if (result) {
        freeaddrinfo(result);
    }
    return -1;
}

