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