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