API Reference Manual 1.51.0
Loading...
Searching...
No Matches
odp_ping.c
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2019-2023 Nokia
3 */
4
15#include <stdio.h>
16#include <string.h>
17#include <signal.h>
18#include <stdlib.h>
19#include <stdint.h>
20#include <inttypes.h>
21#include <getopt.h>
22
23#include <odp_api.h>
24#include <odp/helper/odph_api.h>
25
26#define MAX_PKTIOS 32
27#define MAX_PKTIO_NAME 255
28#define MAX_PKT_NUM 1024
29
30ODP_STATIC_ASSERT(MAX_PKTIOS < UINT8_MAX, "MAX_PKTIOS too large for index lookup");
31
32typedef struct test_options_t {
33 uint64_t num_packet;
34 uint32_t timeout;
35 int promisc;
36 int verbose;
37 int num_pktio;
38 char pktio_name[MAX_PKTIOS][MAX_PKTIO_NAME + 1];
39
40} test_options_t;
41
42typedef struct test_global_t {
43 test_options_t opt;
44 uint64_t rx_packets;
45 uint64_t tx_replies;
46 odp_pool_t pool;
48
49 struct {
50 odph_ethaddr_t eth_addr;
51 odp_pktio_t pktio;
52 odp_pktout_queue_t pktout;
53 int started;
54
55 } pktio[MAX_PKTIOS];
56
57 /* Pktio index lookup table */
58 uint8_t pktio_from_idx[ODP_PKTIO_MAX_INDEX + 1];
59
60} test_global_t;
61
62static test_global_t test_global;
63
64static void sig_handler(int signo)
65{
66 (void)signo;
67
68 odp_atomic_store_u32(&test_global.stop, 1);
69}
70
71static void print_usage(void)
72{
73 printf("\n"
74 "ODP ping example. Replies to ICMPv4 ping requests.\n"
75 "\n"
76 "OPTIONS:\n"
77 " -i, --interface <name> Packet IO interfaces (comma-separated, no spaces)\n"
78 " -n, --num_packet <number> Exit after this many packets. Use 0 to run infinitely. Default 0.\n"
79 " -t, --timeout <sec> Exit after this many seconds. Use 0 to run infinitely. Default 0.\n"
80 " -p, --promisc Set interface into promiscuous mode.\n"
81 " -v, --verbose Print extra packet information.\n"
82 " -h, --help Display help and exit.\n\n");
83}
84
85static int parse_options(int argc, char *argv[], test_global_t *global)
86{
87 int i, opt;
88 char *name, *str;
89 int len, str_len;
90
91 const struct option longopts[] = {
92 {"interface", required_argument, NULL, 'i'},
93 {"num_packet", required_argument, NULL, 'n'},
94 {"timeout", required_argument, NULL, 't'},
95 {"promisc", no_argument, NULL, 'p'},
96 {"verbose", no_argument, NULL, 'v'},
97 {"help", no_argument, NULL, 'h'},
98 {NULL, 0, NULL, 0}
99 };
100 const char *shortopts = "+i:n:t:pvh";
101 int ret = 0;
102
103 while (1) {
104 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
105
106 if (opt == -1)
107 break; /* No more options */
108
109 switch (opt) {
110 case 'i':
111 i = 0;
112 str = optarg;
113 str_len = strlen(str);
114
115 while (str_len > 0) {
116 len = strcspn(str, ",");
117 str_len -= len + 1;
118
119 if (i == MAX_PKTIOS) {
120 ODPH_ERR("Too many interfaces\n");
121 ret = -1;
122 break;
123 }
124
125 if (len > MAX_PKTIO_NAME) {
126 ODPH_ERR("Too long interface name: %s\n", str);
127 ret = -1;
128 break;
129 }
130
131 name = global->opt.pktio_name[i];
132 memcpy(name, str, len);
133 str += len + 1;
134 i++;
135 }
136
137 global->opt.num_pktio = i;
138
139 break;
140 case 'n':
141 global->opt.num_packet = atoll(optarg);
142 break;
143 case 't':
144 global->opt.timeout = atoi(optarg);
145 break;
146 case 'p':
147 global->opt.promisc = 1;
148 break;
149 case 'v':
150 global->opt.verbose = 1;
151 break;
152 case 'h':
153 default:
154 print_usage();
155 return -1;
156 }
157 }
158
159 if (global->opt.num_pktio == 0) {
160 ODPH_ERR("At least one pktio interface needed\n");
161 ret = -1;
162 }
163
164 return ret;
165}
166
167static int open_pktios(test_global_t *global)
168{
169 odp_pool_param_t pool_param;
170 odp_pktio_param_t pktio_param;
171 odp_pool_t pool;
172 odp_pool_capability_t pool_capa;
173 odp_pktio_capability_t pktio_capa;
174 odp_pktio_t pktio;
175 odp_pktio_config_t pktio_config;
176 odp_pktin_queue_param_t pktin_param;
177 odp_pktout_queue_param_t pktout_param;
178 odp_pktout_queue_t pktout;
179 char *name;
180 int i, num_pktio;
181 uint32_t num_pkt = MAX_PKT_NUM;
182
183 num_pktio = global->opt.num_pktio;
184
185 if (odp_pool_capability(&pool_capa)) {
186 ODPH_ERR("Pool capability failed\n");
187 return -1;
188 }
189
190 if (pool_capa.pkt.max_num < MAX_PKT_NUM)
191 num_pkt = pool_capa.pkt.max_num;
192
193 odp_pool_param_init(&pool_param);
194 pool_param.pkt.num = num_pkt;
195 pool_param.type = ODP_POOL_PACKET;
196
197 pool = odp_pool_create("packet pool", &pool_param);
198
199 global->pool = pool;
200
201 if (pool == ODP_POOL_INVALID) {
202 ODPH_ERR("Pool create failed\n");
203 return -1;
204 }
205
206 odp_pktio_param_init(&pktio_param);
207 pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
208 pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT;
209
210 for (i = 0; i < num_pktio; i++)
211 global->pktio[i].pktio = ODP_PKTIO_INVALID;
212
213 /* Open and configure interfaces */
214 for (i = 0; i < num_pktio; i++) {
215 name = global->opt.pktio_name[i];
216 pktio = odp_pktio_open(name, pool, &pktio_param);
217
218 if (pktio == ODP_PKTIO_INVALID) {
219 ODPH_ERR("Pktio open failed: %s\n", name);
220 return -1;
221 }
222
223 global->pktio[i].pktio = pktio;
224
225 if (odp_pktio_capability(pktio, &pktio_capa)) {
226 ODPH_ERR("Packet IO capability failed\n");
227 return -1;
228 }
229
230 if (odp_pktio_mac_addr(pktio,
231 &global->pktio[i].eth_addr.addr,
232 ODPH_ETHADDR_LEN) != ODPH_ETHADDR_LEN) {
233 ODPH_ERR("MAC address read failed: %s\n", name);
234 return -1;
235 }
236
237 odp_pktio_config_init(&pktio_config);
238 pktio_config.pktin.bit.ts_all = 1;
239 pktio_config.parser.layer = ODP_PROTO_LAYER_ALL;
240
241 odp_pktio_config(pktio, &pktio_config);
242
243 odp_pktin_queue_param_init(&pktin_param);
244
248 pktin_param.num_queues = 1;
249
250 if (odp_pktin_queue_config(pktio, &pktin_param)) {
251 ODPH_ERR("Pktin config failed: %s\n", name);
252 return -1;
253 }
254
255 odp_pktout_queue_param_init(&pktout_param);
256 pktout_param.num_queues = 1;
257
258 if (odp_pktout_queue_config(pktio, &pktout_param)) {
259 ODPH_ERR("Pktout config failed: %s\n", name);
260 return -1;
261 }
262
263 if (odp_pktout_queue(pktio, &pktout, 1) != 1) {
264 ODPH_ERR("Pktout queue request failed: %s\n", name);
265 return -1;
266 }
267
268 global->pktio[i].pktout = pktout;
269
270 if (global->opt.promisc && odp_pktio_promisc_mode(pktio) != 1) {
271 if (pktio_capa.set_op.op.promisc_mode == 0) {
272 ODPH_ERR("Promiscuous mode cannot be set: %s\n", name);
273 return -1;
274 }
275
276 if (odp_pktio_promisc_mode_set(pktio, 1)) {
277 ODPH_ERR("Promiscuous mode set failed: %s\n", name);
278 return -1;
279 }
280 }
281
282 odp_pktio_print(pktio);
283 }
284
285 return 0;
286}
287
288static int init_pktio_lookup_tbl(test_global_t *global)
289{
290 for (int i = 0; i < global->opt.num_pktio; i++) {
291 odp_pktio_t pktio = global->pktio[i].pktio;
292 int pktio_idx = odp_pktio_index(pktio);
293
294 if (pktio_idx < 0) {
295 ODPH_ERR("odp_pktio_index() failed: %s\n", global->opt.pktio_name[i]);
296 return -1;
297 }
298
299 global->pktio_from_idx[pktio_idx] = i;
300 }
301 return 0;
302}
303
304static int start_pktios(test_global_t *global)
305{
306 int i;
307
308 for (i = 0; i < global->opt.num_pktio; i++) {
309 if (odp_pktio_start(global->pktio[i].pktio)) {
310 ODPH_ERR("Pktio start failed: %s\n", global->opt.pktio_name[i]);
311 return -1;
312 }
313
314 global->pktio[i].started = 1;
315 }
316
317 return 0;
318}
319
320static int stop_pktios(test_global_t *global)
321{
322 odp_pktio_t pktio;
323 int i, ret = 0;
324
325 for (i = 0; i < global->opt.num_pktio; i++) {
326 pktio = global->pktio[i].pktio;
327
328 if (pktio == ODP_PKTIO_INVALID || global->pktio[i].started == 0)
329 continue;
330
331 if (odp_pktio_stop(pktio)) {
332 ODPH_ERR("Pktio stop failed: %s\n", global->opt.pktio_name[i]);
333 ret = -1;
334 }
335 }
336
337 return ret;
338}
339
340static void empty_queues(void)
341{
342 odp_event_t ev;
343 uint64_t wait_time = odp_schedule_wait_time(ODP_TIME_SEC_IN_NS / 2);
344
345 /* Drop all events from all queues */
346 while (1) {
347 ev = odp_schedule(NULL, wait_time);
348
349 if (ev == ODP_EVENT_INVALID)
350 break;
351
352 odp_event_free(ev);
353 }
354}
355
356static int close_pktios(test_global_t *global)
357{
358 odp_pktio_t pktio;
359 odp_pool_t pool;
360 int i, ret = 0;
361
362 for (i = 0; i < global->opt.num_pktio; i++) {
363 pktio = global->pktio[i].pktio;
364
365 if (pktio == ODP_PKTIO_INVALID)
366 continue;
367
368 if (odp_pktio_close(pktio)) {
369 ODPH_ERR("Pktio close failed: %s\n", global->opt.pktio_name[i]);
370 ret = -1;
371 }
372 }
373
374 pool = global->pool;
375
376 if (pool == ODP_POOL_INVALID)
377 return ret;
378
379 if (odp_pool_destroy(pool)) {
380 ODPH_ERR("Pool destroy failed\n");
381 ret = -1;
382 }
383
384 return ret;
385}
386
387static void print_mac_addr(uint8_t *addr)
388{
389 printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
390 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
391}
392
393static void print_ipv4_addr(uint8_t *addr)
394{
395 printf("%u.%u.%u.%u\n",
396 addr[0], addr[1], addr[2], addr[3]);
397}
398
399static void print_data(odp_packet_t pkt, uint32_t offset, uint32_t len)
400{
401 const uint32_t bytes_per_row = 16;
402 const uint32_t num_char = 1 + (bytes_per_row * 3) + 1;
403 uint8_t data[bytes_per_row];
404 char row[num_char];
405 uint32_t copy_len, i, j;
406 uint32_t data_len = odp_packet_len(pkt);
407
408 if (offset > data_len)
409 return;
410
411 if (offset + len > data_len)
412 len = data_len - offset;
413
414 while (len) {
415 i = 0;
416
417 if (len > bytes_per_row)
418 copy_len = bytes_per_row;
419 else
420 copy_len = len;
421
422 odp_packet_copy_to_mem(pkt, offset, copy_len, data);
423
424 i += snprintf(&row[i], num_char - i, " ");
425
426 for (j = 0; j < copy_len; j++)
427 i += snprintf(&row[i], num_char - i, " %02x", data[j]);
428
429 row[i] = 0;
430 printf("%s\n", row);
431
432 len -= copy_len;
433 offset += copy_len;
434 }
435}
436
437static void print_packet(odp_packet_t pkt, uint64_t num_packet)
438{
439 odp_pktio_t pktio;
440 odp_pktio_info_t pktio_info;
441 odp_time_t time;
442 uint64_t sec, nsec;
443 uint32_t offset;
444 uint8_t *data = odp_packet_data(pkt);
445 uint32_t seg_len = odp_packet_seg_len(pkt);
446 uint32_t l2_offset = odp_packet_l2_offset(pkt);
447 uint32_t l3_offset = odp_packet_l3_offset(pkt);
448 uint32_t l4_offset = odp_packet_l4_offset(pkt);
449 uint32_t data_len = odp_packet_len(pkt);
450 int icmp = odp_packet_has_icmp(pkt);
451 int ipv4 = odp_packet_has_ipv4(pkt);
452
453 if (odp_packet_has_ts(pkt))
454 time = odp_packet_ts(pkt);
455 else
456 time = odp_time_local();
457
458 nsec = odp_time_to_ns(time);
459 sec = nsec / ODP_TIME_SEC_IN_NS;
460 nsec = nsec - (sec * ODP_TIME_SEC_IN_NS);
461 pktio = odp_packet_input(pkt);
462
463 printf("PACKET [%" PRIu64 "]\n", num_packet);
464 printf(" time: %" PRIu64 ".%09" PRIu64 " sec\n", sec, nsec);
465 if (odp_pktio_info(pktio, &pktio_info) == 0)
466 printf(" interface name: %s\n", pktio_info.name);
467 else
468 printf(" interface name: n/a\n");
469 printf(" packet length: %u bytes\n", odp_packet_len(pkt));
470
471 /* L2 */
472 if (odp_packet_has_eth(pkt)) {
473 printf(" Ethernet offset: %u bytes\n", l2_offset);
474 offset = l2_offset;
475 if (offset + 6 <= seg_len) {
476 printf(" dst address: ");
477 print_mac_addr(data + offset);
478 }
479
480 offset = l2_offset + 6;
481 if (offset + 6 <= seg_len) {
482 printf(" src address: ");
483 print_mac_addr(data + offset);
484 }
485 } else if (odp_packet_has_l2(pkt)) {
486 printf(" L2 (%i) offset: %u bytes\n",
487 odp_packet_l2_type(pkt), l2_offset);
488 }
489
490 /* L3 */
491 if (ipv4) {
492 printf(" IPv4 offset: %u bytes\n", l3_offset);
493 offset = l3_offset + 12;
494 if (offset + 4 <= seg_len) {
495 printf(" src address: ");
496 print_ipv4_addr(data + offset);
497 }
498
499 offset = l3_offset + 16;
500 if (offset + 4 <= seg_len) {
501 printf(" dst address: ");
502 print_ipv4_addr(data + offset);
503 }
504 } else if (odp_packet_has_ipv6(pkt)) {
505 printf(" IPv6 offset: %u bytes\n", l3_offset);
506 } else if (odp_packet_has_l3(pkt)) {
507 printf(" L3 (%i) offset: %u bytes\n",
508 odp_packet_l3_type(pkt), l3_offset);
509 }
510
511 /* L4 */
512 if (icmp) {
513 printf(" ICMP offset: %u bytes\n", l4_offset);
514 if (ipv4) {
515 uint32_t len;
516 uint8_t *u8 = odp_packet_l4_ptr(pkt, &len);
517
518 if (u8 && len >= 2) {
519 printf(" type: %u\n", u8[0]);
520 printf(" code: %u\n", u8[1]);
521 }
522 }
523 } else if (odp_packet_has_l4(pkt)) {
524 printf(" L4 (%i) offset: %u bytes\n",
525 odp_packet_l4_type(pkt), l4_offset);
526 }
527
528 print_data(pkt, 0, data_len);
529
530 printf("\n");
531}
532
533/* Updated checksum when a 16 bit word has been changed from old to new */
534static uint16_t update_chksum(uint16_t chksum, uint16_t old, uint16_t new)
535{
536 uint16_t chksum_comp = ~chksum;
537 uint16_t old_comp = ~old;
538 uint32_t sum = chksum_comp + old_comp + new;
539
540 while (sum >> 16)
541 sum = (sum & 0xffff) + (sum >> 16);
542
543 return ~sum;
544}
545
546static void icmp_reply(test_global_t *global, odp_packet_t pkt)
547{
548 uint32_t dst_ip;
549 odph_ipv4hdr_t *ip_hdr;
550 odph_ethhdr_t *eth_hdr;
551 uint16_t old, new;
552 uint32_t len = 0;
553 int index = global->pktio_from_idx[odp_packet_input_index(pkt)];
554 odp_pktout_queue_t pktout = global->pktio[index].pktout;
555 odph_ethaddr_t *eth_addr = &global->pktio[index].eth_addr;
556 int icmp = odp_packet_has_icmp(pkt);
557 int ipv4 = odp_packet_has_ipv4(pkt);
558 int eth = odp_packet_has_eth(pkt);
559 odph_icmphdr_t *icmp_hdr = odp_packet_l4_ptr(pkt, &len);
560
561 if (odp_packet_has_error(pkt))
562 goto error;
563
564 if (eth == 0 || ipv4 == 0 || icmp == 0)
565 goto error;
566
567 /* ICMP type, code and chksum fields are located in the first 4 bytes */
568 if (icmp_hdr == NULL || len < 4)
569 goto error;
570
571 if (icmp_hdr->type != ODPH_ICMP_ECHO || icmp_hdr->code != 0)
572 goto error;
573
574 /* Echo reply */
575 old = *(uint16_t *)(uintptr_t)icmp_hdr;
576 icmp_hdr->type = ODPH_ICMP_ECHOREPLY;
577 new = *(uint16_t *)(uintptr_t)icmp_hdr;
578 icmp_hdr->chksum = update_chksum(icmp_hdr->chksum, old, new);
579
580 /* Swap IP addresses */
581 ip_hdr = odp_packet_l3_ptr(pkt, &len);
582 if (ip_hdr == NULL || len < 20)
583 goto error;
584
585 dst_ip = ip_hdr->dst_addr;
586 ip_hdr->dst_addr = ip_hdr->src_addr;
587 ip_hdr->src_addr = dst_ip;
588
589 /* Swap Ethernet addresses */
590 eth_hdr = odp_packet_l2_ptr(pkt, &len);
591 if (eth_hdr == NULL || len < 14)
592 goto error;
593
594 eth_hdr->dst = eth_hdr->src;
595 eth_hdr->src = *eth_addr;
596
597 if (odp_pktout_send(pktout, &pkt, 1) != 1)
598 goto error;
599
600 global->tx_replies++;
601 return;
602
603error:
604 odp_packet_free(pkt);
605}
606
607static void print_stat(test_global_t *global, uint64_t rx_packets,
608 uint64_t diff_ns)
609{
610 uint64_t prev = global->rx_packets;
611 double per_sec = 1000000000.0 * (rx_packets - prev) / diff_ns;
612
613 printf("Received %" PRIu64 " packets (%.1f / sec). "
614 "Sent %" PRIu64 " replies.\n",
615 rx_packets, per_sec, global->tx_replies);
616
617 global->rx_packets = rx_packets;
618}
619
620static int receive_packets(test_global_t *global)
621{
622 odp_event_t ev;
623 odp_packet_t pkt;
624 uint64_t diff_ns;
625 int print = 0;
626 uint64_t num_packet = 0;
627 uint64_t timeout_ns = global->opt.timeout * ODP_TIME_SEC_IN_NS;
629 odp_time_t start = odp_time_local();
630 odp_time_t cur = start;
631 odp_time_t prev = start;
632
633 while (!odp_atomic_load_u32(&global->stop)) {
634 ev = odp_schedule(NULL, wait);
635
636 cur = odp_time_local();
637 diff_ns = odp_time_diff_ns(cur, prev);
638 if (diff_ns >= ODP_TIME_SEC_IN_NS) {
639 prev = cur;
640 print = 1;
641 }
642
643 if (ev == ODP_EVENT_INVALID) {
644 if (print) {
645 print_stat(global, num_packet, diff_ns);
646 print = 0;
647 }
648
649 if (timeout_ns) {
650 if (odp_time_diff_ns(cur, start) >= timeout_ns)
651 break;
652 }
653
654 continue;
655 }
656
657 if (odp_event_type(ev) != ODP_EVENT_PACKET) {
658 printf("Bad event type: %i\n", odp_event_type(ev));
659 odp_event_free(ev);
660 continue;
661 }
662
663 pkt = odp_packet_from_event(ev);
664
665 if (global->opt.verbose)
666 print_packet(pkt, num_packet);
667
668 /* Reply or drop packet */
669 icmp_reply(global, pkt);
670
671 num_packet++;
672 if (print) {
673 print_stat(global, num_packet, diff_ns);
674 print = 0;
675 }
676
677 if (global->opt.num_packet && num_packet >= global->opt.num_packet)
678 break;
679 }
680
681 /* Timeout before num packets received */
682 if (global->opt.num_packet && num_packet < global->opt.num_packet) {
683 ODPH_ERR("Received %" PRIu64 "/%" PRIu64 " packets\n",
684 num_packet, global->opt.num_packet);
685 return -1;
686 }
687
688 return 0;
689}
690
691int main(int argc, char *argv[])
692{
693 odp_instance_t instance;
694 test_global_t *global;
695 int ret = 0;
696
697 global = &test_global;
698 memset(global, 0, sizeof(test_global_t));
699 odp_atomic_init_u32(&global->stop, 0);
700
701 signal(SIGINT, sig_handler);
702
703 if (parse_options(argc, argv, global))
704 return -1;
705
706 /* Init ODP before calling anything else */
707 if (odp_init_global(&instance, NULL, NULL)) {
708 ODPH_ERR("Global init failed\n");
709 return -1;
710 }
711
712 /* Init this thread */
713 if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
714 ODPH_ERR("Local init failed\n");
715 return -1;
716 }
717
718 global->pool = ODP_POOL_INVALID;
719
721
723
724 if (open_pktios(global)) {
725 ODPH_ERR("Pktio open failed\n");
726 return -1;
727 }
728
729 if (init_pktio_lookup_tbl(global)) {
730 ODPH_ERR("Mapping pktio indexes failed\n");
731 return -1;
732 }
733
734 if (start_pktios(global)) {
735 ODPH_ERR("Pktio start failed\n");
736 return -1;
737 }
738
739 if (receive_packets(global)) {
740 ret = -1;
741 }
742
743 if (stop_pktios(global)) {
744 ODPH_ERR("Pktio stop failed\n");
745 return -1;
746 }
747
748 empty_queues();
749
750 if (close_pktios(global)) {
751 ODPH_ERR("Pktio close failed\n");
752 return -1;
753 }
754
755 if (odp_term_local()) {
756 ODPH_ERR("Term local failed\n");
757 return -1;
758 }
759
760 if (odp_term_global(instance)) {
761 ODPH_ERR("Term global failed\n");
762 return -1;
763 }
764
765 return ret;
766}
void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val)
Initialize atomic uint32 variable.
uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom)
Load value of atomic uint32 variable.
void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val)
Store value to atomic uint32 variable.
void odp_event_free(odp_event_t event)
Free event.
odp_event_type_t odp_event_type(odp_event_t event)
Event type of an event.
#define ODP_EVENT_INVALID
Invalid event.
#define ODP_STATIC_ASSERT(cond, msg)
Compile time assertion macro.
int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type)
Thread local ODP initialization.
int odp_init_global(odp_instance_t *instance, const odp_init_t *params, const odp_platform_init_t *platform_params)
Global ODP initialization.
int odp_term_local(void)
Thread local ODP termination.
int odp_term_global(odp_instance_t instance)
Global ODP termination.
uint64_t odp_instance_t
ODP instance ID.
int odp_pktio_mac_addr(odp_pktio_t pktio, void *mac_addr, int size)
Get the default MAC address of a packet IO interface.
void odp_pktin_queue_param_init(odp_pktin_queue_param_t *param)
Initialize packet input queue parameters.
void odp_pktio_param_init(odp_pktio_param_t *param)
Initialize pktio params.
int odp_pktio_promisc_mode(odp_pktio_t pktio)
Determine if promiscuous mode is enabled for a packet IO interface.
int odp_pktio_close(odp_pktio_t pktio)
Close a packet IO interface.
int odp_pktio_info(odp_pktio_t pktio, odp_pktio_info_t *info)
Retrieve information about a pktio.
int odp_pktout_queue(odp_pktio_t pktio, odp_pktout_queue_t queues[], int num)
Direct packet output queues.
int odp_pktio_promisc_mode_set(odp_pktio_t pktio, odp_bool_t enable)
Set promiscuous mode.
void odp_pktio_config_init(odp_pktio_config_t *config)
Initialize packet IO configuration options.
odp_pktio_t odp_pktio_open(const char *name, odp_pool_t pool, const odp_pktio_param_t *param)
Open a packet IO interface.
int odp_pktio_config(odp_pktio_t pktio, const odp_pktio_config_t *config)
Configure packet IO interface options.
void odp_pktio_print(odp_pktio_t pktio)
Print pktio info to the console.
int odp_pktio_start(odp_pktio_t pktio)
Start packet receive and transmit.
#define ODP_PKTIO_INVALID
Invalid packet IO handle.
void odp_pktout_queue_param_init(odp_pktout_queue_param_t *param)
Initialize packet output queue parameters.
int odp_pktio_stop(odp_pktio_t pktio)
Stop packet receive and transmit.
int odp_pktio_index(odp_pktio_t pktio)
Get pktio interface index.
int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa)
Query packet IO interface capabilities.
#define ODP_PKTIO_MAX_INDEX
Maximum packet IO interface index.
int odp_pktout_send(odp_pktout_queue_t queue, const odp_packet_t packets[], int num)
Send packets directly to an interface output queue.
int odp_pktin_queue_config(odp_pktio_t pktio, const odp_pktin_queue_param_t *param)
Configure packet input queues.
int odp_pktout_queue_config(odp_pktio_t pktio, const odp_pktout_queue_param_t *param)
Configure packet output queues.
@ ODP_PKTOUT_MODE_DIRECT
Direct packet output on the interface.
@ ODP_PKTIN_MODE_SCHED
Packet input through scheduler and scheduled event queues.
int odp_packet_has_l3(odp_packet_t pkt)
Check for layer 3 protocols.
odp_proto_l4_type_t odp_packet_l4_type(odp_packet_t pkt)
Layer 4 protocol type.
int odp_packet_has_ts(odp_packet_t pkt)
Check for packet timestamp.
int odp_packet_input_index(odp_packet_t pkt)
Packet input interface index.
uint32_t odp_packet_seg_len(odp_packet_t pkt)
Packet data length following the data pointer.
int odp_packet_has_icmp(odp_packet_t pkt)
Check for ICMP.
int odp_packet_has_ipv4(odp_packet_t pkt)
Check for IPv4.
uint32_t odp_packet_l4_offset(odp_packet_t pkt)
Layer 4 start offset.
void * odp_packet_data(odp_packet_t pkt)
Packet data pointer.
int odp_packet_has_eth(odp_packet_t pkt)
Check for Ethernet header.
odp_proto_l2_type_t odp_packet_l2_type(odp_packet_t pkt)
Layer 2 protocol type.
int odp_packet_has_l4(odp_packet_t pkt)
Check for layer 4 protocols.
uint32_t odp_packet_len(odp_packet_t pkt)
Packet data length.
int odp_packet_has_error(odp_packet_t pkt)
Check for all parse errors in packet.
int odp_packet_has_ipv6(odp_packet_t pkt)
Check for IPv6.
int odp_packet_has_l2(odp_packet_t pkt)
Check for layer 2 protocols.
void * odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
Layer 3 start pointer.
odp_packet_t odp_packet_from_event(odp_event_t ev)
Get packet handle from event.
void odp_packet_free(odp_packet_t pkt)
Free packet.
uint32_t odp_packet_l3_offset(odp_packet_t pkt)
Layer 3 start offset.
void * odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
Layer 2 start pointer.
odp_proto_l3_type_t odp_packet_l3_type(odp_packet_t pkt)
Layer 3 protocol type.
void * odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len)
Layer 4 start pointer.
int odp_packet_copy_to_mem(odp_packet_t pkt, uint32_t offset, uint32_t len, void *dst)
Copy data from packet to memory.
odp_time_t odp_packet_ts(odp_packet_t pkt)
Packet timestamp.
odp_pktio_t odp_packet_input(odp_packet_t pkt)
Packet input interface.
uint32_t odp_packet_l2_offset(odp_packet_t pkt)
Layer 2 start offset.
@ ODP_PROTO_LAYER_ALL
All layers.
odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *param)
Create a pool.
int odp_pool_capability(odp_pool_capability_t *capa)
Query pool capabilities.
void odp_pool_param_init(odp_pool_param_t *param)
Initialize pool params.
int odp_pool_destroy(odp_pool_t pool)
Destroy a pool previously created by odp_pool_create()
#define ODP_POOL_INVALID
Invalid pool.
@ ODP_POOL_PACKET
Packet pool.
#define ODP_SCHED_SYNC_ATOMIC
Atomic queue synchronization.
int odp_schedule_default_prio(void)
Default scheduling priority level.
int odp_schedule_config(const odp_schedule_config_t *config)
Global schedule configuration.
uint64_t odp_schedule_wait_time(uint64_t ns)
Schedule wait time.
odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait)
Schedule an event.
#define ODP_SCHED_GROUP_ALL
Group of all threads.
void odp_sys_info_print(void)
Print system info.
@ ODP_THREAD_CONTROL
Control thread.
uint64_t odp_time_to_ns(odp_time_t time)
Convert time to nanoseconds.
#define ODP_TIME_SEC_IN_NS
A second in nanoseconds.
odp_time_t odp_time_local(void)
Current local time.
#define ODP_TIME_MSEC_IN_NS
A millisecond in nanoseconds.
uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1)
Time difference in nanoseconds.
The OpenDataPlane API.
Packet input queue parameters.
uint32_t num_queues
Number of input queues to be created.
odp_queue_param_t queue_param
Queue parameters.
odp_pktio_set_op_t set_op
Supported set operations.
Packet IO configuration options.
odp_pktio_parser_config_t parser
Packet input parser configuration.
odp_pktin_config_opt_t pktin
Packet input configuration options bit field.
Packet IO information.
const char * name
Packet IO device name.
Packet IO parameters.
odp_pktin_mode_t in_mode
Packet input mode.
odp_pktout_mode_t out_mode
Packet output mode.
odp_proto_layer_t layer
Protocol parsing level in packet input.
Packet output queue parameters.
uint32_t num_queues
Number of output queues to be created.
uint32_t max_num
Maximum number of buffers of any size.
struct odp_pool_capability_t::@134 pkt
Packet pool capabilities
uint32_t num
Number of buffers in the pool.
struct odp_pool_param_t::@139 pkt
Parameters for packet pools.
odp_pool_type_t type
Pool type.
odp_schedule_param_t sched
Scheduler parameters.
odp_schedule_group_t group
Thread group.
odp_schedule_prio_t prio
Priority level.
odp_schedule_sync_t sync
Synchronization method.
uint64_t ts_all
Timestamp all packets on packet input.
struct odp_pktin_config_opt_t::@108 bit
Option flags.
struct odp_pktio_set_op_t::@112 op
Operation flags.
uint32_t promisc_mode
Promiscuous mode.