/*
 * QEMU VMWARE VMXNET* paravirtual NICs - RX packets abstractions
 *
 * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
 *
 * Developed by Daynix Computing LTD (http://www.daynix.com)
 *
 * Authors:
 * Dmitry Fleytman <dmitry@daynix.com>
 * Tamir Shomer <tamirs@daynix.com>
 * Yan Vugenfirer <yan@daynix.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "vmxnet_rx_pkt.h"
#include "net/eth.h"
#include "qemu-common.h"
#include "qemu/iov.h"
#include "net/checksum.h"
#include "net/tap.h"

/*
 * RX packet may contain up to 2 fragments - rebuilt eth header
 * in case of VLAN tag stripping
 * and payload received from QEMU - in any case
 */
#define VMXNET_MAX_RX_PACKET_FRAGMENTS (2)

struct VmxnetRxPkt {
    struct virtio_net_hdr virt_hdr;
    uint8_t ehdr_buf[ETH_MAX_L2_HDR_LEN];
    struct iovec vec[VMXNET_MAX_RX_PACKET_FRAGMENTS];
    uint16_t vec_len;
    uint32_t tot_len;
    uint16_t tci;
    bool vlan_stripped;
    bool has_virt_hdr;
    eth_pkt_types_e packet_type;

    /* Analysis results */
    bool isip4;
    bool isip6;
    bool isudp;
    bool istcp;
};

void vmxnet_rx_pkt_init(struct VmxnetRxPkt **pkt, bool has_virt_hdr)
{
    struct VmxnetRxPkt *p = g_malloc0(sizeof *p);
    p->has_virt_hdr = has_virt_hdr;
    *pkt = p;
}

void vmxnet_rx_pkt_uninit(struct VmxnetRxPkt *pkt)
{
    g_free(pkt);
}

struct virtio_net_hdr *vmxnet_rx_pkt_get_vhdr(struct VmxnetRxPkt *pkt)
{
    assert(pkt);
    return &pkt->virt_hdr;
}

void vmxnet_rx_pkt_attach_data(struct VmxnetRxPkt *pkt, const void *data,
                               size_t len, bool strip_vlan)
{
    uint16_t tci = 0;
    uint16_t ploff;
    assert(pkt);
    pkt->vlan_stripped = false;

    if (strip_vlan) {
        pkt->vlan_stripped = eth_strip_vlan(data, pkt->ehdr_buf, &ploff, &tci);
    }

    if (pkt->vlan_stripped) {
        pkt->vec[0].iov_base = pkt->ehdr_buf;
        pkt->vec[0].iov_len = ploff - sizeof(struct vlan_header);
        pkt->vec[1].iov_base = (uint8_t *) data + ploff;
        pkt->vec[1].iov_len = len - ploff;
        pkt->vec_len = 2;
        pkt->tot_len = len - ploff + sizeof(struct eth_header);
    } else {
        pkt->vec[0].iov_base = (void *)data;
        pkt->vec[0].iov_len = len;
        pkt->vec_len = 1;
        pkt->tot_len = len;
    }

    pkt->tci = tci;
}

void vmxnet_rx_pkt_dump(struct VmxnetRxPkt *pkt)
{
#ifdef VMXNET_RX_PKT_DEBUG
    VmxnetRxPkt *pkt = (VmxnetRxPkt *)pkt;
    assert(pkt);

    printf("RX PKT: tot_len: %d, vlan_stripped: %d, vlan_tag: %d\n",
              pkt->tot_len, pkt->vlan_stripped, pkt->tci);
#endif
}

void vmxnet_rx_pkt_set_packet_type(struct VmxnetRxPkt *pkt,
    eth_pkt_types_e packet_type)
{
    assert(pkt);

    pkt->packet_type = packet_type;

}

eth_pkt_types_e vmxnet_rx_pkt_get_packet_type(struct VmxnetRxPkt *pkt)
{
    assert(pkt);

    return pkt->packet_type;
}

size_t vmxnet_rx_pkt_get_total_len(struct VmxnetRxPkt *pkt)
{
    assert(pkt);

    return pkt->tot_len;
}

void vmxnet_rx_pkt_set_protocols(struct VmxnetRxPkt *pkt, const void *data,
                                 size_t len)
{
    assert(pkt);

    eth_get_protocols(data, len, &pkt->isip4, &pkt->isip6,
        &pkt->isudp, &pkt->istcp);
}

void vmxnet_rx_pkt_get_protocols(struct VmxnetRxPkt *pkt,
                                 bool *isip4, bool *isip6,
                                 bool *isudp, bool *istcp)
{
    assert(pkt);

    *isip4 = pkt->isip4;
    *isip6 = pkt->isip6;
    *isudp = pkt->isudp;
    *istcp = pkt->istcp;
}

struct iovec *vmxnet_rx_pkt_get_iovec(struct VmxnetRxPkt *pkt)
{
    assert(pkt);

    return pkt->vec;
}

void vmxnet_rx_pkt_set_vhdr(struct VmxnetRxPkt *pkt,
                            struct virtio_net_hdr *vhdr)
{
    assert(pkt);

    memcpy(&pkt->virt_hdr, vhdr, sizeof pkt->virt_hdr);
}

bool vmxnet_rx_pkt_is_vlan_stripped(struct VmxnetRxPkt *pkt)
{
    assert(pkt);

    return pkt->vlan_stripped;
}

bool vmxnet_rx_pkt_has_virt_hdr(struct VmxnetRxPkt *pkt)
{
    assert(pkt);

    return pkt->has_virt_hdr;
}

uint16_t vmxnet_rx_pkt_get_vlan_tag(struct VmxnetRxPkt *pkt)
{
    assert(pkt);

    return pkt->tci;
}
