API Reference Manual  1.46.0
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))
69 typedef 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 
81 typedef struct {
82  char *pktio_dev;
83  int mode;
84 } thread_args_t;
85 
89 typedef 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 
101 static args_t *args;
102 
103 /* helper funcs */
104 static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len);
105 static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len);
106 static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
107 static void print_info(char *progname, appl_args_t *appl_args);
108 static void usage(char *progname);
109 
120 static 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 
177 static 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 
268 static 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 
348 int 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 */
438  odp_schedule_config(NULL);
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 
502  odp_term_local();
503  return odp_term_global(instance);
504 }
505 
517 static 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 
547 static 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 
585 static 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 
698 static 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 
731 static 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.
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.
void * odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
Layer 3 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.
#define ODP_SHM_INVALID
Invalid shared memory block.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
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.
Pool parameters.
uint32_t num
Number of buffers in the pool.
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...
struct odp_pool_param_t::@126 pkt
Parameters for packet pools.
odp_schedule_param_t sched
Scheduler parameters.
odp_schedule_sync_t sync
Synchronization method.