22 #include <odp/helper/odph_api.h>
25 #define MAX_WORKERS (ODP_THREAD_COUNT_MAX - 1)
28 #define SHM_PKT_POOL_SIZE 8192
31 #define SHM_PKT_POOL_BUF_SIZE 1856
34 #define MAX_PKT_BURST 32
43 #define MAC_TBL_SIZE UINT16_MAX
49 #define NO_PATH(file_name) (strrchr((file_name), '/') ? \
50 strrchr((file_name), '/') + 1 : (file_name))
67 unsigned int cpu_count;
68 unsigned int if_count;
76 typedef enum frame_type_t {
97 uint8_t padding[ODP_CACHE_LINE_SIZE];
103 typedef struct pkt_buf_t {
111 typedef struct thread_args_t {
118 } rx_pktio[MAX_PKTIOS];
123 } tx_pktio[MAX_PKTIOS];
125 stats_t *stats[MAX_PKTIOS];
133 stats_t stats[MAX_WORKERS][MAX_PKTIOS];
135 thread_args_t thread[MAX_WORKERS];
151 } pktios[MAX_PKTIOS];
157 static args_t *gbl_args;
161 if (gbl_args == NULL)
173 static inline uint16_t calc_mac_tbl_idx(odph_ethaddr_t *mac)
179 return (uint16_t)(hash & 0xFFFF);
185 static inline uint8_t diff_ticks(uint8_t t2, uint8_t t1)
190 return UINT8_MAX + t2 - t1;
204 static inline int mac_table_get(odph_ethaddr_t *mac, uint8_t *port,
207 mac_tbl_entry_t entry;
210 idx = calc_mac_tbl_idx(mac);
214 if (memcmp(mac->addr, entry.s.mac.addr, ODPH_ETHADDR_LEN))
217 if (
odp_unlikely(diff_ticks(cur_tick, entry.s.tick) > AGING_TIME))
220 *port = entry.s.port;
231 static inline void mac_table_update(odph_ethaddr_t *mac, uint8_t port,
234 mac_tbl_entry_t entry;
237 idx = calc_mac_tbl_idx(mac);
240 if (memcmp(entry.s.mac.addr, mac->addr, ODPH_ETHADDR_LEN) ||
241 entry.s.port != port || entry.s.tick != cur_tick) {
244 entry.s.tick = cur_tick;
261 static int create_pktio(
const char *dev,
int idx,
int num_rx,
int num_tx,
277 printf(
"Error: failed to open %s\n", dev);
285 printf(
"Error: capability query failed %s\n", dev);
300 printf(
"Sharing %i input queues between %i workers\n",
307 printf(
"Sharing %i output queues between %i workers\n",
319 pktout_param.
op_mode = mode_tx;
323 printf(
"Error: input queue config failed %s\n", dev);
327 printf(
"Error: output queue config failed %s\n", dev);
332 printf(
"Error: pktin queue query failed %s\n", dev);
337 printf(
"Error: pktout queue query failed %s\n", dev);
341 printf(
"created %i input and %i output queues on (%s)\n", num_rx,
344 gbl_args->pktios[idx].num_rx_queue = num_rx;
345 gbl_args->pktios[idx].num_tx_queue = num_tx;
346 gbl_args->pktios[idx].pktio = pktio;
362 static int print_speed_stats(
int num_workers, stats_t (*thr_stats)[MAX_PKTIOS],
363 int duration,
int timeout)
365 uint64_t rx_pkts_prev[MAX_PKTIOS] = {0};
366 uint64_t tx_pkts_prev[MAX_PKTIOS] = {0};
367 uint64_t rx_pkts_tot;
368 uint64_t tx_pkts_tot;
369 uint64_t rx_drops_tot;
370 uint64_t tx_drops_tot;
375 int stats_enabled = 1;
376 int loop_forever = (duration == 0);
377 int num_ifaces = gbl_args->appl.if_count;
387 uint64_t rx_pkts[MAX_PKTIOS] = {0};
388 uint64_t tx_pkts[MAX_PKTIOS] = {0};
389 uint64_t rx_drops[MAX_PKTIOS] = {0};
390 uint64_t tx_drops[MAX_PKTIOS] = {0};
400 for (i = 0; i < num_workers; i++) {
401 for (j = 0; j < num_ifaces; j++) {
402 rx_pkts[j] += thr_stats[i][j].s.rx_packets;
403 tx_pkts[j] += thr_stats[i][j].s.tx_packets;
404 rx_drops[j] += thr_stats[i][j].s.rx_drops;
405 tx_drops[j] += thr_stats[i][j].s.tx_drops;
412 for (j = 0; j < num_ifaces; j++) {
413 rx_pps = (rx_pkts[j] - rx_pkts_prev[j]) / timeout;
414 tx_pps = (tx_pkts[j] - tx_pkts_prev[j]) / timeout;
415 printf(
" Port %d: %" PRIu64
" rx pps, %" PRIu64
416 " tx pps, %" PRIu64
" rx pkts, %" PRIu64
417 " tx pkts, %" PRIu64
" rx drops, %" PRIu64
418 " tx drops\n", j, rx_pps, tx_pps, rx_pkts[j],
419 tx_pkts[j], rx_drops[j], tx_drops[j]);
421 rx_pkts_prev[j] = rx_pkts[j];
422 tx_pkts_prev[j] = tx_pkts[j];
423 rx_pkts_tot += rx_pkts[j];
424 tx_pkts_tot += tx_pkts[j];
425 rx_drops_tot += rx_drops[j];
426 tx_drops_tot += tx_drops[j];
429 printf(
"Total: %" PRIu64
" rx pkts, %" PRIu64
" tx pkts, %"
430 PRIu64
" rx drops, %" PRIu64
" tx drops\n", rx_pkts_tot,
431 tx_pkts_tot, rx_drops_tot, tx_drops_tot);
434 (loop_forever || (elapsed < duration)));
436 return rx_pkts_tot >= 100 ? 0 : -1;
442 static void print_port_mapping(
void)
444 int if_count, num_workers;
447 if_count = gbl_args->appl.if_count;
448 num_workers = gbl_args->appl.num_workers;
450 printf(
"\nWorker mapping table (port[queue])\n--------------------\n");
452 for (thr = 0; thr < num_workers; thr++) {
455 thread_args_t *thr_args = &gbl_args->thread[thr];
456 int num = thr_args->num_rx_pktio;
458 printf(
"Worker %i\n", thr);
460 for (pktio = 0; pktio < num; pktio++) {
461 port_idx = thr_args->rx_pktio[pktio].port_idx;
462 queue_idx = thr_args->rx_pktio[pktio].queue_idx;
463 printf(
" %i[%i]\n", port_idx, queue_idx);
467 printf(
"\nPort config\n--------------------\n");
469 for (pktio = 0; pktio < if_count; pktio++) {
470 const char *dev = gbl_args->appl.if_names[pktio];
472 printf(
"Port %i (%s)\n", pktio, dev);
473 printf(
" rx workers %i\n",
474 gbl_args->pktios[pktio].num_rx_thr);
475 printf(
" rx queues %i\n",
476 gbl_args->pktios[pktio].num_rx_queue);
477 printf(
" tx queues %i\n",
478 gbl_args->pktios[pktio].num_tx_queue);
491 static inline void broadcast_packet(
odp_packet_t pkt, thread_args_t *thr_arg,
496 unsigned int buf_len;
498 for (port_out = 0; port_out < gbl_args->appl.if_count; port_out++) {
499 if (port_out == port_in)
502 buf_len = thr_arg->tx_pktio[port_out].buf.len;
505 thr_arg->tx_pktio[port_out].buf.pkt[buf_len] = pkt;
512 printf(
"Error: packet copy failed\n");
515 thr_arg->tx_pktio[port_out].buf.pkt[buf_len] = pkt_cp;
517 thr_arg->tx_pktio[port_out].buf.len++;
528 static frame_type_t check_frame(odph_ethhdr_t *eth)
530 static uint8_t broadcast_addr[ODPH_ETHADDR_LEN] = {0xff, 0xff, 0xff,
532 static uint8_t null_addr[ODPH_ETHADDR_LEN] = {0, 0, 0, 0, 0, 0};
537 !memcmp(eth->dst.addr, null_addr,
539 !memcmp(eth->src.addr, null_addr,
540 ODPH_ETHADDR_LEN))) {
541 return FRAME_INVALID;
543 if (!memcmp(eth->dst.addr, broadcast_addr, ODPH_ETHADDR_LEN))
544 return FRAME_BROADCAST;
546 return FRAME_UNICAST;
563 static inline void forward_packets(
odp_packet_t pkt_tbl[],
unsigned int num,
564 thread_args_t *thr_arg, uint8_t port_in,
571 uint8_t port_out = 0;
574 for (i = 0; i < num; i++) {
578 thr_arg->stats[port_in]->s.rx_drops++;
586 frame_type = check_frame(eth);
588 thr_arg->stats[port_in]->s.rx_drops++;
594 mac_table_update(ð->src, port_in, cur_tick);
597 if (frame_type == FRAME_BROADCAST ||
598 !mac_table_get(ð->dst, &port_out, cur_tick)) {
599 broadcast_packet(pkt, thr_arg, port_in);
602 buf_id = thr_arg->tx_pktio[port_out].buf.len;
604 thr_arg->tx_pktio[port_out].buf.pkt[buf_id] = pkt;
605 thr_arg->tx_pktio[port_out].buf.len++;
623 static void bind_workers(
void)
625 int if_count, num_workers;
626 int rx_idx, thr, pktio;
627 thread_args_t *thr_args;
629 if_count = gbl_args->appl.if_count;
630 num_workers = gbl_args->appl.num_workers;
632 if (if_count > num_workers) {
635 for (rx_idx = 0; rx_idx < if_count; rx_idx++) {
636 thr_args = &gbl_args->thread[thr];
637 pktio = thr_args->num_rx_pktio;
638 thr_args->rx_pktio[pktio].port_idx = rx_idx;
639 thr_args->num_rx_pktio++;
641 gbl_args->pktios[rx_idx].num_rx_thr++;
644 if (thr >= num_workers)
650 for (thr = 0; thr < num_workers; thr++) {
651 thr_args = &gbl_args->thread[thr];
652 pktio = thr_args->num_rx_pktio;
653 thr_args->rx_pktio[pktio].port_idx = rx_idx;
654 thr_args->num_rx_pktio++;
656 gbl_args->pktios[rx_idx].num_rx_thr++;
659 if (rx_idx >= if_count)
670 static int run_worker(
void *arg)
672 thread_args_t *thr_args = arg;
679 unsigned int num_pktio;
680 unsigned int pktio = 0;
685 num_pktio = thr_args->num_rx_pktio;
686 pktin = thr_args->rx_pktio[pktio].pktin;
687 port_in = thr_args->rx_pktio[pktio].port_idx;
702 pktin = thr_args->rx_pktio[pktio].pktin;
703 port_in = thr_args->rx_pktio[pktio].port_idx;
705 if (pktio == num_pktio)
720 time_prev = time_cur;
723 thr_args->stats[port_in]->s.rx_packets += pkts;
726 forward_packets(pkt_tbl, pkts, thr_args, port_in, cur_tick);
729 for (port_out = 0; port_out < gbl_args->appl.if_count;
731 unsigned int tx_pkts;
734 if (port_out == port_in ||
735 thr_args->tx_pktio[port_out].buf.len == 0)
738 tx_pkts = thr_args->tx_pktio[port_out].buf.len;
739 thr_args->tx_pktio[port_out].buf.len = 0;
741 tx_pkt_tbl = thr_args->tx_pktio[port_out].buf.pkt;
743 pktout = thr_args->tx_pktio[port_out].pktout;
748 thr_args->stats[port_out]->s.tx_packets += sent;
750 drops = tx_pkts - sent;
755 thr_args->stats[port_out]->s.tx_drops += drops;
758 for (i = sent; i < tx_pkts; i++)
773 static void bind_queues(
void)
778 num_workers = gbl_args->appl.num_workers;
780 for (thr = 0; thr < num_workers; thr++) {
782 thread_args_t *thr_args = &gbl_args->thread[thr];
783 int num = thr_args->num_rx_pktio;
786 for (pktio = 0; pktio < num; pktio++) {
789 rx_idx = thr_args->rx_pktio[pktio].port_idx;
790 rx_queue = gbl_args->pktios[rx_idx].next_rx_queue;
792 thr_args->rx_pktio[pktio].pktin =
793 gbl_args->pktios[rx_idx].pktin[rx_queue];
794 thr_args->rx_pktio[pktio].queue_idx = rx_queue;
797 if (rx_queue >= gbl_args->pktios[rx_idx].num_rx_queue)
799 gbl_args->pktios[rx_idx].next_rx_queue = rx_queue;
802 for (pktio = 0; pktio < (int)gbl_args->appl.if_count; pktio++) {
805 tx_queue = gbl_args->pktios[pktio].next_tx_queue;
807 thr_args->tx_pktio[pktio].pktout =
808 gbl_args->pktios[pktio].pktout[tx_queue];
809 thr_args->tx_pktio[pktio].queue_idx = tx_queue;
812 if (tx_queue >= gbl_args->pktios[pktio].num_tx_queue)
814 gbl_args->pktios[pktio].next_tx_queue = tx_queue;
822 static void usage(
char *progname)
825 "OpenDataPlane learning switch example.\n"
827 "Usage: %s OPTIONS\n"
828 " E.g. %s -i eth0,eth1,eth2,eth3\n"
830 "Mandatory OPTIONS:\n"
831 " -i, --interface Eth interfaces (comma-separated, no spaces)\n"
832 " Interface count min 2, max %i\n"
834 "Optional OPTIONS:\n"
835 " -c, --count <number> CPU count, 0=all available, default=1\n"
836 " -t, --time <number> Time in seconds to run.\n"
837 " -a, --accuracy <number> Statistics print interval in seconds\n"
838 " (default is 10 second).\n"
839 " -h, --help Display help and exit.\n\n"
840 "\n", NO_PATH(progname), NO_PATH(progname), MAX_PKTIOS
851 static void parse_args(
int argc,
char *argv[], appl_args_t *appl_args)
857 static const struct option longopts[] = {
858 {
"count", required_argument, NULL,
'c'},
859 {
"time", required_argument, NULL,
't'},
860 {
"accuracy", required_argument, NULL,
'a'},
861 {
"interface", required_argument, NULL,
'i'},
862 {
"help", no_argument, NULL,
'h'},
866 static const char *shortopts =
"+c:t:a:i:h";
868 appl_args->cpu_count = 1;
870 appl_args->accuracy = 10;
873 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
880 appl_args->cpu_count = atoi(optarg);
883 appl_args->time = atoi(optarg);
886 appl_args->accuracy = atoi(optarg);
889 len = strlen(optarg);
896 appl_args->if_str = malloc(len);
897 if (appl_args->if_str == NULL) {
903 strcpy(appl_args->if_str, optarg);
904 for (token = strtok(appl_args->if_str,
","), i = 0;
906 token = strtok(NULL,
","), i++)
909 appl_args->if_count = i;
911 if (appl_args->if_count < 2 ||
912 appl_args->if_count > MAX_PKTIOS) {
918 appl_args->if_names =
919 calloc(appl_args->if_count,
sizeof(
char *));
922 strcpy(appl_args->if_str, optarg);
923 for (token = strtok(appl_args->if_str,
","), i = 0;
924 token != NULL; token = strtok(NULL,
","), i++) {
925 appl_args->if_names[i] = token;
937 if (appl_args->if_count == 0) {
948 static void print_info(
char *progname, appl_args_t *appl_args)
954 printf(
"Running ODP appl: \"%s\"\n"
955 "-----------------\n"
958 progname, appl_args->if_count);
959 for (i = 0; i < appl_args->if_count; ++i)
960 printf(
" %s", appl_args->if_names[i]);
965 static void gbl_args_init(args_t *args)
969 memset(args, 0,
sizeof(args_t));
972 for (pktio = 0; pktio < MAX_PKTIOS; pktio++)
976 int main(
int argc,
char **argv)
978 odph_helper_options_t helper_options;
979 odph_thread_t thread_tbl[MAX_WORKERS];
980 odph_thread_common_param_t thr_common;
981 odph_thread_param_t thr_param[MAX_WORKERS];
989 stats_t (*stats)[MAX_PKTIOS];
994 signal(SIGINT, sig_handler);
997 argc = odph_parse_options(argc, argv);
998 if (odph_options(&helper_options)) {
999 printf(
"Error: reading ODP helper options failed.\n");
1004 init_param.
mem_model = helper_options.mem_model;
1008 printf(
"Error: ODP global init failed.\n");
1014 printf(
"Error: ODP local init failed.\n");
1020 ODP_CACHE_LINE_SIZE, 0);
1023 printf(
"Error: shared mem reserve failed.\n");
1029 if (gbl_args == NULL) {
1030 printf(
"Error: shared mem alloc failed.\n");
1033 gbl_args_init(gbl_args);
1035 for (i = 0; (
unsigned int)i < MAC_TBL_SIZE; i++)
1039 parse_args(argc, argv, &gbl_args->appl);
1042 print_info(NO_PATH(argv[0]), &gbl_args->appl);
1044 num_workers = MAX_WORKERS;
1045 if (gbl_args->appl.cpu_count && gbl_args->appl.cpu_count < MAX_WORKERS)
1046 num_workers = gbl_args->appl.cpu_count;
1052 gbl_args->appl.num_workers = num_workers;
1054 if_count = gbl_args->appl.if_count;
1056 printf(
"num worker threads: %i\n", num_workers);
1058 printf(
"cpu mask: %s\n", cpumaskstr);
1063 params.
pkt.
len = SHM_PKT_POOL_BUF_SIZE;
1064 params.
pkt.
num = SHM_PKT_POOL_SIZE;
1069 printf(
"Error: packet pool create failed.\n");
1076 for (i = 0; i < if_count; ++i) {
1077 const char *dev = gbl_args->appl.if_names[i];
1082 num_rx = gbl_args->pktios[i].num_rx_thr;
1084 if (create_pktio(dev, i, num_rx, num_workers, gbl_args->pool))
1090 printf(
"Error: failed to set %s to promiscuous mode.\n", dev);
1099 print_port_mapping();
1101 memset(thread_tbl, 0,
sizeof(thread_tbl));
1105 stats = gbl_args->stats;
1107 odph_thread_common_param_init(&thr_common);
1108 thr_common.instance = instance;
1109 thr_common.cpumask = &cpumask;
1112 for (i = 0; i < num_workers; ++i) {
1113 for (j = 0; j < MAX_PKTIOS; j++)
1114 gbl_args->thread[i].stats[j] = &stats[i][j];
1116 odph_thread_param_init(&thr_param[i]);
1117 thr_param[i].start = run_worker;
1118 thr_param[i].arg = &gbl_args->thread[i];
1122 odph_thread_create(thread_tbl, &thr_common, thr_param, num_workers);
1125 for (i = 0; i < if_count; ++i) {
1128 pktio = gbl_args->pktios[i].pktio;
1131 printf(
"Error: unable to start %s\n",
1132 gbl_args->appl.if_names[i]);
1137 ret = print_speed_stats(num_workers, gbl_args->stats,
1138 gbl_args->appl.time, gbl_args->appl.accuracy);
1142 odph_thread_join(thread_tbl, num_workers);
1145 for (i = 0; i < if_count; i++) {
1149 printf(
"Error: failed to close pktio\n");
1154 free(gbl_args->appl.if_names);
1155 free(gbl_args->appl.if_str);
1158 printf(
"Error: pool destroy\n");
1163 printf(
"Error: shm free\n");
1168 printf(
"Error: term local\n");
1173 printf(
"Error: term global\n");
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_init_u64(odp_atomic_u64_t *atom, uint64_t val)
Initialize atomic uint64 variable.
void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val)
Store value to atomic uint32 variable.
void odp_atomic_store_u64(odp_atomic_u64_t *atom, uint64_t val)
Store value to atomic uint64 variable.
uint64_t odp_atomic_load_u64(odp_atomic_u64_t *atom)
Load value of atomic uint64 variable.
void odp_barrier_init(odp_barrier_t *barr, int count)
Initialize barrier with thread count.
void odp_mb_full(void)
Full memory barrier.
void odp_barrier_wait(odp_barrier_t *barr)
Synchronize thread execution on barrier.
#define ODP_ALIGNED_CACHE
Defines type/struct/variable to be cache line size aligned.
#define odp_unlikely(x)
Branch unlikely taken.
#define ODP_UNUSED
Intentionally unused variables of functions.
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_...
uint32_t odp_hash_crc32c(const void *data, uint32_t data_len, uint32_t init_val)
Calculate CRC-32C.
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_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_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.
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.
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_pktin_recv(odp_pktin_queue_t queue, odp_packet_t packets[], int num)
Receive packets directly from an interface input queue.
int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa)
Query packet IO interface capabilities.
int odp_pktout_send(odp_pktout_queue_t queue, const odp_packet_t packets[], int num)
Send packets directly to an interface output queue.
odp_pktio_op_mode_t
Packet IO operation mode.
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_PKTIO_OP_MT_UNSAFE
Not multithread safe operation.
@ ODP_PKTIO_OP_MT
Multithread safe operation.
odp_packet_t odp_packet_copy(odp_packet_t pkt, odp_pool_t pool)
Full copy of a packet.
int odp_packet_has_eth(odp_packet_t pkt)
Check for Ethernet header.
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.
#define ODP_PACKET_INVALID
Invalid packet.
@ ODP_PROTO_LAYER_L2
Layer L2 protocols (Ethernet, VLAN, etc)
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.
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.
bool odp_bool_t
Boolean type.
void odp_sys_info_print(void)
Print system info.
@ ODP_THREAD_WORKER
Worker thread.
@ ODP_THREAD_CONTROL
Control thread.
uint64_t odp_time_to_ns(odp_time_t time)
Convert time to nanoseconds.
#define ODP_TIME_MIN_IN_NS
A minute in nanoseconds.
odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
Time difference.
odp_time_t odp_time_local_from_ns(uint64_t ns)
Convert nanoseconds to local time.
odp_time_t odp_time_local(void)
Current local time.
int odp_time_cmp(odp_time_t t2, odp_time_t t1)
Compare two times.
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
Packet input queue parameters.
uint32_t num_queues
Number of input queues to be created.
odp_pktio_op_mode_t op_mode
Operation mode.
odp_pktin_hash_proto_t hash_proto
Protocol field selection for hashing.
odp_bool_t hash_enable
Enable flow hashing.
uint32_t max_input_queues
Maximum number of input queues.
uint32_t max_output_queues
Maximum number of output queues.
Packet IO configuration options.
odp_pktio_parser_config_t parser
Packet input parser configuration.
odp_proto_layer_t layer
Protocol parsing level in packet input.
Packet output queue parameters.
odp_pktio_op_mode_t op_mode
Operation mode.
uint32_t num_queues
Number of output queues to be created.
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.
uint32_t ipv4_tcp
IPv4 addresses and TCP port numbers.
uint32_t ipv4_udp
IPv4 addresses and UDP port numbers.
struct odp_pktin_hash_proto_t::@99 proto
Protocol header fields for hashing.