1
2
3
4
5#include <rte_byteorder.h>
6#include <rte_mbuf.h>
7#include <rte_ip.h>
8
9#include "packet_burst_generator.h"
10
11#define UDP_SRC_PORT 1024
12#define UDP_DST_PORT 1024
13
14
15#define IP_DEFTTL 64
16
17static void
18copy_buf_to_pkt_segs(void *buf, unsigned len, struct rte_mbuf *pkt,
19 unsigned offset)
20{
21 struct rte_mbuf *seg;
22 void *seg_buf;
23 unsigned copy_len;
24
25 seg = pkt;
26 while (offset >= seg->data_len) {
27 offset -= seg->data_len;
28 seg = seg->next;
29 }
30 copy_len = seg->data_len - offset;
31 seg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset);
32 while (len > copy_len) {
33 rte_memcpy(seg_buf, buf, (size_t) copy_len);
34 len -= copy_len;
35 buf = ((char *) buf + copy_len);
36 seg = seg->next;
37 seg_buf = rte_pktmbuf_mtod(seg, void *);
38 }
39 rte_memcpy(seg_buf, buf, (size_t) len);
40}
41
42static inline void
43copy_buf_to_pkt(void *buf, unsigned len, struct rte_mbuf *pkt, unsigned offset)
44{
45 if (offset + len <= pkt->data_len) {
46 rte_memcpy(rte_pktmbuf_mtod_offset(pkt, char *, offset), buf,
47 (size_t) len);
48 return;
49 }
50 copy_buf_to_pkt_segs(buf, len, pkt, offset);
51}
52
53void
54initialize_eth_header(struct rte_ether_hdr *eth_hdr,
55 struct rte_ether_addr *src_mac,
56 struct rte_ether_addr *dst_mac, uint16_t ether_type,
57 uint8_t vlan_enabled, uint16_t van_id)
58{
59 rte_ether_addr_copy(dst_mac, ð_hdr->dst_addr);
60 rte_ether_addr_copy(src_mac, ð_hdr->src_addr);
61
62 if (vlan_enabled) {
63 struct rte_vlan_hdr *vhdr = (struct rte_vlan_hdr *)(
64 (uint8_t *)eth_hdr + sizeof(struct rte_ether_hdr));
65
66 eth_hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
67
68 vhdr->eth_proto = rte_cpu_to_be_16(ether_type);
69 vhdr->vlan_tci = van_id;
70 } else {
71 eth_hdr->ether_type = rte_cpu_to_be_16(ether_type);
72 }
73}
74
75void
76initialize_arp_header(struct rte_arp_hdr *arp_hdr,
77 struct rte_ether_addr *src_mac,
78 struct rte_ether_addr *dst_mac,
79 uint32_t src_ip, uint32_t dst_ip,
80 uint32_t opcode)
81{
82 arp_hdr->arp_hardware = rte_cpu_to_be_16(RTE_ARP_HRD_ETHER);
83 arp_hdr->arp_protocol = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
84 arp_hdr->arp_hlen = RTE_ETHER_ADDR_LEN;
85 arp_hdr->arp_plen = sizeof(uint32_t);
86 arp_hdr->arp_opcode = rte_cpu_to_be_16(opcode);
87 rte_ether_addr_copy(src_mac, &arp_hdr->arp_data.arp_sha);
88 arp_hdr->arp_data.arp_sip = src_ip;
89 rte_ether_addr_copy(dst_mac, &arp_hdr->arp_data.arp_tha);
90 arp_hdr->arp_data.arp_tip = dst_ip;
91}
92
93uint16_t
94initialize_udp_header(struct rte_udp_hdr *udp_hdr, uint16_t src_port,
95 uint16_t dst_port, uint16_t pkt_data_len)
96{
97 uint16_t pkt_len;
98
99 pkt_len = (uint16_t) (pkt_data_len + sizeof(struct rte_udp_hdr));
100
101 udp_hdr->src_port = rte_cpu_to_be_16(src_port);
102 udp_hdr->dst_port = rte_cpu_to_be_16(dst_port);
103 udp_hdr->dgram_len = rte_cpu_to_be_16(pkt_len);
104 udp_hdr->dgram_cksum = 0;
105
106 return pkt_len;
107}
108
109uint16_t
110initialize_tcp_header(struct rte_tcp_hdr *tcp_hdr, uint16_t src_port,
111 uint16_t dst_port, uint16_t pkt_data_len)
112{
113 uint16_t pkt_len;
114
115 pkt_len = (uint16_t) (pkt_data_len + sizeof(struct rte_tcp_hdr));
116
117 memset(tcp_hdr, 0, sizeof(struct rte_tcp_hdr));
118 tcp_hdr->src_port = rte_cpu_to_be_16(src_port);
119 tcp_hdr->dst_port = rte_cpu_to_be_16(dst_port);
120 tcp_hdr->data_off = (sizeof(struct rte_tcp_hdr) << 2) & 0xF0;
121
122 return pkt_len;
123}
124
125uint16_t
126initialize_sctp_header(struct rte_sctp_hdr *sctp_hdr, uint16_t src_port,
127 uint16_t dst_port, uint16_t pkt_data_len)
128{
129 uint16_t pkt_len;
130
131 pkt_len = (uint16_t) (pkt_data_len + sizeof(struct rte_udp_hdr));
132
133 sctp_hdr->src_port = rte_cpu_to_be_16(src_port);
134 sctp_hdr->dst_port = rte_cpu_to_be_16(dst_port);
135 sctp_hdr->tag = 0;
136 sctp_hdr->cksum = 0;
137
138 return pkt_len;
139}
140
141uint16_t
142initialize_ipv6_header(struct rte_ipv6_hdr *ip_hdr, uint8_t *src_addr,
143 uint8_t *dst_addr, uint16_t pkt_data_len)
144{
145 ip_hdr->vtc_flow = rte_cpu_to_be_32(0x60000000);
146 ip_hdr->payload_len = rte_cpu_to_be_16(pkt_data_len);
147 ip_hdr->proto = IPPROTO_UDP;
148 ip_hdr->hop_limits = IP_DEFTTL;
149
150 rte_memcpy(ip_hdr->src_addr, src_addr, sizeof(ip_hdr->src_addr));
151 rte_memcpy(ip_hdr->dst_addr, dst_addr, sizeof(ip_hdr->dst_addr));
152
153 return (uint16_t) (pkt_data_len + sizeof(struct rte_ipv6_hdr));
154}
155
156uint16_t
157initialize_ipv4_header(struct rte_ipv4_hdr *ip_hdr, uint32_t src_addr,
158 uint32_t dst_addr, uint16_t pkt_data_len)
159{
160 uint16_t pkt_len;
161 unaligned_uint16_t *ptr16;
162 uint32_t ip_cksum;
163
164
165
166
167 pkt_len = (uint16_t) (pkt_data_len + sizeof(struct rte_ipv4_hdr));
168
169 ip_hdr->version_ihl = RTE_IPV4_VHL_DEF;
170 ip_hdr->type_of_service = 0;
171 ip_hdr->fragment_offset = 0;
172 ip_hdr->time_to_live = IP_DEFTTL;
173 ip_hdr->next_proto_id = IPPROTO_UDP;
174 ip_hdr->packet_id = 0;
175 ip_hdr->total_length = rte_cpu_to_be_16(pkt_len);
176 ip_hdr->src_addr = rte_cpu_to_be_32(src_addr);
177 ip_hdr->dst_addr = rte_cpu_to_be_32(dst_addr);
178
179
180
181
182 ptr16 = (unaligned_uint16_t *)ip_hdr;
183 ip_cksum = 0;
184 ip_cksum += ptr16[0]; ip_cksum += ptr16[1];
185 ip_cksum += ptr16[2]; ip_cksum += ptr16[3];
186 ip_cksum += ptr16[4];
187 ip_cksum += ptr16[6]; ip_cksum += ptr16[7];
188 ip_cksum += ptr16[8]; ip_cksum += ptr16[9];
189
190
191
192
193 ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) +
194 (ip_cksum & 0x0000FFFF);
195 ip_cksum %= 65536;
196 ip_cksum = (~ip_cksum) & 0x0000FFFF;
197 if (ip_cksum == 0)
198 ip_cksum = 0xFFFF;
199 ip_hdr->hdr_checksum = (uint16_t) ip_cksum;
200
201 return pkt_len;
202}
203
204uint16_t
205initialize_ipv4_header_proto(struct rte_ipv4_hdr *ip_hdr, uint32_t src_addr,
206 uint32_t dst_addr, uint16_t pkt_data_len, uint8_t proto)
207{
208 uint16_t pkt_len;
209 unaligned_uint16_t *ptr16;
210 uint32_t ip_cksum;
211
212
213
214
215 pkt_len = (uint16_t) (pkt_data_len + sizeof(struct rte_ipv4_hdr));
216
217 ip_hdr->version_ihl = RTE_IPV4_VHL_DEF;
218 ip_hdr->type_of_service = 0;
219 ip_hdr->fragment_offset = 0;
220 ip_hdr->time_to_live = IP_DEFTTL;
221 ip_hdr->next_proto_id = proto;
222 ip_hdr->packet_id = 0;
223 ip_hdr->total_length = rte_cpu_to_be_16(pkt_len);
224 ip_hdr->src_addr = rte_cpu_to_be_32(src_addr);
225 ip_hdr->dst_addr = rte_cpu_to_be_32(dst_addr);
226
227
228
229
230 ptr16 = (unaligned_uint16_t *)ip_hdr;
231 ip_cksum = 0;
232 ip_cksum += ptr16[0]; ip_cksum += ptr16[1];
233 ip_cksum += ptr16[2]; ip_cksum += ptr16[3];
234 ip_cksum += ptr16[4];
235 ip_cksum += ptr16[6]; ip_cksum += ptr16[7];
236 ip_cksum += ptr16[8]; ip_cksum += ptr16[9];
237
238
239
240
241 ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) +
242 (ip_cksum & 0x0000FFFF);
243 ip_cksum %= 65536;
244 ip_cksum = (~ip_cksum) & 0x0000FFFF;
245 if (ip_cksum == 0)
246 ip_cksum = 0xFFFF;
247 ip_hdr->hdr_checksum = (uint16_t) ip_cksum;
248
249 return pkt_len;
250}
251
252
253
254
255
256#define RTE_MAX_SEGS_PER_PKT 255
257
258
259int
260generate_packet_burst(struct rte_mempool *mp, struct rte_mbuf **pkts_burst,
261 struct rte_ether_hdr *eth_hdr, uint8_t vlan_enabled,
262 void *ip_hdr, uint8_t ipv4, struct rte_udp_hdr *udp_hdr,
263 int nb_pkt_per_burst, uint8_t pkt_len, uint8_t nb_pkt_segs)
264{
265 int i, nb_pkt = 0;
266 size_t eth_hdr_size;
267
268 struct rte_mbuf *pkt_seg;
269 struct rte_mbuf *pkt;
270
271 for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) {
272 pkt = rte_pktmbuf_alloc(mp);
273 if (pkt == NULL) {
274nomore_mbuf:
275 if (nb_pkt == 0)
276 return -1;
277 break;
278 }
279
280 pkt->data_len = pkt_len;
281 pkt_seg = pkt;
282 for (i = 1; i < nb_pkt_segs; i++) {
283 pkt_seg->next = rte_pktmbuf_alloc(mp);
284 if (pkt_seg->next == NULL) {
285 pkt->nb_segs = i;
286 rte_pktmbuf_free(pkt);
287 goto nomore_mbuf;
288 }
289 pkt_seg = pkt_seg->next;
290 pkt_seg->data_len = pkt_len;
291 }
292 pkt_seg->next = NULL;
293
294
295
296
297 if (vlan_enabled)
298 eth_hdr_size = sizeof(struct rte_ether_hdr) +
299 sizeof(struct rte_vlan_hdr);
300 else
301 eth_hdr_size = sizeof(struct rte_ether_hdr);
302
303 copy_buf_to_pkt(eth_hdr, eth_hdr_size, pkt, 0);
304
305 if (ipv4) {
306 copy_buf_to_pkt(ip_hdr, sizeof(struct rte_ipv4_hdr),
307 pkt, eth_hdr_size);
308 copy_buf_to_pkt(udp_hdr, sizeof(*udp_hdr), pkt,
309 eth_hdr_size + sizeof(struct rte_ipv4_hdr));
310 } else {
311 copy_buf_to_pkt(ip_hdr, sizeof(struct rte_ipv6_hdr),
312 pkt, eth_hdr_size);
313 copy_buf_to_pkt(udp_hdr, sizeof(*udp_hdr), pkt,
314 eth_hdr_size + sizeof(struct rte_ipv6_hdr));
315 }
316
317
318
319
320
321 pkt->nb_segs = nb_pkt_segs;
322 pkt->pkt_len = pkt_len;
323 pkt->l2_len = eth_hdr_size;
324
325 if (ipv4) {
326 pkt->vlan_tci = RTE_ETHER_TYPE_IPV4;
327 pkt->l3_len = sizeof(struct rte_ipv4_hdr);
328 } else {
329 pkt->vlan_tci = RTE_ETHER_TYPE_IPV6;
330 pkt->l3_len = sizeof(struct rte_ipv6_hdr);
331 }
332
333 pkts_burst[nb_pkt] = pkt;
334 }
335
336 return nb_pkt;
337}
338
339int
340generate_packet_burst_proto(struct rte_mempool *mp,
341 struct rte_mbuf **pkts_burst, struct rte_ether_hdr *eth_hdr,
342 uint8_t vlan_enabled, void *ip_hdr,
343 uint8_t ipv4, uint8_t proto, void *proto_hdr,
344 int nb_pkt_per_burst, uint8_t pkt_len, uint8_t nb_pkt_segs)
345{
346 int i, nb_pkt = 0;
347 size_t eth_hdr_size;
348
349 struct rte_mbuf *pkt_seg;
350 struct rte_mbuf *pkt;
351
352 for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) {
353 pkt = rte_pktmbuf_alloc(mp);
354 if (pkt == NULL) {
355nomore_mbuf:
356 if (nb_pkt == 0)
357 return -1;
358 break;
359 }
360
361 pkt->data_len = pkt_len;
362 pkt_seg = pkt;
363 for (i = 1; i < nb_pkt_segs; i++) {
364 pkt_seg->next = rte_pktmbuf_alloc(mp);
365 if (pkt_seg->next == NULL) {
366 pkt->nb_segs = i;
367 rte_pktmbuf_free(pkt);
368 goto nomore_mbuf;
369 }
370 pkt_seg = pkt_seg->next;
371 pkt_seg->data_len = pkt_len;
372 }
373 pkt_seg->next = NULL;
374
375
376
377
378 if (vlan_enabled)
379 eth_hdr_size = sizeof(struct rte_ether_hdr) +
380 sizeof(struct rte_vlan_hdr);
381 else
382 eth_hdr_size = sizeof(struct rte_ether_hdr);
383
384 copy_buf_to_pkt(eth_hdr, eth_hdr_size, pkt, 0);
385
386 if (ipv4) {
387 copy_buf_to_pkt(ip_hdr, sizeof(struct rte_ipv4_hdr),
388 pkt, eth_hdr_size);
389 switch (proto) {
390 case IPPROTO_UDP:
391 copy_buf_to_pkt(proto_hdr,
392 sizeof(struct rte_udp_hdr), pkt,
393 eth_hdr_size +
394 sizeof(struct rte_ipv4_hdr));
395 break;
396 case IPPROTO_TCP:
397 copy_buf_to_pkt(proto_hdr,
398 sizeof(struct rte_tcp_hdr), pkt,
399 eth_hdr_size +
400 sizeof(struct rte_ipv4_hdr));
401 break;
402 case IPPROTO_SCTP:
403 copy_buf_to_pkt(proto_hdr,
404 sizeof(struct rte_sctp_hdr), pkt,
405 eth_hdr_size +
406 sizeof(struct rte_ipv4_hdr));
407 break;
408 default:
409 break;
410 }
411 } else {
412 copy_buf_to_pkt(ip_hdr, sizeof(struct rte_ipv6_hdr),
413 pkt, eth_hdr_size);
414 switch (proto) {
415 case IPPROTO_UDP:
416 copy_buf_to_pkt(proto_hdr,
417 sizeof(struct rte_udp_hdr), pkt,
418 eth_hdr_size +
419 sizeof(struct rte_ipv6_hdr));
420 break;
421 case IPPROTO_TCP:
422 copy_buf_to_pkt(proto_hdr,
423 sizeof(struct rte_tcp_hdr), pkt,
424 eth_hdr_size +
425 sizeof(struct rte_ipv6_hdr));
426 break;
427 case IPPROTO_SCTP:
428 copy_buf_to_pkt(proto_hdr,
429 sizeof(struct rte_sctp_hdr), pkt,
430 eth_hdr_size +
431 sizeof(struct rte_ipv6_hdr));
432 break;
433 default:
434 break;
435 }
436 }
437
438
439
440
441
442 pkt->nb_segs = nb_pkt_segs;
443 pkt->pkt_len = pkt_len;
444 pkt->l2_len = eth_hdr_size;
445
446 if (ipv4) {
447 pkt->vlan_tci = RTE_ETHER_TYPE_IPV4;
448 pkt->l3_len = sizeof(struct rte_ipv4_hdr);
449 } else {
450 pkt->vlan_tci = RTE_ETHER_TYPE_IPV6;
451 pkt->l3_len = sizeof(struct rte_ipv6_hdr);
452 }
453
454 pkts_burst[nb_pkt] = pkt;
455 }
456
457 return nb_pkt;
458}
459