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
)