xref: /qemu/hw/net/net_rx_pkt.h (revision a3fb4e93a3a7cf2be355c41cd550bef856f5ffe4)
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  *
41e263cd49SDmitry Fleytman  */
42aac8f89dSAkihiko Odaki void net_rx_pkt_init(struct NetRxPkt **pkt);
43e263cd49SDmitry Fleytman 
44e263cd49SDmitry Fleytman /**
45e263cd49SDmitry Fleytman  * returns total length of data attached to rx context
46e263cd49SDmitry Fleytman  *
47e263cd49SDmitry Fleytman  * @pkt:            packet
48e263cd49SDmitry Fleytman  *
49e263cd49SDmitry Fleytman  * Return:  nothing
50e263cd49SDmitry Fleytman  *
51e263cd49SDmitry Fleytman  */
52605d52e6SDmitry Fleytman size_t net_rx_pkt_get_total_len(struct NetRxPkt *pkt);
53e263cd49SDmitry Fleytman 
54e263cd49SDmitry Fleytman /**
55fcf0cdc3SShmulik Ladkani  * parse and set packet analysis results
56fcf0cdc3SShmulik Ladkani  *
57fcf0cdc3SShmulik Ladkani  * @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
61fcf0cdc3SShmulik Ladkani  *
62fcf0cdc3SShmulik Ladkani  */
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);
66fcf0cdc3SShmulik Ladkani 
67fcf0cdc3SShmulik Ladkani /**
68e263cd49SDmitry Fleytman  * fetches packet analysis results
69e263cd49SDmitry Fleytman  *
70e263cd49SDmitry 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
74e263cd49SDmitry Fleytman  *
75e263cd49SDmitry Fleytman  */
76605d52e6SDmitry Fleytman void net_rx_pkt_get_protocols(struct NetRxPkt *pkt,
7769ff5ef8SAkihiko Odaki                                  bool *hasip4, bool *hasip6,
7865f474bbSAkihiko Odaki                                  EthL4HdrProto *l4hdr_proto);
79e263cd49SDmitry Fleytman 
80e263cd49SDmitry Fleytman /**
81eb700029SDmitry Fleytman * fetches L4 header offset
82eb700029SDmitry Fleytman *
83eb700029SDmitry Fleytman * @pkt:            packet
84eb700029SDmitry Fleytman *
85eb700029SDmitry Fleytman */
86eb700029SDmitry Fleytman size_t net_rx_pkt_get_l4_hdr_offset(struct NetRxPkt *pkt);
87eb700029SDmitry Fleytman 
88eb700029SDmitry Fleytman /**
89eb700029SDmitry Fleytman * fetches L5 header offset
90eb700029SDmitry Fleytman *
91eb700029SDmitry Fleytman * @pkt:            packet
92eb700029SDmitry Fleytman *
93eb700029SDmitry Fleytman */
94eb700029SDmitry Fleytman size_t net_rx_pkt_get_l5_hdr_offset(struct NetRxPkt *pkt);
95eb700029SDmitry Fleytman 
96eb700029SDmitry Fleytman /**
97eb700029SDmitry Fleytman  * fetches IP6 header analysis results
98eb700029SDmitry Fleytman  *
99eb700029SDmitry Fleytman  * Return:  pointer to analysis results structure which is stored in internal
100eb700029SDmitry Fleytman  *          packet area.
101eb700029SDmitry Fleytman  *
102eb700029SDmitry Fleytman  */
103eb700029SDmitry Fleytman eth_ip6_hdr_info *net_rx_pkt_get_ip6_info(struct NetRxPkt *pkt);
104eb700029SDmitry Fleytman 
105eb700029SDmitry Fleytman /**
106eb700029SDmitry Fleytman  * fetches IP4 header analysis results
107eb700029SDmitry Fleytman  *
108eb700029SDmitry Fleytman  * Return:  pointer to analysis results structure which is stored in internal
109eb700029SDmitry Fleytman  *          packet area.
110eb700029SDmitry Fleytman  *
111eb700029SDmitry Fleytman  */
112eb700029SDmitry Fleytman eth_ip4_hdr_info *net_rx_pkt_get_ip4_info(struct NetRxPkt *pkt);
113eb700029SDmitry Fleytman 
114eb700029SDmitry Fleytman typedef enum {
115eb700029SDmitry Fleytman     NetPktRssIpV4,
116eb700029SDmitry Fleytman     NetPktRssIpV4Tcp,
117eb700029SDmitry Fleytman     NetPktRssIpV6Tcp,
118eb700029SDmitry Fleytman     NetPktRssIpV6,
11933bbc05eSYuri Benditovich     NetPktRssIpV6Ex,
12033bbc05eSYuri Benditovich     NetPktRssIpV6TcpEx,
12133bbc05eSYuri Benditovich     NetPktRssIpV4Udp,
12233bbc05eSYuri Benditovich     NetPktRssIpV6Udp,
12333bbc05eSYuri Benditovich     NetPktRssIpV6UdpEx,
124eb700029SDmitry Fleytman } NetRxPktRssType;
125eb700029SDmitry Fleytman 
126eb700029SDmitry Fleytman /**
127eb700029SDmitry Fleytman * calculates RSS hash for packet
128eb700029SDmitry Fleytman *
129eb700029SDmitry Fleytman * @pkt:            packet
130eb700029SDmitry Fleytman * @type:           RSS hash type
131eb700029SDmitry Fleytman *
132eb700029SDmitry Fleytman * Return:  Toeplitz RSS hash.
133eb700029SDmitry Fleytman *
134eb700029SDmitry Fleytman */
135eb700029SDmitry Fleytman uint32_t
136eb700029SDmitry Fleytman net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt,
137eb700029SDmitry Fleytman                          NetRxPktRssType type,
138eb700029SDmitry Fleytman                          uint8_t *key);
139eb700029SDmitry Fleytman 
140eb700029SDmitry Fleytman /**
141eb700029SDmitry Fleytman * fetches IP identification for the packet
142eb700029SDmitry Fleytman *
143eb700029SDmitry Fleytman * @pkt:            packet
144eb700029SDmitry Fleytman *
145eb700029SDmitry Fleytman */
146eb700029SDmitry Fleytman uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt);
147eb700029SDmitry Fleytman 
148eb700029SDmitry Fleytman /**
149eb700029SDmitry Fleytman * check if given packet is a TCP ACK packet
150eb700029SDmitry Fleytman *
151eb700029SDmitry Fleytman * @pkt:            packet
152eb700029SDmitry Fleytman *
153eb700029SDmitry Fleytman */
154eb700029SDmitry Fleytman bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt);
155eb700029SDmitry Fleytman 
156eb700029SDmitry Fleytman /**
157eb700029SDmitry Fleytman * check if given packet contains TCP data
158eb700029SDmitry Fleytman *
159eb700029SDmitry Fleytman * @pkt:            packet
160eb700029SDmitry Fleytman *
161eb700029SDmitry Fleytman */
162eb700029SDmitry Fleytman bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt);
163eb700029SDmitry Fleytman 
164eb700029SDmitry Fleytman /**
165e263cd49SDmitry Fleytman  * returns virtio header stored in rx context
166e263cd49SDmitry Fleytman  *
167e263cd49SDmitry Fleytman  * @pkt:            packet
168e263cd49SDmitry Fleytman  * @ret:            virtio header
169e263cd49SDmitry Fleytman  *
170e263cd49SDmitry Fleytman  */
171605d52e6SDmitry Fleytman struct virtio_net_hdr *net_rx_pkt_get_vhdr(struct NetRxPkt *pkt);
172e263cd49SDmitry Fleytman 
173e263cd49SDmitry Fleytman /**
174e263cd49SDmitry Fleytman  * returns packet type
175e263cd49SDmitry Fleytman  *
176e263cd49SDmitry Fleytman  * @pkt:            packet
177e263cd49SDmitry Fleytman  * @ret:            packet type
178e263cd49SDmitry Fleytman  *
179e263cd49SDmitry Fleytman  */
180605d52e6SDmitry Fleytman eth_pkt_types_e net_rx_pkt_get_packet_type(struct NetRxPkt *pkt);
181e263cd49SDmitry Fleytman 
182e263cd49SDmitry Fleytman /**
183e263cd49SDmitry Fleytman  * returns vlan tag
184e263cd49SDmitry Fleytman  *
185e263cd49SDmitry Fleytman  * @pkt:            packet
186e263cd49SDmitry Fleytman  * @ret:            VLAN tag
187e263cd49SDmitry Fleytman  *
188e263cd49SDmitry Fleytman  */
189605d52e6SDmitry Fleytman uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt);
190e263cd49SDmitry Fleytman 
191e263cd49SDmitry Fleytman /**
192e263cd49SDmitry Fleytman  * tells whether vlan was stripped from the packet
193e263cd49SDmitry Fleytman  *
194e263cd49SDmitry Fleytman  * @pkt:            packet
195e263cd49SDmitry Fleytman  * @ret:            VLAN stripped sign
196e263cd49SDmitry Fleytman  *
197e263cd49SDmitry Fleytman  */
198605d52e6SDmitry Fleytman bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt);
199e263cd49SDmitry Fleytman 
200e263cd49SDmitry Fleytman /**
201eb700029SDmitry Fleytman * attach scatter-gather data to rx packet
202eb700029SDmitry Fleytman *
203eb700029SDmitry Fleytman * @pkt:            packet
204eb700029SDmitry Fleytman * @iov:            received data scatter-gather list
205eb700029SDmitry Fleytman * @iovcnt          number of elements in iov
206eb700029SDmitry Fleytman * @iovoff          data start offset in the iov
207eb700029SDmitry Fleytman * @strip_vlan:     should the module strip vlan from data
208eb700029SDmitry Fleytman *
209eb700029SDmitry Fleytman */
210eb700029SDmitry Fleytman void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt,
211eb700029SDmitry Fleytman                                 const struct iovec *iov,
212eb700029SDmitry Fleytman                                 int iovcnt, size_t iovoff,
213eb700029SDmitry Fleytman                                 bool strip_vlan);
214eb700029SDmitry Fleytman 
215eb700029SDmitry Fleytman /**
216eb700029SDmitry Fleytman * attach scatter-gather data to rx packet
217eb700029SDmitry Fleytman *
218eb700029SDmitry Fleytman * @pkt:              packet
219eb700029SDmitry Fleytman * @iov:              received data scatter-gather list
220*7e64a9caSAkihiko Odaki * @iovcnt:           number of elements in iov
221*7e64a9caSAkihiko Odaki * @iovoff:           data start offset in the iov
222*7e64a9caSAkihiko Odaki * @strip_vlan_index: index of Q tag if it is to be stripped. negative otherwise.
223eb700029SDmitry Fleytman * @vet:              VLAN tag Ethernet type
224*7e64a9caSAkihiko Odaki * @vet_ext:          outer VLAN tag Ethernet type
225eb700029SDmitry Fleytman *
226eb700029SDmitry Fleytman */
227eb700029SDmitry Fleytman void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt,
228eb700029SDmitry Fleytman                                 const struct iovec *iov, int iovcnt,
229*7e64a9caSAkihiko Odaki                                 size_t iovoff, int strip_vlan_index,
230*7e64a9caSAkihiko Odaki                                 uint16_t vet, uint16_t vet_ext);
231eb700029SDmitry Fleytman 
232eb700029SDmitry Fleytman /**
233e263cd49SDmitry Fleytman  * attach data to rx packet
234e263cd49SDmitry Fleytman  *
235e263cd49SDmitry Fleytman  * @pkt:            packet
236e263cd49SDmitry Fleytman  * @data:           pointer to the data buffer
237e263cd49SDmitry Fleytman  * @len:            data length
238e263cd49SDmitry Fleytman  * @strip_vlan:     should the module strip vlan from data
239e263cd49SDmitry Fleytman  *
240e263cd49SDmitry Fleytman  */
241eb700029SDmitry Fleytman static inline void
net_rx_pkt_attach_data(struct NetRxPkt * pkt,const void * data,size_t len,bool strip_vlan)242eb700029SDmitry Fleytman net_rx_pkt_attach_data(struct NetRxPkt *pkt, const void *data,
243eb700029SDmitry Fleytman                           size_t len, bool strip_vlan)
244eb700029SDmitry Fleytman {
245eb700029SDmitry Fleytman     const struct iovec iov = {
246eb700029SDmitry Fleytman         .iov_base = (void *) data,
247eb700029SDmitry Fleytman         .iov_len = len
248eb700029SDmitry Fleytman     };
249eb700029SDmitry Fleytman 
250eb700029SDmitry Fleytman     net_rx_pkt_attach_iovec(pkt, &iov, 1, 0, strip_vlan);
251eb700029SDmitry Fleytman }
252e263cd49SDmitry Fleytman 
253e263cd49SDmitry Fleytman /**
254e263cd49SDmitry Fleytman  * returns io vector that holds the attached data
255e263cd49SDmitry Fleytman  *
256e263cd49SDmitry Fleytman  * @pkt:            packet
257e263cd49SDmitry Fleytman  * @ret:            pointer to IOVec
258e263cd49SDmitry Fleytman  *
259e263cd49SDmitry Fleytman  */
260605d52e6SDmitry Fleytman struct iovec *net_rx_pkt_get_iovec(struct NetRxPkt *pkt);
261e263cd49SDmitry Fleytman 
262e263cd49SDmitry Fleytman /**
263e263cd49SDmitry Fleytman  * prints rx packet data if debug is enabled
264e263cd49SDmitry Fleytman  *
265e263cd49SDmitry Fleytman  * @pkt:            packet
266e263cd49SDmitry Fleytman  *
267e263cd49SDmitry Fleytman  */
268605d52e6SDmitry Fleytman void net_rx_pkt_dump(struct NetRxPkt *pkt);
269e263cd49SDmitry Fleytman 
270e263cd49SDmitry Fleytman /**
271e263cd49SDmitry Fleytman  * copy passed vhdr data to packet context
272e263cd49SDmitry Fleytman  *
273e263cd49SDmitry Fleytman  * @pkt:            packet
274e263cd49SDmitry Fleytman  * @vhdr:           VHDR buffer
275e263cd49SDmitry Fleytman  *
276e263cd49SDmitry Fleytman  */
277605d52e6SDmitry Fleytman void net_rx_pkt_set_vhdr(struct NetRxPkt *pkt,
278e263cd49SDmitry Fleytman     struct virtio_net_hdr *vhdr);
279e263cd49SDmitry Fleytman 
280e263cd49SDmitry Fleytman /**
281eb700029SDmitry Fleytman * copy passed vhdr data to packet context
282eb700029SDmitry Fleytman *
283eb700029SDmitry Fleytman * @pkt:            packet
284eb700029SDmitry Fleytman * @iov:            VHDR iov
285eb700029SDmitry Fleytman * @iovcnt:         VHDR iov array size
286eb700029SDmitry Fleytman *
287eb700029SDmitry Fleytman */
288eb700029SDmitry Fleytman void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt,
289eb700029SDmitry Fleytman     const struct iovec *iov, int iovcnt);
290eb700029SDmitry Fleytman 
291eb700029SDmitry Fleytman /**
292ffbd2dbdSAkihiko Odaki  * unset vhdr data from packet context
293ffbd2dbdSAkihiko Odaki  *
294ffbd2dbdSAkihiko Odaki  * @pkt:            packet
295ffbd2dbdSAkihiko Odaki  *
296ffbd2dbdSAkihiko Odaki  */
297ffbd2dbdSAkihiko Odaki void net_rx_pkt_unset_vhdr(struct NetRxPkt *pkt);
298ffbd2dbdSAkihiko Odaki 
299ffbd2dbdSAkihiko Odaki /**
300e263cd49SDmitry Fleytman  * save packet type in packet context
301e263cd49SDmitry Fleytman  *
302e263cd49SDmitry Fleytman  * @pkt:            packet
303e263cd49SDmitry Fleytman  * @packet_type:    the packet type
304e263cd49SDmitry Fleytman  *
305e263cd49SDmitry Fleytman  */
306605d52e6SDmitry Fleytman void net_rx_pkt_set_packet_type(struct NetRxPkt *pkt,
307e263cd49SDmitry Fleytman     eth_pkt_types_e packet_type);
308e263cd49SDmitry Fleytman 
309eb700029SDmitry Fleytman /**
310eb700029SDmitry Fleytman * validate TCP/UDP checksum of the packet
311eb700029SDmitry Fleytman *
312eb700029SDmitry Fleytman * @pkt:            packet
313eb700029SDmitry Fleytman * @csum_valid:     checksum validation result
314eb700029SDmitry Fleytman * @ret:            true if validation was performed, false in case packet is
315eb700029SDmitry Fleytman *                  not TCP/UDP or checksum validation is not possible
316eb700029SDmitry Fleytman *
317eb700029SDmitry Fleytman */
318eb700029SDmitry Fleytman bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid);
319eb700029SDmitry Fleytman 
320eb700029SDmitry Fleytman /**
321eb700029SDmitry Fleytman * validate IPv4 checksum of the packet
322eb700029SDmitry Fleytman *
323eb700029SDmitry Fleytman * @pkt:            packet
324eb700029SDmitry Fleytman * @csum_valid:     checksum validation result
325eb700029SDmitry Fleytman * @ret:            true if validation was performed, false in case packet is
326eb700029SDmitry Fleytman *                  not TCP/UDP or checksum validation is not possible
327eb700029SDmitry Fleytman *
328eb700029SDmitry Fleytman */
329eb700029SDmitry Fleytman bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid);
330eb700029SDmitry Fleytman 
331eb700029SDmitry Fleytman /**
332eb700029SDmitry Fleytman * fix IPv4 checksum of the packet
333eb700029SDmitry Fleytman *
334eb700029SDmitry Fleytman * @pkt:            packet
335eb700029SDmitry Fleytman * @ret:            true if checksum was fixed, false in case packet is
336eb700029SDmitry Fleytman *                  not TCP/UDP or checksum correction is not possible
337eb700029SDmitry Fleytman *
338eb700029SDmitry Fleytman */
339eb700029SDmitry Fleytman bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt);
340eb700029SDmitry Fleytman 
341e263cd49SDmitry Fleytman #endif
342