xref: /qemu/hw/net/net_rx_pkt.h (revision 7e64a9ca)
1605d52e6SDmitry Fleytman /*
2605d52e6SDmitry Fleytman  * QEMU RX packets abstraction
3605d52e6SDmitry Fleytman  *
4605d52e6SDmitry Fleytman  * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
5605d52e6SDmitry Fleytman  *
6605d52e6SDmitry Fleytman  * Developed by Daynix Computing LTD (http://www.daynix.com)
7605d52e6SDmitry Fleytman  *
8605d52e6SDmitry Fleytman  * Authors:
9605d52e6SDmitry Fleytman  * Dmitry Fleytman <dmitry@daynix.com>
10605d52e6SDmitry Fleytman  * Tamir Shomer <tamirs@daynix.com>
11605d52e6SDmitry Fleytman  * Yan Vugenfirer <yan@daynix.com>
12605d52e6SDmitry Fleytman  *
13605d52e6SDmitry Fleytman  * This work is licensed under the terms of the GNU GPL, version 2 or later.
14605d52e6SDmitry Fleytman  * See the COPYING file in the top-level directory.
15605d52e6SDmitry Fleytman  *
16605d52e6SDmitry Fleytman  */
17605d52e6SDmitry Fleytman 
18605d52e6SDmitry Fleytman #ifndef NET_RX_PKT_H
19605d52e6SDmitry Fleytman #define NET_RX_PKT_H
20605d52e6SDmitry Fleytman 
21605d52e6SDmitry Fleytman #include "net/eth.h"
22605d52e6SDmitry Fleytman 
23605d52e6SDmitry Fleytman /* defines to enable packet dump functions */
24605d52e6SDmitry Fleytman /*#define NET_RX_PKT_DEBUG*/
25605d52e6SDmitry Fleytman 
26605d52e6SDmitry Fleytman struct NetRxPkt;
27605d52e6SDmitry Fleytman 
28605d52e6SDmitry Fleytman /**
29605d52e6SDmitry Fleytman  * Clean all rx packet resources
30605d52e6SDmitry Fleytman  *
31605d52e6SDmitry Fleytman  * @pkt:            packet
32605d52e6SDmitry Fleytman  *
33605d52e6SDmitry Fleytman  */
34605d52e6SDmitry Fleytman void net_rx_pkt_uninit(struct NetRxPkt *pkt);
35605d52e6SDmitry Fleytman 
36605d52e6SDmitry Fleytman /**
37605d52e6SDmitry Fleytman  * Init function for rx packet functionality
38605d52e6SDmitry Fleytman  *
39605d52e6SDmitry Fleytman  * @pkt:            packet pointer
40605d52e6SDmitry Fleytman  *
41605d52e6SDmitry Fleytman  */
42aac8f89dSAkihiko Odaki void net_rx_pkt_init(struct NetRxPkt **pkt);
43605d52e6SDmitry Fleytman 
44605d52e6SDmitry Fleytman /**
45605d52e6SDmitry Fleytman  * returns total length of data attached to rx context
46605d52e6SDmitry Fleytman  *
47605d52e6SDmitry Fleytman  * @pkt:            packet
48605d52e6SDmitry Fleytman  *
49605d52e6SDmitry Fleytman  * Return:  nothing
50605d52e6SDmitry Fleytman  *
51605d52e6SDmitry Fleytman  */
52605d52e6SDmitry Fleytman size_t net_rx_pkt_get_total_len(struct NetRxPkt *pkt);
53605d52e6SDmitry Fleytman 
54605d52e6SDmitry Fleytman /**
55605d52e6SDmitry Fleytman  * parse and set packet analysis results
56605d52e6SDmitry Fleytman  *
57605d52e6SDmitry Fleytman  * @pkt:            packet
582f0fa232SAkihiko Odaki  * @iov:            received data scatter-gather list
592f0fa232SAkihiko Odaki  * @iovcnt:         number of elements in iov
602f0fa232SAkihiko Odaki  * @iovoff:         data start offset in the iov
61605d52e6SDmitry Fleytman  *
62605d52e6SDmitry Fleytman  */
632f0fa232SAkihiko Odaki void net_rx_pkt_set_protocols(struct NetRxPkt *pkt,
642f0fa232SAkihiko Odaki                               const struct iovec *iov, size_t iovcnt,
652f0fa232SAkihiko Odaki                               size_t iovoff);
66605d52e6SDmitry Fleytman 
67605d52e6SDmitry Fleytman /**
68605d52e6SDmitry Fleytman  * fetches packet analysis results
69605d52e6SDmitry Fleytman  *
70605d52e6SDmitry Fleytman  * @pkt:            packet
7169ff5ef8SAkihiko Odaki  * @hasip4:          whether the packet has an IPv4 header
7269ff5ef8SAkihiko Odaki  * @hasip6:          whether the packet has an IPv6 header
7365f474bbSAkihiko Odaki  * @l4hdr_proto:     protocol of L4 header
74605d52e6SDmitry Fleytman  *
75605d52e6SDmitry Fleytman  */
76605d52e6SDmitry Fleytman void net_rx_pkt_get_protocols(struct NetRxPkt *pkt,
7769ff5ef8SAkihiko Odaki                                  bool *hasip4, bool *hasip6,
7865f474bbSAkihiko Odaki                                  EthL4HdrProto *l4hdr_proto);
79605d52e6SDmitry Fleytman 
80605d52e6SDmitry Fleytman /**
81eb700029SDmitry Fleytman * fetches L3 header offset
82eb700029SDmitry Fleytman *
83eb700029SDmitry Fleytman * @pkt:            packet
84eb700029SDmitry Fleytman *
85eb700029SDmitry Fleytman */
86eb700029SDmitry Fleytman size_t net_rx_pkt_get_l3_hdr_offset(struct NetRxPkt *pkt);
87eb700029SDmitry Fleytman 
88eb700029SDmitry Fleytman /**
89eb700029SDmitry Fleytman * fetches L4 header offset
90eb700029SDmitry Fleytman *
91eb700029SDmitry Fleytman * @pkt:            packet
92eb700029SDmitry Fleytman *
93eb700029SDmitry Fleytman */
94eb700029SDmitry Fleytman size_t net_rx_pkt_get_l4_hdr_offset(struct NetRxPkt *pkt);
95eb700029SDmitry Fleytman 
96eb700029SDmitry Fleytman /**
97eb700029SDmitry Fleytman * fetches L5 header offset
98eb700029SDmitry Fleytman *
99eb700029SDmitry Fleytman * @pkt:            packet
100eb700029SDmitry Fleytman *
101eb700029SDmitry Fleytman */
102eb700029SDmitry Fleytman size_t net_rx_pkt_get_l5_hdr_offset(struct NetRxPkt *pkt);
103eb700029SDmitry Fleytman 
104eb700029SDmitry Fleytman /**
105eb700029SDmitry Fleytman  * fetches IP6 header analysis results
106eb700029SDmitry Fleytman  *
107eb700029SDmitry Fleytman  * Return:  pointer to analysis results structure which is stored in internal
108eb700029SDmitry Fleytman  *          packet area.
109eb700029SDmitry Fleytman  *
110eb700029SDmitry Fleytman  */
111eb700029SDmitry Fleytman eth_ip6_hdr_info *net_rx_pkt_get_ip6_info(struct NetRxPkt *pkt);
112eb700029SDmitry Fleytman 
113eb700029SDmitry Fleytman /**
114eb700029SDmitry Fleytman  * fetches IP4 header analysis results
115eb700029SDmitry Fleytman  *
116eb700029SDmitry Fleytman  * Return:  pointer to analysis results structure which is stored in internal
117eb700029SDmitry Fleytman  *          packet area.
118eb700029SDmitry Fleytman  *
119eb700029SDmitry Fleytman  */
120eb700029SDmitry Fleytman eth_ip4_hdr_info *net_rx_pkt_get_ip4_info(struct NetRxPkt *pkt);
121eb700029SDmitry Fleytman 
122eb700029SDmitry Fleytman typedef enum {
123eb700029SDmitry Fleytman     NetPktRssIpV4,
124eb700029SDmitry Fleytman     NetPktRssIpV4Tcp,
125eb700029SDmitry Fleytman     NetPktRssIpV6Tcp,
126eb700029SDmitry Fleytman     NetPktRssIpV6,
12733bbc05eSYuri Benditovich     NetPktRssIpV6Ex,
12833bbc05eSYuri Benditovich     NetPktRssIpV6TcpEx,
12933bbc05eSYuri Benditovich     NetPktRssIpV4Udp,
13033bbc05eSYuri Benditovich     NetPktRssIpV6Udp,
13133bbc05eSYuri Benditovich     NetPktRssIpV6UdpEx,
132eb700029SDmitry Fleytman } NetRxPktRssType;
133eb700029SDmitry Fleytman 
134eb700029SDmitry Fleytman /**
135eb700029SDmitry Fleytman * calculates RSS hash for packet
136eb700029SDmitry Fleytman *
137eb700029SDmitry Fleytman * @pkt:            packet
138eb700029SDmitry Fleytman * @type:           RSS hash type
139eb700029SDmitry Fleytman *
140eb700029SDmitry Fleytman * Return:  Toeplitz RSS hash.
141eb700029SDmitry Fleytman *
142eb700029SDmitry Fleytman */
143eb700029SDmitry Fleytman uint32_t
144eb700029SDmitry Fleytman net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt,
145eb700029SDmitry Fleytman                          NetRxPktRssType type,
146eb700029SDmitry Fleytman                          uint8_t *key);
147eb700029SDmitry Fleytman 
148eb700029SDmitry Fleytman /**
149eb700029SDmitry Fleytman * fetches IP identification for the packet
150eb700029SDmitry Fleytman *
151eb700029SDmitry Fleytman * @pkt:            packet
152eb700029SDmitry Fleytman *
153eb700029SDmitry Fleytman */
154eb700029SDmitry Fleytman uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt);
155eb700029SDmitry Fleytman 
156eb700029SDmitry Fleytman /**
157eb700029SDmitry Fleytman * check if given packet is a TCP ACK packet
158eb700029SDmitry Fleytman *
159eb700029SDmitry Fleytman * @pkt:            packet
160eb700029SDmitry Fleytman *
161eb700029SDmitry Fleytman */
162eb700029SDmitry Fleytman bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt);
163eb700029SDmitry Fleytman 
164eb700029SDmitry Fleytman /**
165eb700029SDmitry Fleytman * check if given packet contains TCP data
166eb700029SDmitry Fleytman *
167eb700029SDmitry Fleytman * @pkt:            packet
168eb700029SDmitry Fleytman *
169eb700029SDmitry Fleytman */
170eb700029SDmitry Fleytman bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt);
171eb700029SDmitry Fleytman 
172eb700029SDmitry Fleytman /**
173605d52e6SDmitry Fleytman  * returns virtio header stored in rx context
174605d52e6SDmitry Fleytman  *
175605d52e6SDmitry Fleytman  * @pkt:            packet
176605d52e6SDmitry Fleytman  * @ret:            virtio header
177605d52e6SDmitry Fleytman  *
178605d52e6SDmitry Fleytman  */
179605d52e6SDmitry Fleytman struct virtio_net_hdr *net_rx_pkt_get_vhdr(struct NetRxPkt *pkt);
180605d52e6SDmitry Fleytman 
181605d52e6SDmitry Fleytman /**
182605d52e6SDmitry Fleytman  * returns packet type
183605d52e6SDmitry Fleytman  *
184605d52e6SDmitry Fleytman  * @pkt:            packet
185605d52e6SDmitry Fleytman  * @ret:            packet type
186605d52e6SDmitry Fleytman  *
187605d52e6SDmitry Fleytman  */
188605d52e6SDmitry Fleytman eth_pkt_types_e net_rx_pkt_get_packet_type(struct NetRxPkt *pkt);
189605d52e6SDmitry Fleytman 
190605d52e6SDmitry Fleytman /**
191605d52e6SDmitry Fleytman  * returns vlan tag
192605d52e6SDmitry Fleytman  *
193605d52e6SDmitry Fleytman  * @pkt:            packet
194605d52e6SDmitry Fleytman  * @ret:            VLAN tag
195605d52e6SDmitry Fleytman  *
196605d52e6SDmitry Fleytman  */
197605d52e6SDmitry Fleytman uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt);
198605d52e6SDmitry Fleytman 
199605d52e6SDmitry Fleytman /**
200605d52e6SDmitry Fleytman  * tells whether vlan was stripped from the packet
201605d52e6SDmitry Fleytman  *
202605d52e6SDmitry Fleytman  * @pkt:            packet
203605d52e6SDmitry Fleytman  * @ret:            VLAN stripped sign
204605d52e6SDmitry Fleytman  *
205605d52e6SDmitry Fleytman  */
206605d52e6SDmitry Fleytman bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt);
207605d52e6SDmitry Fleytman 
208605d52e6SDmitry Fleytman /**
209eb700029SDmitry Fleytman * attach scatter-gather data to rx packet
210eb700029SDmitry Fleytman *
211eb700029SDmitry Fleytman * @pkt:            packet
212eb700029SDmitry Fleytman * @iov:            received data scatter-gather list
213eb700029SDmitry Fleytman * @iovcnt          number of elements in iov
214eb700029SDmitry Fleytman * @iovoff          data start offset in the iov
215eb700029SDmitry Fleytman * @strip_vlan:     should the module strip vlan from data
216eb700029SDmitry Fleytman *
217eb700029SDmitry Fleytman */
218eb700029SDmitry Fleytman void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt,
219eb700029SDmitry Fleytman                                 const struct iovec *iov,
220eb700029SDmitry Fleytman                                 int iovcnt, size_t iovoff,
221eb700029SDmitry Fleytman                                 bool strip_vlan);
222eb700029SDmitry Fleytman 
223eb700029SDmitry Fleytman /**
224eb700029SDmitry Fleytman * attach scatter-gather data to rx packet
225eb700029SDmitry Fleytman *
226eb700029SDmitry Fleytman * @pkt:              packet
227eb700029SDmitry Fleytman * @iov:              received data scatter-gather list
228*7e64a9caSAkihiko Odaki * @iovcnt:           number of elements in iov
229*7e64a9caSAkihiko Odaki * @iovoff:           data start offset in the iov
230*7e64a9caSAkihiko Odaki * @strip_vlan_index: index of Q tag if it is to be stripped. negative otherwise.
231eb700029SDmitry Fleytman * @vet:              VLAN tag Ethernet type
232*7e64a9caSAkihiko Odaki * @vet_ext:          outer VLAN tag Ethernet type
233eb700029SDmitry Fleytman *
234eb700029SDmitry Fleytman */
235eb700029SDmitry Fleytman void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt,
236eb700029SDmitry Fleytman                                 const struct iovec *iov, int iovcnt,
237*7e64a9caSAkihiko Odaki                                 size_t iovoff, int strip_vlan_index,
238*7e64a9caSAkihiko Odaki                                 uint16_t vet, uint16_t vet_ext);
239eb700029SDmitry Fleytman 
240eb700029SDmitry Fleytman /**
241605d52e6SDmitry Fleytman  * attach data to rx packet
242605d52e6SDmitry Fleytman  *
243605d52e6SDmitry Fleytman  * @pkt:            packet
244605d52e6SDmitry Fleytman  * @data:           pointer to the data buffer
245605d52e6SDmitry Fleytman  * @len:            data length
246605d52e6SDmitry Fleytman  * @strip_vlan:     should the module strip vlan from data
247605d52e6SDmitry Fleytman  *
248605d52e6SDmitry Fleytman  */
249eb700029SDmitry Fleytman static inline void
net_rx_pkt_attach_data(struct NetRxPkt * pkt,const void * data,size_t len,bool strip_vlan)250eb700029SDmitry Fleytman net_rx_pkt_attach_data(struct NetRxPkt *pkt, const void *data,
251eb700029SDmitry Fleytman                           size_t len, bool strip_vlan)
252eb700029SDmitry Fleytman {
253eb700029SDmitry Fleytman     const struct iovec iov = {
254eb700029SDmitry Fleytman         .iov_base = (void *) data,
255eb700029SDmitry Fleytman         .iov_len = len
256eb700029SDmitry Fleytman     };
257eb700029SDmitry Fleytman 
258eb700029SDmitry Fleytman     net_rx_pkt_attach_iovec(pkt, &iov, 1, 0, strip_vlan);
259eb700029SDmitry Fleytman }
260605d52e6SDmitry Fleytman 
261605d52e6SDmitry Fleytman /**
262605d52e6SDmitry Fleytman  * returns io vector that holds the attached data
263605d52e6SDmitry Fleytman  *
264605d52e6SDmitry Fleytman  * @pkt:            packet
265605d52e6SDmitry Fleytman  * @ret:            pointer to IOVec
266605d52e6SDmitry Fleytman  *
267605d52e6SDmitry Fleytman  */
268605d52e6SDmitry Fleytman struct iovec *net_rx_pkt_get_iovec(struct NetRxPkt *pkt);
269605d52e6SDmitry Fleytman 
270605d52e6SDmitry Fleytman /**
271eb700029SDmitry Fleytman * returns io vector length that holds the attached data
272eb700029SDmitry Fleytman *
273eb700029SDmitry Fleytman * @pkt:            packet
274eb700029SDmitry Fleytman * @ret:            IOVec length
275eb700029SDmitry Fleytman *
276eb700029SDmitry Fleytman */
277eb700029SDmitry Fleytman uint16_t net_rx_pkt_get_iovec_len(struct NetRxPkt *pkt);
278eb700029SDmitry Fleytman 
279eb700029SDmitry Fleytman /**
280605d52e6SDmitry Fleytman  * prints rx packet data if debug is enabled
281605d52e6SDmitry Fleytman  *
282605d52e6SDmitry Fleytman  * @pkt:            packet
283605d52e6SDmitry Fleytman  *
284605d52e6SDmitry Fleytman  */
285605d52e6SDmitry Fleytman void net_rx_pkt_dump(struct NetRxPkt *pkt);
286605d52e6SDmitry Fleytman 
287605d52e6SDmitry Fleytman /**
288605d52e6SDmitry Fleytman  * copy passed vhdr data to packet context
289605d52e6SDmitry Fleytman  *
290605d52e6SDmitry Fleytman  * @pkt:            packet
291605d52e6SDmitry Fleytman  * @vhdr:           VHDR buffer
292605d52e6SDmitry Fleytman  *
293605d52e6SDmitry Fleytman  */
294605d52e6SDmitry Fleytman void net_rx_pkt_set_vhdr(struct NetRxPkt *pkt,
295605d52e6SDmitry Fleytman     struct virtio_net_hdr *vhdr);
296605d52e6SDmitry Fleytman 
297605d52e6SDmitry Fleytman /**
298eb700029SDmitry Fleytman * copy passed vhdr data to packet context
299eb700029SDmitry Fleytman *
300eb700029SDmitry Fleytman * @pkt:            packet
301eb700029SDmitry Fleytman * @iov:            VHDR iov
302eb700029SDmitry Fleytman * @iovcnt:         VHDR iov array size
303eb700029SDmitry Fleytman *
304eb700029SDmitry Fleytman */
305eb700029SDmitry Fleytman void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt,
306eb700029SDmitry Fleytman     const struct iovec *iov, int iovcnt);
307eb700029SDmitry Fleytman 
308eb700029SDmitry Fleytman /**
309ffbd2dbdSAkihiko Odaki  * unset vhdr data from packet context
310ffbd2dbdSAkihiko Odaki  *
311ffbd2dbdSAkihiko Odaki  * @pkt:            packet
312ffbd2dbdSAkihiko Odaki  *
313ffbd2dbdSAkihiko Odaki  */
314ffbd2dbdSAkihiko Odaki void net_rx_pkt_unset_vhdr(struct NetRxPkt *pkt);
315ffbd2dbdSAkihiko Odaki 
316ffbd2dbdSAkihiko Odaki /**
317605d52e6SDmitry Fleytman  * save packet type in packet context
318605d52e6SDmitry Fleytman  *
319605d52e6SDmitry Fleytman  * @pkt:            packet
320605d52e6SDmitry Fleytman  * @packet_type:    the packet type
321605d52e6SDmitry Fleytman  *
322605d52e6SDmitry Fleytman  */
323605d52e6SDmitry Fleytman void net_rx_pkt_set_packet_type(struct NetRxPkt *pkt,
324605d52e6SDmitry Fleytman     eth_pkt_types_e packet_type);
325605d52e6SDmitry Fleytman 
326eb700029SDmitry Fleytman /**
327eb700029SDmitry Fleytman * validate TCP/UDP checksum of the packet
328eb700029SDmitry Fleytman *
329eb700029SDmitry Fleytman * @pkt:            packet
330eb700029SDmitry Fleytman * @csum_valid:     checksum validation result
331eb700029SDmitry Fleytman * @ret:            true if validation was performed, false in case packet is
332eb700029SDmitry Fleytman *                  not TCP/UDP or checksum validation is not possible
333eb700029SDmitry Fleytman *
334eb700029SDmitry Fleytman */
335eb700029SDmitry Fleytman bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid);
336eb700029SDmitry Fleytman 
337eb700029SDmitry Fleytman /**
338eb700029SDmitry Fleytman * validate IPv4 checksum of the packet
339eb700029SDmitry Fleytman *
340eb700029SDmitry Fleytman * @pkt:            packet
341eb700029SDmitry Fleytman * @csum_valid:     checksum validation result
342eb700029SDmitry Fleytman * @ret:            true if validation was performed, false in case packet is
343eb700029SDmitry Fleytman *                  not TCP/UDP or checksum validation is not possible
344eb700029SDmitry Fleytman *
345eb700029SDmitry Fleytman */
346eb700029SDmitry Fleytman bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid);
347eb700029SDmitry Fleytman 
348eb700029SDmitry Fleytman /**
349eb700029SDmitry Fleytman * fix IPv4 checksum of the packet
350eb700029SDmitry Fleytman *
351eb700029SDmitry Fleytman * @pkt:            packet
352eb700029SDmitry Fleytman * @ret:            true if checksum was fixed, false in case packet is
353eb700029SDmitry Fleytman *                  not TCP/UDP or checksum correction is not possible
354eb700029SDmitry Fleytman *
355eb700029SDmitry Fleytman */
356eb700029SDmitry Fleytman bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt);
357eb700029SDmitry Fleytman 
358605d52e6SDmitry Fleytman #endif
359