24 #include "dummy_crc.h"
27 #include <odp/helper/odph_api.h>
47 #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
49 #define mix(a, b, c) \
51 a -= c; a ^= rot(c, 4); c += b; \
52 b -= a; b ^= rot(a, 6); a += c; \
53 c -= b; c ^= rot(b, 8); b += a; \
54 a -= c; a ^= rot(c, 16); c += b; \
55 b -= a; b ^= rot(a, 19); a += c; \
56 c -= b; c ^= rot(b, 4); b += a; \
59 #define final(a, b, c) \
61 c ^= b; c -= rot(b, 14); \
62 a ^= c; a -= rot(c, 11); \
63 b ^= a; b -= rot(a, 25); \
64 c ^= b; c -= rot(b, 16); \
65 a ^= c; a -= rot(c, 4); \
66 b ^= a; b -= rot(a, 14); \
67 c ^= b; c -= rot(b, 24); \
70 #define JHASH_GOLDEN_RATIO 0x9e3779b9
73 #define MAX_NUM_PKT (8 * 1024)
76 #define MAX_WORKERS (ODP_THREAD_COUNT_MAX - 1)
79 #define PKT_POOL_BUF_SIZE 1856
82 #define PKT_UAREA_SIZE 32
85 #define MAX_PKT_BURST 32
97 "MAX_FLOWS must be greater than MAX_PKTIOS\n");
100 #define MIN_PACKET_LEN (ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_UDPHDR_LEN)
103 #define DEF_NUM_RX_QUEUES 1
106 #define DEF_NUM_FLOWS 12
109 #define DEF_EXTRA_ROUNDS 15
112 #define DEF_STATS_INT 1
115 #define NO_PATH(file_name) (strrchr((file_name), '/') ? \
116 strrchr((file_name), '/') + 1 : (file_name))
121 typedef enum pktin_mode_t {
131 unsigned int cpu_count;
138 odph_ethaddr_t addrs[MAX_PKTIOS];
139 pktin_mode_t in_mode;
152 uint64_t seq[MAX_FLOWS];
167 "Flow data doesn't fit in the packet user area\n");
181 uint64_t invalid_seq;
184 uint8_t padding[ODP_CACHE_LINE_SIZE];
205 odph_ipv4hdr_t *ipv4;
212 typedef struct thread_args_t {
221 stats_t stats[MAX_WORKERS];
225 thread_args_t thread[MAX_WORKERS];
227 odph_ethaddr_t port_eth_addr[MAX_PKTIOS];
229 odph_ethaddr_t dst_eth_addr[MAX_PKTIOS];
231 int dst_port[MAX_PKTIOS];
235 qcontext_t flow_qcontext[MAX_PKTIOS][MAX_FLOWS];
237 qcontext_t input_qcontext[MAX_PKTIOS][MAX_QUEUES];
245 } pktios[MAX_PKTIOS];
253 static args_t *gbl_args;
267 for (src_idx = -1, i = 0; gbl_args->pktios[i].pktio
269 if (gbl_args->pktios[i].pktio == pktio_src)
273 ODPH_ABORT(
"Failed to determine pktio input\n");
275 return gbl_args->dst_port[src_idx];
287 static inline int packet_hdr(
odp_packet_t pkt, packet_hdr_t *hdr)
304 hdr->ipv4 = (odph_ipv4hdr_t *)(hdr->eth + 1);
308 ihl = ODPH_IPV4HDR_IHL(hdr->ipv4->ver_ihl);
312 udp = (uint8_t *)hdr->ipv4 + (ihl * 4);
314 hdr->udp = (odph_udphdr_t *)udp;
326 static inline uint64_t calc_ipv4_5tuple_hash(ipv4_tuple5_t *tuple)
330 a = tuple->proto + JHASH_GOLDEN_RATIO;
331 b = tuple->src_ip + JHASH_GOLDEN_RATIO;
332 c = tuple->dst_ip + JHASH_GOLDEN_RATIO;
336 a += ((uint32_t)tuple->src_port << 16) + tuple->dst_port + JHASH_GOLDEN_RATIO;
349 static inline uint64_t calc_flow_idx(packet_hdr_t *hdr)
356 tuple.proto = hdr->ipv4->proto;
361 idx = calc_ipv4_5tuple_hash(&tuple);
363 return idx % gbl_args->appl.num_flows;
372 static inline void fill_eth_addrs(packet_hdr_t *hdr,
int dst_port)
374 hdr->eth->src = gbl_args->port_eth_addr[dst_port];
375 hdr->eth->dst = gbl_args->dst_eth_addr[dst_port];
387 static inline void process_flow(
odp_event_t ev_tbl[],
int num, stats_t *stats,
388 qcontext_t *qcontext,
398 for (i = 0; i < num; i++) {
403 queue_seq = qcontext->seq[flow->src_idx];
406 if (gbl_args->appl.in_mode != SCHED_PARALLEL &&
408 printf(
"Invalid sequence number: packet_seq=%" PRIu64
""
409 " queue_seq=%" PRIu64
", src_if=%" PRIu8
", "
410 "dst_if=%" PRIu8
", flow=%" PRIu16
"\n",
411 flow->seq, queue_seq, flow->src_idx,
412 flow->dst_idx, flow->idx);
413 qcontext->seq[flow->src_idx] = flow->seq + 1;
414 stats->s.invalid_seq++;
416 qcontext->seq[flow->src_idx]++;
419 dst_if = flow->dst_idx;
438 static inline void process_input(
odp_event_t ev_tbl[],
int num, stats_t *stats,
439 qcontext_t *qcontext)
442 flow_t *flow_tbl[MAX_PKT_BURST];
447 for (i = 0; i < num; i++) {
456 ret = packet_hdr(pkt, &hdr);
463 flow_idx = calc_flow_idx(&hdr);
465 fill_eth_addrs(&hdr, flow_idx);
468 flow->idx = flow_idx;
469 flow->src_idx = qcontext->idx;
470 flow->dst_idx = lookup_dest_port(pkt);
471 flow_tbl[pkts] = flow;
474 for (j = 0; j < gbl_args->appl.extra_rounds; j++)
484 if (gbl_args->appl.in_mode == SCHED_ORDERED)
487 for (i = 0; i < pkts; i++) {
489 flow->seq = qcontext->seq[flow->idx]++;
492 if (gbl_args->appl.in_mode == SCHED_ORDERED)
495 for (i = 0; i < pkts; i++) {
497 ret =
odp_queue_enq(gbl_args->fqueue[flow->dst_idx][flow->idx],
501 ODPH_ERR(
"odp_queue_enq() failed\n");
515 static int run_worker(
void *arg)
520 qcontext_t *qcontext;
521 thread_args_t *thr_args = arg;
522 stats_t *stats = thr_args->stats;
526 memset(pktout, 0,
sizeof(pktout));
528 for (i = 0; i < gbl_args->appl.if_count; i++) {
529 for (j = 0; j < gbl_args->appl.num_flows; j++) {
530 pktout[i][j] = gbl_args->pktios[i].pktout[j %
531 gbl_args->pktios[i].num_tx_queue];
545 if (qcontext->input_queue)
546 process_input(ev_tbl, pkts, stats, qcontext);
548 process_flow(ev_tbl, pkts, stats, qcontext, pktout);
579 static int create_pktio(
const char *dev,
int idx,
int num_rx,
int num_tx,
598 ODPH_ERR(
"Error: failed to open %s\n", dev);
602 printf(
"Created pktio %" PRIu64
" (%s)\n",
606 ODPH_ERR(
"Error: capability query failed %s\n", dev);
617 ODPH_ERR(
"Error: promisc mode set not supported %s\n",
624 ODPH_ERR(
"Error: promisc mode enable failed %s\n", dev);
635 if (gbl_args->appl.in_mode == SCHED_ATOMIC) {
637 }
else if (gbl_args->appl.in_mode == SCHED_PARALLEL) {
647 printf(
"Allocating %i shared input queues, %i requested\n",
654 printf(
"Allocating %i shared output queues, %i requested\n",
665 pktout_param.
op_mode = mode_tx;
669 ODPH_ERR(
"Error: input queue config failed %s\n", dev);
674 ODPH_ERR(
"Error: output queue config failed %s\n", dev);
680 ODPH_ERR(
"Error: pktin event queue query failed %s\n", dev);
685 for (i = 0; i < num_rx; i++) {
686 gbl_args->input_qcontext[idx][i].idx = idx;
687 gbl_args->input_qcontext[idx][i].input_queue = 1;
690 &gbl_args->input_qcontext[idx][i],
691 sizeof(qcontext_t))) {
692 ODPH_ERR(
"Error: pktin queue context set failed %s\n",
699 gbl_args->pktios[idx].pktout,
701 ODPH_ERR(
"Error: pktout queue query failed %s\n", dev);
705 printf(
"Created %i input and %i output queues on (%s)\n",
706 num_rx, num_tx, dev);
708 gbl_args->pktios[idx].num_rx_queue = num_rx;
709 gbl_args->pktios[idx].num_tx_queue = num_tx;
710 gbl_args->pktios[idx].pktio = pktio;
724 static int print_speed_stats(
int num_workers, stats_t *thr_stats,
725 int duration,
int timeout)
728 uint64_t pkts_prev = 0;
730 uint64_t rx_drops, tx_drops, invalid_seq;
731 uint64_t maximum_pps = 0;
734 int stats_enabled = 1;
735 int loop_forever = (duration == 0);
752 for (i = 0; i < num_workers; i++) {
753 pkts += thr_stats[i].s.packets;
754 rx_drops += thr_stats[i].s.rx_drops;
755 tx_drops += thr_stats[i].s.tx_drops;
756 invalid_seq += thr_stats[i].s.invalid_seq;
759 pps = (pkts - pkts_prev) / timeout;
760 if (pps > maximum_pps)
762 printf(
"%" PRIu64
" pps, %" PRIu64
" max pps, ", pps,
765 printf(
"%" PRIu64
" rx drops, %" PRIu64
" tx drops, ",
768 printf(
"%" PRIu64
" invalid seq\n", invalid_seq);
773 }
while (loop_forever || (elapsed < duration));
776 printf(
"TEST RESULT: %" PRIu64
" maximum packets per second.\n",
779 return (pkts > 100 && !invalid_seq) ? 0 : -1;
787 static int find_dest_port(
int port)
790 if (gbl_args->appl.if_count % 2 == 0)
791 return (port % 2 == 0) ? port + 1 : port - 1;
794 if (port == gbl_args->appl.if_count - 1)
803 static void init_forwarding_tbl(
void)
807 for (rx_idx = 0; rx_idx < gbl_args->appl.if_count; rx_idx++)
808 gbl_args->dst_port[rx_idx] = find_dest_port(rx_idx);
814 static void usage(
char *progname)
817 "OpenDataPlane ordered pktio application.\n"
819 "Usage: %s OPTIONS\n"
820 " E.g. %s -i eth0,eth1\n"
821 " In the above example,\n"
822 " eth0 will send pkts to eth1 and vice versa\n"
824 "Mandatory OPTIONS:\n"
825 " -i, --interface Eth interfaces (comma-separated, no spaces)\n"
826 " Interface count min 1, max %i\n"
828 "Optional OPTIONS:\n"
829 " -m, --mode Packet input mode\n"
830 " 0: Scheduled ordered queues (default)\n"
831 " 1: Scheduled atomic queues\n"
832 " 2: Scheduled parallel queues (packet order not maintained)\n"
833 " -r, --num_rx_q Number of RX queues per interface\n"
834 " -f, --num_flows Number of packet flows\n"
835 " -e, --extra_input <number> Number of extra input processing rounds\n"
836 " -c, --count <number> CPU count, 0=all available, default=1\n"
837 " -t, --time <number> Time in seconds to run.\n"
838 " -a, --accuracy <number> Statistics print interval in seconds\n"
839 " (default is 1 second).\n"
840 " -d, --dst_addr Destination addresses (comma-separated, no spaces)\n"
841 " -P, --promisc_mode Enable promiscuous mode.\n"
842 " -h, --help Display help and exit.\n\n"
843 "\n", NO_PATH(progname), NO_PATH(progname), MAX_PKTIOS
854 static void parse_args(
int argc,
char *argv[], appl_args_t *appl_args)
861 static const struct option longopts[] = {
862 {
"count", required_argument, NULL,
'c'},
863 {
"time", required_argument, NULL,
't'},
864 {
"accuracy", required_argument, NULL,
'a'},
865 {
"interface", required_argument, NULL,
'i'},
866 {
"mode", required_argument, NULL,
'm'},
867 {
"dst_addr", required_argument, NULL,
'd'},
868 {
"num_rx_q", required_argument, NULL,
'r'},
869 {
"num_flows", required_argument, NULL,
'f'},
870 {
"extra_input", required_argument, NULL,
'e'},
871 {
"promisc_mode", no_argument, NULL,
'P'},
872 {
"help", no_argument, NULL,
'h'},
876 static const char *shortopts =
"+c:t:a:i:m:d:r:f:e:Ph";
879 appl_args->accuracy = DEF_STATS_INT;
880 appl_args->cpu_count = 1;
881 appl_args->num_rx_q = DEF_NUM_RX_QUEUES;
882 appl_args->num_flows = DEF_NUM_FLOWS;
883 appl_args->extra_rounds = DEF_EXTRA_ROUNDS;
884 appl_args->promisc_mode = 0;
887 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
894 appl_args->cpu_count = atoi(optarg);
897 appl_args->time = atoi(optarg);
900 appl_args->accuracy = atoi(optarg);
904 len = strlen(optarg);
911 addr_str = malloc(len);
912 if (addr_str == NULL) {
918 strcpy(addr_str, optarg);
919 for (token = strtok(addr_str,
","), i = 0;
920 token != NULL; token = strtok(NULL,
","), i++) {
921 if (i >= MAX_PKTIOS) {
922 printf(
"too many MAC addresses\n");
926 if (odph_eth_addr_parse(&appl_args->addrs[i],
928 printf(
"invalid MAC address\n");
933 appl_args->addr_count = i;
934 if (appl_args->addr_count < 1) {
941 len = strlen(optarg);
948 appl_args->if_str = malloc(len);
949 if (appl_args->if_str == NULL) {
955 strcpy(appl_args->if_str, optarg);
956 for (token = strtok(appl_args->if_str,
","), i = 0;
958 token = strtok(NULL,
","), i++)
961 appl_args->if_count = i;
963 if (appl_args->if_count < 1 ||
964 appl_args->if_count > MAX_PKTIOS) {
970 appl_args->if_names =
971 calloc(appl_args->if_count,
sizeof(
char *));
974 strcpy(appl_args->if_str, optarg);
975 for (token = strtok(appl_args->if_str,
","), i = 0;
976 token != NULL; token = strtok(NULL,
","), i++) {
977 appl_args->if_names[i] = token;
983 appl_args->in_mode = SCHED_ATOMIC;
985 appl_args->in_mode = SCHED_PARALLEL;
987 appl_args->in_mode = SCHED_ORDERED;
990 appl_args->num_rx_q = atoi(optarg);
993 appl_args->num_flows = atoi(optarg);
996 appl_args->extra_rounds = atoi(optarg);
999 appl_args->promisc_mode = 1;
1010 if (appl_args->num_flows > MAX_FLOWS) {
1011 printf(
"Too many flows requested %d, max: %d\n",
1012 appl_args->num_flows, MAX_FLOWS);
1016 if (appl_args->if_count == 0 || appl_args->num_flows == 0 ||
1017 appl_args->num_rx_q == 0) {
1021 if (appl_args->addr_count != 0 &&
1022 appl_args->addr_count != appl_args->if_count) {
1023 printf(
"Number of destination addresses differs from number"
1024 " of interfaces\n");
1035 static void print_info(
char *progname, appl_args_t *appl_args)
1041 printf(
"%s options\n"
1042 "-------------------------\n"
1045 progname, appl_args->if_count);
1046 for (i = 0; i < appl_args->if_count; ++i)
1047 printf(
" %s", appl_args->if_names[i]);
1049 "Input queues: %d\n"
1052 "Extra rounds: %d\n"
1053 "Promisc mode: %s\n", appl_args->num_rx_q,
1054 (appl_args->in_mode == SCHED_ATOMIC) ?
"PKTIN_SCHED_ATOMIC" :
1055 (appl_args->in_mode == SCHED_PARALLEL ?
"PKTIN_SCHED_PARALLEL" :
1056 "PKTIN_SCHED_ORDERED"), appl_args->num_flows,
1057 appl_args->extra_rounds, appl_args->promisc_mode ?
1058 "enabled" :
"disabled");
1062 static void gbl_args_init(args_t *args)
1066 memset(args, 0,
sizeof(args_t));
1069 for (pktio = 0; pktio < MAX_PKTIOS; pktio++) {
1072 for (queue = 0; queue < MAX_QUEUES; queue++)
1080 int main(
int argc,
char *argv[])
1091 odph_ethaddr_t new_addr;
1092 odph_helper_options_t helper_options;
1093 odph_thread_t thread_tbl[MAX_WORKERS];
1094 odph_thread_common_param_t thr_common;
1095 odph_thread_param_t thr_param[MAX_WORKERS];
1102 uint32_t queue_size, pool_size;
1105 argc = odph_parse_options(argc, argv);
1106 if (odph_options(&helper_options)) {
1107 ODPH_ERR(
"Error: reading ODP helper options failed.\n");
1112 init_param.
mem_model = helper_options.mem_model;
1116 ODPH_ERR(
"Error: ODP global init failed.\n");
1122 ODPH_ERR(
"Error: ODP local init failed.\n");
1127 printf(
"Error: Schedule capa failed.\n");
1132 ODPH_ERR(
"Error: Pool capa failed\n");
1138 ODP_CACHE_LINE_SIZE, 0);
1141 ODPH_ERR(
"Error: shared mem reserve failed.\n");
1147 if (gbl_args == NULL) {
1148 ODPH_ERR(
"Error: shared mem alloc failed.\n");
1152 gbl_args_init(gbl_args);
1155 parse_args(argc, argv, &gbl_args->appl);
1160 if (gbl_args->appl.in_mode == SCHED_ORDERED) {
1163 ODPH_ERR(
"Error: Ordered locks not available.\n");
1168 print_info(NO_PATH(argv[0]), &gbl_args->appl);
1170 num_workers = MAX_WORKERS;
1171 if (gbl_args->appl.cpu_count && gbl_args->appl.cpu_count < MAX_WORKERS)
1172 num_workers = gbl_args->appl.cpu_count;
1178 if_count = gbl_args->appl.if_count;
1180 printf(
"Num worker threads: %i\n", num_workers);
1182 printf(
"CPU mask: %s\n\n", cpumaskstr);
1184 pool_size = MAX_NUM_PKT;
1188 queue_size = MAX_NUM_PKT;
1195 if (pool_size > queue_size)
1196 pool_size = queue_size;
1201 params.
pkt.
len = PKT_POOL_BUF_SIZE;
1202 params.
pkt.
num = pool_size;
1209 ODPH_ERR(
"Error: packet pool create failed.\n");
1214 init_forwarding_tbl();
1216 for (i = 0; i < if_count; ++i) {
1217 const char *dev = gbl_args->appl.if_names[i];
1220 num_rx = gbl_args->appl.num_rx_q;
1221 num_tx = gbl_args->appl.num_flows;
1223 if (create_pktio(dev, i, num_rx, num_tx, pool))
1228 gbl_args->port_eth_addr[i].addr,
1229 ODPH_ETHADDR_LEN) != ODPH_ETHADDR_LEN) {
1230 ODPH_ERR(
"Error: interface ethernet address unknown\n");
1238 memset(&new_addr, 0,
sizeof(odph_ethaddr_t));
1239 if (gbl_args->appl.addr_count) {
1240 memcpy(&new_addr, &gbl_args->appl.addrs[i],
1241 sizeof(odph_ethaddr_t));
1243 new_addr.addr[0] = 0x02;
1244 new_addr.addr[5] = i;
1246 gbl_args->dst_eth_addr[i] = new_addr;
1252 for (i = 0; i < if_count; i++) {
1256 ODPH_ERR(
"Error: pktio capability failed.\n");
1265 for (i = 0; i < if_count; i++) {
1266 for (j = 0; j < gbl_args->appl.num_flows; j++) {
1271 snprintf(qname,
sizeof(qname),
"flow_%d_%d", i, j);
1278 qparam.
size = queue_size;
1280 gbl_args->flow_qcontext[i][j].idx = i;
1281 gbl_args->flow_qcontext[i][j].input_queue = 0;
1282 qparam.
context = &gbl_args->flow_qcontext[i][j];
1287 ODPH_ERR(
"Error: flow queue create failed.\n");
1291 gbl_args->fqueue[i][j] = queue;
1295 memset(thread_tbl, 0,
sizeof(thread_tbl));
1297 stats = gbl_args->stats;
1302 odph_thread_common_param_init(&thr_common);
1303 thr_common.instance = instance;
1304 thr_common.cpumask = &cpumask;
1306 for (i = 0; i < num_workers; ++i) {
1307 gbl_args->thread[i].stats = &stats[i];
1309 odph_thread_param_init(&thr_param[i]);
1310 thr_param[i].start = run_worker;
1311 thr_param[i].arg = &gbl_args->thread[i];
1315 odph_thread_create(thread_tbl, &thr_common, thr_param, num_workers);
1318 for (i = 0; i < if_count; ++i) {
1321 pktio = gbl_args->pktios[i].pktio;
1324 ODPH_ERR(
"Error: unable to start %s\n",
1325 gbl_args->appl.if_names[i]);
1330 ret = print_speed_stats(num_workers, stats, gbl_args->appl.time,
1331 gbl_args->appl.accuracy);
1334 for (i = 0; i < if_count; i++)
1340 odph_thread_join(thread_tbl, num_workers);
1342 for (i = 0; i < if_count; i++) {
1345 for (j = 0; j < gbl_args->appl.num_flows; j++)
1349 free(gbl_args->appl.if_names);
1350 free(gbl_args->appl.if_str);
1353 ODPH_ERR(
"Error: pool destroy\n");
1358 ODPH_ERR(
"Error: shm free\n");
1363 ODPH_ERR(
"Error: term local\n");
1368 ODPH_ERR(
"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_store_u32(odp_atomic_u32_t *atom, uint32_t val)
Store value to atomic uint32 variable.
void odp_barrier_init(odp_barrier_t *barr, int count)
Initialize barrier with thread count.
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.
uint16_t odp_be_to_cpu_16(odp_u16be_t be16)
Convert 16bit big endian to cpu native uint16_t.
uint32_t odp_be_to_cpu_32(odp_u32be_t be32)
Convert 32bit big endian to cpu native uint32_t.
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_...
void odp_event_free(odp_event_t event)
Free event.
#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.
#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_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.
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_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_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
Multithread safe operation.
@ ODP_PKTIN_MODE_SCHED
Packet input through scheduler and scheduled event queues.
uint32_t odp_packet_seg_len(odp_packet_t pkt)
Packet data length following the data pointer.
void odp_packet_prefetch(odp_packet_t pkt, uint32_t offset, uint32_t len)
Packet data prefetch.
void * odp_packet_data(odp_packet_t pkt)
Packet data pointer.
int odp_packet_has_eth(odp_packet_t pkt)
Check for Ethernet header.
void * odp_packet_user_area(odp_packet_t pkt)
User area address.
uint32_t odp_packet_len(odp_packet_t pkt)
Packet data length.
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.
odp_pktio_t odp_packet_input(odp_packet_t pkt)
Packet input interface.
@ 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.
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()
void odp_pool_print(odp_pool_t pool)
Print pool info.
#define ODP_POOL_INVALID
Invalid pool.
@ ODP_POOL_PACKET
Packet pool.
int odp_queue_context_set(odp_queue_t queue, void *context, uint32_t len)
Set queue context.
void odp_queue_param_init(odp_queue_param_t *param)
Initialize queue params.
#define ODP_QUEUE_INVALID
Invalid queue.
#define ODP_QUEUE_NAME_LEN
Maximum queue name length, including the null character.
void * odp_queue_context(odp_queue_t queue)
Get queue context.
int odp_queue_enq(odp_queue_t queue, odp_event_t ev)
Enqueue an event to a queue.
odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param)
Queue create.
int odp_queue_destroy(odp_queue_t queue)
Destroy ODP queue.
@ ODP_QUEUE_TYPE_SCHED
Scheduled queue.
#define ODP_SCHED_SYNC_PARALLEL
Parallel scheduled queues.
int odp_schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t events[], int num)
Schedule multiple events.
void odp_schedule_config_init(odp_schedule_config_t *config)
Initialize schedule configuration options.
#define ODP_SCHED_SYNC_ATOMIC
Atomic queue synchronization.
#define ODP_SCHED_SYNC_ORDERED
Ordered queue synchronization.
void odp_schedule_order_unlock(uint32_t lock_index)
Release ordered context lock.
#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.
int odp_schedule_capability(odp_schedule_capability_t *capa)
Query scheduler capabilities.
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_schedule_order_lock(uint32_t lock_index)
Acquire ordered context lock.
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.
#define ODP_TIME_SEC_IN_NS
A second in nanoseconds.
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_queue_param_t queue_param
Queue parameters.
odp_pktin_hash_proto_t hash_proto
Protocol field selection for hashing.
odp_bool_t hash_enable
Enable flow hashing.
odp_pktio_set_op_t set_op
Supported set operations.
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_pktin_mode_t in_mode
Packet input mode.
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.
struct odp_pool_capability_t::@122 pkt
Packet pool capabilities
uint32_t max_num
Maximum number of buffers of any size.
uint32_t uarea_size
Minimum user area size in bytes.
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_queue_type_t type
Queue type.
uint32_t context_len
Queue context data length.
void * context
Queue context pointer.
uint32_t max_ordered_locks
Maximum number of ordered locks per queue.
uint32_t queue_size
Maximum number of events required to be stored simultaneously in scheduled queue.
odp_schedule_group_t group
Thread group.
odp_schedule_prio_t prio
Priority level.
uint32_t lock_count
Ordered lock count for this queue.
odp_schedule_sync_t sync
Synchronization method.
uint32_t ipv4_udp
IPv4 addresses and UDP port numbers.
struct odp_pktin_hash_proto_t::@99 proto
Protocol header fields for hashing.
struct odp_pktio_set_op_t::@104 op
Operation flags.
uint32_t promisc_mode
Promiscuous mode.