xref: /qemu/hw/net/net_rx_pkt.h (revision 65f474bbae9a33b08707084efb95701e187f79e3)
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
58fcf0cdc3SShmulik Ladkani  * @data:           pointer to the data buffer to be parsed
59fcf0cdc3SShmulik Ladkani  * @len:            data length
60fcf0cdc3SShmulik Ladkani  *
61fcf0cdc3SShmulik Ladkani  */
62605d52e6SDmitry Fleytman void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data,
63fcf0cdc3SShmulik Ladkani                               size_t len);
64fcf0cdc3SShmulik Ladkani 
65fcf0cdc3SShmulik Ladkani /**
66e263cd49SDmitry Fleytman  * fetches packet analysis results
67e263cd49SDmitry Fleytman  *
68e263cd49SDmitry Fleytman  * @pkt:            packet
6969ff5ef8SAkihiko Odaki  * @hasip4:          whether the packet has an IPv4 header
7069ff5ef8SAkihiko Odaki  * @hasip6:          whether the packet has an IPv6 header
71*65f474bbSAkihiko Odaki  * @l4hdr_proto:     protocol of L4 header
72e263cd49SDmitry Fleytman  *
73e263cd49SDmitry Fleytman  */
74605d52e6SDmitry Fleytman void net_rx_pkt_get_protocols(struct NetRxPkt *pkt,
7569ff5ef8SAkihiko Odaki                                  bool *hasip4, bool *hasip6,
76*65f474bbSAkihiko Odaki                                  EthL4HdrProto *l4hdr_proto);
77e263cd49SDmitry Fleytman 
78e263cd49SDmitry Fleytman /**
79eb700029SDmitry Fleytman * fetches L3 header offset
80eb700029SDmitry Fleytman *
81eb700029SDmitry Fleytman * @pkt:            packet
82eb700029SDmitry Fleytman *
83eb700029SDmitry Fleytman */
84eb700029SDmitry Fleytman size_t net_rx_pkt_get_l3_hdr_offset(struct NetRxPkt *pkt);
85eb700029SDmitry Fleytman 
86eb700029SDmitry Fleytman /**
87eb700029SDmitry Fleytman * fetches L4 header offset
88eb700029SDmitry Fleytman *
89eb700029SDmitry Fleytman * @pkt:            packet
90eb700029SDmitry Fleytman *
91eb700029SDmitry Fleytman */
92eb700029SDmitry Fleytman size_t net_rx_pkt_get_l4_hdr_offset(struct NetRxPkt *pkt);
93eb700029SDmitry Fleytman 
94eb700029SDmitry Fleytman /**
95eb700029SDmitry Fleytman * fetches L5 header offset
96eb700029SDmitry Fleytman *
97eb700029SDmitry Fleytman * @pkt:            packet
98eb700029SDmitry Fleytman *
99eb700029SDmitry Fleytman */
100eb700029SDmitry Fleytman size_t net_rx_pkt_get_l5_hdr_offset(struct NetRxPkt *pkt);
101eb700029SDmitry Fleytman 
102eb700029SDmitry Fleytman /**
103eb700029SDmitry Fleytman  * fetches IP6 header analysis results
104eb700029SDmitry Fleytman  *
105eb700029SDmitry Fleytman  * Return:  pointer to analysis results structure which is stored in internal
106eb700029SDmitry Fleytman  *          packet area.
107eb700029SDmitry Fleytman  *
108eb700029SDmitry Fleytman  */
109eb700029SDmitry Fleytman eth_ip6_hdr_info *net_rx_pkt_get_ip6_info(struct NetRxPkt *pkt);
110eb700029SDmitry Fleytman 
111eb700029SDmitry Fleytman /**
112eb700029SDmitry Fleytman  * fetches IP4 header analysis results
113eb700029SDmitry Fleytman  *
114eb700029SDmitry Fleytman  * Return:  pointer to analysis results structure which is stored in internal
115eb700029SDmitry Fleytman  *          packet area.
116eb700029SDmitry Fleytman  *
117eb700029SDmitry Fleytman  */
118eb700029SDmitry Fleytman eth_ip4_hdr_info *net_rx_pkt_get_ip4_info(struct NetRxPkt *pkt);
119eb700029SDmitry Fleytman 
120eb700029SDmitry Fleytman /**
121eb700029SDmitry Fleytman  * fetches L4 header analysis results
122eb700029SDmitry Fleytman  *
123eb700029SDmitry Fleytman  * Return:  pointer to analysis results structure which is stored in internal
124eb700029SDmitry Fleytman  *          packet area.
125eb700029SDmitry Fleytman  *
126eb700029SDmitry Fleytman  */
127eb700029SDmitry Fleytman eth_l4_hdr_info *net_rx_pkt_get_l4_info(struct NetRxPkt *pkt);
128eb700029SDmitry Fleytman 
129eb700029SDmitry Fleytman typedef enum {
130eb700029SDmitry Fleytman     NetPktRssIpV4,
131eb700029SDmitry Fleytman     NetPktRssIpV4Tcp,
132eb700029SDmitry Fleytman     NetPktRssIpV6Tcp,
133eb700029SDmitry Fleytman     NetPktRssIpV6,
13433bbc05eSYuri Benditovich     NetPktRssIpV6Ex,
13533bbc05eSYuri Benditovich     NetPktRssIpV6TcpEx,
13633bbc05eSYuri Benditovich     NetPktRssIpV4Udp,
13733bbc05eSYuri Benditovich     NetPktRssIpV6Udp,
13833bbc05eSYuri Benditovich     NetPktRssIpV6UdpEx,
139eb700029SDmitry Fleytman } NetRxPktRssType;
140eb700029SDmitry Fleytman 
141eb700029SDmitry Fleytman /**
142eb700029SDmitry Fleytman * calculates RSS hash for packet
143eb700029SDmitry Fleytman *
144eb700029SDmitry Fleytman * @pkt:            packet
145eb700029SDmitry Fleytman * @type:           RSS hash type
146eb700029SDmitry Fleytman *
147eb700029SDmitry Fleytman * Return:  Toeplitz RSS hash.
148eb700029SDmitry Fleytman *
149eb700029SDmitry Fleytman */
150eb700029SDmitry Fleytman uint32_t
151eb700029SDmitry Fleytman net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt,
152eb700029SDmitry Fleytman                          NetRxPktRssType type,
153eb700029SDmitry Fleytman                          uint8_t *key);
154eb700029SDmitry Fleytman 
155eb700029SDmitry Fleytman /**
156eb700029SDmitry Fleytman * fetches IP identification for the packet
157eb700029SDmitry Fleytman *
158eb700029SDmitry Fleytman * @pkt:            packet
159eb700029SDmitry Fleytman *
160eb700029SDmitry Fleytman */
161eb700029SDmitry Fleytman uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt);
162eb700029SDmitry Fleytman 
163eb700029SDmitry Fleytman /**
164eb700029SDmitry Fleytman * check if given packet is a TCP ACK packet
165eb700029SDmitry Fleytman *
166eb700029SDmitry Fleytman * @pkt:            packet
167eb700029SDmitry Fleytman *
168eb700029SDmitry Fleytman */
169eb700029SDmitry Fleytman bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt);
170eb700029SDmitry Fleytman 
171eb700029SDmitry Fleytman /**
172eb700029SDmitry Fleytman * check if given packet contains TCP data
173eb700029SDmitry Fleytman *
174eb700029SDmitry Fleytman * @pkt:            packet
175eb700029SDmitry Fleytman *
176eb700029SDmitry Fleytman */
177eb700029SDmitry Fleytman bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt);
178eb700029SDmitry Fleytman 
179eb700029SDmitry Fleytman /**
180e263cd49SDmitry Fleytman  * returns virtio header stored in rx context
181e263cd49SDmitry Fleytman  *
182e263cd49SDmitry Fleytman  * @pkt:            packet
183e263cd49SDmitry Fleytman  * @ret:            virtio header
184e263cd49SDmitry Fleytman  *
185e263cd49SDmitry Fleytman  */
186605d52e6SDmitry Fleytman struct virtio_net_hdr *net_rx_pkt_get_vhdr(struct NetRxPkt *pkt);
187e263cd49SDmitry Fleytman 
188e263cd49SDmitry Fleytman /**
189e263cd49SDmitry Fleytman  * returns packet type
190e263cd49SDmitry Fleytman  *
191e263cd49SDmitry Fleytman  * @pkt:            packet
192e263cd49SDmitry Fleytman  * @ret:            packet type
193e263cd49SDmitry Fleytman  *
194e263cd49SDmitry Fleytman  */
195605d52e6SDmitry Fleytman eth_pkt_types_e net_rx_pkt_get_packet_type(struct NetRxPkt *pkt);
196e263cd49SDmitry Fleytman 
197e263cd49SDmitry Fleytman /**
198e263cd49SDmitry Fleytman  * returns vlan tag
199e263cd49SDmitry Fleytman  *
200e263cd49SDmitry Fleytman  * @pkt:            packet
201e263cd49SDmitry Fleytman  * @ret:            VLAN tag
202e263cd49SDmitry Fleytman  *
203e263cd49SDmitry Fleytman  */
204605d52e6SDmitry Fleytman uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt);
205e263cd49SDmitry Fleytman 
206e263cd49SDmitry Fleytman /**
207e263cd49SDmitry Fleytman  * tells whether vlan was stripped from the packet
208e263cd49SDmitry Fleytman  *
209e263cd49SDmitry Fleytman  * @pkt:            packet
210e263cd49SDmitry Fleytman  * @ret:            VLAN stripped sign
211e263cd49SDmitry Fleytman  *
212e263cd49SDmitry Fleytman  */
213605d52e6SDmitry Fleytman bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt);
214e263cd49SDmitry Fleytman 
215e263cd49SDmitry Fleytman /**
216eb700029SDmitry Fleytman * attach scatter-gather data to rx packet
217eb700029SDmitry Fleytman *
218eb700029SDmitry Fleytman * @pkt:            packet
219eb700029SDmitry Fleytman * @iov:            received data scatter-gather list
220eb700029SDmitry Fleytman * @iovcnt          number of elements in iov
221eb700029SDmitry Fleytman * @iovoff          data start offset in the iov
222eb700029SDmitry Fleytman * @strip_vlan:     should the module strip vlan from data
223eb700029SDmitry Fleytman *
224eb700029SDmitry Fleytman */
225eb700029SDmitry Fleytman void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt,
226eb700029SDmitry Fleytman                                 const struct iovec *iov,
227eb700029SDmitry Fleytman                                 int iovcnt, size_t iovoff,
228eb700029SDmitry Fleytman                                 bool strip_vlan);
229eb700029SDmitry Fleytman 
230eb700029SDmitry Fleytman /**
231eb700029SDmitry Fleytman * attach scatter-gather data to rx packet
232eb700029SDmitry Fleytman *
233eb700029SDmitry Fleytman * @pkt:            packet
234eb700029SDmitry Fleytman * @iov:            received data scatter-gather list
235eb700029SDmitry Fleytman * @iovcnt          number of elements in iov
236eb700029SDmitry Fleytman * @iovoff          data start offset in the iov
237eb700029SDmitry Fleytman * @strip_vlan:     should the module strip vlan from data
238eb700029SDmitry Fleytman * @vet:            VLAN tag Ethernet type
239eb700029SDmitry Fleytman *
240eb700029SDmitry Fleytman */
241eb700029SDmitry Fleytman void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt,
242eb700029SDmitry Fleytman                                    const struct iovec *iov, int iovcnt,
243eb700029SDmitry Fleytman                                    size_t iovoff, bool strip_vlan,
244eb700029SDmitry Fleytman                                    uint16_t vet);
245eb700029SDmitry Fleytman 
246eb700029SDmitry Fleytman /**
247e263cd49SDmitry Fleytman  * attach data to rx packet
248e263cd49SDmitry Fleytman  *
249e263cd49SDmitry Fleytman  * @pkt:            packet
250e263cd49SDmitry Fleytman  * @data:           pointer to the data buffer
251e263cd49SDmitry Fleytman  * @len:            data length
252e263cd49SDmitry Fleytman  * @strip_vlan:     should the module strip vlan from data
253e263cd49SDmitry Fleytman  *
254e263cd49SDmitry Fleytman  */
255eb700029SDmitry Fleytman static inline void
256eb700029SDmitry Fleytman net_rx_pkt_attach_data(struct NetRxPkt *pkt, const void *data,
257eb700029SDmitry Fleytman                           size_t len, bool strip_vlan)
258eb700029SDmitry Fleytman {
259eb700029SDmitry Fleytman     const struct iovec iov = {
260eb700029SDmitry Fleytman         .iov_base = (void *) data,
261eb700029SDmitry Fleytman         .iov_len = len
262eb700029SDmitry Fleytman     };
263eb700029SDmitry Fleytman 
264eb700029SDmitry Fleytman     net_rx_pkt_attach_iovec(pkt, &iov, 1, 0, strip_vlan);
265eb700029SDmitry Fleytman }
266e263cd49SDmitry Fleytman 
267e263cd49SDmitry Fleytman /**
268e263cd49SDmitry Fleytman  * returns io vector that holds the attached data
269e263cd49SDmitry Fleytman  *
270e263cd49SDmitry Fleytman  * @pkt:            packet
271e263cd49SDmitry Fleytman  * @ret:            pointer to IOVec
272e263cd49SDmitry Fleytman  *
273e263cd49SDmitry Fleytman  */
274605d52e6SDmitry Fleytman struct iovec *net_rx_pkt_get_iovec(struct NetRxPkt *pkt);
275e263cd49SDmitry Fleytman 
276e263cd49SDmitry Fleytman /**
277eb700029SDmitry Fleytman * returns io vector length that holds the attached data
278eb700029SDmitry Fleytman *
279eb700029SDmitry Fleytman * @pkt:            packet
280eb700029SDmitry Fleytman * @ret:            IOVec length
281eb700029SDmitry Fleytman *
282eb700029SDmitry Fleytman */
283eb700029SDmitry Fleytman uint16_t net_rx_pkt_get_iovec_len(struct NetRxPkt *pkt);
284eb700029SDmitry Fleytman 
285eb700029SDmitry Fleytman /**
286e263cd49SDmitry Fleytman  * prints rx packet data if debug is enabled
287e263cd49SDmitry Fleytman  *
288e263cd49SDmitry Fleytman  * @pkt:            packet
289e263cd49SDmitry Fleytman  *
290e263cd49SDmitry Fleytman  */
291605d52e6SDmitry Fleytman void net_rx_pkt_dump(struct NetRxPkt *pkt);
292e263cd49SDmitry Fleytman 
293e263cd49SDmitry Fleytman /**
294e263cd49SDmitry Fleytman  * copy passed vhdr data to packet context
295e263cd49SDmitry Fleytman  *
296e263cd49SDmitry Fleytman  * @pkt:            packet
297e263cd49SDmitry Fleytman  * @vhdr:           VHDR buffer
298e263cd49SDmitry Fleytman  *
299e263cd49SDmitry Fleytman  */
300605d52e6SDmitry Fleytman void net_rx_pkt_set_vhdr(struct NetRxPkt *pkt,
301e263cd49SDmitry Fleytman     struct virtio_net_hdr *vhdr);
302e263cd49SDmitry Fleytman 
303e263cd49SDmitry Fleytman /**
304eb700029SDmitry Fleytman * copy passed vhdr data to packet context
305eb700029SDmitry Fleytman *
306eb700029SDmitry Fleytman * @pkt:            packet
307eb700029SDmitry Fleytman * @iov:            VHDR iov
308eb700029SDmitry Fleytman * @iovcnt:         VHDR iov array size
309eb700029SDmitry Fleytman *
310eb700029SDmitry Fleytman */
311eb700029SDmitry Fleytman void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt,
312eb700029SDmitry Fleytman     const struct iovec *iov, int iovcnt);
313eb700029SDmitry Fleytman 
314eb700029SDmitry Fleytman /**
315ffbd2dbdSAkihiko Odaki  * unset vhdr data from packet context
316ffbd2dbdSAkihiko Odaki  *
317ffbd2dbdSAkihiko Odaki  * @pkt:            packet
318ffbd2dbdSAkihiko Odaki  *
319ffbd2dbdSAkihiko Odaki  */
320ffbd2dbdSAkihiko Odaki void net_rx_pkt_unset_vhdr(struct NetRxPkt *pkt);
321ffbd2dbdSAkihiko Odaki 
322ffbd2dbdSAkihiko Odaki /**
323e263cd49SDmitry Fleytman  * save packet type in packet context
324e263cd49SDmitry Fleytman  *
325e263cd49SDmitry Fleytman  * @pkt:            packet
326e263cd49SDmitry Fleytman  * @packet_type:    the packet type
327e263cd49SDmitry Fleytman  *
328e263cd49SDmitry Fleytman  */
329605d52e6SDmitry Fleytman void net_rx_pkt_set_packet_type(struct NetRxPkt *pkt,
330e263cd49SDmitry Fleytman     eth_pkt_types_e packet_type);
331e263cd49SDmitry Fleytman 
332eb700029SDmitry Fleytman /**
333eb700029SDmitry Fleytman * validate TCP/UDP checksum of the packet
334eb700029SDmitry Fleytman *
335eb700029SDmitry Fleytman * @pkt:            packet
336eb700029SDmitry Fleytman * @csum_valid:     checksum validation result
337eb700029SDmitry Fleytman * @ret:            true if validation was performed, false in case packet is
338eb700029SDmitry Fleytman *                  not TCP/UDP or checksum validation is not possible
339eb700029SDmitry Fleytman *
340eb700029SDmitry Fleytman */
341eb700029SDmitry Fleytman bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid);
342eb700029SDmitry Fleytman 
343eb700029SDmitry Fleytman /**
344eb700029SDmitry Fleytman * validate IPv4 checksum of the packet
345eb700029SDmitry Fleytman *
346eb700029SDmitry Fleytman * @pkt:            packet
347eb700029SDmitry Fleytman * @csum_valid:     checksum validation result
348eb700029SDmitry Fleytman * @ret:            true if validation was performed, false in case packet is
349eb700029SDmitry Fleytman *                  not TCP/UDP or checksum validation is not possible
350eb700029SDmitry Fleytman *
351eb700029SDmitry Fleytman */
352eb700029SDmitry Fleytman bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid);
353eb700029SDmitry Fleytman 
354eb700029SDmitry Fleytman /**
355eb700029SDmitry Fleytman * fix IPv4 checksum of the packet
356eb700029SDmitry Fleytman *
357eb700029SDmitry Fleytman * @pkt:            packet
358eb700029SDmitry Fleytman * @ret:            true if checksum was fixed, false in case packet is
359eb700029SDmitry Fleytman *                  not TCP/UDP or checksum correction is not possible
360eb700029SDmitry Fleytman *
361eb700029SDmitry Fleytman */
362eb700029SDmitry Fleytman bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt);
363eb700029SDmitry Fleytman 
364e263cd49SDmitry Fleytman #endif
365