]> Git Repo - qemu.git/blame - hw/net/vmxnet_rx_pkt.c
Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging
[qemu.git] / hw / net / vmxnet_rx_pkt.c
CommitLineData
e263cd49
DF
1/*
2 * QEMU VMWARE VMXNET* paravirtual NICs - RX packets abstractions
3 *
4 * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
5 *
6 * Developed by Daynix Computing LTD (http://www.daynix.com)
7 *
8 * Authors:
9 * Dmitry Fleytman <[email protected]>
10 * Tamir Shomer <[email protected]>
11 * Yan Vugenfirer <[email protected]>
12 *
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.
15 *
16 */
17
18#include "vmxnet_rx_pkt.h"
19#include "net/eth.h"
20#include "qemu-common.h"
21#include "qemu/iov.h"
22#include "net/checksum.h"
23#include "net/tap.h"
24
25/*
26 * RX packet may contain up to 2 fragments - rebuilt eth header
27 * in case of VLAN tag stripping
28 * and payload received from QEMU - in any case
29 */
30#define VMXNET_MAX_RX_PACKET_FRAGMENTS (2)
31
32struct VmxnetRxPkt {
33 struct virtio_net_hdr virt_hdr;
34 uint8_t ehdr_buf[ETH_MAX_L2_HDR_LEN];
35 struct iovec vec[VMXNET_MAX_RX_PACKET_FRAGMENTS];
36 uint16_t vec_len;
37 uint32_t tot_len;
38 uint16_t tci;
39 bool vlan_stripped;
40 bool has_virt_hdr;
41 eth_pkt_types_e packet_type;
42
43 /* Analysis results */
44 bool isip4;
45 bool isip6;
46 bool isudp;
47 bool istcp;
48};
49
50void vmxnet_rx_pkt_init(struct VmxnetRxPkt **pkt, bool has_virt_hdr)
51{
52 struct VmxnetRxPkt *p = g_malloc0(sizeof *p);
53 p->has_virt_hdr = has_virt_hdr;
54 *pkt = p;
55}
56
57void vmxnet_rx_pkt_uninit(struct VmxnetRxPkt *pkt)
58{
59 g_free(pkt);
60}
61
62struct virtio_net_hdr *vmxnet_rx_pkt_get_vhdr(struct VmxnetRxPkt *pkt)
63{
64 assert(pkt);
65 return &pkt->virt_hdr;
66}
67
68void vmxnet_rx_pkt_attach_data(struct VmxnetRxPkt *pkt, const void *data,
69 size_t len, bool strip_vlan)
70{
71 uint16_t tci = 0;
72 uint16_t ploff;
73 assert(pkt);
74 pkt->vlan_stripped = false;
75
76 if (strip_vlan) {
77 pkt->vlan_stripped = eth_strip_vlan(data, pkt->ehdr_buf, &ploff, &tci);
78 }
79
80 if (pkt->vlan_stripped) {
81 pkt->vec[0].iov_base = pkt->ehdr_buf;
82 pkt->vec[0].iov_len = ploff - sizeof(struct vlan_header);
83 pkt->vec[1].iov_base = (uint8_t *) data + ploff;
84 pkt->vec[1].iov_len = len - ploff;
85 pkt->vec_len = 2;
86 pkt->tot_len = len - ploff + sizeof(struct eth_header);
87 } else {
88 pkt->vec[0].iov_base = (void *)data;
89 pkt->vec[0].iov_len = len;
90 pkt->vec_len = 1;
91 pkt->tot_len = len;
92 }
93
94 pkt->tci = tci;
e263cd49
DF
95}
96
97void vmxnet_rx_pkt_dump(struct VmxnetRxPkt *pkt)
98{
99#ifdef VMXNET_RX_PKT_DEBUG
100 VmxnetRxPkt *pkt = (VmxnetRxPkt *)pkt;
101 assert(pkt);
102
103 printf("RX PKT: tot_len: %d, vlan_stripped: %d, vlan_tag: %d\n",
104 pkt->tot_len, pkt->vlan_stripped, pkt->tci);
105#endif
106}
107
108void vmxnet_rx_pkt_set_packet_type(struct VmxnetRxPkt *pkt,
109 eth_pkt_types_e packet_type)
110{
111 assert(pkt);
112
113 pkt->packet_type = packet_type;
114
115}
116
117eth_pkt_types_e vmxnet_rx_pkt_get_packet_type(struct VmxnetRxPkt *pkt)
118{
119 assert(pkt);
120
121 return pkt->packet_type;
122}
123
124size_t vmxnet_rx_pkt_get_total_len(struct VmxnetRxPkt *pkt)
125{
126 assert(pkt);
127
128 return pkt->tot_len;
129}
130
fcf0cdc3
SL
131void vmxnet_rx_pkt_set_protocols(struct VmxnetRxPkt *pkt, const void *data,
132 size_t len)
133{
134 assert(pkt);
135
136 eth_get_protocols(data, len, &pkt->isip4, &pkt->isip6,
137 &pkt->isudp, &pkt->istcp);
138}
139
e263cd49
DF
140void vmxnet_rx_pkt_get_protocols(struct VmxnetRxPkt *pkt,
141 bool *isip4, bool *isip6,
142 bool *isudp, bool *istcp)
143{
144 assert(pkt);
145
146 *isip4 = pkt->isip4;
147 *isip6 = pkt->isip6;
148 *isudp = pkt->isudp;
149 *istcp = pkt->istcp;
150}
151
152struct iovec *vmxnet_rx_pkt_get_iovec(struct VmxnetRxPkt *pkt)
153{
154 assert(pkt);
155
156 return pkt->vec;
157}
158
159void vmxnet_rx_pkt_set_vhdr(struct VmxnetRxPkt *pkt,
160 struct virtio_net_hdr *vhdr)
161{
162 assert(pkt);
163
164 memcpy(&pkt->virt_hdr, vhdr, sizeof pkt->virt_hdr);
165}
166
167bool vmxnet_rx_pkt_is_vlan_stripped(struct VmxnetRxPkt *pkt)
168{
169 assert(pkt);
170
171 return pkt->vlan_stripped;
172}
173
174bool vmxnet_rx_pkt_has_virt_hdr(struct VmxnetRxPkt *pkt)
175{
176 assert(pkt);
177
178 return pkt->has_virt_hdr;
179}
180
e263cd49
DF
181uint16_t vmxnet_rx_pkt_get_vlan_tag(struct VmxnetRxPkt *pkt)
182{
183 assert(pkt);
184
185 return pkt->tci;
186}
This page took 0.179416 seconds and 4 git commands to generate.