27 #include <odp/helper/odph_api.h>
28 #include <libconfig.h>
30 #define PROG_NAME "odp_ipsecfwd"
31 #define SHORT_PROG_NAME "ipsfwd"
37 #define MAX_SPIS (UINT16_MAX + 1U)
38 #define MAX_WORKERS (ODP_THREAD_COUNT_MAX - 1)
39 #define MAX_QUEUES 64U
40 #define MAX_SA_QUEUES 1024U
41 #define PKT_SIZE 1024U
42 #define PKT_CNT 32768U
45 #define IP_ADDR_LEN 32U
47 #define ALG_ENTRY(_alg_name, _type) \
72 typedef struct pktio_s pktio_t;
74 typedef struct pktio_s {
81 odph_ethaddr_t src_mac;
84 uint32_t (*send_fn)(
const pktio_t *pktio, uint8_t index,
odp_packet_t pkts[],
int num);
92 odph_ethaddr_t dst_mac;
97 fwd_entry_t entries[MAX_FWDS];
102 uint64_t ipsec_in_pkts;
103 uint64_t ipsec_out_pkts;
104 uint64_t ipsec_in_errs;
105 uint64_t ipsec_out_errs;
106 uint64_t status_errs;
111 typedef struct prog_config_s prog_config_t;
115 prog_config_t *prog_config;
122 char cipher_key[65U];
123 char cipher_key_extra[5U];
125 char auth_key_extra[5U];
131 typedef uint32_t (*rx_fn_t)(thread_config_t *config,
odp_event_t evs[],
int num);
132 typedef void (*ipsec_fn_t)(
odp_packet_t pkts[],
int num, lookup_table_t *fwd_tbl, stats_t *stats);
133 typedef void (*drain_fn_t)(prog_config_t *config);
142 typedef struct prog_config_s {
143 odph_thread_t thread_tbl[MAX_WORKERS];
144 thread_config_t thread_config[MAX_WORKERS];
147 pktio_t pktios[MAX_IFS];
148 lookup_table_t fwd_tbl;
150 sa_config_t default_cfg;
158 uint32_t num_input_qs;
160 uint32_t num_output_qs;
179 const pktio_t *pktio;
184 pkt_vec_t vecs[MAX_QUEUES];
189 pkt_out_t ifs[MAX_IFS];
194 static const exposed_alg_t exposed_algs[] = {
221 static const int ipsec_out_mark;
222 static __thread pkt_ifs_t ifs;
223 static prog_config_t *prog_conf;
225 static void init_config(prog_config_t *config)
227 memset(config, 0,
sizeof(*config));
231 config->num_input_qs = 1;
232 config->num_sa_qs = 1;
233 config->num_output_qs = 1;
234 config->num_thrs = 1;
242 static void parse_interfaces(prog_config_t *config,
const char *optarg)
244 char *tmp_str = strdup(optarg), *tmp;
249 tmp = strtok(tmp_str, DELIMITER);
251 while (tmp && config->num_ifs < MAX_IFS) {
252 config->pktios[config->num_ifs].name = strdup(tmp);
254 if (config->pktios[config->num_ifs].name != NULL)
257 tmp = strtok(NULL, DELIMITER);
266 const size_t len = ODPH_ARRAY_SIZE(exposed_algs);
268 printf(
" Cipher algorithms:\n");
270 for (
size_t i = 0U; i < len; ++i) {
271 if ((exposed_algs[i].type == CIPHER_TYPE ||
272 exposed_algs[i].type == COMB_CIPHER_TYPE) &&
280 exposed_algs[i].idx, exposed_algs[i].name);
281 printf(exposed_algs[i].type == COMB_CIPHER_TYPE ?
" (combined)" :
"");
287 for (
int j = 0; j < c_cnt; ++j)
288 printf(j == 0 ?
" (key lengths: %u" :
", %u", capa[j].key_len);
294 printf(
" Authentication algorithms:\n");
296 for (
size_t i = 0U; i < len; ++i) {
297 if ((exposed_algs[i].type == AUTH_TYPE ||
298 exposed_algs[i].type == COMB_AUTH_TYPE) &&
299 (ipsec_capa->
auths.
all_bits & (1 << exposed_algs[i].idx)) > 0U) {
306 exposed_algs[i].idx, exposed_algs[i].name);
307 printf(exposed_algs[i].type == COMB_AUTH_TYPE ?
" (combined)" :
"");
313 for (
int j = 0; j < a_cnt; ++j)
314 printf(j == 0 ?
" (key/icv lengths: %u/%u" :
", %u/%u",
315 capa[j].key_len, capa[j].icv_len);
322 static void print_usage(
void)
328 ODPH_ERR(
"Error querying pool capabilities\n");
333 ODPH_ERR(
"Error querying IPsec capabilities\n");
338 "Simple IPsec performance tester. Forward and process plain and IPsec packets.\n"
340 "Usage: %s OPTIONS\n"
342 " E.g. %s -i ens9f1 -C /etc/odp/ipsecfwd.conf\n"
344 " With ipsecfwd.conf containing, for example:\n"
351 " cipher_key = \"jWnZr4t7w!zwC*F-\"\n"
353 " auth_key = \"n2r5u7x!A%%D*\"\n"
363 " src_addr = \"192.168.1.10\"\n"
364 " dst_addr = \"192.168.1.16\"\n"
372 " src_addr = \"192.168.3.110\"\n"
373 " dst_addr = \"192.168.3.116\"\n"
381 " prefix: \"192.168.1.0/24\"\n"
383 " dst_mac: \"00:00:05:00:07:00\"\n"
386 " prefix: \"192.1.0.0/16\"\n"
388 " dst_mac: \"00:00:05:00:08:00\"\n"
392 "Mandatory OPTIONS:\n"
394 " -i, --interfaces Ethernet interfaces for packet I/O, comma-separated,\n"
396 " -C, --conf Configuration file. 'libconfig' syntax is expected.\n"
397 " SA configuration supports default fallback, i.e.\n"
398 " individual SA configuration blocks may omit some\n"
399 " parameters and instead set these once in default block\n"
400 " which then are used to fill missing parameters. The only\n"
401 " required argument for an SA is the 'spi' parameter.\n"
402 " Individual SA parameter blocks are expected to be in\n"
403 " 'sa'-named list. Parameter naming follows API\n"
404 " specification, see 'odp_ipsec_sa_param_t' for parameter\n"
405 " names and hierarchy. Traffic is mapped to SAs based on UDP\n"
406 " port: the port is used as the SPI. For forwarding entries,\n"
407 " individual parameter blocks are similarly expected to be\n"
408 " in 'fwd'-named list. With forwarding entries, every\n"
409 " parameter is always required and interfaces present in\n"
410 " forwarding entries should be one of the interfaces passed\n"
411 " with '--interfaces' option. The entries are looked up\n"
412 " in the order they are in the list. See example above for\n"
413 " potential SA and forwarding configuration.\n"
415 " Supported cipher and authentication algorithms for SAs:\n",
416 PROG_NAME, PROG_NAME);
417 print_supported_algos(&ipsec_capa);
419 "Optional OPTIONS:\n"
421 " -n, --num_pkts Number of packet buffers allocated for packet I/O pool.\n"
423 " -l, --pkt_len Maximum size of packet buffers in packet I/O pool. %u by\n"
425 " -c, --count Worker thread count. 1 by default.\n"
426 " -m, --mode Queueing mode.\n"
427 " 0: ordered (default)\n"
429 " -I, --num_input_qs Input queue count. 1 by default.\n"
430 " -S, --num_sa_qs SA queue count. 1 by default.\n"
431 " -O, --num_output_qs Output queue count. 1 by default.\n"
432 " -d, --direct_rx Use direct RX. Interfaces will be polled by workers\n"
433 " directly. '--mode', '--num_input_qs' and '--num_output_qs'\n"
434 " options are ignored, input and output queue counts will\n"
435 " match worker count.\n"
436 " -h, --help This help.\n"
455 return spi <= UINT16_MAX ? spi_to_sa_map[DIR_IN][spi] : NULL;
461 int left, sent = 0, ret;
463 memset(¶m, 0,
sizeof(param));
465 for (
int i = 0; i < num; ++i)
471 param.
sa = &sas[sent];
496 return dst_port ? spi_to_sa_map[DIR_OUT][dst_port] : NULL;
502 int left, sent = 0, ret;
504 memset(¶m, 0,
sizeof(param));
506 for (
int i = 0; i < num; ++i)
512 param.
sa = &sas[sent];
524 static inline const fwd_entry_t *get_fwd_entry(lookup_table_t *table, uint32_t ip)
528 for (uint32_t i = 0U; i < table->num; ++i) {
529 entry = &table->entries[i];
531 if ((ip & entry->mask) == entry->prefix)
538 static inline const pktio_t *lookup_and_apply(
odp_packet_t pkt, lookup_table_t *fwd_tbl,
543 uint32_t dst_ip, src_ip;
544 const fwd_entry_t *fwd;
551 fwd = get_fwd_entry(fwd_tbl, dst_ip);
556 if (l3_off != ODPH_ETHHDR_LEN) {
557 if (l3_off > ODPH_ETHHDR_LEN) {
566 eth.dst = fwd->dst_mac;
567 eth.src = fwd->pktio->src_mac;
575 *q_idx = (src_ip ^ dst_ip) % fwd->pktio->num_tx_qs;
581 static inline uint32_t forward_packets(
odp_packet_t pkts[],
int num, lookup_table_t *fwd_tbl)
585 uint8_t q_idx = is_hashed_tx ? 0U : ifs.q_idx, qs_done;
586 uint8_t *q_idx_ptr = is_hashed_tx ? &q_idx : NULL;
587 const pktio_t *pktio;
590 uint32_t num_procd = 0U, ret;
592 for (
int i = 0; i < num; ++i) {
594 pktio = lookup_and_apply(pkt, fwd_tbl, q_idx_ptr);
601 out = &ifs.ifs[pktio->idx];
602 vec = &out->vecs[q_idx];
607 vec->pkts[vec->num++] = pkt;
611 for (uint32_t i = 0U; i < MAX_IFS; ++i) {
615 for (uint32_t j = 0U; j < MAX_QUEUES && qs_done < out->num_qs; ++j) {
616 if (out->vecs[j].num == 0U)
621 ret = pktio->send_fn(pktio, j, vec->pkts, vec->num);
637 static inline void process_packets_out_enq(
odp_packet_t pkts[],
int num, lookup_table_t *fwd_tbl,
640 odp_packet_t pkt, pkts_ips[MAX_BURST], pkts_fwd[MAX_BURST];
642 int num_pkts_ips = 0, num_pkts_fwd = 0, num_procd;
644 for (
int i = 0; i < num; ++i) {
646 sa = get_out_sa(pkt);
649 sas[num_pkts_ips] = *sa;
650 pkts_ips[num_pkts_ips] = pkt;
653 pkts_fwd[num_pkts_fwd++] = pkt;
657 if (num_pkts_ips > 0) {
658 num_procd = process_ipsec_out_enq(pkts_ips, sas, num_pkts_ips);
661 stats->ipsec_out_errs += num_pkts_ips - num_procd;
666 if (num_pkts_fwd > 0) {
667 num_procd = forward_packets(pkts_fwd, num_pkts_fwd, fwd_tbl);
668 stats->discards += num_pkts_fwd - num_procd;
669 stats->fwd_pkts += num_procd;
673 static void process_packets_in_enq(
odp_packet_t pkts[],
int num, lookup_table_t *fwd_tbl,
676 odp_packet_t pkt, pkts_ips[MAX_BURST], pkts_out[MAX_BURST];
678 int num_pkts_ips = 0, num_pkts_out = 0, num_procd;
680 for (
int i = 0; i < num; ++i) {
692 sas[num_pkts_ips] = *sa;
693 pkts_ips[num_pkts_ips] = pkt;
696 pkts_out[num_pkts_out++] = pkt;
700 if (num_pkts_ips > 0) {
701 num_procd = process_ipsec_in_enq(pkts_ips, sas, num_pkts_ips);
704 stats->ipsec_in_errs += num_pkts_ips - num_procd;
709 if (num_pkts_out > 0)
710 process_packets_out_enq(pkts_out, num_pkts_out, fwd_tbl, stats);
718 static void complete_ipsec_ops(
odp_packet_t pkts[],
int num, lookup_table_t *fwd_tbl,
721 odp_packet_t pkt, pkts_out[MAX_BURST], pkts_fwd[MAX_BURST];
724 int num_pkts_out = 0, num_pkts_fwd = 0, num_procd;
726 for (
int i = 0; i < num; ++i) {
728 is_in = is_ipsec_in(pkt);
731 is_in ? ++stats->ipsec_in_errs : ++stats->ipsec_out_errs;
737 is_in ? ++stats->ipsec_in_errs : ++stats->ipsec_out_errs;
743 ++stats->ipsec_in_pkts;
744 pkts_out[num_pkts_out++] = pkt;
746 ++stats->ipsec_out_pkts;
747 pkts_fwd[num_pkts_fwd++] = pkt;
751 if (num_pkts_out > 0)
752 process_packets_out_enq(pkts_out, num_pkts_out, fwd_tbl, stats);
754 if (num_pkts_fwd > 0) {
755 num_procd = forward_packets(pkts_fwd, num_pkts_fwd, fwd_tbl);
756 stats->discards += num_pkts_fwd - num_procd;
757 stats->fwd_pkts += num_procd;
761 static void drain_scheduler(prog_config_t *config
ODP_UNUSED)
779 int left, sent = 0, num_out, ret;
781 memset(¶m, 0,
sizeof(param));
787 param.
sa = &sas[sent];
788 ret =
odp_ipsec_in(&pkts[sent], left, &pkts_out[sent], &num_out, ¶m);
803 int left, sent = 0, num_out, ret;
805 memset(¶m, 0,
sizeof(param));
811 param.
sa = &sas[sent];
812 ret =
odp_ipsec_out(&pkts[sent], left, &pkts_out[sent], &num_out, ¶m);
823 static inline void process_packets_out(
odp_packet_t pkts[],
int num, lookup_table_t *fwd_tbl,
826 odp_packet_t pkt, pkts_ips[MAX_BURST], pkts_fwd[MAX_BURST], pkts_ips_out[MAX_BURST];
828 int num_pkts_ips = 0, num_pkts_fwd = 0, num_procd;
831 for (
int i = 0; i < num; ++i) {
833 sa = get_out_sa(pkt);
836 sas[num_pkts_ips] = *sa;
837 pkts_ips[num_pkts_ips] = pkt;
840 pkts_fwd[num_pkts_fwd++] = pkt;
844 if (num_pkts_ips > 0) {
845 num_procd = process_ipsec_out(pkts_ips, sas, num_pkts_ips, pkts_ips_out);
848 stats->ipsec_out_errs += num_pkts_ips - num_procd;
852 for (
int i = 0; i < num_procd; ++i) {
853 pkt = pkts_ips_out[i];
856 ++stats->ipsec_out_errs;
862 ++stats->ipsec_out_errs;
867 ++stats->ipsec_out_pkts;
868 pkts_fwd[num_pkts_fwd++] = pkt;
872 if (num_pkts_fwd > 0) {
873 num_procd = forward_packets(pkts_fwd, num_pkts_fwd, fwd_tbl);
874 stats->discards += num_pkts_fwd - num_procd;
875 stats->fwd_pkts += num_procd;
879 static void process_packets_in(
odp_packet_t pkts[],
int num, lookup_table_t *fwd_tbl,
882 odp_packet_t pkt, pkts_ips[MAX_BURST], pkts_out[MAX_BURST], pkts_ips_out[MAX_BURST];
884 int num_pkts_ips = 0, num_pkts_out = 0, num_procd;
887 for (
int i = 0; i < num; ++i) {
899 sas[num_pkts_ips] = *sa;
900 pkts_ips[num_pkts_ips] = pkt;
903 pkts_out[num_pkts_out++] = pkt;
907 if (num_pkts_ips > 0) {
908 num_procd = process_ipsec_in(pkts_ips, sas, num_pkts_ips, pkts_ips_out);
911 stats->ipsec_in_errs += num_pkts_ips - num_procd;
915 for (
int i = 0; i < num_procd; ++i) {
916 pkt = pkts_ips_out[i];
919 ++stats->ipsec_in_errs;
925 ++stats->ipsec_in_errs;
930 ++stats->ipsec_in_pkts;
931 pkts_out[num_pkts_out++] = pkt;
935 if (num_pkts_out > 0)
936 process_packets_out(pkts_out, num_pkts_out, fwd_tbl, stats);
939 static void drain_direct_inputs(prog_config_t *config)
943 for (uint32_t i = 0U; i < config->num_ifs; ++i) {
944 for (uint32_t j = 0U; j < config->num_input_qs; ++j) {
945 while (
odp_pktin_recv(config->pktios[i].in_dir_qs[j], &pkt, 1) == 1)
951 static odp_bool_t setup_ipsec(prog_config_t *config)
957 if (!config->is_dir_rx) {
958 snprintf(q_name,
sizeof(q_name), SHORT_PROG_NAME
"_sa_status");
967 ODPH_ERR(
"Error creating IPsec completion queue\n");
974 if (!config->is_dir_rx) {
977 config->ops.proc = process_packets_in_enq;
978 config->ops.compl = complete_ipsec_ops;
979 config->ops.drain = drain_scheduler;
983 config->ops.proc = process_packets_in;
984 config->ops.compl = NULL;
985 config->ops.drain = drain_direct_inputs;
993 ODPH_ERR(
"Error configuring IPsec\n");
1001 prog_config_t *config)
1004 const uint32_t max_sa_qs = ODPH_MIN(MAX_SA_QUEUES, ipsec_capa->
max_queues);
1006 if (config->num_sa_qs == 0U || config->num_sa_qs > max_sa_qs) {
1007 ODPH_ERR(
"Invalid number of SA queues: %u (min: 1, max: %u)\n", config->num_sa_qs,
1009 config->num_sa_qs = 0U;
1013 for (uint32_t i = 0U; i < config->num_sa_qs; ++i) {
1016 snprintf(q_name,
sizeof(q_name), SHORT_PROG_NAME
"_sa_compl_%u", i);
1026 ODPH_ERR(
"Error creating SA destination queue (created count: %u)\n", i);
1027 config->num_sa_qs = i;
1035 static void parse_crypto(config_setting_t *cfg, sa_config_t *config)
1038 const char *val_str;
1039 config_setting_t *cs = config_setting_lookup(cfg,
"crypto");
1044 if (config_setting_lookup_int(cs,
"cipher_alg", &val) == CONFIG_TRUE)
1045 config->sa_param.crypto.cipher_alg = val;
1047 if (config_setting_lookup_string(cs,
"cipher_key", &val_str) == CONFIG_TRUE) {
1048 strcpy(config->cipher_key, val_str);
1049 config->sa_param.crypto.cipher_key.data = (uint8_t *)config->cipher_key;
1050 config->sa_param.crypto.cipher_key.length =
1051 strlen((
const char *)config->cipher_key);
1054 if (config_setting_lookup_string(cs,
"cipher_key_extra", &val_str) == CONFIG_TRUE) {
1055 strcpy(config->cipher_key_extra, val_str);
1056 config->sa_param.crypto.cipher_key_extra.data =
1057 (uint8_t *)config->cipher_key_extra;
1058 config->sa_param.crypto.cipher_key_extra.length =
1059 strlen((
const char *)config->cipher_key_extra);
1062 if (config_setting_lookup_int(cs,
"auth_alg", &val) == CONFIG_TRUE)
1063 config->sa_param.crypto.auth_alg = val;
1065 if (config_setting_lookup_string(cs,
"auth_key", &val_str) == CONFIG_TRUE) {
1066 strcpy(config->auth_key, val_str);
1067 config->sa_param.crypto.auth_key.data = (uint8_t *)config->auth_key;
1068 config->sa_param.crypto.auth_key.length = strlen((
const char *)config->auth_key);
1071 if (config_setting_lookup_string(cs,
"auth_key_extra", &val_str) == CONFIG_TRUE) {
1072 strcpy(config->auth_key_extra, val_str);
1073 config->sa_param.crypto.auth_key_extra.data = (uint8_t *)config->auth_key_extra;
1074 config->sa_param.crypto.auth_key_extra.length =
1075 strlen((
const char *)config->auth_key_extra);
1078 if (config_setting_lookup_int(cs,
"icv_len", &val) == CONFIG_TRUE)
1079 config->sa_param.crypto.icv_len = val;
1082 static void parse_opt(config_setting_t *cfg, sa_config_t *config)
1085 config_setting_t *cs = config_setting_lookup(cfg,
"opt");
1090 if (config_setting_lookup_int(cs,
"esn", &val) == CONFIG_TRUE)
1091 config->sa_param.opt.esn = val;
1093 if (config_setting_lookup_int(cs,
"udp_encap", &val) == CONFIG_TRUE)
1094 config->sa_param.opt.udp_encap = val;
1096 if (config_setting_lookup_int(cs,
"copy_dscp", &val) == CONFIG_TRUE)
1097 config->sa_param.opt.copy_dscp = val;
1099 if (config_setting_lookup_int(cs,
"copy_flabel", &val) == CONFIG_TRUE)
1100 config->sa_param.opt.copy_flabel = val;
1102 if (config_setting_lookup_int(cs,
"copy_df", &val) == CONFIG_TRUE)
1103 config->sa_param.opt.copy_df = val;
1105 if (config_setting_lookup_int(cs,
"dec_ttl", &val) == CONFIG_TRUE)
1106 config->sa_param.opt.dec_ttl = val;
1109 static void parse_limits(config_setting_t *cfg, sa_config_t *config)
1111 config_setting_t *cs = config_setting_lookup(cfg,
"lifetime"), *soft, *hard;
1117 soft = config_setting_lookup(cs,
"soft_limit");
1118 hard = config_setting_lookup(cs,
"hard_limit");
1121 if (config_setting_lookup_int64(soft,
"bytes", &val) == CONFIG_TRUE)
1122 config->sa_param.lifetime.soft_limit.bytes = val;
1124 if (config_setting_lookup_int64(soft,
"packets", &val) == CONFIG_TRUE)
1125 config->sa_param.lifetime.soft_limit.packets = val;
1129 if (config_setting_lookup_int64(hard,
"bytes", &val) == CONFIG_TRUE)
1130 config->sa_param.lifetime.hard_limit.bytes = val;
1132 if (config_setting_lookup_int64(hard,
"packets", &val) == CONFIG_TRUE)
1133 config->sa_param.lifetime.hard_limit.packets = val;
1137 static void parse_inbound(config_setting_t *cfg, sa_config_t *config)
1139 config_setting_t *cs = config_setting_lookup(cfg,
"inbound");
1141 const char *val_str;
1146 if (config_setting_lookup_int(cs,
"lookup_mode", &val) == CONFIG_TRUE)
1147 config->sa_param.inbound.lookup_mode = val;
1149 if (config_setting_lookup_string(cs,
"lookup_dst_addr", &val_str) == CONFIG_TRUE) {
1150 if (odph_ipv4_addr_parse(&config->lkp_dst_ip, val_str) == 0) {
1152 config->sa_param.inbound.lookup_param.dst_addr = &config->lkp_dst_ip;
1156 if (config_setting_lookup_int(cs,
"antireplay_ws", &val) == CONFIG_TRUE)
1157 config->sa_param.inbound.antireplay_ws = val;
1159 if (config_setting_lookup_int(cs,
"reassembly_en", &val) == CONFIG_TRUE)
1160 config->sa_param.inbound.reassembly_en = val;
1163 static void parse_outbound(config_setting_t *cfg, sa_config_t *config)
1165 config_setting_t *cs = config_setting_lookup(cfg,
"outbound"), *tunnel;
1166 const char *val_str;
1172 tunnel = config_setting_lookup(cs,
"tunnel");
1174 if (tunnel != NULL) {
1175 if (config_setting_lookup_string(tunnel,
"src_addr", &val_str) == CONFIG_TRUE) {
1176 if (odph_ipv4_addr_parse(&config->src_ip, val_str) == 0) {
1178 config->sa_param.outbound.tunnel.ipv4.src_addr = &config->src_ip;
1182 if (config_setting_lookup_string(tunnel,
"dst_addr", &val_str) == CONFIG_TRUE) {
1183 if (odph_ipv4_addr_parse(&config->dst_ip, val_str) == 0) {
1185 config->sa_param.outbound.tunnel.ipv4.dst_addr = &config->dst_ip;
1189 if (config_setting_lookup_int(tunnel,
"dscp", &val) == CONFIG_TRUE)
1190 config->sa_param.outbound.tunnel.ipv4.dscp = val;
1192 if (config_setting_lookup_int(tunnel,
"df", &val) == CONFIG_TRUE)
1193 config->sa_param.outbound.tunnel.ipv4.df = val;
1195 if (config_setting_lookup_int(tunnel,
"ttl", &val) == CONFIG_TRUE)
1196 config->sa_param.outbound.tunnel.ipv4.ttl = val;
1199 if (config_setting_lookup_int(cs,
"frag_mode", &val) == CONFIG_TRUE)
1200 config->sa_param.outbound.frag_mode = val;
1202 if (config_setting_lookup_int(cs,
"mtu", &val) == CONFIG_TRUE)
1203 config->sa_param.outbound.mtu = val;
1206 static void parse_sa_entry(config_setting_t *cfg, sa_config_t *config)
1210 if (config_setting_lookup_int(cfg,
"dir", &val) == CONFIG_TRUE)
1211 config->sa_param.dir = val;
1213 if (config_setting_lookup_int(cfg,
"proto", &val) == CONFIG_TRUE)
1214 config->sa_param.proto = val;
1216 if (config_setting_lookup_int(cfg,
"mode", &val) == CONFIG_TRUE)
1217 config->sa_param.mode = val;
1219 if (config_setting_lookup_int(cfg,
"spi", &val) == CONFIG_TRUE)
1220 config->sa_param.spi = val;
1222 parse_crypto(cfg, config);
1223 parse_opt(cfg, config);
1224 parse_limits(cfg, config);
1225 parse_inbound(cfg, config);
1226 parse_outbound(cfg, config);
1230 uint32_t max_num_sa)
1232 uint32_t dir = sa_param->
dir;
1233 uint32_t spi = sa_param->
spi;
1236 if (config->num_sas == max_num_sa) {
1237 ODPH_ERR(
"Maximum number of SAs parsed (%u), ignoring rest\n", max_num_sa);
1241 if (spi > UINT16_MAX) {
1242 ODPH_ERR(
"Unsupported SPI value for SA %u (> %u)\n", spi, UINT16_MAX);
1246 if (spi_to_sa_map[dir][spi] != NULL) {
1247 ODPH_ERR(
"Non-unique SPIs not supported for SA %u\n", spi);
1251 sa_param->
dest_queue = config->sa_qs[config->num_sas % config->num_sa_qs];
1255 ODPH_ERR(
"Error creating SA handle for SA %u\n", spi);
1259 config->sas[config->num_sas] = sa;
1260 spi_to_sa_map[dir][spi] = &config->sas[config->num_sas];
1264 static void parse_and_create_sa_entries(config_t *cfg, prog_config_t *config, uint32_t max_num_sa)
1266 config_setting_t *cs;
1269 cs = config_lookup(cfg,
"default");
1272 parse_sa_entry(cs, &config->default_cfg);
1274 cs = config_lookup(cfg,
"sa");
1279 count = config_setting_length(cs);
1281 for (
int i = 0; i < count; i++) {
1283 config_setting_t *sa;
1286 sa_cfg = config->default_cfg;
1287 sa = config_setting_get_elem(cs, i);
1292 if (config_setting_lookup_int(sa,
"spi", &val) == CONFIG_TRUE) {
1293 parse_sa_entry(sa, &sa_cfg);
1294 create_sa_entry(&sa_cfg.sa_param, config, max_num_sa);
1299 static void parse_sas(config_t *cfg, prog_config_t *config)
1302 uint32_t max_num_sa;
1305 ODPH_ERR(
"Error querying IPsec capabilities\n");
1309 if (!setup_ipsec(config))
1312 if (!config->is_dir_rx && !create_sa_dest_queues(&ipsec_capa, config))
1315 max_num_sa = ODPH_MIN(MAX_SAS, ipsec_capa.
max_num_sa);
1316 parse_and_create_sa_entries(cfg, config, max_num_sa);
1319 static const pktio_t *get_pktio(
const char *iface,
const prog_config_t *config)
1321 for (uint32_t i = 0U; i < config->num_ifs; ++i) {
1322 if (strcmp(iface, config->pktios[i].name) == 0)
1323 return &config->pktios[i];
1329 static void create_fwd_table_entry(config_setting_t *cfg, prog_config_t *config)
1331 const char *val_str;
1332 char dst_ip_str[16U] = { 0 };
1333 uint32_t mask, dst_ip;
1334 odph_ethaddr_t dst_mac;
1335 const pktio_t *pktio = NULL;
1338 if (config->fwd_tbl.num == MAX_FWDS) {
1339 ODPH_ERR(
"Maximum number of forwarding entries parsed (%u), ignoring rest\n",
1344 if (config_setting_lookup_string(cfg,
"prefix", &val_str) == CONFIG_TRUE) {
1345 if (sscanf(val_str,
"%[^/]/%u", dst_ip_str, &mask) != 2) {
1346 ODPH_ERR(
"Error parsing IP and subnet mask for forwarding entry\n");
1350 if (odph_ipv4_addr_parse(&dst_ip, dst_ip_str) < 0) {
1351 ODPH_ERR(
"Syntax error in IP address for forwarding entry\n");
1355 if (mask > IP_ADDR_LEN) {
1356 ODPH_ERR(
"Invalid subnet mask for forwarding entry: %u\n", mask);
1363 if (config_setting_lookup_string(cfg,
"if", &val_str) == CONFIG_TRUE) {
1364 pktio = get_pktio(val_str, config);
1366 if (pktio == NULL) {
1367 ODPH_ERR(
"Error parsing next interface for forwarding entry\n");
1374 if (config_setting_lookup_string(cfg,
"dst_mac", &val_str) == CONFIG_TRUE) {
1375 if (odph_eth_addr_parse(&dst_mac, val_str) < 0) {
1376 ODPH_ERR(
"Syntax error in destination MAC for forwarding entry\n");
1383 mask = mask > 0U ? 0xFFFFFFFF << (IP_ADDR_LEN - mask) : 0U;
1384 entry = &config->fwd_tbl.entries[config->fwd_tbl.num];
1385 entry->prefix = dst_ip & mask;
1387 entry->dst_mac = dst_mac;
1388 entry->pktio = pktio;
1389 ++config->fwd_tbl.num;
1392 static void parse_fwd_table(config_t *cfg, prog_config_t *config)
1394 config_setting_t *cs;
1397 cs = config_lookup(cfg,
"fwd");
1402 count = config_setting_length(cs);
1404 for (
int i = 0; i < count; i++) {
1405 config_setting_t *fwd = config_setting_get_elem(cs, i);
1410 create_fwd_table_entry(fwd, config);
1414 static parse_result_t check_options(prog_config_t *config)
1419 ODPH_ERR(
"Error querying pool capabilities\n");
1423 if (config->num_ifs == 0U) {
1424 ODPH_ERR(
"Invalid number of interfaces: %u (min: 1, max: %u)\n", config->num_ifs,
1429 if (config->fwd_tbl.num == 0U) {
1430 ODPH_ERR(
"Invalid number of forwarding entries: %u (min: 1, max: %u)\n",
1431 config->fwd_tbl.num, MAX_FWDS);
1436 ODPH_ERR(
"Invalid pool packet count: %u (max: %u)\n", config->num_pkts,
1441 if (config->num_pkts == 0U)
1442 config->num_pkts = pool_capa.
pkt.
max_num > 0U ?
1443 ODPH_MIN(pool_capa.
pkt.
max_num, PKT_CNT) : PKT_CNT;
1446 ODPH_ERR(
"Invalid pool packet length: %u (max: %u)\n", config->pkt_len,
1451 if (config->pkt_len == 0U)
1452 config->pkt_len = pool_capa.
pkt.
max_len > 0U ?
1453 ODPH_MIN(pool_capa.
pkt.
max_len, PKT_SIZE) : PKT_SIZE;
1455 if (config->num_thrs <= 0 || config->num_thrs > MAX_WORKERS) {
1456 ODPH_ERR(
"Invalid thread count: %d (min: 1, max: %d)\n", config->num_thrs,
1461 if (config->is_dir_rx) {
1462 config->num_input_qs = config->num_thrs;
1463 config->num_output_qs = config->num_thrs;
1469 static parse_result_t parse_options(
int argc,
char **argv, prog_config_t *config)
1474 static const struct option longopts[] = {
1475 {
"interfaces", required_argument, NULL,
'i' },
1476 {
"num_pkts", required_argument, NULL,
'n' },
1477 {
"pkt_len", required_argument, NULL,
'l' },
1478 {
"count", required_argument, NULL,
'c' },
1479 {
"mode", required_argument, NULL,
'm' },
1480 {
"conf", required_argument, NULL,
'C' },
1481 {
"num_input_qs", required_argument, NULL,
'I' },
1482 {
"num_sa_qs", required_argument, NULL,
'S' },
1483 {
"num_output_qs", required_argument, NULL,
'O' },
1484 {
"direct_rx", no_argument, NULL,
'd' },
1485 {
"help", no_argument, NULL,
'h' },
1486 { NULL, 0, NULL, 0 }
1489 static const char *shortopts =
"i:n:l:c:m:C:I:S:O:dh";
1492 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
1499 parse_interfaces(config, optarg);
1502 config->num_pkts = atoi(optarg);
1505 config->pkt_len = atoi(optarg);
1508 config->num_thrs = atoi(optarg);
1511 config->mode = !!atoi(optarg);
1514 config->conf_file = strdup(optarg);
1517 config->num_input_qs = atoi(optarg);
1520 config->num_sa_qs = atoi(optarg);
1523 config->num_output_qs = atoi(optarg);
1526 config->is_dir_rx =
true;
1540 if (config_read_file(&cfg, config->conf_file) == CONFIG_FALSE) {
1541 ODPH_ERR(
"Error opening SA configuration file: %s\n", config_error_text(&cfg));
1542 config_destroy(&cfg);
1546 parse_sas(&cfg, config);
1547 parse_fwd_table(&cfg, config);
1548 config_destroy(&cfg);
1550 return check_options(config);
1553 static parse_result_t setup_program(
int argc,
char **argv, prog_config_t *config)
1555 struct sigaction action = { .sa_handler = terminate };
1557 if (sigemptyset(&action.sa_mask) == -1 || sigaddset(&action.sa_mask, SIGINT) == -1 ||
1558 sigaddset(&action.sa_mask, SIGTERM) == -1 ||
1559 sigaddset(&action.sa_mask, SIGHUP) == -1 || sigaction(SIGINT, &action, NULL) == -1 ||
1560 sigaction(SIGTERM, &action, NULL) == -1 || sigaction(SIGHUP, &action, NULL) == -1) {
1561 ODPH_ERR(
"Error installing signal handler\n");
1565 return parse_options(argc, argv, config);
1573 static uint32_t recv(thread_config_t *config,
odp_event_t evs[],
int num)
1575 prog_config_t *prog_config = config->prog_config;
1576 pktio_t *pktio = &prog_config->pktios[config->pktio++ % prog_config->num_ifs];
1577 odp_pktin_queue_t in_q = pktio->in_dir_qs[config->thr_idx % prog_config->num_input_qs];
1591 static uint32_t send(
const pktio_t *pktio, uint8_t index,
odp_packet_t pkts[],
int num)
1595 return ret < 0 ? 0U : (uint32_t)ret;
1598 static uint32_t enqueue(
const pktio_t *pktio, uint8_t index,
odp_packet_t pkts[],
int num)
1607 return ret < 0 ? 0U : (uint32_t)ret;
1610 static odp_bool_t setup_pktios(prog_config_t *config)
1619 uint32_t max_output_qs;
1623 pool_param.
pkt.
len = config->pkt_len;
1624 pool_param.
pkt.
num = config->num_pkts;
1629 ODPH_ERR(
"Error creating packet I/O pool\n");
1633 config->ops.rx = !config->is_dir_rx ? schedule : recv;
1634 config->is_hashed_tx = !config->is_dir_rx && config->mode == ORDERED;
1636 for (uint32_t i = 0U; i < config->num_ifs; ++i) {
1637 pktio = &config->pktios[i];
1640 pktio_param.
in_mode = !config->is_dir_rx ?
1642 pktio_param.
out_mode = config->is_hashed_tx ?
1644 pktio->handle =
odp_pktio_open(pktio->name, config->pktio_pool, &pktio_param);
1647 ODPH_ERR(
"Error opening packet I/O (%s)\n", pktio->name);
1652 ODPH_ERR(
"Error querying packet I/O capabilities (%s)\n", pktio->name);
1656 if (config->num_input_qs == 0U || config->num_input_qs > capa.
max_input_queues) {
1657 ODPH_ERR(
"Invalid number of input queues for packet I/O: %u (min: 1, max: "
1665 if (config->num_output_qs == 0U || config->num_output_qs > max_output_qs) {
1666 ODPH_ERR(
"Invalid number of output queues for packet I/O: %u (min: 1, "
1667 "max: %u) (%s)\n", config->num_output_qs, max_output_qs,
1674 if (config->is_hashed_tx)
1677 if (config->num_input_qs > 1U) {
1680 pktin_param.
num_queues = config->num_input_qs;
1683 pktin_param.
op_mode = (config->is_dir_rx &&
1684 config->num_thrs > (int)config->num_input_qs) ?
1688 ODPH_ERR(
"Error configuring packet I/O input queues (%s)\n", pktio->name);
1692 if (config->is_dir_rx) {
1693 if (
odp_pktin_queue(pktio->handle, pktio->in_dir_qs, config->num_input_qs)
1694 != (
int)config->num_input_qs) {
1695 ODPH_ERR(
"Error querying packet I/O input queue (%s)\n",
1701 pktio->send_fn = config->is_hashed_tx ? enqueue : send;
1702 pktio->num_tx_qs = config->num_output_qs;
1706 if (!config->is_hashed_tx) {
1707 pktout_param.
op_mode = config->num_thrs > (int)pktio->num_tx_qs ?
1712 ODPH_ERR(
"Error configuring packet I/O output queues (%s)\n", pktio->name);
1716 if (config->is_hashed_tx) {
1718 pktio->num_tx_qs) != (
int)pktio->num_tx_qs) {
1719 ODPH_ERR(
"Error querying packet I/O output event queue (%s)\n",
1725 != (
int)pktio->num_tx_qs) {
1726 ODPH_ERR(
"Error querying packet I/O output queue (%s)\n",
1735 ODPH_ERR(
"Error configuring packet I/O extra options (%s)\n", pktio->name);
1740 !=
sizeof(pktio->src_mac)) {
1741 ODPH_ERR(
"Error getting packet I/O MAC address (%s)\n", pktio->name);
1746 ODPH_ERR(
"Error starting packet I/O (%s)\n", pktio->name);
1754 static inline void check_ipsec_status_ev(
odp_event_t ev, stats_t *stats)
1759 ++stats->status_errs;
1764 static int process_packets(
void *args)
1766 thread_config_t *config = args;
1769 ops_t ops = config->prog_config->ops;
1774 odp_packet_t pkt, pkts_in[MAX_BURST], pkts_ips[MAX_BURST];
1775 lookup_table_t *fwd_tbl = &config->prog_config->fwd_tbl;
1776 stats_t *stats = &config->stats;
1778 ifs.is_hashed_tx = config->prog_config->is_hashed_tx;
1779 ifs.q_idx = thr_idx % config->prog_config->num_output_qs;
1780 config->thr_idx = thr_idx;
1784 int num_pkts_in = 0, num_pkts_ips = 0;
1786 cnt = ops.rx(config, evs, MAX_BURST);
1791 for (uint32_t i = 0U; i < cnt; ++i) {
1796 if (type == ODP_EVENT_PACKET) {
1797 if (subtype == ODP_EVENT_PACKET_BASIC) {
1798 pkts_in[num_pkts_in++] = pkt;
1799 }
else if (subtype == ODP_EVENT_PACKET_IPSEC) {
1800 pkts_ips[num_pkts_ips++] = pkt;
1805 }
else if (type == ODP_EVENT_IPSEC_STATUS) {
1806 check_ipsec_status_ev(ev, stats);
1813 if (num_pkts_in > 0)
1814 ops.proc(pkts_in, num_pkts_in, fwd_tbl, stats);
1816 if (ops.compl && num_pkts_ips > 0)
1817 ops.compl(pkts_ips, num_pkts_ips, fwd_tbl, stats);
1821 ops.drain(config->prog_config);
1826 static odp_bool_t setup_workers(prog_config_t *config)
1828 odph_thread_common_param_t thr_common;
1829 odph_thread_param_t thr_param[config->num_thrs];
1834 odph_thread_common_param_init(&thr_common);
1835 thr_common.instance = config->odp_instance;
1836 thr_common.cpumask = &cpumask;
1838 for (
int i = 0; i < config->num_thrs; ++i) {
1839 odph_thread_param_init(&thr_param[i]);
1840 thr_param[i].start = process_packets;
1842 config->thread_config[i].prog_config = config;
1843 thr_param[i].arg = &config->thread_config[i];
1846 num_workers = odph_thread_create(config->thread_tbl, &thr_common, thr_param, num_workers);
1848 if (num_workers != config->num_thrs) {
1849 ODPH_ERR(
"Error configuring worker threads\n");
1856 static odp_bool_t setup_test(prog_config_t *config)
1861 if (!setup_pktios(config))
1864 if (!setup_workers(config))
1872 static void stop_test(prog_config_t *config)
1874 for (uint32_t i = 0U; i < config->num_ifs; ++i)
1879 (void)odph_thread_join(config->thread_tbl, config->num_thrs);
1882 static void print_stats(
const prog_config_t *config)
1884 const stats_t *stats;
1886 printf(
"\n====================\n\n"
1887 "IPsec forwarder done\n\n"
1888 " configuration file: %s\n"
1889 " queuing mode: %s\n"
1890 " input queue count: %u\n"
1891 " SA queue count: %u\n"
1892 " output queue count: %u\n"
1893 " RX mode: %s\n", config->conf_file,
1894 config->mode == ORDERED ?
"ordered" :
"parallel", config->num_input_qs,
1895 config->num_sa_qs, config->num_output_qs,
1896 config->is_dir_rx ?
"direct" :
"scheduled");
1898 for (
int i = 0; i < config->num_thrs; ++i) {
1899 stats = &config->thread_config[i].stats;
1901 printf(
"\n worker %d:\n"
1902 " IPsec in packets: %" PRIu64
"\n"
1903 " IPsec out packets: %" PRIu64
"\n"
1904 " IPsec in packet errors: %" PRIu64
"\n"
1905 " IPsec out packet errors: %" PRIu64
"\n"
1906 " IPsec status errors: %" PRIu64
"\n"
1907 " packets forwarded: %" PRIu64
"\n"
1908 " packets dropped: %" PRIu64
"\n", i, stats->ipsec_in_pkts,
1909 stats->ipsec_out_pkts, stats->ipsec_in_errs, stats->ipsec_out_errs,
1910 stats->status_errs, stats->fwd_pkts, stats->discards);
1913 printf(
"\n====================\n");
1916 static void wait_sas_disabled(uint32_t num_sas)
1918 uint32_t num_sas_dis = 0U;
1922 while (num_sas_dis < num_sas) {
1945 static void teardown_test(
const prog_config_t *config)
1947 for (uint32_t i = 0U; i < config->num_ifs; ++i) {
1948 free(config->pktios[i].name);
1957 for (uint32_t i = 0U; i < config->num_sas; ++i)
1960 if (!config->is_dir_rx)
1962 wait_sas_disabled(config->num_sas);
1964 for (uint32_t i = 0U; i < config->num_sas; ++i)
1967 for (uint32_t i = 0U; i < config->num_sa_qs; ++i)
1973 free(config->conf_file);
1976 int main(
int argc,
char **argv)
1978 odph_helper_options_t odph_opts;
1982 parse_result_t parse_res;
1983 int ret = EXIT_SUCCESS;
1985 argc = odph_parse_options(argc, argv);
1987 if (odph_options(&odph_opts) == -1) {
1988 ODPH_ERR(
"Error while reading ODP helper options, exiting\n");
1993 init_param.
mem_model = odph_opts.mem_model;
1996 ODPH_ERR(
"ODP global init failed, exiting\n");
2001 ODPH_ERR(
"ODP local init failed, exiting\n");
2005 shm_cfg =
odp_shm_reserve(PROG_NAME
"_cfg",
sizeof(prog_config_t), ODP_CACHE_LINE_SIZE,
2009 ODPH_ERR(
"Error reserving shared memory\n");
2016 if (prog_conf == NULL) {
2017 ODPH_ERR(
"Error resolving shared memory address\n");
2022 init_config(prog_conf);
2025 ODPH_ERR(
"Error configuring scheduler\n");
2030 parse_res = setup_program(argc, argv, prog_conf);
2032 if (parse_res == PRS_NOK) {
2037 if (parse_res == PRS_TERM) {
2045 if (!setup_test(prog_conf)) {
2053 stop_test(prog_conf);
2054 print_stats(prog_conf);
2057 teardown_test(prog_conf);
2064 ODPH_ERR(
"ODP local terminate failed, exiting\n");
2069 ODPH_ERR(
"ODP global terminate failed, exiting\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.
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.
#define ODP_UNUSED
Intentionally unused variables of functions.
uint16_t odp_be_to_cpu_16(odp_u16be_t be16)
Convert 16bit big endian to cpu native uint16_t.
odp_u32be_t odp_cpu_to_be_32(uint32_t cpu32)
Convert cpu native uint32_t to 32bit big endian.
uint32_t odp_be_to_cpu_32(odp_u32be_t be32)
Convert 32bit big endian to cpu native uint32_t.
void odp_cpu_pause(void)
Pause CPU execution for a short while.
int odp_cpumask_default_worker(odp_cpumask_t *mask, int num)
Default CPU mask for worker threads.
@ ODP_CIPHER_ALG_AES_CCM
AES-CCM.
@ ODP_CIPHER_ALG_AES_ECB
AES with electronic codebook.
@ ODP_CIPHER_ALG_AES_CTR
AES with counter mode.
@ ODP_CIPHER_ALG_CHACHA20_POLY1305
ChaCha20-Poly1305.
@ ODP_CIPHER_ALG_AES_CBC
AES with cipher block chaining.
@ ODP_CIPHER_ALG_AES_GCM
AES-GCM.
@ ODP_CIPHER_ALG_3DES_CBC
Triple DES with cipher block chaining.
@ ODP_CIPHER_ALG_NULL
No cipher algorithm specified.
@ ODP_AUTH_ALG_SHA384_HMAC
HMAC-SHA-384.
@ ODP_AUTH_ALG_CHACHA20_POLY1305
ChaCha20-Poly1305 AEAD.
@ ODP_AUTH_ALG_AES_CMAC
AES-CMAC.
@ ODP_AUTH_ALG_NULL
No authentication algorithm specified.
@ ODP_AUTH_ALG_MD5_HMAC
HMAC-MD5.
@ ODP_AUTH_ALG_SHA512_HMAC
HMAC-SHA-512.
@ ODP_AUTH_ALG_SHA1_HMAC
HMAC-SHA-1.
@ ODP_AUTH_ALG_SHA256_HMAC
HMAC-SHA-256.
@ ODP_AUTH_ALG_SHA224_HMAC
HMAC-SHA-224.
@ ODP_AUTH_ALG_AES_GMAC
AES-GMAC.
@ ODP_AUTH_ALG_AES_XCBC_MAC
AES-XCBC-MAC.
@ ODP_AUTH_ALG_AES_GCM
AES-GCM.
@ ODP_AUTH_ALG_AES_CCM
AES-CCM.
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.
odp_event_subtype_t
Event subtype.
odp_event_type_t
Event type.
odp_event_type_t odp_event_types(odp_event_t event, odp_event_subtype_t *subtype)
Event type and subtype of an event.
#define ODP_EVENT_INVALID
Invalid event.
int odp_instance(odp_instance_t *instance)
Get instance handle.
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_ipsec_in_enq(const odp_packet_t pkt[], int num, const odp_ipsec_in_param_t *param)
Inbound asynchronous IPSEC operation.
int odp_ipsec_in(const odp_packet_t pkt_in[], int num_in, odp_packet_t pkt_out[], int *num_out, const odp_ipsec_in_param_t *param)
Inbound synchronous IPSEC operation.
int odp_ipsec_auth_capability(odp_auth_alg_t auth, odp_ipsec_auth_capability_t capa[], int num)
Query supported IPSEC authentication algorithm capabilities.
#define ODP_IPSEC_OK
IPSEC operation status has no errors.
int odp_ipsec_capability(odp_ipsec_capability_t *capa)
Query IPSEC capabilities.
int odp_ipsec_out(const odp_packet_t pkt_in[], int num_in, odp_packet_t pkt_out[], int *num_out, const odp_ipsec_out_param_t *param)
Outbound synchronous IPSEC operation.
void odp_ipsec_config_init(odp_ipsec_config_t *config)
Initialize IPSEC configuration options.
void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param)
Initialize IPSEC SA parameters.
int odp_ipsec_config(const odp_ipsec_config_t *config)
Global IPSEC configuration.
int odp_ipsec_sa_disable(odp_ipsec_sa_t sa)
Disable IPSEC SA.
int odp_ipsec_out_enq(const odp_packet_t pkt[], int num, const odp_ipsec_out_param_t *param)
Outbound asynchronous IPSEC operation.
int odp_ipsec_status(odp_ipsec_status_t *status, odp_event_t event)
Get IPSEC status information from an ODP_EVENT_IPSEC_STATUS event.
int odp_ipsec_cipher_capability(odp_cipher_alg_t cipher, odp_ipsec_cipher_capability_t capa[], int num)
Query supported IPSEC cipher algorithm capabilities.
#define ODP_IPSEC_SA_INVALID
Invalid IPSEC SA.
odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
Create IPSEC SA.
int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa)
Destroy IPSEC SA.
int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t packet)
Get IPSEC operation results from an IPSEC processed packet.
@ ODP_IPSEC_OP_MODE_SYNC
Synchronous IPSEC operation.
@ ODP_IPSEC_OP_MODE_ASYNC
Asynchronous IPSEC operation.
@ ODP_IPSEC_STATUS_SA_DISABLE
Response to SA disable command.
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_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.
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_pktout_event_queue(odp_pktio_t pktio, odp_queue_t queues[], int num)
Event queues for packet output.
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.
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_PKTOUT_MODE_QUEUE
Packet output through event queues.
@ ODP_PKTIO_OP_MT_UNSAFE
Not multithread safe operation.
@ ODP_PKTIO_OP_MT
Multithread safe operation.
@ ODP_PKTIN_MODE_DIRECT
Direct packet input from the interface.
@ ODP_PKTIN_MODE_SCHED
Packet input through scheduler and scheduled event queues.
void * odp_packet_pull_head(odp_packet_t pkt, uint32_t len)
Pull in packet head.
void * odp_packet_user_ptr(odp_packet_t pkt)
User context pointer.
void odp_packet_to_event_multi(const odp_packet_t pkt[], odp_event_t ev[], int num)
Convert multiple packet handles to events.
void * odp_packet_push_head(odp_packet_t pkt, uint32_t len)
Push out packet head.
uint32_t odp_packet_l4_offset(odp_packet_t pkt)
Layer 4 start offset.
int odp_packet_has_error(odp_packet_t pkt)
Check for all parse errors in packet.
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.
uint32_t odp_packet_l3_offset(odp_packet_t pkt)
Layer 3 start offset.
int odp_packet_copy_from_mem(odp_packet_t pkt, uint32_t offset, uint32_t len, const void *src)
Copy data from memory to packet.
int odp_packet_has_ipsec(odp_packet_t pkt)
Check for IPSec.
void odp_packet_user_ptr_set(odp_packet_t pkt, const void *user_ptr)
Set user context pointer.
void odp_packet_free_multi(const odp_packet_t pkt[], int num)
Free multiple packets.
int odp_packet_copy_to_mem(odp_packet_t pkt, uint32_t offset, uint32_t len, void *dst)
Copy data from packet to memory.
int odp_packet_has_udp(odp_packet_t pkt)
Check for UDP.
@ ODP_PROTO_LAYER_L4
Layer L4 protocols (UDP, TCP, SCTP)
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.
int odp_queue_enq_multi(odp_queue_t queue, const odp_event_t events[], int num)
Enqueue multiple events to a queue.
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.
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.
int odp_schedule_multi_no_wait(odp_queue_t *from, odp_event_t events[], int num)
Schedule, do not wait for events.
#define ODP_SCHED_SYNC_PARALLEL
Parallel scheduled queues.
#define ODP_SCHED_SYNC_ORDERED
Ordered queue synchronization.
#define ODP_SCHED_NO_WAIT
Do not wait.
int odp_schedule_default_prio(void)
Default scheduling priority level.
int odp_schedule_max_prio(void)
Maximum scheduling priority level.
int odp_schedule_config(const odp_schedule_config_t *config)
Global schedule configuration.
odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait)
Schedule an event.
#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.
bool odp_bool_t
Boolean type.
int odp_thread_id(void)
Get thread identifier.
@ ODP_THREAD_WORKER
Worker thread.
@ ODP_THREAD_CONTROL
Control thread.
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
Authentication algorithm capabilities.
odp_crypto_cipher_algos_t ciphers
Supported cipher algorithms.
uint32_t max_num_sa
Maximum number of IPSEC SAs.
odp_crypto_auth_algos_t auths
Supported authentication algorithms.
uint32_t max_queues
Maximum number of different destination queues.
Cipher algorithm capabilities.
IPSEC configuration options.
odp_ipsec_op_mode_t outbound_mode
Outbound IPSEC operation mode.
odp_ipsec_inbound_config_t inbound
IPSEC inbound processing configuration.
odp_ipsec_op_mode_t inbound_mode
Inbound IPSEC operation mode.
IPSEC inbound operation parameters.
const odp_ipsec_sa_t * sa
Pointer to an array of IPSEC SAs.
odp_queue_t default_queue
Default destination queue for IPSEC events.
odp_proto_layer_t parse_level
Parse packet headers after IPSEC transformation.
uint64_t all
All status bits.
IPSEC outbound operation parameters.
const odp_ipsec_sa_t * sa
Pointer to an array of IPSEC SAs.
IPSEC operation result for a packet.
odp_ipsec_op_status_t status
IPSEC operation status.
IPSEC Security Association (SA) parameters.
odp_queue_t dest_queue
Destination queue for IPSEC events.
odp_ipsec_dir_t dir
IPSEC SA direction: inbound or outbound.
int result
Result of the operation.
odp_ipsec_status_id_t id
IPSEC status ID.
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.
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_pktin_mode_t in_mode
Packet input mode.
odp_pktout_mode_t out_mode
Packet output mode.
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 max_len
Maximum packet data length 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.
odp_schedule_group_t group
Thread group.
odp_schedule_prio_t prio
Priority level.
odp_schedule_sync_t sync
Synchronization method.
uint64_t all_bits
All bits of the bit field structure.
uint64_t all_bits
All bits of the bit field structure.
uint32_t ipv4_udp
IPv4 addresses and UDP port numbers.
struct odp_pktin_hash_proto_t::@99 proto
Protocol header fields for hashing.