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