2 * QEMU VMWARE VMXNET* paravirtual NICs - RX packets abstractions
4 * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
6 * Developed by Daynix Computing LTD (http://www.daynix.com)
9 * Dmitry Fleytman <dmitry@daynix.com>
10 * Tamir Shomer <tamirs@daynix.com>
11 * Yan Vugenfirer <yan@daynix.com>
13 * This work is licensed under the terms of the GNU GPL, version 2 or later.
14 * See the COPYING file in the top-level directory.
18 #include "qemu/osdep.h"
19 #include "vmxnet_rx_pkt.h"
21 #include "qemu-common.h"
23 #include "net/checksum.h"
27 * RX packet may contain up to 2 fragments - rebuilt eth header
28 * in case of VLAN tag stripping
29 * and payload received from QEMU - in any case
31 #define VMXNET_MAX_RX_PACKET_FRAGMENTS (2)
34 struct virtio_net_hdr virt_hdr;
35 uint8_t ehdr_buf[ETH_MAX_L2_HDR_LEN];
36 struct iovec vec[VMXNET_MAX_RX_PACKET_FRAGMENTS];
42 eth_pkt_types_e packet_type;
44 /* Analysis results */
51 void vmxnet_rx_pkt_init(struct VmxnetRxPkt **pkt, bool has_virt_hdr)
53 struct VmxnetRxPkt *p = g_malloc0(sizeof *p);
54 p->has_virt_hdr = has_virt_hdr;
58 void vmxnet_rx_pkt_uninit(struct VmxnetRxPkt *pkt)
63 struct virtio_net_hdr *vmxnet_rx_pkt_get_vhdr(struct VmxnetRxPkt *pkt)
66 return &pkt->virt_hdr;
69 void vmxnet_rx_pkt_attach_data(struct VmxnetRxPkt *pkt, const void *data,
70 size_t len, bool strip_vlan)
75 pkt->vlan_stripped = false;
78 pkt->vlan_stripped = eth_strip_vlan(data, pkt->ehdr_buf, &ploff, &tci);
81 if (pkt->vlan_stripped) {
82 pkt->vec[0].iov_base = pkt->ehdr_buf;
83 pkt->vec[0].iov_len = ploff - sizeof(struct vlan_header);
84 pkt->vec[1].iov_base = (uint8_t *) data + ploff;
85 pkt->vec[1].iov_len = len - ploff;
87 pkt->tot_len = len - ploff + sizeof(struct eth_header);
89 pkt->vec[0].iov_base = (void *)data;
90 pkt->vec[0].iov_len = len;
98 void vmxnet_rx_pkt_dump(struct VmxnetRxPkt *pkt)
100 #ifdef VMXNET_RX_PKT_DEBUG
101 VmxnetRxPkt *pkt = (VmxnetRxPkt *)pkt;
104 printf("RX PKT: tot_len: %d, vlan_stripped: %d, vlan_tag: %d\n",
105 pkt->tot_len, pkt->vlan_stripped, pkt->tci);
109 void vmxnet_rx_pkt_set_packet_type(struct VmxnetRxPkt *pkt,
110 eth_pkt_types_e packet_type)
114 pkt->packet_type = packet_type;
118 eth_pkt_types_e vmxnet_rx_pkt_get_packet_type(struct VmxnetRxPkt *pkt)
122 return pkt->packet_type;
125 size_t vmxnet_rx_pkt_get_total_len(struct VmxnetRxPkt *pkt)
132 void vmxnet_rx_pkt_set_protocols(struct VmxnetRxPkt *pkt, const void *data,
137 eth_get_protocols(data, len, &pkt->isip4, &pkt->isip6,
138 &pkt->isudp, &pkt->istcp);
141 void vmxnet_rx_pkt_get_protocols(struct VmxnetRxPkt *pkt,
142 bool *isip4, bool *isip6,
143 bool *isudp, bool *istcp)
153 struct iovec *vmxnet_rx_pkt_get_iovec(struct VmxnetRxPkt *pkt)
160 void vmxnet_rx_pkt_set_vhdr(struct VmxnetRxPkt *pkt,
161 struct virtio_net_hdr *vhdr)
165 memcpy(&pkt->virt_hdr, vhdr, sizeof pkt->virt_hdr);
168 bool vmxnet_rx_pkt_is_vlan_stripped(struct VmxnetRxPkt *pkt)
172 return pkt->vlan_stripped;
175 bool vmxnet_rx_pkt_has_virt_hdr(struct VmxnetRxPkt *pkt)
179 return pkt->has_virt_hdr;
182 uint16_t vmxnet_rx_pkt_get_vlan_tag(struct VmxnetRxPkt *pkt)