API Reference Manual  1.46.0
odp_packet_dump.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2018 Linaro Limited
3  * Copyright (c) 2024 Nokia
4  */
5 
14 #include <stdio.h>
15 #include <string.h>
16 #include <signal.h>
17 #include <stdlib.h>
18 #include <stdint.h>
19 #include <inttypes.h>
20 #include <getopt.h>
21 
22 #include <odp_api.h>
23 #include <odp/helper/odph_api.h>
24 
25 #define MAX_PKTIOS 32
26 #define MAX_PKTIO_NAME 255
27 #define MAX_PKT_NUM 1024
28 #define MAX_FILTERS 32
29 
30 typedef struct test_options_t {
31  uint64_t num_packet;
32  uint32_t data_offset;
33  uint32_t data_len;
34  int verbose;
35  int num_pktio;
36  char pktio_name[MAX_PKTIOS][MAX_PKTIO_NAME + 1];
37  int num_filter_l3;
38  int filter_l3[MAX_FILTERS];
39  int num_filter_l4;
40  int filter_l4[MAX_FILTERS];
41 
42 } test_options_t;
43 
44 typedef struct test_global_t {
45  test_options_t opt;
46  odp_pool_t pool;
47  odp_atomic_u32_t stop;
48 
49  struct {
50  odp_pktio_t pktio;
51  int started;
52 
53  } pktio[MAX_PKTIOS];
54 
55 } test_global_t;
56 
57 static test_global_t test_global;
58 
59 static void sig_handler(int signo)
60 {
61  (void)signo;
62 
63  odp_atomic_store_u32(&test_global.stop, 1);
64 }
65 
66 static void print_usage(void)
67 {
68  printf("\n"
69  "Print received packets\n"
70  "\n"
71  "OPTIONS:\n"
72  " -i, --interface <name> Packet IO interfaces (comma-separated, no spaces)\n"
73  " -n, --num_packet <number> Exit after this many packets. Use 0 to run infinitely. Default 0.\n"
74  " -o, --data_offset <number> Data print start offset in bytes. Default 0.\n"
75  " -l, --data_length <number> Data print length in bytes. Default 0.\n"
76  " --filter_l3 <type> Print only packets with matching L3 type. Comma-separated\n"
77  " list (no spaces) of ODP L3 type values (e.g. value of ODP_PROTO_L3_TYPE_IPV4).\n"
78  " --filter_l4 <type> Print only packets with matching L4 type. Comma-separated\n"
79  " list (no spaces) of ODP L4 type values (e.g. value of ODP_PROTO_L4_TYPE_TCP).\n"
80  " -v, --verbose Print extra packet information.\n"
81  " -h, --help Display help and exit.\n\n");
82 }
83 
84 static int parse_int_list(char *str, int integer[], int max_num)
85 {
86  int str_len, len;
87  int i = 0;
88 
89  str_len = strlen(str);
90 
91  while (str_len > 0) {
92  len = strcspn(str, ",");
93  str[len] = 0;
94 
95  if (i == max_num) {
96  ODPH_ERR("Maximum number of options is %i\n", max_num);
97  return -1;
98  }
99 
100  integer[i] = atoi(str);
101 
102  str_len -= len + 1;
103  str += len + 1;
104  i++;
105  }
106 
107  return i;
108 }
109 
110 static int parse_options(int argc, char *argv[], test_global_t *global)
111 {
112  int i, opt;
113  char *name, *str;
114  int len, str_len, num;
115 
116  const struct option longopts[] = {
117  {"interface", required_argument, NULL, 'i'},
118  {"num_packet", required_argument, NULL, 'n'},
119  {"data_offset", required_argument, NULL, 'o'},
120  {"data_length", required_argument, NULL, 'l'},
121  {"verbose", no_argument, NULL, 'v'},
122  {"help", no_argument, NULL, 'h'},
123  {"filter_l3", required_argument, NULL, 0 },
124  {"filter_l4", required_argument, NULL, 1 },
125  {NULL, 0, NULL, 0}
126  };
127  const char *shortopts = "+i:n:o:l:vh";
128  int ret = 0;
129 
130  while (1) {
131  opt = getopt_long(argc, argv, shortopts, longopts, NULL);
132 
133  if (opt == -1)
134  break; /* No more options */
135 
136  switch (opt) {
137  case 0:
138  /* --filter_l3 */
139  num = parse_int_list(optarg, global->opt.filter_l3,
140  MAX_FILTERS);
141  global->opt.num_filter_l3 = num;
142 
143  if (num < 0)
144  ret = -1;
145  break;
146  case 1:
147  /* --filter_l4 */
148  num = parse_int_list(optarg, global->opt.filter_l4,
149  MAX_FILTERS);
150  global->opt.num_filter_l4 = num;
151 
152  if (num < 0)
153  ret = -1;
154  break;
155  case 'i':
156  i = 0;
157  str = optarg;
158  str_len = strlen(str);
159 
160  while (str_len > 0) {
161  len = strcspn(str, ",");
162  str_len -= len + 1;
163 
164  if (i == MAX_PKTIOS) {
165  ODPH_ERR("Too many interfaces\n");
166  ret = -1;
167  break;
168  }
169 
170  if (len > MAX_PKTIO_NAME) {
171  ODPH_ERR("Too long interface name %s\n", str);
172  ret = -1;
173  break;
174  }
175 
176  name = global->opt.pktio_name[i];
177  memcpy(name, str, len);
178  str += len + 1;
179  i++;
180  }
181 
182  global->opt.num_pktio = i;
183 
184  break;
185  case 'o':
186  global->opt.data_offset = atoi(optarg);
187  break;
188  case 'l':
189  global->opt.data_len = atoi(optarg);
190  break;
191  case 'n':
192  global->opt.num_packet = atoll(optarg);
193  break;
194  case 'v':
195  global->opt.verbose = 1;
196  break;
197  case 'h':
198  default:
199  print_usage();
200  return -1;
201  }
202  }
203 
204  if (global->opt.num_pktio == 0) {
205  ODPH_ERR("At least one pktio interface needed\n");
206  ret = -1;
207  }
208 
209  return ret;
210 }
211 
212 static int open_pktios(test_global_t *global)
213 {
214  odp_pool_param_t pool_param;
215  odp_pktio_param_t pktio_param;
216  odp_pool_t pool;
217  odp_pktio_capability_t pktio_capa;
218  odp_pool_capability_t pool_capa;
219  odp_pktio_t pktio;
220  odp_pktio_config_t pktio_config;
221  odp_pktin_queue_param_t pktin_param;
222  char *name;
223  int i, num_pktio;
224  uint32_t num_pkt = MAX_PKT_NUM;
225 
226  num_pktio = global->opt.num_pktio;
227 
228  if (odp_pool_capability(&pool_capa)) {
229  ODPH_ERR("Pool capability failed\n");
230  return -1;
231  }
232 
233  if (pool_capa.pkt.max_num < MAX_PKT_NUM)
234  num_pkt = pool_capa.pkt.max_num;
235 
236  odp_pool_param_init(&pool_param);
237  pool_param.pkt.num = num_pkt;
238  pool_param.type = ODP_POOL_PACKET;
239 
240  pool = odp_pool_create("packet pool", &pool_param);
241 
242  global->pool = pool;
243 
244  if (pool == ODP_POOL_INVALID) {
245  ODPH_ERR("Pool create failed\n");
246  return -1;
247  }
248 
249  odp_pktio_param_init(&pktio_param);
250  pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
251  pktio_param.out_mode = ODP_PKTOUT_MODE_DISABLED;
252 
253  for (i = 0; i < num_pktio; i++)
254  global->pktio[i].pktio = ODP_PKTIO_INVALID;
255 
256  /* Open and configure interfaces */
257  for (i = 0; i < num_pktio; i++) {
258  name = global->opt.pktio_name[i];
259  pktio = odp_pktio_open(name, pool, &pktio_param);
260 
261  if (pktio == ODP_PKTIO_INVALID) {
262  ODPH_ERR("Pktio open failed for %s\n", name);
263  return -1;
264  }
265 
266  global->pktio[i].pktio = pktio;
267 
268  if (odp_pktio_capability(pktio, &pktio_capa)) {
269  ODPH_ERR("Pktio capability failed for %s\n", name);
270  return -1;
271  }
272 
273  odp_pktio_print(pktio);
274 
275  odp_pktio_config_init(&pktio_config);
276  pktio_config.pktin.bit.ts_all = pktio_capa.config.pktin.bit.ts_all;
277  pktio_config.parser.layer = ODP_PROTO_LAYER_ALL;
278 
279  odp_pktio_config(pktio, &pktio_config);
280 
281  odp_pktin_queue_param_init(&pktin_param);
282 
286  pktin_param.num_queues = 1;
287 
288  if (odp_pktin_queue_config(pktio, &pktin_param)) {
289  ODPH_ERR("Pktin config failed for %s\n", name);
290  return -1;
291  }
292  }
293 
294  return 0;
295 }
296 
297 static int start_pktios(test_global_t *global)
298 {
299  int i;
300 
301  for (i = 0; i < global->opt.num_pktio; i++) {
302  if (odp_pktio_start(global->pktio[i].pktio)) {
303  ODPH_ERR("Pktio start failed for %s\n", global->opt.pktio_name[i]);
304 
305  return -1;
306  }
307 
308  global->pktio[i].started = 1;
309  }
310 
311  return 0;
312 }
313 
314 static int stop_pktios(test_global_t *global)
315 {
316  odp_pktio_t pktio;
317  int i, ret = 0;
318 
319  for (i = 0; i < global->opt.num_pktio; i++) {
320  pktio = global->pktio[i].pktio;
321 
322  if (pktio == ODP_PKTIO_INVALID || global->pktio[i].started == 0)
323  continue;
324 
325  if (odp_pktio_stop(pktio)) {
326  ODPH_ERR("Pktio stop failed for %s\n", global->opt.pktio_name[i]);
327  ret = -1;
328  }
329  }
330 
331  return ret;
332 }
333 
334 static void empty_queues(void)
335 {
336  odp_event_t ev;
337  uint64_t wait_time = odp_schedule_wait_time(ODP_TIME_SEC_IN_NS / 2);
338 
339  /* Drop all events from all queues */
340  while (1) {
341  ev = odp_schedule(NULL, wait_time);
342 
343  if (ev == ODP_EVENT_INVALID)
344  break;
345 
346  odp_event_free(ev);
347  }
348 }
349 
350 static int close_pktios(test_global_t *global)
351 {
352  odp_pktio_t pktio;
353  odp_pool_t pool;
354  int i, ret = 0;
355 
356  for (i = 0; i < global->opt.num_pktio; i++) {
357  pktio = global->pktio[i].pktio;
358 
359  if (pktio == ODP_PKTIO_INVALID)
360  continue;
361 
362  if (odp_pktio_close(pktio)) {
363  ODPH_ERR("Pktio close failed for %s\n", global->opt.pktio_name[i]);
364  ret = -1;
365  }
366  }
367 
368  pool = global->pool;
369 
370  if (pool == ODP_POOL_INVALID)
371  return ret;
372 
373  if (odp_pool_destroy(pool)) {
374  ODPH_ERR("Pool destroy failed\n");
375  ret = -1;
376  }
377 
378  return ret;
379 }
380 
381 static void print_mac_addr(uint8_t *addr)
382 {
383  printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
384  addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
385 }
386 
387 static void print_ipv4_addr(uint8_t *addr)
388 {
389  printf("%u.%u.%u.%u\n",
390  addr[0], addr[1], addr[2], addr[3]);
391 }
392 
393 static void print_port(uint8_t *ptr)
394 {
395  uint16_t *port = (uint16_t *)(uintptr_t)ptr;
396 
397  printf("%u\n", odp_be_to_cpu_16(*port));
398 }
399 
400 static void print_data(odp_packet_t pkt, uint32_t offset, uint32_t len)
401 {
402  const uint32_t bytes_per_row = 16;
403  const uint32_t num_char = 1 + (bytes_per_row * 3) + 1;
404  uint8_t data[bytes_per_row];
405  char row[num_char];
406  uint32_t copy_len, i, j;
407  uint32_t data_len = odp_packet_len(pkt);
408 
409  if (offset > data_len)
410  return;
411 
412  if (offset + len > data_len)
413  len = data_len - offset;
414 
415  while (len) {
416  i = 0;
417 
418  if (len > bytes_per_row)
419  copy_len = bytes_per_row;
420  else
421  copy_len = len;
422 
423  odp_packet_copy_to_mem(pkt, offset, copy_len, data);
424 
425  i += snprintf(&row[i], num_char - i, " ");
426 
427  for (j = 0; j < copy_len; j++)
428  i += snprintf(&row[i], num_char - i, " %02x", data[j]);
429 
430  row[i] = 0;
431  printf("%s\n", row);
432 
433  len -= copy_len;
434  offset += copy_len;
435  }
436 }
437 
438 static int print_packet(test_global_t *global, odp_packet_t pkt,
439  uint64_t num_packet)
440 {
441  odp_pktio_t pktio = odp_packet_input(pkt);
442  odp_pktio_info_t pktio_info;
443  odp_time_t pktio_time, time;
444  uint64_t sec, nsec;
445  uint32_t offset;
446  int i, type, match;
447  int num_filter_l3 = global->opt.num_filter_l3;
448  int num_filter_l4 = global->opt.num_filter_l4;
449  uint8_t *data = odp_packet_data(pkt);
450  uint32_t seg_len = odp_packet_seg_len(pkt);
451  uint32_t l2_offset = odp_packet_l2_offset(pkt);
452  uint32_t l3_offset = odp_packet_l3_offset(pkt);
453  uint32_t l4_offset = odp_packet_l4_offset(pkt);
454  int tcp = odp_packet_has_tcp(pkt);
455  int udp = odp_packet_has_udp(pkt);
456  int sctp = odp_packet_has_sctp(pkt);
457  int icmp = odp_packet_has_icmp(pkt);
458  int ipv4 = odp_packet_has_ipv4(pkt);
459 
460  if (odp_packet_has_ts(pkt)) {
461  pktio_time = odp_pktio_time(pktio, NULL);
462  time = odp_packet_ts(pkt);
463  } else {
464  time = odp_time_local();
465  pktio_time = ODP_TIME_NULL;
466  }
467 
468  /* Filter based on L3 type */
469  if (num_filter_l3) {
470  match = 0;
471 
472  for (i = 0; i < num_filter_l3; i++) {
473  type = global->opt.filter_l3[i];
474 
475  if (type == odp_packet_l3_type(pkt)) {
476  match = 1;
477  break;
478  }
479  }
480 
481  if (!match)
482  return 0;
483  }
484 
485  /* Filter based on L4 type */
486  if (num_filter_l4) {
487  match = 0;
488 
489  for (i = 0; i < num_filter_l4; i++) {
490  type = global->opt.filter_l4[i];
491 
492  if (type == odp_packet_l4_type(pkt)) {
493  match = 1;
494  break;
495  }
496  }
497 
498  if (!match)
499  return 0;
500  }
501 
502  nsec = odp_time_to_ns(time);
503  sec = nsec / ODP_TIME_SEC_IN_NS;
504  nsec = nsec - (sec * ODP_TIME_SEC_IN_NS);
505 
506  if (odp_pktio_info(pktio, &pktio_info)) {
507  ODPH_ERR("Pktio info failed\n");
508  return -1;
509  }
510 
511  printf("PACKET [%" PRIu64 "]\n", num_packet);
512  printf(" time: %" PRIu64 ".%09" PRIu64 " sec\n", sec, nsec);
513 
514  if (odp_time_cmp(pktio_time, ODP_TIME_NULL)) {
515  nsec = odp_time_to_ns(pktio_time);
516  sec = nsec / ODP_TIME_SEC_IN_NS;
517  nsec = nsec - (sec * ODP_TIME_SEC_IN_NS);
518  printf(" pktio time: %" PRIu64 ".%09" PRIu64 " sec\n", sec, nsec);
519  printf(" input delay: %" PRIu64 " nsec\n", odp_time_diff_ns(pktio_time, time));
520  }
521 
522  printf(" interface name: %s\n", pktio_info.name);
523  printf(" packet length: %u bytes\n", odp_packet_len(pkt));
524 
525  /* L2 */
526  if (odp_packet_has_eth(pkt)) {
527  uint8_t *eth = data + l2_offset;
528 
529  printf(" Ethernet offset: %u bytes\n", l2_offset);
530  if (l2_offset + 6 <= seg_len) {
531  printf(" dst address: ");
532  print_mac_addr(eth);
533  }
534 
535  if (l2_offset + 12 <= seg_len) {
536  printf(" src address: ");
537  print_mac_addr(eth + 6);
538  }
539 
540  /* VLAN */
541  if (odp_packet_has_vlan(pkt)) {
542  int qinq = odp_packet_has_vlan_qinq(pkt);
543  uint16_t *tpid = (uint16_t *)(uintptr_t)(eth + 12);
544  uint16_t *tci = tpid + 1;
545 
546  if (qinq)
547  printf(" VLAN (outer):\n");
548  else
549  printf(" VLAN:\n");
550 
551  if (l2_offset + 14 <= seg_len) {
552  printf(" TPID: 0x%04x\n",
553  odp_be_to_cpu_16(*tpid));
554  }
555 
556  if (l2_offset + 16 <= seg_len) {
557  printf(" TCI: 0x%04x (VID: %u)\n",
558  odp_be_to_cpu_16(*tci),
559  odp_be_to_cpu_16(*tci) & 0x0fff);
560  }
561 
562  if (qinq) {
563  printf(" VLAN (inner):\n");
564  tpid += 2;
565  tci += 2;
566 
567  if (l2_offset + 18 <= seg_len) {
568  printf(" TPID: 0x%04x\n",
569  odp_be_to_cpu_16(*tpid));
570  }
571 
572  if (l2_offset + 20 <= seg_len) {
573  printf(" TCI: 0x%04x (VID: %u)\n",
574  odp_be_to_cpu_16(*tci),
575  odp_be_to_cpu_16(*tci) & 0x0fff);
576  }
577  }
578  }
579 
580  } else if (odp_packet_has_l2(pkt)) {
581  printf(" L2 (%i) offset: %u bytes\n",
582  odp_packet_l2_type(pkt), l2_offset);
583  }
584 
585  /* L3 */
586  if (ipv4) {
587  printf(" IPv4 offset: %u bytes\n", l3_offset);
588  offset = l3_offset + 12;
589  if (offset + 4 <= seg_len) {
590  printf(" src address: ");
591  print_ipv4_addr(data + offset);
592  }
593 
594  offset = l3_offset + 16;
595  if (offset + 4 <= seg_len) {
596  printf(" dst address: ");
597  print_ipv4_addr(data + offset);
598  }
599  } else if (odp_packet_has_ipv6(pkt)) {
600  printf(" IPv6 offset: %u bytes\n", l3_offset);
601  } else if (odp_packet_has_l3(pkt)) {
602  printf(" L3 (%i) offset: %u bytes\n",
603  odp_packet_l3_type(pkt), l3_offset);
604  }
605 
606  /* L4 */
607  if (tcp || udp || sctp) {
608  if (tcp)
609  printf(" TCP offset: %u bytes\n", l4_offset);
610  else if (udp)
611  printf(" UDP offset: %u bytes\n", l4_offset);
612  else
613  printf(" SCTP offset: %u bytes\n", l4_offset);
614 
615  offset = l4_offset;
616  if (offset + 2 <= seg_len) {
617  printf(" src port: ");
618  print_port(data + offset);
619  }
620 
621  offset = l4_offset + 2;
622  if (offset + 2 <= seg_len) {
623  printf(" dst port: ");
624  print_port(data + offset);
625  }
626  } else if (icmp) {
627  printf(" ICMP offset: %u bytes\n", l4_offset);
628  if (ipv4) {
629  uint32_t len;
630  uint8_t *u8 = odp_packet_l4_ptr(pkt, &len);
631 
632  if (u8 && len >= 2) {
633  printf(" type: %u\n", u8[0]);
634  printf(" code: %u\n", u8[1]);
635  }
636  }
637  } else if (odp_packet_has_l4(pkt)) {
638  printf(" L4 (%i) offset: %u bytes\n",
639  odp_packet_l4_type(pkt), l4_offset);
640  }
641 
642  /* User defined data range */
643  if (global->opt.data_len)
644  print_data(pkt, global->opt.data_offset, global->opt.data_len);
645 
646  if (global->opt.verbose)
647  odp_packet_print(pkt);
648 
649  printf("\n");
650 
651  return 1;
652 }
653 
654 static int receive_packets(test_global_t *global)
655 {
656  odp_event_t ev;
657  odp_packet_t pkt;
658  int printed;
659  uint64_t num_packet = 0;
660 
661  while (!odp_atomic_load_u32(&global->stop)) {
662  ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
663 
664  if (ev == ODP_EVENT_INVALID)
665  continue;
666 
667  if (odp_event_type(ev) != ODP_EVENT_PACKET) {
668  ODPH_ERR("Bad event type: %i\n", odp_event_type(ev));
669  odp_event_free(ev);
670  continue;
671  }
672 
673  pkt = odp_packet_from_event(ev);
674 
675  printed = print_packet(global, pkt, num_packet);
676 
677  odp_packet_free(pkt);
678 
679  if (odp_unlikely(printed < 0))
680  return -1;
681 
682  if (!printed)
683  continue;
684 
685  num_packet++;
686  if (global->opt.num_packet &&
687  num_packet >= global->opt.num_packet)
688  break;
689  }
690 
691  return 0;
692 }
693 
694 int main(int argc, char *argv[])
695 {
696  odp_instance_t instance;
697  test_global_t *global;
698  int ret = 0;
699 
700  global = &test_global;
701  memset(global, 0, sizeof(test_global_t));
702  odp_atomic_init_u32(&global->stop, 0);
703 
704  signal(SIGINT, sig_handler);
705 
706  if (parse_options(argc, argv, global))
707  return -1;
708 
709  /* Init ODP before calling anything else */
710  if (odp_init_global(&instance, NULL, NULL)) {
711  ODPH_ERR("Global init failed\n");
712  return -1;
713  }
714 
715  /* Init this thread */
716  if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
717  ODPH_ERR("Local init failed\n");
718  return -1;
719  }
720 
721  global->pool = ODP_POOL_INVALID;
722 
723  odp_schedule_config(NULL);
724 
726 
727  if (open_pktios(global)) {
728  ODPH_ERR("Pktio open failed\n");
729  return -1;
730  }
731 
732  if (start_pktios(global)) {
733  ODPH_ERR("Pktio start failed\n");
734  return -1;
735  }
736 
737  if (receive_packets(global)) {
738  ODPH_ERR("Packet receive failed\n");
739  return -1;
740  }
741 
742  if (stop_pktios(global)) {
743  ODPH_ERR("Pktio stop failed\n");
744  return -1;
745  }
746 
747  empty_queues();
748 
749  if (close_pktios(global)) {
750  ODPH_ERR("Pktio close failed\n");
751  return -1;
752  }
753 
754  if (odp_term_local()) {
755  ODPH_ERR("Term local failed\n");
756  return -1;
757  }
758 
759  if (odp_term_global(instance)) {
760  ODPH_ERR("Term global failed\n");
761  return -1;
762  }
763 
764  return ret;
765 }
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
uint16_t odp_be_to_cpu_16(odp_u16be_t be16)
Convert 16bit big endian to cpu native uint16_t.
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.
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.
int odp_pktio_info(odp_pktio_t pktio, odp_pktio_info_t *info)
Retrieve information about a pktio.
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.
odp_time_t odp_pktio_time(odp_pktio_t pktio, odp_time_t *ts_global)
Current packet IO time and global time.
int odp_pktio_stop(odp_pktio_t pktio)
Stop packet receive and transmit.
int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa)
Query packet IO interface capabilities.
int odp_pktin_queue_config(odp_pktio_t pktio, const odp_pktin_queue_param_t *param)
Configure packet input queues.
@ ODP_PKTOUT_MODE_DISABLED
Application will never send to this 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.
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.
int odp_packet_has_vlan_qinq(odp_packet_t pkt)
Check for VLAN QinQ (stacked VLAN)
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_ipv6(odp_packet_t pkt)
Check for IPv6.
int odp_packet_has_l2(odp_packet_t pkt)
Check for layer 2 protocols.
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.
int odp_packet_has_vlan(odp_packet_t pkt)
Check for VLAN.
uint32_t odp_packet_l3_offset(odp_packet_t pkt)
Layer 3 start offset.
void * odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len)
Layer 4 start pointer.
int odp_packet_has_sctp(odp_packet_t pkt)
Check for SCTP.
odp_proto_l3_type_t odp_packet_l3_type(odp_packet_t pkt)
Layer 3 protocol type.
int odp_packet_has_tcp(odp_packet_t pkt)
Check for TCP.
void odp_packet_print(odp_packet_t pkt)
Print packet debug information.
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.
int odp_packet_has_udp(odp_packet_t pkt)
Check for UDP.
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.
#define ODP_SCHED_NO_WAIT
Do not wait.
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_NULL
Zero time stamp.
int odp_time_cmp(odp_time_t t2, odp_time_t t1)
Compare two times.
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_config_t config
Supported pktio configuration options.
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.
struct odp_pool_capability_t::@122 pkt
Packet pool capabilities
uint32_t max_num
Maximum number of buffers of any size.
Pool parameters.
uint32_t num
Number of buffers in the pool.
odp_pool_type_t type
Pool type.
struct odp_pool_param_t::@126 pkt
Parameters for packet pools.
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::@100 bit
Option flags.