23 #include <odp/helper/odph_api.h>
32 #define MAX_WORKERS (ODP_THREAD_COUNT_MAX - 1)
37 #define MAX_PKT_BURST 64
42 #define DEF_PKT_BURST 32
47 #define SHM_PKT_POOL_SIZE 10000
52 #define SHM_PKT_POOL_BUF_SIZE 1856
57 #define MAX_PMR_COUNT 32
62 #define DISPLAY_STRING_LEN 32
65 #define MAX_VAL_SIZE 16
68 #define NO_PATH(file_name) (strrchr((file_name), '/') ? \
69 strrchr((file_name), '/') + 1 : (file_name))
82 uint8_t value_be[MAX_VAL_SIZE];
83 uint8_t mask_be[MAX_VAL_SIZE];
87 char value[DISPLAY_STRING_LEN];
88 char mask[DISPLAY_STRING_LEN];
101 global_statistics stats[MAX_PMR_COUNT];
102 ci_pass_counters ci_pass_rules[MAX_PMR_COUNT];
104 int num_ci_pass_rules;
107 unsigned int cpu_count;
114 int classifier_enable;
126 static appl_args_t *appl_args_gbl;
128 static int drop_err_pkts(
odp_packet_t pkt_tbl[],
unsigned len);
129 static void swap_pkt_addrs(
odp_packet_t pkt_tbl[],
unsigned len);
130 static int parse_args(
int argc,
char *argv[], appl_args_t *appl_args);
131 static void print_info(
char *progname, appl_args_t *appl_args);
132 static void usage(
void);
134 static inline int check_ci_pass_count(appl_args_t *args)
139 if (args->num_ci_pass_rules == 0)
142 for (i = 0; i < args->num_ci_pass_rules; i++) {
143 for (j = 0; j < args->policy_count; j++) {
144 if (!strcmp(args->stats[j].cos_name,
145 args->ci_pass_rules[i].cos_name)) {
147 if (args->ci_pass_rules[i].count > count) {
148 ODPH_ERR(
"Error: Cos = %s, expected packets = %" PRIu64
","
149 "received packet = %" PRIu64
"\n",
150 args->stats[j].cos_name,
151 args->ci_pass_rules[i].count, count);
157 if (j == args->policy_count) {
158 ODPH_ERR(
"Error: invalid Cos:%s specified for CI pass count\n",
159 args->ci_pass_rules[i].cos_name);
166 static inline void print_cls_statistics(appl_args_t *args)
173 for (i = 0; i < 40; i++)
177 printf(
"CLASSIFIER EXAMPLE STATISTICS\n");
178 for (i = 0; i < 40; i++)
181 printf(
"CONFIGURATION\n");
183 printf(
"COS\tVALUE\t\tMASK\n");
184 for (i = 0; i < 40; i++)
187 for (i = 0; i < args->policy_count - 1; i++) {
188 printf(
"%s\t", args->stats[i].cos_name);
189 printf(
"%s\t", args->stats[i].value);
190 printf(
"%s\n", args->stats[i].mask);
193 printf(
"RECEIVED PACKETS\n");
194 for (i = 0; i < 40; i++)
197 for (i = 0; i < args->policy_count; i++)
198 printf(
"%-12s |", args->stats[i].cos_name);
199 printf(
"%-6s %-6s",
"Total",
"Mpps");
201 for (i = 0; i < args->policy_count; i++)
202 printf(
"%-6s %-6s|",
"queue",
"pool");
205 timeout = args->time;
212 uint64_t total_packets, last_total_packets = 0;
216 for (; timeout > 0 || infinite; timeout--) {
218 for (i = 0; i < args->policy_count; i++) {
219 printf(
"%-6" PRIu64
" ",
222 printf(
"%-6" PRIu64
"|",
229 mpps = (total_packets - last_total_packets) /
231 printf(
"%-6" PRIu64
" %-6.3f\n", total_packets, mpps);
232 last_total_packets = total_packets;
235 if (args->shutdown_sig)
242 static int parse_custom(
const char *str, uint8_t *buf_be,
int max_size)
248 if (len > 2 * max_size)
251 for (i = 0; i < len; i += 2)
252 if (sscanf(&str[i],
"%2" SCNx8, &buf_be[i / 2]) != 1)
283 ODPH_ERR(
"pktio create failed for %s\n", dev);
288 ODPH_ERR(
"pktio capability failed for %s\n", dev);
296 ODPH_ERR(
"pktin queue config failed for %s\n", dev);
300 num_tx = appl_args_gbl->cpu_count;
303 printf(
"Sharing %i output queues between %i workers\n",
308 appl_args_gbl->num_pktout = num_tx;
314 ODPH_ERR(
"pktout queue config failed for %s\n", dev);
319 ODPH_ERR(
"Pktout queue query failed: %s\n", dev);
325 ODPH_ERR(
"enabling promisc mode not supported %s\n", dev);
330 ODPH_ERR(
"failed to enable promisc mode for %s\n", dev);
341 for (
int c = 0; c < (int)
sizeof(mac); c++)
342 printf(
":%02x", mac.addr[c]);
350 ODPH_ERR(
"failed to configure pktio %s\n", dev);
361 static int pktio_receive_thread(
void *arg)
368 int i, j, num, dropped, sent;
369 global_statistics *stats;
370 unsigned long err_cnt = 0;
372 appl_args_t *appl = (appl_args_t *)arg;
391 for (j = 0; j < num; j++) {
396 printf(
"Queue: %s\n", info.
name);
409 dropped = drop_err_pkts(pkt, num);
413 ODPH_ERR(
"Drop frame - err_cnt:%lu\n", err_cnt);
416 for (j = 0; j < num; j++) {
419 for (i = 0; i < MAX_PMR_COUNT; i++) {
420 stats = &appl->stats[i];
421 if (queue == stats->queue)
423 if (pool == stats->pool)
428 if (appl->appl_mode == APPL_MODE_DROP) {
434 swap_pkt_addrs(pkt, num);
437 sent = sent < 0 ? 0 : sent;
440 ODPH_ERR(
" [%i] Packet send failed\n", thr);
448 static odp_pool_t pool_create(
const char *name)
457 pool_params.
pkt.
seg_len = SHM_PKT_POOL_BUF_SIZE;
458 pool_params.
pkt.
len = SHM_PKT_POOL_BUF_SIZE;
459 pool_params.
pkt.
num = appl_args_gbl->pool_size;
464 ODPH_ERR(
"Error: failed to create pool %s\n", name);
474 const char *queue_name =
"DefaultQueue";
475 const char *pool_name =
"DefaultPool";
476 const char *cos_name =
"DefaultCos";
481 global_statistics *stats = args->stats;
490 ODPH_ERR(
"Error: default queue create failed\n");
494 pool_default = pool_create(pool_name);
497 cls_param.
pool = pool_default;
498 cls_param.
queue = queue_default;
503 ODPH_ERR(
"Error: default cos create failed\n");
508 ODPH_ERR(
"odp_pktio_default_cos_set failed\n");
511 stats[args->policy_count].cos = cos_default;
513 stats[args->policy_count].queue = queue_default;
514 if (appl_args_gbl->cos_pools)
515 stats[args->policy_count].pool = pool_default;
516 snprintf(stats[args->policy_count].cos_name,
517 sizeof(stats[args->policy_count].cos_name),
521 args->policy_count++;
525 static int find_cos(appl_args_t *args,
const char *name,
odp_cos_t *cos)
527 global_statistics *stats;
530 for (i = 0; i < args->policy_count - 1; i++) {
531 stats = &args->stats[i];
533 if (strcmp(stats->cos_name, name) == 0) {
542 static void configure_cos(
odp_cos_t default_cos, appl_args_t *args)
546 const char *queue_name;
549 global_statistics *stats;
552 for (i = 0; i < args->policy_count - 1; i++) {
553 stats = &args->stats[i];
560 queue_name = args->stats[i].cos_name;
563 ODPH_ERR(
"odp_queue_create failed\n");
567 snprintf(pool_name,
sizeof(pool_name),
"%sPool%d",
568 args->stats[i].cos_name, i);
570 snprintf(cos_name,
sizeof(cos_name),
"CoS%s",
573 cls_param.
pool = pool_create(pool_name);
574 if (appl_args_gbl->cos_pools)
575 stats->pool = cls_param.
pool;
576 cls_param.
queue = stats->queue;
584 for (i = 0; i < args->policy_count - 1; i++) {
588 stats = &args->stats[i];
590 if (stats->has_src_cos) {
591 if (find_cos(args, stats->src_cos_name, &src_cos)) {
592 ODPH_ERR(
"find_cos failed\n");
598 pmr_param.
term = stats->rule.term;
599 pmr_param.
match.value = stats->rule.value_be;
600 pmr_param.
match.mask = stats->rule.mask_be;
601 pmr_param.
val_sz = stats->rule.val_sz;
602 pmr_param.
offset = stats->rule.offset;
607 ODPH_ERR(
"odp_pktio_pmr_cos failed\n");
614 static void sig_handler(
int signo)
618 if (appl_args_gbl == NULL)
620 appl_args_gbl->shutdown_sig = 1;
626 int main(
int argc,
char *argv[])
628 odph_helper_options_t helper_options;
629 odph_thread_t thread_tbl[MAX_WORKERS];
642 odph_thread_common_param_t thr_common;
643 odph_thread_param_t thr_param;
645 signal(SIGINT, sig_handler);
648 argc = odph_parse_options(argc, argv);
649 if (odph_options(&helper_options)) {
650 ODPH_ERR(
"Error: reading ODP helper options failed\n");
655 init_param.
mem_model = helper_options.mem_model;
659 ODPH_ERR(
"Error: ODP global init failed\n");
665 ODPH_ERR(
"Error: ODP local init failed\n");
671 ODP_CACHE_LINE_SIZE, 0);
674 ODPH_ERR(
"Error: shared mem reserve failed\n");
681 ODPH_ERR(
"Error: shared mem alloc failed\n");
685 appl_args_gbl = args;
686 memset(args, 0,
sizeof(*args));
688 if (parse_args(argc, argv, args))
692 print_info(NO_PATH(argv[0]), args);
694 num_workers = MAX_WORKERS;
695 if (args->cpu_count && args->cpu_count < MAX_WORKERS)
696 num_workers = args->cpu_count;
702 printf(
"num worker threads: %i\n", num_workers);
704 printf(
"cpu mask: %s\n", cpumaskstr);
707 pool = pool_create(
"packet_pool");
716 pktio = create_pktio(args->if_name, pool);
719 default_cos = configure_default_cos(pktio, args);
721 configure_cos(default_cos, args);
728 ODPH_ERR(
"Error: unable to start pktio\n");
733 memset(thread_tbl, 0,
sizeof(thread_tbl));
734 odph_thread_common_param_init(&thr_common);
735 odph_thread_param_init(&thr_param);
737 thr_param.start = pktio_receive_thread;
738 thr_param.arg = args;
741 thr_common.instance = instance;
742 thr_common.cpumask = &cpumask;
743 thr_common.share_param = 1;
745 odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers);
747 if (args->verbose == 0) {
748 print_cls_statistics(args);
750 int timeout = args->time;
752 for (i = 0; timeout == 0 || i < timeout; i++) {
753 if (args->shutdown_sig)
762 odph_thread_join(thread_tbl, num_workers);
764 if (check_ci_pass_count(args)) {
765 ODPH_ERR(
"Error: Packet count verification failed\n");
769 for (i = 0; i < args->policy_count; i++) {
770 if ((i != args->policy_count - 1) &&
772 ODPH_ERR(
"err: odp_cls_pmr_destroy for %d\n", i);
774 ODPH_ERR(
"err: odp_cos_destroy for %d\n", i);
776 ODPH_ERR(
"err: odp_queue_destroy for %d\n", i);
778 ODPH_ERR(
"err: odp_pool_destroy for %d\n", i);
782 ODPH_ERR(
"err: close pktio error\n");
784 ODPH_ERR(
"err: odp_pool_destroy error\n");
793 ODPH_ERR(
"odp_term_local error %d\n", ret);
796 ODPH_ERR(
"odp_term_global error %d\n", ret);
812 static int drop_err_pkts(
odp_packet_t pkt_tbl[],
unsigned len)
818 for (i = 0, j = 0; i < len; ++i) {
838 static void swap_pkt_addrs(
odp_packet_t pkt_tbl[],
unsigned len)
842 odph_ethaddr_t tmp_addr;
847 for (i = 0; i < len; ++i) {
858 ip = (odph_ipv4hdr_t *)
861 ip_tmp_addr = ip->src_addr;
862 ip->src_addr = ip->dst_addr;
863 ip->dst_addr = ip_tmp_addr;
874 if (strcasecmp(token,
"ODP_PMR_ETHTYPE_0") == 0) {
877 }
else if (strcasecmp(token,
"ODP_PMR_ETHTYPE_X") == 0) {
880 }
else if (strcasecmp(token,
"ODP_PMR_VLAN_ID_0") == 0) {
883 }
else if (strcasecmp(token,
"ODP_PMR_VLAN_ID_X") == 0) {
886 }
else if (strcasecmp(token,
"ODP_PMR_UDP_DPORT") == 0) {
889 }
else if (strcasecmp(token,
"ODP_PMR_TCP_DPORT") == 0) {
892 }
else if (strcasecmp(token,
"ODP_PMR_UDP_SPORT") == 0) {
895 }
else if (strcasecmp(token,
"ODP_PMR_TCP_SPORT") == 0) {
898 }
else if (strcasecmp(token,
"ODP_PMR_DIP_ADDR") == 0) {
901 }
else if (strcasecmp(token,
"ODP_PMR_SIP_ADDR") == 0) {
904 }
else if (strcasecmp(token,
"ODP_PMR_DMAC") == 0) {
907 }
else if (strcasecmp(token,
"ODP_PMR_CUSTOM_FRAME") == 0) {
910 }
else if (strcasecmp(token,
"ODP_PMR_CUSTOM_L3") == 0) {
918 static int parse_pmr_policy(appl_args_t *appl_args,
char *optarg)
921 char *token, *cos0, *cos1, *cur_char;
924 global_statistics *stats;
927 uint32_t offset, ip_addr, u32;
928 unsigned long int value, mask;
932 policy_count = appl_args->policy_count;
933 stats = appl_args->stats;
936 if (policy_count >= MAX_PMR_COUNT - 1) {
937 ODPH_ERR(
"Too many policies. Max count is %i.\n",
942 len = strlen(optarg);
944 pmr_str = malloc(len);
945 if (pmr_str == NULL) {
946 ODPH_ERR(
"Memory allocation failed\n");
949 strcpy(pmr_str, optarg);
953 token = strtok(pmr_str,
":");
954 if (convert_str_to_pmr_enum(token, &term)) {
955 ODPH_ERR(
"Invalid ODP_PMR_TERM string\n");
958 stats[policy_count].rule.term = term;
959 stats[policy_count].rule.offset = 0;
981 token = strtok(NULL,
":");
982 odph_strcpy(stats[policy_count].value, token,
984 value = strtoul(token, NULL, 0);
987 memcpy(stats[policy_count].rule.value_be, &u16,
sizeof(u16));
989 token = strtok(NULL,
":");
990 odph_strcpy(stats[policy_count].mask, token,
992 mask = strtoul(token, NULL, 0);
995 memcpy(stats[policy_count].rule.mask_be, &u16,
sizeof(u16));
997 stats[policy_count].rule.val_sz = 2;
1003 token = strtok(NULL,
":");
1004 odph_strcpy(stats[policy_count].value, token,
1005 DISPLAY_STRING_LEN);
1007 if (odph_ipv4_addr_parse(&ip_addr, token)) {
1008 ODPH_ERR(
"Bad IP address\n");
1013 memcpy(stats[policy_count].rule.value_be, &u32,
sizeof(u32));
1015 token = strtok(NULL,
":");
1016 odph_strcpy(stats[policy_count].mask, token,
1017 DISPLAY_STRING_LEN);
1018 mask = strtoul(token, NULL, 0);
1021 memcpy(stats[policy_count].rule.mask_be, &u32,
sizeof(u32));
1023 stats[policy_count].rule.val_sz = 4;
1027 token = strtok(NULL,
":");
1028 odph_strcpy(stats[policy_count].value, token,
1029 DISPLAY_STRING_LEN);
1034 while ((cur_char = strchr(cur_char,
'-')) != NULL)
1037 if (odph_eth_addr_parse(&mac, token)) {
1038 ODPH_ERR(
"Invalid MAC address. Use format 11-22-33-44-55-66.\n");
1042 memcpy(stats[policy_count].rule.value_be, mac.addr, ODPH_ETHADDR_LEN);
1043 stats[policy_count].rule.val_sz = 6;
1045 token = strtok(NULL,
":");
1046 odph_strcpy(stats[policy_count].mask, token, DISPLAY_STRING_LEN);
1047 mask_sz = parse_custom(token, stats[policy_count].rule.mask_be, ODPH_ETHADDR_LEN);
1048 if (mask_sz != ODPH_ETHADDR_LEN) {
1049 ODPH_ERR(
"Invalid mask. Provide mask without 0x prefix.\n");
1057 token = strtok(NULL,
":");
1059 offset = strtoul(token, NULL, 0);
1060 stats[policy_count].rule.offset = offset;
1064 token = strtok(NULL,
":");
1065 odph_strcpy(stats[policy_count].value, token,
1066 DISPLAY_STRING_LEN);
1067 val_sz = parse_custom(token,
1068 stats[policy_count].rule.value_be,
1070 stats[policy_count].rule.val_sz = val_sz;
1074 token = strtok(NULL,
":");
1075 odph_strcpy(stats[policy_count].mask, token,
1076 DISPLAY_STRING_LEN);
1077 mask_sz = parse_custom(token,
1078 stats[policy_count].rule.mask_be,
1080 if (mask_sz != val_sz)
1089 cos0 = strtok(NULL,
":");
1090 cos1 = strtok(NULL,
":");
1095 stats[policy_count].has_src_cos = 1;
1096 odph_strcpy(stats[policy_count].src_cos_name, cos0,
1098 odph_strcpy(stats[policy_count].cos_name, cos1,
1101 odph_strcpy(stats[policy_count].cos_name, cos0,
1105 appl_args->policy_count++;
1114 static int parse_policy_ci_pass_count(appl_args_t *appl_args,
char *optarg)
1116 int num_ci_pass_rules;
1117 char *token, *value;
1119 ci_pass_counters *ci_pass_rules;
1122 num_ci_pass_rules = appl_args->num_ci_pass_rules;
1123 ci_pass_rules = appl_args->ci_pass_rules;
1126 if (num_ci_pass_rules >= MAX_PMR_COUNT) {
1127 ODPH_ERR(
"Too many ci pass counters. Max count is %i.\n",
1132 len = strlen(optarg);
1134 count_str = malloc(len);
1135 if (count_str == NULL) {
1136 ODPH_ERR(
"Memory allocation failed\n");
1139 strcpy(count_str, optarg);
1141 token = strtok(count_str,
":");
1142 value = strtok(NULL,
":");
1143 if (!token || !value) {
1147 strcpy(ci_pass_rules[num_ci_pass_rules].cos_name, token);
1148 ci_pass_rules[num_ci_pass_rules].count = atoll(value);
1149 appl_args->num_ci_pass_rules++;
1161 static int parse_args(
int argc,
char *argv[], appl_args_t *appl_args)
1169 static const struct option longopts[] = {
1170 {
"count", required_argument, NULL,
'c'},
1171 {
"interface", required_argument, NULL,
'i'},
1172 {
"policy", required_argument, NULL,
'p'},
1173 {
"mode", required_argument, NULL,
'm'},
1174 {
"time", required_argument, NULL,
't'},
1175 {
"ci_pass", required_argument, NULL,
'C'},
1176 {
"promisc_mode", no_argument, NULL,
'P'},
1177 {
"verbose", no_argument, NULL,
'v'},
1178 {
"help", no_argument, NULL,
'h'},
1179 {
"enable", required_argument, NULL,
'e'},
1180 {
"layer", required_argument, NULL,
'l'},
1181 {
"dedicated", required_argument, NULL,
'd'},
1182 {
"size", required_argument, NULL,
's'},
1183 {
"burst", required_argument, NULL,
'b'},
1187 static const char *shortopts =
"+c:t:i:p:m:t:C:Pvhe:l:d:s:b:";
1189 appl_args->cpu_count = 1;
1190 appl_args->verbose = 0;
1191 appl_args->promisc_mode = 0;
1192 appl_args->classifier_enable = 1;
1194 appl_args->cos_pools = 1;
1195 appl_args->pool_size = SHM_PKT_POOL_SIZE;
1196 appl_args->burst_size = DEF_PKT_BURST;
1199 opt = getopt_long(argc, argv, shortopts,
1207 appl_args->cpu_count = atoi(optarg);
1210 if (parse_pmr_policy(appl_args, optarg)) {
1216 appl_args->time = atoi(optarg);
1219 len = strlen(optarg);
1226 appl_args->if_name = malloc(len);
1227 if (appl_args->if_name == NULL) {
1232 strcpy(appl_args->if_name, optarg);
1238 appl_args->appl_mode = APPL_MODE_DROP;
1240 appl_args->appl_mode = APPL_MODE_REPLY;
1243 if (parse_policy_ci_pass_count(appl_args, optarg)) {
1249 appl_args->promisc_mode = 1;
1252 appl_args->verbose = 1;
1258 appl_args->classifier_enable = atoi(optarg);
1261 appl_args->parse_layer = atoi(optarg);
1264 appl_args->cos_pools = atoi(optarg);
1267 appl_args->pool_size = atoi(optarg);
1270 appl_args->burst_size = atoi(optarg);
1280 if (appl_args->if_name == NULL)
1285 free(appl_args->if_name);
1297 static void print_info(
char *progname, appl_args_t *appl_args)
1301 printf(
"Running ODP appl: \"%s\"\n"
1302 "-----------------\n"
1304 progname, appl_args->if_name);
1305 printf(
"Promisc mode: %s\n", appl_args->promisc_mode ?
"enabled" :
"disabled");
1313 static void usage(
void)
1316 "ODP Classifier example.\n"
1317 "Usage: odp_classifier OPTIONS\n"
1318 " E.g. odp_classifier -i eth1 -m 0 -p \"ODP_PMR_SIP_ADDR:10.10.10.0:0xFFFFFF00:queue1\" \\\n"
1319 " -p \"ODP_PMR_SIP_ADDR:10.10.10.10:0xFFFFFFFF:queue1:queue2\"\n"
1321 "The above example would classify:\n"
1322 " 1) Packets from source IP address 10.10.10.0/24 to queue1, except ...\n"
1323 " 2) Packets from source IP address 10.10.10.10 to queue2\n"
1324 " 3) All other packets to DefaultCos\n"
1326 "Mandatory OPTIONS:\n"
1327 " -i, --interface <interface name>\n"
1329 "Optional OPTIONS\n"
1330 " -p, --policy <PMR term>:<offset>:<value>:<mask>:<src queue>:<dst queue>\n"
1332 " <PMR term> PMR term name defined in odp_cls_pmr_term_t\n"
1333 " <offset> If term is ODP_PMR_CUSTOM_FRAME or _CUSTOM_L3, offset in bytes is used\n"
1334 " <value> PMR value to be matched\n"
1335 " <mask> PMR mask bits to be applied on the PMR value.\n"
1336 " CUSTOM PMR terms accept plain hex string, other PMR terms require\n"
1337 " hex string with '0x' prefix.\n"
1338 " <src queue> Optional name of the source queue (CoS). The default CoS is used when\n"
1339 " this is not defined.\n"
1340 " <dst queue> Name of the destination queue (CoS).\n"
1342 " -c, --count <num> CPU count, 0=all available, default=1\n"
1344 " -m, --mode <mode> 0: Packet Drop mode. Received packets will be dropped\n"
1345 " !0: Echo mode. Received packets will be sent back\n"
1346 " default: Packet Drop mode\n"
1348 " -t, --time <sec> !0: Time for which the classifier will be run in seconds\n"
1349 " 0: Runs in infinite loop\n"
1350 " default: Runs in infinite loop\n"
1352 " -e, --enable <enable> 0: Classifier is disabled\n"
1353 " 1: Classifier is enabled\n"
1354 " default: Classifier is enabled\n"
1356 " -l, --layer <layer> Parse packets up to and including this layer. See odp_proto_layer_t\n"
1357 " default: ODP_PROTO_LAYER_ALL\n"
1359 " -d, --dedicated <enable> 0: One pool for pktio and all CoSes\n"
1360 " 1: Dedicated pools for pktio and each CoS\n"
1361 " default: Dedicated pools\n"
1363 " -s, --size <num> Number of packets in each packet pool\n"
1366 " -b, --burst <num> Packet burst size\n"
1369 " -C, --ci_pass <dst queue:count>\n"
1370 " Minimum acceptable packet count for a CoS destination queue.\n"
1371 " If the received packet count is smaller than this value,\n"
1372 " the application will exit with an error.\n"
1373 " E.g: -C \"queue1:100\" -C \"queue2:200\" -C \"DefaultQueue:100\"\n"
1374 " -P, --promisc_mode Enable promiscuous mode.\n"
1375 " -v, --verbose Verbose output.\n"
1376 " -h, --help Display help and exit.\n"
1377 "\n", SHM_PKT_POOL_SIZE, DEF_PKT_BURST);
void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
Initialize atomic uint64 variable.
void odp_atomic_inc_u64(odp_atomic_u64_t *atom)
Increment atomic uint64 variable.
void odp_atomic_add_u64(odp_atomic_u64_t *atom, uint64_t val)
Add to atomic uint64 variable.
uint64_t odp_atomic_load_u64(odp_atomic_u64_t *atom)
Load value of atomic uint64 variable.
#define ODP_COS_NAME_LEN
Maximum class of service name length, including the null character.
int odp_cos_destroy(odp_cos_t cos)
Discard a class-of-service along with all its associated resources.
odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms, odp_cos_t src_cos, odp_cos_t dst_cos)
Create Packet Matching Rule (PMR)
odp_cls_pmr_term_t
Packet Matching Rule terms.
#define ODP_PMR_INVALID
Invalid packet matching rule handle.
void odp_cls_print_all(void)
Print classifier info.
int odp_cls_pmr_destroy(odp_pmr_t pmr)
Function to destroy a packet match rule.
#define ODP_COS_INVALID
Invalid class of service handle.
odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param)
Create a class-of-service.
void odp_cls_cos_param_init(odp_cls_cos_param_t *param)
Initialize class of service parameters.
void odp_cls_pmr_param_init(odp_pmr_param_t *param)
Initialize packet matching rule parameters.
@ ODP_PMR_TCP_DPORT
Destination TCP port (val_sz = 2)
@ ODP_PMR_ETHTYPE_0
Initial (outer) Ethertype only (val_sz = 2)
@ ODP_PMR_SIP_ADDR
Source IPv4 address (val_sz = 4)
@ ODP_PMR_DIP_ADDR
Destination IPv4 address (val_sz = 4)
@ ODP_PMR_TCP_SPORT
Source TCP port (val_sz = 2)
@ ODP_PMR_VLAN_ID_X
Last (most inner) VLAN ID (val_sz = 2)
@ ODP_PMR_CUSTOM_FRAME
Custom frame match rule.
@ ODP_PMR_UDP_SPORT
Source UDP port (val_sz = 2)
@ ODP_PMR_VLAN_ID_0
First (outer) VLAN ID (val_sz = 2)
@ ODP_PMR_UDP_DPORT
Destination UDP port (val_sz = 2)
@ ODP_PMR_DMAC
Destination MAC address (val_sz = 6)
@ ODP_PMR_ETHTYPE_X
Ethertype of most inner VLAN tag (val_sz = 2)
@ ODP_PMR_CUSTOM_L3
Custom layer 3 match rule.
#define odp_unlikely(x)
Branch unlikely taken.
uint32_t odp_u32be_t
unsigned 32bit big endian
odp_u16be_t odp_cpu_to_be_16(uint16_t cpu16)
Convert cpu native uint16_t to 16bit big endian.
odp_u32be_t odp_cpu_to_be_32(uint32_t cpu32)
Convert cpu native uint32_t to 32bit big endian.
int odp_cpumask_default_worker(odp_cpumask_t *mask, int num)
Default CPU mask for worker threads.
int odp_cpumask_first(const odp_cpumask_t *mask)
Find first set CPU in mask.
int32_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int32_t size)
Format a string from CPU mask.
#define ODP_CPUMASK_STR_SIZE
The maximum number of characters needed to record any CPU mask as a string (output of odp_cpumask_to_...
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.
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.
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.
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.
uint64_t odp_pktio_to_u64(odp_pktio_t pktio)
Get printable value for an odp_pktio_t.
int odp_pktio_default_cos_set(odp_pktio_t pktio, odp_cos_t default_cos)
Setup per-port default class-of-service.
int odp_pktin_queue_config(odp_pktio_t pktio, const odp_pktin_queue_param_t *param)
Configure packet input queues.
int odp_pktout_queue_config(odp_pktio_t pktio, const odp_pktout_queue_param_t *param)
Configure packet output queues.
@ ODP_PKTIN_MODE_SCHED
Packet input through scheduler and scheduled event queues.
void odp_packet_print_data(odp_packet_t pkt, uint32_t offset, uint32_t len)
Print packet data.
void odp_packet_from_event_multi(odp_packet_t pkt[], const odp_event_t ev[], int num)
Convert multiple packet events to packet handles.
int odp_packet_has_ipv4(odp_packet_t pkt)
Check for IPv4.
int odp_packet_has_eth(odp_packet_t pkt)
Check for Ethernet header.
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.
void odp_packet_free(odp_packet_t pkt)
Free packet.
void * odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
Layer 2 start pointer.
void * odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
Layer 3 start pointer.
void odp_packet_free_multi(const odp_packet_t pkt[], int num)
Free multiple packets.
odp_pool_t odp_packet_pool(odp_packet_t pkt)
Packet pool.
@ ODP_PROTO_LAYER_ALL
All layers.
#define ODP_POOL_NAME_LEN
Maximum pool name length, including the null character.
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_all(void)
Print debug info about all pools.
#define ODP_POOL_INVALID
Invalid pool.
@ ODP_POOL_PACKET
Packet pool.
void odp_queue_param_init(odp_queue_param_t *param)
Initialize queue params.
#define ODP_QUEUE_INVALID
Invalid 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.
int odp_queue_info(odp_queue_t queue, odp_queue_info_t *info)
Retrieve information about a 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.
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.
#define ODP_SCHED_GROUP_ALL
Group of all threads.
int odp_shm_free(odp_shm_t shm)
Free a contiguous block of shared memory.
#define ODP_SHM_INVALID
Invalid shared memory block.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags)
Reserve a contiguous block of shared memory.
void odp_sys_info_print(void)
Print system info.
int odp_thread_id(void)
Get thread identifier.
@ ODP_THREAD_WORKER
Worker thread.
@ ODP_THREAD_CONTROL
Control thread.
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.
Dummy type for strong typing.
Class of service parameters Used to communicate class of service creation options.
odp_queue_t queue
Mapping used when num_queue = 1, hashing is disabled in this case and application has to configure th...
odp_pool_t pool
Pool associated with CoS.
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
Packet input queue parameters.
odp_bool_t classifier_enable
Enable classifier.
odp_pktio_set_op_t set_op
Supported set operations.
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.
uint32_t num_queues
Number of output queues to be created.
Packet Matching Rule parameter structure.
uint32_t offset
Offset to the value.
uint32_t val_sz
Size of the value to be matched.
struct odp_pmr_param_t::@8::@10 match
Parameters for single-valued matches.
odp_cls_pmr_term_t term
Packet Matching Rule term.
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.
Queue information Retrieve information about a queue with odp_queue_info()
const char * name
queue name
odp_schedule_param_t sched
Scheduler parameters.
odp_queue_type_t type
Queue type.
odp_schedule_group_t group
Thread group.
odp_schedule_sync_t sync
Synchronization method.
struct odp_pktio_set_op_t::@104 op
Operation flags.
uint32_t promisc_mode
Promiscuous mode.