API Reference Manual  1.46.0
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 
30 ODP_STATIC_ASSERT(MAX_PKTIOS < UINT8_MAX, "MAX_PKTIOS too large for index lookup");
31 
32 typedef 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 
42 typedef struct test_global_t {
43  test_options_t opt;
44  uint64_t rx_packets;
45  uint64_t tx_replies;
46  odp_pool_t pool;
47  odp_atomic_u32_t stop;
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 
62 static test_global_t test_global;
63 
64 static void sig_handler(int signo)
65 {
66  (void)signo;
67 
68  odp_atomic_store_u32(&test_global.stop, 1);
69 }
70 
71 static 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 
85 static 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 
167 static 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 
288 static 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 
304 static 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 
320 static 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 
340 static 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 
356 static 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 
387 static 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 
393 static 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 
399 static 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 
437 static 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 */
534 static 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 
546 static 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 
603 error:
604  odp_packet_free(pkt);
605 }
606 
607 static 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 
620 static 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 
691 int 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 
720  odp_schedule_config(NULL);
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.
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.
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.
odp_proto_l3_type_t odp_packet_l3_type(odp_packet_t pkt)
Layer 3 protocol type.
void * odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
Layer 3 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.
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.
struct odp_pktio_set_op_t::@104 op
Operation flags.
uint32_t promisc_mode
Promiscuous mode.