API Reference Manual 1.51.0
Loading...
Searching...
No Matches
odp_pktio.c
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2013-2018 Linaro Limited
3 */
4
13#include <stdlib.h>
14#include <string.h>
15#include <getopt.h>
16#include <unistd.h>
17#include <inttypes.h>
18
19#include <odp_api.h>
20#include <odp/helper/odph_api.h>
21
25#define MAX_WORKERS (ODP_THREAD_COUNT_MAX - 1)
26
30#define SHM_PKT_POOL_SIZE (512*2048)
31
35#define SHM_PKT_POOL_BUF_SIZE 1856
36
40#define MAX_PKT_BURST 16
41
45#define APPL_MODE_PKT_BURST 0
46
50#define APPL_MODE_PKT_QUEUE 1
51
55#define APPL_MODE_PKT_SCHED 2
56
61#define PRINT_APPL_MODE(x) printf("%s(%i)\n", #x, (x))
62
64#define NO_PATH(file_name) (strrchr((file_name), '/') ? \
65 strrchr((file_name), '/') + 1 : (file_name))
69typedef struct {
70 unsigned int cpu_count;
71 int if_count;
72 char **if_names;
73 int mode;
74 char *if_str;
75 double time;
76} appl_args_t;
77
81typedef struct {
82 char *pktio_dev;
83 int mode;
84} thread_args_t;
85
89typedef struct {
91 appl_args_t appl;
93 odp_shm_t shm;
95 thread_args_t thread[MAX_WORKERS];
97 odp_atomic_u32_t exit_threads;
98} args_t;
99
101static args_t *args;
102
103/* helper funcs */
104static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len);
105static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len);
106static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
107static void print_info(char *progname, appl_args_t *appl_args);
108static void usage(char *progname);
109
120static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool, int mode)
121{
122 odp_pktio_t pktio;
123 int ret;
124 odp_pktio_param_t pktio_param;
125 odp_pktin_queue_param_t pktin_param;
126
127 odp_pktio_param_init(&pktio_param);
128
129 switch (mode) {
130 case APPL_MODE_PKT_BURST:
131 pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT;
132 break;
133 case APPL_MODE_PKT_QUEUE:
134 pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE;
135 break;
136 case APPL_MODE_PKT_SCHED:
137 pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
138 break;
139 default:
140 ODPH_ABORT("invalid mode %d\n", mode);
141 }
142
143 /* Open a packet IO instance */
144 pktio = odp_pktio_open(dev, pool, &pktio_param);
145 if (pktio == ODP_PKTIO_INVALID)
146 ODPH_ABORT("Error: pktio create failed for %s\n", dev);
147
148 odp_pktin_queue_param_init(&pktin_param);
149
150 if (mode == APPL_MODE_PKT_SCHED)
152
153 if (odp_pktin_queue_config(pktio, &pktin_param))
154 ODPH_ABORT("Error: pktin config failed for %s\n", dev);
155
156 if (odp_pktout_queue_config(pktio, NULL))
157 ODPH_ABORT("Error: pktout config failed for %s\n", dev);
158
159 ret = odp_pktio_start(pktio);
160 if (ret != 0)
161 ODPH_ABORT("Error: unable to start %s\n", dev);
162
163 printf(" created pktio:%02" PRIu64
164 ", dev:%s, queue mode (ATOMIC queues)\n"
165 " \tdefault pktio%02" PRIu64 "\n",
166 odp_pktio_to_u64(pktio), dev,
167 odp_pktio_to_u64(pktio));
168
169 return pktio;
170}
171
177static int pktio_queue_thread(void *arg)
178{
179 int thr;
180 odp_pktio_t pktio;
181 thread_args_t *thr_args;
182 odp_pktout_queue_t pktout;
183 odp_queue_t inq;
184 odp_packet_t pkt;
185 odp_event_t ev;
186 unsigned long pkt_cnt = 0;
187 unsigned long err_cnt = 0;
188 uint64_t sched_wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS * 100);
189
190 thr = odp_thread_id();
191 thr_args = arg;
192
193 pktio = odp_pktio_lookup(thr_args->pktio_dev);
194 if (pktio == ODP_PKTIO_INVALID) {
195 ODPH_ERR(" [%02i] Error: lookup of pktio %s failed\n",
196 thr, thr_args->pktio_dev);
197 return -1;
198 }
199
200 printf(" [%02i] looked up pktio:%02" PRIu64
201 ", queue mode (ATOMIC queues)\n"
202 " default pktio%02" PRIu64 "\n",
203 thr, odp_pktio_to_u64(pktio), odp_pktio_to_u64(pktio));
204
205 inq = ODP_QUEUE_INVALID;
206
207 if ((thr_args->mode == APPL_MODE_PKT_QUEUE) &&
208 (odp_pktin_event_queue(pktio, &inq, 1) != 1)) {
209 ODPH_ERR(" [%02i] Error: no input queue for %s\n",
210 thr, thr_args->pktio_dev);
211 return -1;
212 }
213
214 /* Loop packets */
215 while (!odp_atomic_load_u32(&args->exit_threads)) {
216 odp_pktio_t pktio_tmp;
217
218 if (inq != ODP_QUEUE_INVALID)
219 ev = odp_queue_deq(inq);
220 else
221 ev = odp_schedule(NULL, sched_wait);
222
223 if (ev == ODP_EVENT_INVALID)
224 continue;
225
226 pkt = odp_packet_from_event(ev);
227 if (!odp_packet_is_valid(pkt))
228 continue;
229
230 /* Drop packets with errors */
231 if (odp_unlikely(drop_err_pkts(&pkt, 1) == 0)) {
232 ODPH_ERR("Drop frame - err_cnt:%lu\n", ++err_cnt);
233 continue;
234 }
235
236 pktio_tmp = odp_packet_input(pkt);
237
238 if (odp_pktout_queue(pktio_tmp, &pktout, 1) != 1) {
239 ODPH_ERR(" [%02i] Error: no pktout queue\n", thr);
240 return -1;
241 }
242
243 /* Swap Eth MACs and possibly IP-addrs before sending back */
244 swap_pkt_addrs(&pkt, 1);
245
246 /* Enqueue the packet for output */
247 if (odp_pktout_send(pktout, &pkt, 1) != 1) {
248 ODPH_ERR(" [%i] Packet send failed.\n", thr);
249 odp_packet_free(pkt);
250 continue;
251 }
252
253 /* Print packet counts every once in a while */
254 if (odp_unlikely(pkt_cnt++ % 100000 == 0)) {
255 printf(" [%02i] pkt_cnt:%lu\n", thr, pkt_cnt);
256 fflush(NULL);
257 }
258 }
259
260 return 0;
261}
262
268static int pktio_ifburst_thread(void *arg)
269{
270 int thr;
271 odp_pktio_t pktio;
272 odp_pktin_queue_t pktin;
273 odp_pktout_queue_t pktout;
274 thread_args_t *thr_args;
275 int pkts, pkts_ok;
276 odp_packet_t pkt_tbl[MAX_PKT_BURST];
277 unsigned long pkt_cnt = 0;
278 unsigned long err_cnt = 0;
279 unsigned long tmp = 0;
280
281 thr = odp_thread_id();
282 thr_args = arg;
283
284 pktio = odp_pktio_lookup(thr_args->pktio_dev);
285 if (pktio == ODP_PKTIO_INVALID) {
286 ODPH_ERR(" [%02i] Error: lookup of pktio %s failed\n",
287 thr, thr_args->pktio_dev);
288 return -1;
289 }
290
291 printf(" [%02i] looked up pktio:%02" PRIu64 ", burst mode\n",
292 thr, odp_pktio_to_u64(pktio));
293
294 if (odp_pktin_queue(pktio, &pktin, 1) != 1) {
295 ODPH_ERR(" [%02i] Error: no pktin queue\n", thr);
296 return -1;
297 }
298
299 if (odp_pktout_queue(pktio, &pktout, 1) != 1) {
300 ODPH_ERR(" [%02i] Error: no pktout queue\n", thr);
301 return -1;
302 }
303
304 /* Loop packets */
305 while (!odp_atomic_load_u32(&args->exit_threads)) {
306 pkts = odp_pktin_recv(pktin, pkt_tbl, MAX_PKT_BURST);
307 if (pkts > 0) {
308 /* Drop packets with errors */
309 pkts_ok = drop_err_pkts(pkt_tbl, pkts);
310 if (pkts_ok > 0) {
311 int sent;
312
313 /* Swap Eth MACs and IP-addrs */
314 swap_pkt_addrs(pkt_tbl, pkts_ok);
315 sent = odp_pktout_send(pktout, pkt_tbl,
316 pkts_ok);
317 sent = sent > 0 ? sent : 0;
318 if (odp_unlikely(sent < pkts_ok)) {
319 err_cnt += pkts_ok - sent;
320 do
321 odp_packet_free(pkt_tbl[sent]);
322 while (++sent < pkts_ok);
323 }
324 }
325
326 if (odp_unlikely(pkts_ok != pkts))
327 ODPH_ERR("Dropped frames:%u - err_cnt:%lu\n",
328 pkts - pkts_ok, ++err_cnt);
329
330 /* Print packet counts every once in a while */
331 tmp += pkts_ok;
332 if (odp_unlikely((tmp >= 100000) || /* OR first print:*/
333 ((pkt_cnt == 0) && ((tmp-1) < MAX_PKT_BURST)))) {
334 pkt_cnt += tmp;
335 printf(" [%02i] pkt_cnt:%lu\n", thr, pkt_cnt);
336 fflush(NULL);
337 tmp = 0;
338 }
339 }
340 }
341
342 return 0;
343}
344
348int main(int argc, char *argv[])
349{
350 odph_helper_options_t helper_options;
351 odph_thread_t thread_tbl[MAX_WORKERS];
352 odph_thread_common_param_t thr_common;
353 odph_thread_param_t thr_param[MAX_WORKERS];
354 odp_pool_t pool;
355 int num_workers;
356 int i;
357 odp_cpumask_t cpumask;
358 char cpumaskstr[ODP_CPUMASK_STR_SIZE];
359 odp_pool_param_t params;
360 odp_instance_t instance;
361 odp_init_t init_param;
362 odp_shm_t shm;
363
364 /* Let helper collect its own arguments (e.g. --odph_proc) */
365 argc = odph_parse_options(argc, argv);
366 if (odph_options(&helper_options)) {
367 ODPH_ERR("Error: reading ODP helper options failed.\n");
368 exit(EXIT_FAILURE);
369 }
370
371 odp_init_param_init(&init_param);
372 init_param.mem_model = helper_options.mem_model;
373
374 /* Init ODP before calling anything else */
375 if (odp_init_global(&instance, &init_param, NULL)) {
376 ODPH_ERR("Error: ODP global init failed.\n");
377 exit(EXIT_FAILURE);
378 }
379
380 /* Init this thread */
381 if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
382 ODPH_ERR("Error: ODP local init failed.\n");
383 exit(EXIT_FAILURE);
384 }
385
386 /* Reserve memory for args from shared mem */
387 shm = odp_shm_reserve("_appl_global_data", sizeof(args_t),
388 ODP_CACHE_LINE_SIZE, 0);
389 if (shm == ODP_SHM_INVALID) {
390 ODPH_ERR("Error: shared mem reserve failed.\n");
391 exit(EXIT_FAILURE);
392 }
393
394 args = odp_shm_addr(shm);
395 if (args == NULL) {
396 ODPH_ERR("Error: shared mem alloc failed.\n");
397 exit(EXIT_FAILURE);
398 }
399
400 memset(args, 0, sizeof(args_t));
401 odp_atomic_init_u32(&args->exit_threads, 0);
402 args->shm = shm;
403
404 /* Parse and store the application arguments */
405 parse_args(argc, argv, &args->appl);
406
407 /* Print both system and application information */
408 print_info(NO_PATH(argv[0]), &args->appl);
409
410 num_workers = MAX_WORKERS;
411 if (args->appl.cpu_count && args->appl.cpu_count < MAX_WORKERS)
412 num_workers = args->appl.cpu_count;
413
414 /* Get default worker cpumask */
415 num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
416 (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));
417
418 printf("num worker threads: %i\n", num_workers);
419 printf("first CPU: %i\n", odp_cpumask_first(&cpumask));
420 printf("cpu mask: %s\n", cpumaskstr);
421
422 /* Create packet pool */
423 odp_pool_param_init(&params);
424 params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE;
425 params.pkt.len = SHM_PKT_POOL_BUF_SIZE;
426 params.pkt.num = SHM_PKT_POOL_SIZE/SHM_PKT_POOL_BUF_SIZE;
427 params.type = ODP_POOL_PACKET;
428
429 pool = odp_pool_create("packet_pool", &params);
430
431 if (pool == ODP_POOL_INVALID) {
432 ODPH_ERR("Error: packet pool create failed.\n");
433 exit(EXIT_FAILURE);
434 }
435 odp_pool_print(pool);
436
437 /* Config and start scheduler */
439
440 /* Create a pktio instance for each interface */
441 for (i = 0; i < args->appl.if_count; ++i)
442 create_pktio(args->appl.if_names[i], pool, args->appl.mode);
443
444 /* Create and init worker threads */
445 odph_thread_common_param_init(&thr_common);
446 thr_common.instance = instance;
447 thr_common.cpumask = &cpumask;
448
449 for (i = 0; i < num_workers; ++i) {
450 int (*thr_run_func)(void *);
451 int if_idx;
452
453 if_idx = i % args->appl.if_count;
454
455 args->thread[i].pktio_dev = args->appl.if_names[if_idx];
456 args->thread[i].mode = args->appl.mode;
457
458 if (args->appl.mode == APPL_MODE_PKT_BURST)
459 thr_run_func = pktio_ifburst_thread;
460 else /* APPL_MODE_PKT_QUEUE */
461 thr_run_func = pktio_queue_thread;
462
463 odph_thread_param_init(&thr_param[i]);
464 thr_param[i].start = thr_run_func;
465 thr_param[i].arg = &args->thread[i];
466 thr_param[i].thr_type = ODP_THREAD_WORKER;
467 }
468
469 memset(thread_tbl, 0, sizeof(thread_tbl));
470 odph_thread_create(thread_tbl, &thr_common, thr_param, num_workers);
471
472 if (args->appl.time > 0.0) {
473 odp_time_wait_ns(args->appl.time *
475 for (i = 0; i < args->appl.if_count; ++i) {
476 odp_pktio_t pktio;
477
478 pktio = odp_pktio_lookup(args->thread[i].pktio_dev);
479 odp_pktio_stop(pktio);
480 }
481 /* use delay to let workers clean up queues */
483 odp_atomic_store_u32(&args->exit_threads, 1);
484 }
485
486 /* Master thread waits for other threads to exit */
487 odph_thread_join(thread_tbl, num_workers);
488
489 for (i = 0; i < args->appl.if_count; ++i)
490 odp_pktio_close(odp_pktio_lookup(args->thread[i].pktio_dev));
491
492 free(args->appl.if_names);
493 free(args->appl.if_str);
494
495 odp_pool_destroy(pool);
496
497 if (odp_shm_free(args->shm)) {
498 ODPH_ERR("Error: shm free global data\n");
499 exit(EXIT_FAILURE);
500 }
501
503 return odp_term_global(instance);
504}
505
517static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len)
518{
519 odp_packet_t pkt;
520 unsigned pkt_cnt = len;
521 unsigned i, j;
522
523 for (i = 0, j = 0; i < len; ++i) {
524 pkt = pkt_tbl[i];
525
527 odp_packet_free(pkt); /* Drop */
528 pkt_cnt--;
529 } else if (odp_unlikely(i != j++)) {
530#pragma GCC diagnostic push
531#pragma GCC diagnostic ignored "-Warray-bounds"
532 pkt_tbl[j-1] = pkt;
533#pragma GCC diagnostic pop
534 }
535 }
536
537 return pkt_cnt;
538}
539
547static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len)
548{
549 odp_packet_t pkt;
550 odph_ethhdr_t *eth;
551 odph_ethaddr_t tmp_addr;
552 odph_ipv4hdr_t *ip;
553 odp_u32be_t ip_tmp_addr; /* tmp ip addr */
554 unsigned i;
555
556 for (i = 0; i < len; ++i) {
557 pkt = pkt_tbl[i];
558 if (odp_packet_has_eth(pkt)) {
559 eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
560
561 tmp_addr = eth->dst;
562 eth->dst = eth->src;
563 eth->src = tmp_addr;
564
565 if (odp_packet_has_ipv4(pkt)) {
566 /* IPv4 */
567 ip = (odph_ipv4hdr_t *)
568 odp_packet_l3_ptr(pkt, NULL);
569
570 ip_tmp_addr = ip->src_addr;
571 ip->src_addr = ip->dst_addr;
572 ip->dst_addr = ip_tmp_addr;
573 }
574 }
575 }
576}
577
585static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
586{
587 int opt;
588 char *token;
589 size_t len;
590 int i;
591 static const struct option longopts[] = {
592 {"count", required_argument, NULL, 'c'},
593 {"time", required_argument, NULL, 't'},
594 {"interface", required_argument, NULL, 'i'}, /* return 'i' */
595 {"mode", required_argument, NULL, 'm'}, /* return 'm' */
596 {"help", no_argument, NULL, 'h'}, /* return 'h' */
597 {NULL, 0, NULL, 0}
598 };
599
600 static const char *shortopts = "+c:i:m:t:h";
601
602 appl_args->cpu_count = 1; /* use one worker by default */
603 appl_args->mode = APPL_MODE_PKT_SCHED;
604 appl_args->time = 0;
606 while (1) {
607 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
608
609 if (opt == -1)
610 break; /* No more options */
611
612 switch (opt) {
613 case 'c':
614 appl_args->cpu_count = atoi(optarg);
615 break;
616 case 't':
617 appl_args->time = atof(optarg);
618 break;
619 /* parse packet-io interface names */
620 case 'i':
621 len = strlen(optarg);
622 if (len == 0) {
623 usage(argv[0]);
624 exit(EXIT_FAILURE);
625 }
626 len += 1; /* add room for '\0' */
627
628 appl_args->if_str = malloc(len);
629 if (appl_args->if_str == NULL) {
630 usage(argv[0]);
631 exit(EXIT_FAILURE);
632 }
633
634 /* count the number of tokens separated by ',' */
635 strcpy(appl_args->if_str, optarg);
636 for (token = strtok(appl_args->if_str, ","), i = 0;
637 token != NULL;
638 token = strtok(NULL, ","), i++)
639 ;
640
641 appl_args->if_count = i;
642
643 if (appl_args->if_count == 0) {
644 usage(argv[0]);
645 exit(EXIT_FAILURE);
646 }
647
648 /* allocate storage for the if names */
649 appl_args->if_names =
650 calloc(appl_args->if_count, sizeof(char *));
651
652 /* store the if names (reset names string) */
653 strcpy(appl_args->if_str, optarg);
654 for (token = strtok(appl_args->if_str, ","), i = 0;
655 token != NULL; token = strtok(NULL, ","), i++) {
656 appl_args->if_names[i] = token;
657 }
658 break;
659
660 case 'm':
661 i = atoi(optarg);
662 switch (i) {
663 case 0:
664 appl_args->mode = APPL_MODE_PKT_BURST;
665 break;
666 case 1:
667 appl_args->mode = APPL_MODE_PKT_QUEUE;
668 break;
669 case 2:
670 appl_args->mode = APPL_MODE_PKT_SCHED;
671 break;
672 default:
673 usage(argv[0]);
674 exit(EXIT_FAILURE);
675 }
676 break;
677 case 'h':
678 usage(argv[0]);
679 exit(EXIT_SUCCESS);
680 break;
681
682 default:
683 break;
684 }
685 }
686
687 if (appl_args->if_count == 0 || appl_args->mode == -1) {
688 usage(argv[0]);
689 exit(EXIT_FAILURE);
690 }
691
692 optind = 1; /* reset 'extern optind' from the getopt lib */
693}
694
698static void print_info(char *progname, appl_args_t *appl_args)
699{
700 int i;
701
703
704 printf("Running ODP appl: \"%s\"\n"
705 "-----------------\n"
706 "IF-count: %i\n"
707 "Using IFs: ",
708 progname, appl_args->if_count);
709 for (i = 0; i < appl_args->if_count; ++i)
710 printf(" %s", appl_args->if_names[i]);
711 printf("\n"
712 "Mode: ");
713 switch (appl_args->mode) {
714 case APPL_MODE_PKT_BURST:
715 PRINT_APPL_MODE(APPL_MODE_PKT_BURST);
716 break;
717 case APPL_MODE_PKT_QUEUE:
718 PRINT_APPL_MODE(APPL_MODE_PKT_QUEUE);
719 break;
720 case APPL_MODE_PKT_SCHED:
721 PRINT_APPL_MODE(APPL_MODE_PKT_SCHED);
722 break;
723 }
724 printf("\n\n");
725 fflush(NULL);
726}
727
731static void usage(char *progname)
732{
733 printf("\n"
734 "Usage: %s OPTIONS\n"
735 " E.g. %s -i eth1,eth2,eth3 -m 0\n"
736 "\n"
737 "OpenDataPlane example application.\n"
738 "\n"
739 "Mandatory OPTIONS:\n"
740 " -i, --interface Eth interfaces (comma-separated, no spaces)\n"
741 "\n"
742 "Optional OPTIONS\n"
743 " -c, --count <number> CPU count, 0=all available, default=1\n"
744 " -t, --time <seconds> Number of seconds to run (e.g. 0.1).\n"
745 " -m, --mode 0: Receive and send directly (no queues)\n"
746 " 1: Receive and send via queues.\n"
747 " 2: Receive via scheduler, send via queues.\n"
748 " -h, --help Display help and exit.\n"
749 "\n", NO_PATH(progname), NO_PATH(progname)
750 );
751}
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.
#define odp_unlikely(x)
Branch unlikely taken.
Definition spec/hints.h:64
uint32_t odp_u32be_t
unsigned 32bit big endian
int odp_cpumask_default_worker(odp_cpumask_t *mask, int num)
Default CPU mask for worker threads.
int odp_cpumask_first(const odp_cpumask_t *mask)
Find first set CPU in mask.
int32_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int32_t size)
Format a string from CPU mask.
#define ODP_CPUMASK_STR_SIZE
The maximum number of characters needed to record any CPU mask as a string (output of odp_cpumask_to_...
#define ODP_EVENT_INVALID
Invalid event.
void odp_init_param_init(odp_init_t *param)
Initialize the odp_init_t to default values for all fields.
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.
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_close(odp_pktio_t pktio)
Close a packet IO interface.
odp_pktio_t odp_pktio_lookup(const char *name)
Return a packet IO handle for an already open device.
int odp_pktout_queue(odp_pktio_t pktio, odp_pktout_queue_t queues[], int num)
Direct packet output queues.
int odp_pktin_event_queue(odp_pktio_t pktio, odp_queue_t queues[], int num)
Event queues for packet input.
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_start(odp_pktio_t pktio)
Start packet receive and transmit.
#define ODP_PKTIO_INVALID
Invalid packet IO handle.
int odp_pktin_queue(odp_pktio_t pktio, odp_pktin_queue_t queues[], int num)
Direct packet input queues.
int odp_pktio_stop(odp_pktio_t pktio)
Stop packet receive and transmit.
int odp_pktin_recv(odp_pktin_queue_t queue, odp_packet_t packets[], int num)
Receive packets directly from an interface input queue.
int odp_pktout_send(odp_pktout_queue_t queue, const odp_packet_t packets[], int num)
Send packets directly to an interface output queue.
uint64_t odp_pktio_to_u64(odp_pktio_t pktio)
Get printable value for an odp_pktio_t.
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_PKTIN_MODE_DIRECT
Direct packet input from the interface.
@ ODP_PKTIN_MODE_QUEUE
Packet input through plain event queues.
@ ODP_PKTIN_MODE_SCHED
Packet input through scheduler and scheduled event queues.
int odp_packet_has_ipv4(odp_packet_t pkt)
Check for IPv4.
int odp_packet_has_eth(odp_packet_t pkt)
Check for Ethernet header.
int odp_packet_has_error(odp_packet_t pkt)
Check for all parse errors in packet.
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.
void * odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
Layer 2 start pointer.
int odp_packet_is_valid(odp_packet_t pkt)
Check that packet is valid.
odp_pktio_t odp_packet_input(odp_packet_t pkt)
Packet input interface.
odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *param)
Create a pool.
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()
void odp_pool_print(odp_pool_t pool)
Print pool info.
#define ODP_POOL_INVALID
Invalid pool.
@ ODP_POOL_PACKET
Packet pool.
#define ODP_QUEUE_INVALID
Invalid queue.
odp_event_t odp_queue_deq(odp_queue_t queue)
Dequeue an event from a queue.
#define ODP_SCHED_SYNC_ATOMIC
Atomic queue synchronization.
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.
int odp_shm_free(odp_shm_t shm)
Free a contiguous block of shared memory.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
#define ODP_SHM_INVALID
Invalid shared memory block.
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags)
Reserve a contiguous block of shared memory.
void odp_sys_info_print(void)
Print system info.
int odp_thread_id(void)
Get thread identifier.
@ ODP_THREAD_WORKER
Worker thread.
@ ODP_THREAD_CONTROL
Control thread.
#define ODP_TIME_SEC_IN_NS
A second in nanoseconds.
void odp_time_wait_ns(uint64_t ns)
Wait the specified number of nanoseconds.
#define ODP_TIME_MSEC_IN_NS
A millisecond in nanoseconds.
The OpenDataPlane API.
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
Packet input queue parameters.
odp_queue_param_t queue_param
Queue parameters.
Packet IO parameters.
odp_pktin_mode_t in_mode
Packet input mode.
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.
uint32_t len
Minimum length of 'num' packets.
uint32_t seg_len
Minimum number of packet data bytes that can be stored in the first segment of a newly allocated pack...
odp_schedule_param_t sched
Scheduler parameters.
odp_schedule_sync_t sync
Synchronization method.