xref: /qemu/hw/net/net_rx_pkt.h (revision 27a4a30e)
1 /*
2  * QEMU RX packets abstraction
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 <dmitry@daynix.com>
10  * Tamir Shomer <tamirs@daynix.com>
11  * Yan Vugenfirer <yan@daynix.com>
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 #ifndef NET_RX_PKT_H
19 #define NET_RX_PKT_H
20 
21 #include "net/eth.h"
22 
23 /* defines to enable packet dump functions */
24 /*#define NET_RX_PKT_DEBUG*/
25 
26 struct NetRxPkt;
27 
28 /**
29  * Clean all rx packet resources
30  *
31  * @pkt:            packet
32  *
33  */
34 void net_rx_pkt_uninit(struct NetRxPkt *pkt);
35 
36 /**
37  * Init function for rx packet functionality
38  *
39  * @pkt:            packet pointer
40  * @has_virt_hdr:   device uses virtio header
41  *
42  */
43 void net_rx_pkt_init(struct NetRxPkt **pkt, bool has_virt_hdr);
44 
45 /**
46  * returns total length of data attached to rx context
47  *
48  * @pkt:            packet
49  *
50  * Return:  nothing
51  *
52  */
53 size_t net_rx_pkt_get_total_len(struct NetRxPkt *pkt);
54 
55 /**
56  * parse and set packet analysis results
57  *
58  * @pkt:            packet
59  * @data:           pointer to the data buffer to be parsed
60  * @len:            data length
61  *
62  */
63 void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data,
64                               size_t len);
65 
66 /**
67  * fetches packet analysis results
68  *
69  * @pkt:            packet
70  * @isip4:          whether the packet given is IPv4
71  * @isip6:          whether the packet given is IPv6
72  * @isudp:          whether the packet given is UDP
73  * @istcp:          whether the packet given is TCP
74  *
75  */
76 void net_rx_pkt_get_protocols(struct NetRxPkt *pkt,
77                                  bool *isip4, bool *isip6,
78                                  bool *isudp, bool *istcp);
79 
80 /**
81 * fetches L3 header offset
82 *
83 * @pkt:            packet
84 *
85 */
86 size_t net_rx_pkt_get_l3_hdr_offset(struct NetRxPkt *pkt);
87 
88 /**
89 * fetches L4 header offset
90 *
91 * @pkt:            packet
92 *
93 */
94 size_t net_rx_pkt_get_l4_hdr_offset(struct NetRxPkt *pkt);
95 
96 /**
97 * fetches L5 header offset
98 *
99 * @pkt:            packet
100 *
101 */
102 size_t net_rx_pkt_get_l5_hdr_offset(struct NetRxPkt *pkt);
103 
104 /**
105  * fetches IP6 header analysis results
106  *
107  * Return:  pointer to analysis results structure which is stored in internal
108  *          packet area.
109  *
110  */
111 eth_ip6_hdr_info *net_rx_pkt_get_ip6_info(struct NetRxPkt *pkt);
112 
113 /**
114  * fetches IP4 header analysis results
115  *
116  * Return:  pointer to analysis results structure which is stored in internal
117  *          packet area.
118  *
119  */
120 eth_ip4_hdr_info *net_rx_pkt_get_ip4_info(struct NetRxPkt *pkt);
121 
122 /**
123  * fetches L4 header analysis results
124  *
125  * Return:  pointer to analysis results structure which is stored in internal
126  *          packet area.
127  *
128  */
129 eth_l4_hdr_info *net_rx_pkt_get_l4_info(struct NetRxPkt *pkt);
130 
131 typedef enum {
132     NetPktRssIpV4,
133     NetPktRssIpV4Tcp,
134     NetPktRssIpV6Tcp,
135     NetPktRssIpV6,
136     NetPktRssIpV6Ex,
137     NetPktRssIpV6TcpEx,
138     NetPktRssIpV4Udp,
139     NetPktRssIpV6Udp,
140     NetPktRssIpV6UdpEx,
141 } NetRxPktRssType;
142 
143 /**
144 * calculates RSS hash for packet
145 *
146 * @pkt:            packet
147 * @type:           RSS hash type
148 *
149 * Return:  Toeplitz RSS hash.
150 *
151 */
152 uint32_t
153 net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt,
154                          NetRxPktRssType type,
155                          uint8_t *key);
156 
157 /**
158 * fetches IP identification for the packet
159 *
160 * @pkt:            packet
161 *
162 */
163 uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt);
164 
165 /**
166 * check if given packet is a TCP ACK packet
167 *
168 * @pkt:            packet
169 *
170 */
171 bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt);
172 
173 /**
174 * check if given packet contains TCP data
175 *
176 * @pkt:            packet
177 *
178 */
179 bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt);
180 
181 /**
182  * returns virtio header stored in rx context
183  *
184  * @pkt:            packet
185  * @ret:            virtio header
186  *
187  */
188 struct virtio_net_hdr *net_rx_pkt_get_vhdr(struct NetRxPkt *pkt);
189 
190 /**
191  * returns packet type
192  *
193  * @pkt:            packet
194  * @ret:            packet type
195  *
196  */
197 eth_pkt_types_e net_rx_pkt_get_packet_type(struct NetRxPkt *pkt);
198 
199 /**
200  * returns vlan tag
201  *
202  * @pkt:            packet
203  * @ret:            VLAN tag
204  *
205  */
206 uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt);
207 
208 /**
209  * tells whether vlan was stripped from the packet
210  *
211  * @pkt:            packet
212  * @ret:            VLAN stripped sign
213  *
214  */
215 bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt);
216 
217 /**
218  * notifies caller if the packet has virtio header
219  *
220  * @pkt:            packet
221  * @ret:            true if packet has virtio header, false otherwize
222  *
223  */
224 bool net_rx_pkt_has_virt_hdr(struct NetRxPkt *pkt);
225 
226 /**
227 * attach scatter-gather data to rx packet
228 *
229 * @pkt:            packet
230 * @iov:            received data scatter-gather list
231 * @iovcnt          number of elements in iov
232 * @iovoff          data start offset in the iov
233 * @strip_vlan:     should the module strip vlan from data
234 *
235 */
236 void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt,
237                                 const struct iovec *iov,
238                                 int iovcnt, size_t iovoff,
239                                 bool strip_vlan);
240 
241 /**
242 * attach scatter-gather data to rx packet
243 *
244 * @pkt:            packet
245 * @iov:            received data scatter-gather list
246 * @iovcnt          number of elements in iov
247 * @iovoff          data start offset in the iov
248 * @strip_vlan:     should the module strip vlan from data
249 * @vet:            VLAN tag Ethernet type
250 *
251 */
252 void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt,
253                                    const struct iovec *iov, int iovcnt,
254                                    size_t iovoff, bool strip_vlan,
255                                    uint16_t vet);
256 
257 /**
258  * attach data to rx packet
259  *
260  * @pkt:            packet
261  * @data:           pointer to the data buffer
262  * @len:            data length
263  * @strip_vlan:     should the module strip vlan from data
264  *
265  */
266 static inline void
267 net_rx_pkt_attach_data(struct NetRxPkt *pkt, const void *data,
268                           size_t len, bool strip_vlan)
269 {
270     const struct iovec iov = {
271         .iov_base = (void *) data,
272         .iov_len = len
273     };
274 
275     net_rx_pkt_attach_iovec(pkt, &iov, 1, 0, strip_vlan);
276 }
277 
278 /**
279  * returns io vector that holds the attached data
280  *
281  * @pkt:            packet
282  * @ret:            pointer to IOVec
283  *
284  */
285 struct iovec *net_rx_pkt_get_iovec(struct NetRxPkt *pkt);
286 
287 /**
288 * returns io vector length that holds the attached data
289 *
290 * @pkt:            packet
291 * @ret:            IOVec length
292 *
293 */
294 uint16_t net_rx_pkt_get_iovec_len(struct NetRxPkt *pkt);
295 
296 /**
297  * prints rx packet data if debug is enabled
298  *
299  * @pkt:            packet
300  *
301  */
302 void net_rx_pkt_dump(struct NetRxPkt *pkt);
303 
304 /**
305  * copy passed vhdr data to packet context
306  *
307  * @pkt:            packet
308  * @vhdr:           VHDR buffer
309  *
310  */
311 void net_rx_pkt_set_vhdr(struct NetRxPkt *pkt,
312     struct virtio_net_hdr *vhdr);
313 
314 /**
315 * copy passed vhdr data to packet context
316 *
317 * @pkt:            packet
318 * @iov:            VHDR iov
319 * @iovcnt:         VHDR iov array size
320 *
321 */
322 void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt,
323     const struct iovec *iov, int iovcnt);
324 
325 /**
326  * save packet type in packet context
327  *
328  * @pkt:            packet
329  * @packet_type:    the packet type
330  *
331  */
332 void net_rx_pkt_set_packet_type(struct NetRxPkt *pkt,
333     eth_pkt_types_e packet_type);
334 
335 /**
336 * validate TCP/UDP checksum of the packet
337 *
338 * @pkt:            packet
339 * @csum_valid:     checksum validation result
340 * @ret:            true if validation was performed, false in case packet is
341 *                  not TCP/UDP or checksum validation is not possible
342 *
343 */
344 bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid);
345 
346 /**
347 * validate IPv4 checksum of the packet
348 *
349 * @pkt:            packet
350 * @csum_valid:     checksum validation result
351 * @ret:            true if validation was performed, false in case packet is
352 *                  not TCP/UDP or checksum validation is not possible
353 *
354 */
355 bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid);
356 
357 /**
358 * fix IPv4 checksum of the packet
359 *
360 * @pkt:            packet
361 * @ret:            true if checksum was fixed, false in case packet is
362 *                  not TCP/UDP or checksum correction is not possible
363 *
364 */
365 bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt);
366 
367 #endif
368