diff options
author | Matias Elo <matias.elo@nokia.com> | 2023-04-14 10:46:15 +0300 |
---|---|---|
committer | Matias Elo <matias.elo@nokia.com> | 2023-04-14 10:46:15 +0300 |
commit | 7efdbaa4934c0cab3aa274d350d82af2d756d4d2 (patch) | |
tree | f533bed82bfa212e92efbadc92a48fcee7939f2a /test | |
parent | f3a95e9658ffda83da051e9b3f9338583389dc42 (diff) | |
parent | d1433e17eda246d24b61cadae88b339f5a0226ba (diff) |
Merge tag 'v1.41.0.0' of https://github.com/OpenDataPlane/odp into odp-dpdk
Signed-off-by: Matias Elo <matias.elo@nokia.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/performance/Makefile.am | 10 | ||||
-rw-r--r-- | test/performance/odp_atomic_perf.c | 5 | ||||
-rw-r--r-- | test/performance/odp_crypto.c | 76 | ||||
-rw-r--r-- | test/performance/odp_ipsecfwd.c | 535 | ||||
-rw-r--r-- | test/performance/odp_ipsecfwd.conf | 41 | ||||
-rw-r--r-- | test/performance/odp_packet_gen.c | 2 | ||||
-rw-r--r-- | test/performance/odp_timer_perf.c | 2 | ||||
-rw-r--r-- | test/validation/api/classification/odp_classification_basic.c | 10 | ||||
-rw-r--r-- | test/validation/api/classification/odp_classification_test_pmr.c | 24 | ||||
-rw-r--r-- | test/validation/api/classification/odp_classification_tests.c | 20 | ||||
-rw-r--r-- | test/validation/api/crypto/odp_crypto_test_inp.c | 1081 | ||||
-rw-r--r-- | test/validation/api/dma/dma.c | 334 | ||||
-rw-r--r-- | test/validation/api/ipsec/ipsec_test_out.c | 27 | ||||
-rw-r--r-- | test/validation/api/pktio/pktio.c | 11 | ||||
-rw-r--r-- | test/validation/api/stash/stash.c | 258 | ||||
-rw-r--r-- | test/validation/api/timer/timer.c | 160 |
16 files changed, 1943 insertions, 653 deletions
diff --git a/test/performance/Makefile.am b/test/performance/Makefile.am index beeb652cc..9dc83fd22 100644 --- a/test/performance/Makefile.am +++ b/test/performance/Makefile.am @@ -18,7 +18,6 @@ COMPILE_ONLY = odp_cpu_bench \ odp_crypto \ odp_dma_perf \ odp_ipsec \ - odp_ipsecfwd \ odp_l2fwd \ odp_packet_gen \ odp_pktio_ordered \ @@ -29,6 +28,10 @@ COMPILE_ONLY = odp_cpu_bench \ odp_stress \ odp_timer_perf +if LIBCONFIG +COMPILE_ONLY += odp_ipsecfwd +endif + TESTSCRIPTS = odp_cpu_bench_run.sh \ odp_crypto_run.sh \ odp_dma_perf_run.sh \ @@ -62,7 +65,6 @@ odp_crc_SOURCES = odp_crc.c odp_crypto_SOURCES = odp_crypto.c odp_dma_perf_SOURCES = odp_dma_perf.c odp_ipsec_SOURCES = odp_ipsec.c -odp_ipsecfwd_SOURCES = odp_ipsecfwd.c odp_lock_perf_SOURCES = odp_lock_perf.c odp_mem_perf_SOURCES = odp_mem_perf.c odp_packet_gen_SOURCES = odp_packet_gen.c @@ -78,6 +80,10 @@ odp_sched_perf_SOURCES = odp_sched_perf.c odp_stress_SOURCES = odp_stress.c odp_timer_perf_SOURCES = odp_timer_perf.c +if LIBCONFIG +odp_ipsecfwd_SOURCES = odp_ipsecfwd.c +endif + # l2fwd test depends on generator example EXTRA_odp_l2fwd_DEPENDENCIES = $(top_builddir)/example/generator/odp_generator$(EXEEXT) $(top_builddir)/example/generator/odp_generator$(EXEEXT): diff --git a/test/performance/odp_atomic_perf.c b/test/performance/odp_atomic_perf.c index ee760babf..5eeba8442 100644 --- a/test/performance/odp_atomic_perf.c +++ b/test/performance/odp_atomic_perf.c @@ -18,8 +18,9 @@ /* Default number of test rounds */ #define NUM_ROUNDS 1000000u -/* Initial value for atomic variables */ -#define INIT_VAL 1234567 +/* Initial value for atomic variables. Supports up to 2 billion + * rounds of 32-bit min and max tests. */ +#define INIT_VAL 0x80000000 /* Max number of workers if num_cpu=0 */ #define DEFAULT_MAX_WORKERS 10 diff --git a/test/performance/odp_crypto.c b/test/performance/odp_crypto.c index 2f79ae644..52af6d2fc 100644 --- a/test/performance/odp_crypto.c +++ b/test/performance/odp_crypto.c @@ -90,20 +90,20 @@ typedef struct { */ typedef struct { /** - * If non zero prints content of packets. Enabled by -d or + * If non-zero, prints content of packets. Enabled by -d or * --debug option. */ int debug_packets; /** - * If non zero Try to run crypto operation in place. Note some + * If non-zero, try to run crypto operation in place. Note some * implementation may not support such mode. Enabled by -n or * --inplace option. */ int in_place; /** - * If non zeor output of previous operation taken as input for + * If non-zero, output of previous operation taken as input for * next encrypt operations. Enabled by -r or --reuse option. */ int reuse_packet; @@ -118,7 +118,7 @@ typedef struct { /** * Number of iteration to repeat crypto operation to get good - * average number. Specified through -i or --terations option. + * average number. Specified through -i or --iterations option. * Default is 10000. */ int iteration_count; @@ -136,7 +136,7 @@ typedef struct { /** * Pointer to selected algorithm to test. If NULL all available - * alogorthims are tested. Name of algorithm is passed through + * algorithms are tested. Name of algorithm is passed through * -a or --algorithm option. */ crypto_alg_config_t *alg_config; @@ -451,6 +451,49 @@ static crypto_alg_config_t algs_config[] = { .auth_digest_len = 4, }, }, + { + .name = "snow3g-uea2", + .session = { + .cipher_alg = ODP_CIPHER_ALG_SNOW3G_UEA2, + .cipher_key = { + .data = test_key16, + .length = sizeof(test_key16) + }, + .cipher_iv_len = 16, + .auth_alg = ODP_AUTH_ALG_NULL, + }, + }, + { + .name = "snow3g-uia2", + .session = { + .cipher_alg = ODP_CIPHER_ALG_NULL, + .auth_alg = ODP_AUTH_ALG_SNOW3G_UIA2, + .auth_key = { + .data = test_key16, + .length = sizeof(test_key16) + }, + .auth_iv_len = 16, + .auth_digest_len = 4, + }, + }, + { + .name = "snow3g-uea2-snow3g-uia2", + .session = { + .cipher_alg = ODP_CIPHER_ALG_SNOW3G_UEA2, + .cipher_key = { + .data = test_key16, + .length = sizeof(test_key16) + }, + .cipher_iv_len = 16, + .auth_alg = ODP_AUTH_ALG_SNOW3G_UIA2, + .auth_key = { + .data = test_key16, + .length = sizeof(test_key16) + }, + .auth_iv_len = 16, + .auth_digest_len = 4, + }, + }, }; /** @@ -810,8 +853,6 @@ run_measure_one(crypto_args_t *cargs, } packets_sent += rc; } else { - odp_crypto_packet_result_t result; - rc = odp_crypto_op(&pkt, &out_pkt, ¶ms, 1); if (rc <= 0) { @@ -822,8 +863,7 @@ run_measure_one(crypto_args_t *cargs, } packets_sent += rc; packets_received++; - if (odp_unlikely(odp_crypto_result(&result, out_pkt) != 0) || - odp_unlikely(!result.ok)) { + if (odp_unlikely(odp_crypto_result(NULL, out_pkt) != 0)) { ODPH_ERR("Crypto operation failed\n"); odp_packet_free(out_pkt); return -1; @@ -846,7 +886,6 @@ run_measure_one(crypto_args_t *cargs, if (cargs->schedule || cargs->poll) { odp_event_t ev; - odp_crypto_packet_result_t result; odp_packet_t out_pkt; if (cargs->schedule) @@ -857,8 +896,7 @@ run_measure_one(crypto_args_t *cargs, while (ev != ODP_EVENT_INVALID) { out_pkt = odp_crypto_packet_from_event(ev); - if (odp_unlikely(odp_crypto_result(&result, out_pkt) != 0) || - odp_unlikely(!result.ok)) { + if (odp_unlikely(odp_crypto_result(NULL, out_pkt) != 0)) { ODPH_ERR("Crypto operation failed\n"); odp_packet_free(out_pkt); return -1; @@ -948,6 +986,11 @@ static int check_cipher_alg(const odp_crypto_capability_t *capa, case ODP_CIPHER_ALG_ZUC_EEA3: if (capa->ciphers.bit.zuc_eea3) return 0; + break; + case ODP_CIPHER_ALG_SNOW3G_UEA2: + if (capa->ciphers.bit.snow3g_uea2) + return 0; + break; default: break; } @@ -1002,6 +1045,11 @@ static int check_auth_alg(const odp_crypto_capability_t *capa, case ODP_AUTH_ALG_ZUC_EIA3: if (capa->auths.bit.zuc_eia3) return 0; + break; + case ODP_AUTH_ALG_SNOW3G_UIA2: + if (capa->auths.bit.snow3g_uia2) + return 0; + break; default: break; } @@ -1096,7 +1144,7 @@ static int check_auth_params(const odp_crypto_capability_t *crypto_capa, } /** - * Process one algorithm. Note if paload size is specicified it is + * Process one algorithm. Note if payload size is specified it is * only one run. Or iterate over set of predefined payloads. */ static int run_measure_one_config(test_run_arg_t *arg) @@ -1442,7 +1490,7 @@ static void parse_args(int argc, char *argv[], crypto_args_t *cargs) } /** - * Prinf usage information + * Print usage information */ static void usage(char *progname) { diff --git a/test/performance/odp_ipsecfwd.c b/test/performance/odp_ipsecfwd.c index 6098fd964..a6df747f3 100644 --- a/test/performance/odp_ipsecfwd.c +++ b/test/performance/odp_ipsecfwd.c @@ -19,6 +19,7 @@ #include <odp_api.h> #include <odp/helper/odph_api.h> +#include <libconfig.h> #define PROG_NAME "odp_ipsecfwd" #define SHORT_PROG_NAME "ipsfwd" @@ -105,6 +106,17 @@ typedef struct ODP_ALIGNED_CACHE { uint8_t pktio; } thread_config_t; +typedef struct { + odp_ipsec_sa_param_t sa_param; + char cipher_key[65U]; + char cipher_key_extra[5U]; + char auth_key[65U]; + char auth_key_extra[5U]; + odp_u32be_t lkp_dst_ip; + odp_u32be_t src_ip; + odp_u32be_t dst_ip; +} sa_config_t; + typedef uint32_t (*rx_fn_t)(thread_config_t *config, odp_event_t evs[], int num); typedef void (*ipsec_fn_t)(odp_packet_t pkts[], int num, odph_table_t fwd_tbl, stats_t *stats); typedef void (*drain_fn_t)(prog_config_t *config); @@ -123,9 +135,9 @@ typedef struct prog_config_s { fwd_entry_t fwd_entries[MAX_FWDS]; odp_queue_t sa_qs[MAX_SA_QUEUES]; pktio_t pktios[MAX_IFS]; + sa_config_t default_cfg; ops_t ops; - char *sa_conf_file; - char *fwd_conf_file; + char *conf_file; odp_instance_t odp_instance; odp_queue_t compl_q; odp_pool_t pktio_pool; @@ -203,6 +215,7 @@ static __thread pkt_ifs_t ifs; static void init_config(prog_config_t *config) { memset(config, 0, sizeof(*config)); + odp_ipsec_sa_param_init(&config->default_cfg.sa_param); config->compl_q = ODP_QUEUE_INVALID; config->pktio_pool = ODP_POOL_INVALID; config->num_input_qs = 1; @@ -315,14 +328,50 @@ static void print_usage(void) "Simple IPsec performance tester. Forward and process plain and ipsec packets.\n" "\n" "Examples:\n" - " %s -i ens9f1 -s /etc/odp/sa.conf -f /etc/odp/fwd.conf\n" + " %s -i ens9f1 -C /etc/odp/ipsecfwd.conf\n" "\n" - " With sa.conf containing, for example:\n" - " 0 222 192.168.1.10 192.168.1.16 4 jWnZr4t7w!zwC*F- 0 2" - " n2r5u7x!A%%D*G-KaPdSg 0 12\n" + " With ipsecfwd.conf containing, for example:\n" + " default: {\n" + " dir = 1\n" + " proto = 0\n" + " mode = 0\n" + " crypto: {\n" + " cipher_alg = 4\n" + " cipher_key = \"jWnZr4t7w!zwC*F-\"\n" + " auth_alg = 2\n" + " auth_key = \"n2r5u7x!A%%D*\"\n" + " icv_len = 12\n" + " };\n" + " };\n" "\n" - " With fwd.conf containing, for example:\n" - " 192.168.1.0/24 ens9f1 aa:bb:cc:dd:11:22\n" + " sa: (\n" + " {\n" + " spi = 1337\n" + " outbound: {\n" + " tunnel: {\n" + " src_addr = \"192.168.1.10\"\n" + " dst_addr = \"192.168.1.16\"\n" + " };\n" + " };\n" + " },\n" + " {\n" + " spi = 1338\n" + " outbound: {\n" + " tunnel: {\n" + " src_addr = \"192.168.3.110\"\n" + " dst_addr = \"192.168.3.116\"\n" + " };\n" + " };\n" + " }\n" + " );\n" + "\n" + " fwd: (\n" + " {\n" + " prefix: \"192.168.1.0/24\"\n" + " if: \"ens9f1\"\n" + " dst_mac: \"00:00:05:00:07:00\"\n" + " }\n" + " );\n" "\n" "Usage: %s [options]\n" "\n" @@ -336,39 +385,35 @@ static void print_usage(void) " -m, --mode Queueing mode.\n" " 0: ordered (default)\n" " 1: parallel\n" - " -s, --sa SA configuration file. Individual SA configuration is\n" - " expected to be within a single line, values whitespace\n" - " separated:\n" - "\n" - " <line in file> Dir SPI TunSrcIPv4 TunDstIPv4" - " CipherAlgoIdx CipherKey CipherKeyExtra AuthAlgIdx AuthKey AuthKeyExtra ICVLen\n" + " -C, --conf Configuration file. 'libconfig' syntax is expected.\n" + " SA configuration supports default fallback, i.e.\n" + " individual SA configuration blocks may omit some\n" + " parameters and instead set these once in default block\n" + " which then are used to fill missing parameters. The only\n" + " required argument for an SA is the 'spi' parameter.\n" + " Individual SA parameter blocks are expected to be in\n" + " 'sa'-named list. Parameter naming follows API\n" + " specification, see 'odp_ipsec_sa_param_t' for parameter\n" + " names and hierarchy. Traffic is mapped to SAs based on UDP\n" + " port: the port is used as the SPI. For forwarding entries,\n" + " individual parameter blocks are similarly expected to be\n" + " in 'fwd'-named list. With forwarding entries, every\n" + " parameter is always required and interfaces present in\n" + " forwarding entries should be one of the interfaces passed\n" + " with '--interfaces' option. See example above for\n" + " potential SA and forwarding configuration.\n" "\n" - " With combined algorithms, authentication data is ignored.\n" - " Traffic is mapped to SAs based on UDP port: the port is\n" - " used as the SPI. Non-zero Dir value declares an outbound\n" - " SA whereas zero Dir value declares an inbound SA.\n" - "\n" - " Supported cipher and authentication algorithms:\n", + " Supported cipher and authentication algorithms for SAs:\n", PROG_NAME, PROG_NAME, MIN(pool_capa.pkt.max_num, PKT_CNT), MIN(pool_capa.pkt.max_len, PKT_SIZE)); print_supported_algos(&ipsec_capa); - printf(" -f, --fwd_table Forwarding configuration file. Individual forwarding\n" - " configuration is expected to be within a single line,\n" - " values whitespace separated:\n" - "\n" - " <line in file> IPv4Prefix/MaskLen NetIf DstMac\n" - "\n" - " IPv4Prefix and MaskLen define a matchable prefix and NetIf\n" - " and DstMac define the outgoing interface and destination\n" - " MAC address for a match. NetIf should be one of the\n" - " interfaces passed with \"--interfaces\" option\n" - " -I, --num_input_qs Input queue count. 1 by default.\n" + printf(" -I, --num_input_qs Input queue count. 1 by default.\n" " -S, --num_sa_qs SA queue count. 1 by default.\n" " -O, --num_output_qs Output queue count. 1 by default.\n" " -d, --direct_rx Use direct RX. Interfaces will be polled by workers\n" - " directly. \"--mode\", \"--num_input_qs\" and\n" - " \"--num_output_qs\" options are ignored, input and output\n" - " queue counts will match worker count.\n" + " directly. '--mode', '--num_input_qs' and '--num_output_qs'\n" + " options are ignored, input and output queue counts will\n" + " match worker count.\n" " -h, --help This help.\n" "\n"); } @@ -949,25 +994,206 @@ static odp_bool_t create_sa_dest_queues(odp_ipsec_capability_t *ipsec_capa, return true; } -static void create_sa_entry(uint32_t dir, uint32_t spi, const char *src_ip_str, - const char *dst_ip_str, int cipher_idx, uint8_t *cipher_key, - uint8_t *cipher_key_extra, int auth_idx, uint8_t *auth_key, - uint8_t *auth_key_extra, uint32_t icv_len, uint32_t ar_ws, - uint32_t max_num_sa, prog_config_t *config) +static void parse_crypto(config_setting_t *cfg, sa_config_t *config) { - uint32_t src_ip, dst_ip; - odp_ipsec_sa_param_t sa_param; - odp_ipsec_crypto_param_t crypto_param; - odp_ipsec_sa_t sa; + int val; + const char *val_str; + config_setting_t *cs = config_setting_lookup(cfg, "crypto"); - if (config->num_sas == max_num_sa) { - ODPH_ERR("Maximum number of SAs parsed (%u), ignoring rest\n", max_num_sa); + if (cs == NULL) + return; + + if (config_setting_lookup_int(cs, "cipher_alg", &val) == CONFIG_TRUE) + config->sa_param.crypto.cipher_alg = val; + + if (config_setting_lookup_string(cs, "cipher_key", &val_str) == CONFIG_TRUE) { + strcpy(config->cipher_key, val_str); + config->sa_param.crypto.cipher_key.data = (uint8_t *)config->cipher_key; + config->sa_param.crypto.cipher_key.length = + strlen((const char *)config->cipher_key); + } + + if (config_setting_lookup_string(cs, "cipher_key_extra", &val_str) == CONFIG_TRUE) { + strcpy(config->cipher_key_extra, val_str); + config->sa_param.crypto.cipher_key_extra.data = + (uint8_t *)config->cipher_key_extra; + config->sa_param.crypto.cipher_key_extra.length = + strlen((const char *)config->cipher_key_extra); + } + + if (config_setting_lookup_int(cs, "auth_alg", &val) == CONFIG_TRUE) + config->sa_param.crypto.auth_alg = val; + + if (config_setting_lookup_string(cs, "auth_key", &val_str) == CONFIG_TRUE) { + strcpy(config->auth_key, val_str); + config->sa_param.crypto.auth_key.data = (uint8_t *)config->auth_key; + config->sa_param.crypto.auth_key.length = strlen((const char *)config->auth_key); + } + + if (config_setting_lookup_string(cs, "auth_key_extra", &val_str) == CONFIG_TRUE) { + strcpy(config->auth_key_extra, val_str); + config->sa_param.crypto.auth_key_extra.data = (uint8_t *)config->auth_key_extra; + config->sa_param.crypto.auth_key_extra.length = + strlen((const char *)config->auth_key_extra); + } + + if (config_setting_lookup_int(cs, "icv_len", &val) == CONFIG_TRUE) + config->sa_param.crypto.icv_len = val; +} + +static void parse_opt(config_setting_t *cfg, sa_config_t *config) +{ + int val; + config_setting_t *cs = config_setting_lookup(cfg, "opt"); + + if (cs == NULL) + return; + + if (config_setting_lookup_int(cs, "esn", &val) == CONFIG_TRUE) + config->sa_param.opt.esn = val; + + if (config_setting_lookup_int(cs, "udp_encap", &val) == CONFIG_TRUE) + config->sa_param.opt.udp_encap = val; + + if (config_setting_lookup_int(cs, "copy_dscp", &val) == CONFIG_TRUE) + config->sa_param.opt.copy_dscp = val; + + if (config_setting_lookup_int(cs, "copy_flabel", &val) == CONFIG_TRUE) + config->sa_param.opt.copy_flabel = val; + + if (config_setting_lookup_int(cs, "copy_df", &val) == CONFIG_TRUE) + config->sa_param.opt.copy_df = val; + + if (config_setting_lookup_int(cs, "dec_ttl", &val) == CONFIG_TRUE) + config->sa_param.opt.dec_ttl = val; +} + +static void parse_limits(config_setting_t *cfg, sa_config_t *config) +{ + config_setting_t *cs = config_setting_lookup(cfg, "lifetime"), *soft, *hard; + long long val; + + if (cs == NULL) return; + + soft = config_setting_lookup(cs, "soft_limit"); + hard = config_setting_lookup(cs, "hard_limit"); + + if (soft != NULL) { + if (config_setting_lookup_int64(soft, "bytes", &val) == CONFIG_TRUE) + config->sa_param.lifetime.soft_limit.bytes = val; + + if (config_setting_lookup_int64(soft, "packets", &val) == CONFIG_TRUE) + config->sa_param.lifetime.soft_limit.packets = val; + } + + if (hard != NULL) { + if (config_setting_lookup_int64(hard, "bytes", &val) == CONFIG_TRUE) + config->sa_param.lifetime.hard_limit.bytes = val; + + if (config_setting_lookup_int64(hard, "packets", &val) == CONFIG_TRUE) + config->sa_param.lifetime.hard_limit.packets = val; } +} - if (odph_ipv4_addr_parse(&src_ip, src_ip_str) < 0 || - odph_ipv4_addr_parse(&dst_ip, dst_ip_str) < 0) { - ODPH_ERR("Error parsing IP addresses for SA %u\n", spi); +static void parse_inbound(config_setting_t *cfg, sa_config_t *config) +{ + config_setting_t *cs = config_setting_lookup(cfg, "inbound"); + int val; + const char *val_str; + + if (cs == NULL) + return; + + if (config_setting_lookup_int(cs, "lookup_mode", &val) == CONFIG_TRUE) + config->sa_param.inbound.lookup_mode = val; + + if (config_setting_lookup_string(cs, "lookup_dst_addr", &val_str) == CONFIG_TRUE) { + odph_ipv4_addr_parse(&config->lkp_dst_ip, val_str); + config->lkp_dst_ip = odp_cpu_to_be_32(config->lkp_dst_ip); + config->sa_param.inbound.lookup_param.dst_addr = &config->lkp_dst_ip; + } + + if (config_setting_lookup_int(cs, "antireplay_ws", &val) == CONFIG_TRUE) + config->sa_param.inbound.antireplay_ws = val; + + if (config_setting_lookup_int(cs, "reassembly_en", &val) == CONFIG_TRUE) + config->sa_param.inbound.reassembly_en = val; +} + +static void parse_outbound(config_setting_t *cfg, sa_config_t *config) +{ + config_setting_t *cs = config_setting_lookup(cfg, "outbound"), *tunnel; + const char *val_str; + int val; + + if (cs == NULL) + return; + + tunnel = config_setting_lookup(cs, "tunnel"); + + if (tunnel != NULL) { + if (config_setting_lookup_string(tunnel, "src_addr", &val_str) == CONFIG_TRUE) { + odph_ipv4_addr_parse(&config->src_ip, val_str); + config->src_ip = odp_cpu_to_be_32(config->src_ip); + config->sa_param.outbound.tunnel.ipv4.src_addr = &config->src_ip; + } + + if (config_setting_lookup_string(tunnel, "dst_addr", &val_str) == CONFIG_TRUE) { + odph_ipv4_addr_parse(&config->dst_ip, val_str); + config->dst_ip = odp_cpu_to_be_32(config->dst_ip); + config->sa_param.outbound.tunnel.ipv4.dst_addr = &config->dst_ip; + } + + if (config_setting_lookup_int(tunnel, "dscp", &val) == CONFIG_TRUE) + config->sa_param.outbound.tunnel.ipv4.dscp = val; + + if (config_setting_lookup_int(tunnel, "df", &val) == CONFIG_TRUE) + config->sa_param.outbound.tunnel.ipv4.df = val; + + if (config_setting_lookup_int(tunnel, "ttl", &val) == CONFIG_TRUE) + config->sa_param.outbound.tunnel.ipv4.ttl = val; + } + + if (config_setting_lookup_int(cs, "frag_mode", &val) == CONFIG_TRUE) + config->sa_param.outbound.frag_mode = val; + + if (config_setting_lookup_int(cs, "mtu", &val) == CONFIG_TRUE) + config->sa_param.outbound.mtu = val; +} + +static void parse_sa_entry(config_setting_t *cfg, sa_config_t *config) +{ + int val; + + if (config_setting_lookup_int(cfg, "dir", &val) == CONFIG_TRUE) + config->sa_param.dir = val; + + if (config_setting_lookup_int(cfg, "proto", &val) == CONFIG_TRUE) + config->sa_param.proto = val; + + if (config_setting_lookup_int(cfg, "mode", &val) == CONFIG_TRUE) + config->sa_param.mode = val; + + if (config_setting_lookup_int(cfg, "spi", &val) == CONFIG_TRUE) + config->sa_param.spi = val; + + parse_crypto(cfg, config); + parse_opt(cfg, config); + parse_limits(cfg, config); + parse_inbound(cfg, config); + parse_outbound(cfg, config); +} + +static void create_sa_entry(odp_ipsec_sa_param_t *sa_param, prog_config_t *config, + uint32_t max_num_sa) +{ + uint32_t dir = sa_param->dir; + uint32_t spi = sa_param->spi; + odp_ipsec_sa_t sa; + + if (config->num_sas == max_num_sa) { + ODPH_ERR("Maximum number of SAs parsed (%u), ignoring rest\n", max_num_sa); return; } @@ -981,37 +1207,8 @@ static void create_sa_entry(uint32_t dir, uint32_t spi, const char *src_ip_str, return; } - src_ip = odp_cpu_to_be_32(src_ip); - dst_ip = odp_cpu_to_be_32(dst_ip); - odp_ipsec_sa_param_init(&sa_param); - sa_param.proto = ODP_IPSEC_ESP; - sa_param.mode = ODP_IPSEC_MODE_TUNNEL; - sa_param.spi = spi; - sa_param.dest_queue = config->sa_qs[config->num_sas % config->num_sa_qs]; - - if (dir > 0U) { - sa_param.dir = ODP_IPSEC_DIR_OUTBOUND; - sa_param.outbound.tunnel.ipv4.src_addr = &src_ip; - sa_param.outbound.tunnel.ipv4.dst_addr = &dst_ip; - } else { - sa_param.dir = ODP_IPSEC_DIR_INBOUND; - sa_param.inbound.lookup_mode = ODP_IPSEC_LOOKUP_DISABLED; - sa_param.inbound.antireplay_ws = ar_ws; - } - - crypto_param.cipher_alg = cipher_idx; - crypto_param.cipher_key.data = cipher_key; - crypto_param.cipher_key.length = strlen((const char *)cipher_key); - crypto_param.cipher_key_extra.data = cipher_key_extra; - crypto_param.cipher_key_extra.length = strlen((const char *)cipher_key_extra); - crypto_param.auth_alg = auth_idx; - crypto_param.auth_key.data = auth_key; - crypto_param.auth_key.length = strlen((const char *)auth_key); - crypto_param.auth_key_extra.data = auth_key_extra; - crypto_param.auth_key_extra.length = strlen((const char *)auth_key_extra); - crypto_param.icv_len = icv_len; - sa_param.crypto = crypto_param; - sa = odp_ipsec_sa_create(&sa_param); + sa_param->dest_queue = config->sa_qs[config->num_sas % config->num_sa_qs]; + sa = odp_ipsec_sa_create(sa_param); if (sa == ODP_IPSEC_SA_INVALID) { ODPH_ERR("Error creating SA handle for SA %u\n", spi); @@ -1023,19 +1220,46 @@ static void create_sa_entry(uint32_t dir, uint32_t spi, const char *src_ip_str, ++config->num_sas; } -static void parse_sas(prog_config_t *config) +static void parse_and_create_sa_entries(config_t *cfg, prog_config_t *config, uint32_t max_num_sa) { - odp_ipsec_capability_t ipsec_capa; - FILE *file; - int cipher_idx, auth_idx; - uint32_t ar_ws, max_num_sa, dir, spi, icv_len; - char src_ip[16U] = { 0 }, dst_ip[16U] = { 0 }; - uint8_t cipher_key[65U] = { 0U }, cipher_key_extra[5U] = { 0U }, auth_key[65U] = { 0U }, - auth_key_extra[5U] = { 0U }; - - if (config->sa_conf_file == NULL) + config_setting_t *cs; + int count; + + cs = config_lookup(cfg, "default"); + + if (cs != NULL) + parse_sa_entry(cs, &config->default_cfg); + + cs = config_lookup(cfg, "sa"); + + if (cs == NULL) return; + count = config_setting_length(cs); + + for (int i = 0; i < count; i++) { + sa_config_t sa_cfg; + config_setting_t *sa; + int val; + + sa_cfg = config->default_cfg; + sa = config_setting_get_elem(cs, i); + + if (sa == NULL) + continue; + + if (config_setting_lookup_int(sa, "spi", &val) == CONFIG_TRUE) { + parse_sa_entry(sa, &sa_cfg); + create_sa_entry(&sa_cfg.sa_param, config, max_num_sa); + } + } +} + +static void parse_sas(config_t *cfg, prog_config_t *config) +{ + odp_ipsec_capability_t ipsec_capa; + uint32_t max_num_sa; + if (odp_ipsec_capability(&ipsec_capa) < 0) { ODPH_ERR("Error querying IPsec capabilities\n"); return; @@ -1047,24 +1271,8 @@ static void parse_sas(prog_config_t *config) if (!config->is_dir_rx && !create_sa_dest_queues(&ipsec_capa, config)) return; - file = fopen(config->sa_conf_file, "r"); - - if (file == NULL) { - ODPH_ERR("Error opening SA configuration file: %s\n", strerror(errno)); - return; - } - - ar_ws = MIN(32U, ipsec_capa.max_antireplay_ws); max_num_sa = MIN(MAX_SAS, ipsec_capa.max_num_sa); - - while (fscanf(file, "%u%u%s%s%d%s%s%d%s%s%u", &dir, &spi, src_ip, dst_ip, - &cipher_idx, cipher_key, cipher_key_extra, &auth_idx, auth_key, - auth_key_extra, &icv_len) == 11) - create_sa_entry(!!dir, spi, src_ip, dst_ip, cipher_idx, cipher_key, - cipher_key_extra, auth_idx, auth_key, auth_key_extra, icv_len, - ar_ws, max_num_sa, config); - - (void)fclose(file); + parse_and_create_sa_entries(cfg, config, max_num_sa); } static const pktio_t *get_pktio(const char *iface, const prog_config_t *config) @@ -1077,12 +1285,14 @@ static const pktio_t *get_pktio(const char *iface, const prog_config_t *config) return NULL; } -static void create_fwd_table_entry(const char *dst_ip_str, const char *iface, - const char *dst_mac_str, uint8_t mask, prog_config_t *config) +static void create_fwd_table_entry(config_setting_t *cfg, prog_config_t *config) { - fwd_entry_t *entry; + const char *val_str; + char dst_ip_str[16U] = { 0 }; + uint32_t mask, dst_ip; odph_ethaddr_t dst_mac; - uint32_t dst_ip; + const pktio_t *pktio = NULL; + fwd_entry_t *entry; odph_iplookup_prefix_t prefix; if (config->num_fwds == MAX_FWDS) { @@ -1091,50 +1301,69 @@ static void create_fwd_table_entry(const char *dst_ip_str, const char *iface, return; } - entry = &config->fwd_entries[config->num_fwds]; + if (config_setting_lookup_string(cfg, "prefix", &val_str) == CONFIG_TRUE) { + if (sscanf(val_str, "%[^/]/%u", dst_ip_str, &mask) != 2) { + ODPH_ERR("Error parsing IP and subnet mask for forwarding entry\n"); + return; + } - if (odph_eth_addr_parse(&dst_mac, dst_mac_str) < 0 || - odph_ipv4_addr_parse(&dst_ip, dst_ip_str) < 0) { - ODPH_ERR("Error parsing MAC and IP addresses for forwarding entry\n"); + if (odph_ipv4_addr_parse(&dst_ip, dst_ip_str) < 0) { + ODPH_ERR("Syntax error in IP address for forwarding entry\n"); + return; + } + } else { return; } - entry->pktio = get_pktio(iface, config); + if (config_setting_lookup_string(cfg, "if", &val_str) == CONFIG_TRUE) { + pktio = get_pktio(val_str, config); + + if (pktio == NULL) { + ODPH_ERR("Error parsing next interface for forwarding entry\n"); + return; + } + } else { + return; + } - if (entry->pktio == NULL) { - ODPH_ERR("Invalid interface in forwarding entry: %s\n", iface); + if (config_setting_lookup_string(cfg, "dst_mac", &val_str) == CONFIG_TRUE) { + if (odph_eth_addr_parse(&dst_mac, val_str) < 0) { + ODPH_ERR("Syntax error in destination MAC for forwarding entry\n"); + return; + } + } else { return; } + entry = &config->fwd_entries[config->num_fwds]; entry->dst_mac = dst_mac; + entry->pktio = pktio; prefix.ip = dst_ip; prefix.cidr = mask; entry->prefix = prefix; ++config->num_fwds; } -static void parse_fwd_table(prog_config_t *config) +static void parse_fwd_table(config_t *cfg, prog_config_t *config) { - FILE *file; - char dst_ip[16U] = { 0 }, iface[64U] = { 0 }, dst_mac[18U] = { 0 }; - uint32_t mask; + config_setting_t *cs; + int count; - if (config->fwd_conf_file == NULL) { - ODPH_ERR("Invalid forwarding configuration file\n"); + cs = config_lookup(cfg, "fwd"); + + if (cs == NULL) return; - } - file = fopen(config->fwd_conf_file, "r"); + count = config_setting_length(cs); - if (file == NULL) { - ODPH_ERR("Error opening forwarding configuration file: %s\n", strerror(errno)); - return; - } + for (int i = 0; i < count; i++) { + config_setting_t *fwd = config_setting_get_elem(cs, i); - while (fscanf(file, " %[^/]/%u%s%s", dst_ip, &mask, iface, dst_mac) == 4) - create_fwd_table_entry(dst_ip, iface, dst_mac, mask, config); + if (fwd == NULL) + continue; - (void)fclose(file); + create_fwd_table_entry(fwd, config); + } } static parse_result_t check_options(prog_config_t *config) @@ -1152,11 +1381,6 @@ static parse_result_t check_options(prog_config_t *config) return PRS_NOK; } - if (config->sa_conf_file != NULL && config->num_sas == 0U) { - ODPH_ERR("Invalid SA configuration\n"); - return PRS_NOK; - } - if (config->num_fwds == 0U) { ODPH_ERR("Invalid number of forwarding entries: %u (min: 1, max: %u)\n", config->num_fwds, MAX_FWDS); @@ -1198,24 +1422,24 @@ static parse_result_t check_options(prog_config_t *config) static parse_result_t parse_options(int argc, char **argv, prog_config_t *config) { int opt, long_index; + config_t cfg; static const struct option longopts[] = { - { "interfaces", required_argument, NULL, 'i'}, - { "num_pkts", required_argument, NULL, 'n'}, - { "pkt_len", required_argument, NULL, 'l'}, + { "interfaces", required_argument, NULL, 'i' }, + { "num_pkts", required_argument, NULL, 'n' }, + { "pkt_len", required_argument, NULL, 'l' }, { "count", required_argument, NULL, 'c' }, { "mode", required_argument, NULL, 'm' }, - { "sa", required_argument, NULL, 's'}, - { "fwd_table", required_argument, NULL, 'f' }, + { "conf", required_argument, NULL, 'C' }, { "num_input_qs", required_argument, NULL, 'I' }, { "num_sa_qs", required_argument, NULL, 'S' }, { "num_output_qs", required_argument, NULL, 'O' }, - { "direct_rx", no_argument, NULL, 'd'}, + { "direct_rx", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; - static const char *shortopts = "i:n:l:c:m:s:f:I:S:O:dh"; + static const char *shortopts = "i:n:l:c:m:C:I:S:O:dh"; while (true) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); @@ -1239,11 +1463,8 @@ static parse_result_t parse_options(int argc, char **argv, prog_config_t *config case 'm': config->mode = !!atoi(optarg); break; - case 's': - config->sa_conf_file = strdup(optarg); - break; - case 'f': - config->fwd_conf_file = strdup(optarg); + case 'C': + config->conf_file = strdup(optarg); break; case 'I': config->num_input_qs = atoi(optarg); @@ -1267,8 +1488,17 @@ static parse_result_t parse_options(int argc, char **argv, prog_config_t *config } } - parse_sas(config); - parse_fwd_table(config); + config_init(&cfg); + + if (config_read_file(&cfg, config->conf_file) == CONFIG_FALSE) { + ODPH_ERR("Error opening SA configuration file: %s\n", config_error_text(&cfg)); + config_destroy(&cfg); + return PRS_NOK; + } + + parse_sas(&cfg, config); + parse_fwd_table(&cfg, config); + config_destroy(&cfg); return check_options(config); } @@ -1686,8 +1916,7 @@ static void teardown_test(const prog_config_t *config) if (config->compl_q != ODP_QUEUE_INVALID) (void)odp_queue_destroy(config->compl_q); - free(config->sa_conf_file); - free(config->fwd_conf_file); + free(config->conf_file); } static void print_stats(const prog_config_t *config) diff --git a/test/performance/odp_ipsecfwd.conf b/test/performance/odp_ipsecfwd.conf new file mode 100644 index 000000000..81ddaef7e --- /dev/null +++ b/test/performance/odp_ipsecfwd.conf @@ -0,0 +1,41 @@ +default: { + dir = 1 + proto = 0 + mode = 0 + crypto: { + cipher_alg = 4 + cipher_key = "jWnZr4t7w!zwC*F-" + auth_alg = 2 + auth_key = "n2r5u7x!A%D*" + icv_len = 12 + }; +}; + +sa: ( + { + spi = 1337 + outbound: { + tunnel: { + src_addr = "192.168.1.10" + dst_addr = "192.168.1.16" + }; + }; + }, + { + spi = 1338 + outbound: { + tunnel: { + src_addr = "192.168.3.110" + dst_addr = "192.168.3.116" + }; + }; + } +); + +fwd: ( + { + prefix: "192.168.1.0/24" + if: "ens9f1" + dst_mac: "00:00:05:00:07:00" + } +); diff --git a/test/performance/odp_packet_gen.c b/test/performance/odp_packet_gen.c index e02ffe95e..85b0c740b 100644 --- a/test/performance/odp_packet_gen.c +++ b/test/performance/odp_packet_gen.c @@ -1312,7 +1312,6 @@ static int init_packets(test_global_t *global, int pktio, void *data; uint8_t *u8; odph_ethhdr_t *eth; - odph_vlanhdr_t *vlan; odph_ipv4hdr_t *ip; odph_udphdr_t *udp; uint16_t tpid; @@ -1323,6 +1322,7 @@ static int init_packets(test_global_t *global, int pktio, uint16_t udp_dst = test_options->udp_dst; uint32_t udp_src_cnt = 0; uint32_t udp_dst_cnt = 0; + odph_vlanhdr_t *vlan = NULL; /* Fixes bogus compiler warning */ if (num_vlan > MAX_VLANS) num_vlan = MAX_VLANS; diff --git a/test/performance/odp_timer_perf.c b/test/performance/odp_timer_perf.c index ccea30a14..3df9a875f 100644 --- a/test/performance/odp_timer_perf.c +++ b/test/performance/odp_timer_perf.c @@ -292,6 +292,8 @@ static int create_timer_pools(test_global_t *global) printf(" num timer %u\n", num_timer); printf(" resolution %" PRIu64 " nsec\n", res_ns); printf(" period %" PRIu64 " nsec\n", period_ns); + printf(" max timeout %" PRIu64 " nsec\n", max_tmo_ns); + printf(" min timeout %" PRIu64 " nsec\n", min_tmo_ns); printf(" first timer at %.2f sec\n", (double)START_NS / ODP_TIME_SEC_IN_NS); if (mode == MODE_SCHED_OVERH) printf(" test duration %.2f sec\n", (double)max_tmo_ns / ODP_TIME_SEC_IN_NS); diff --git a/test/validation/api/classification/odp_classification_basic.c b/test/validation/api/classification/odp_classification_basic.c index f7aa96e52..2969dedab 100644 --- a/test/validation/api/classification/odp_classification_basic.c +++ b/test/validation/api/classification/odp_classification_basic.c @@ -203,13 +203,14 @@ static void classification_test_create_pmr_match(void) retval = odp_cls_pmr_destroy(ODP_PMR_INVALID); CU_ASSERT(retval < 0); + odp_cos_destroy(cos); odp_queue_destroy(queue); odp_pool_destroy(pool); odp_pool_destroy(pkt_pool); - odp_cos_destroy(cos); + odp_pktio_default_cos_set(pktio, ODP_COS_INVALID); + odp_cos_destroy(default_cos); odp_queue_destroy(default_queue); odp_pool_destroy(default_pool); - odp_cos_destroy(default_cos); odp_pktio_close(pktio); } @@ -401,13 +402,14 @@ static void classification_test_pmr_composite_create(void) retval = odp_cls_pmr_destroy(pmr_composite); CU_ASSERT(retval == 0); + odp_cos_destroy(cos); odp_queue_destroy(queue); odp_pool_destroy(pool); odp_pool_destroy(pkt_pool); - odp_cos_destroy(cos); + odp_pktio_default_cos_set(pktio, ODP_COS_INVALID); + odp_cos_destroy(default_cos); odp_queue_destroy(default_queue); odp_pool_destroy(default_pool); - odp_cos_destroy(default_cos); odp_pktio_close(pktio); } diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index 0b29783c0..bf067719b 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -194,9 +194,10 @@ static void classification_test_pktin_classifier_flag(void) CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); odp_packet_free(pkt); + odp_cls_pmr_destroy(pmr); odp_cos_destroy(cos); + odp_pktio_default_cos_set(pktio, ODP_COS_INVALID); odp_cos_destroy(default_cos); - odp_cls_pmr_destroy(pmr); stop_pktio(pktio); odp_queue_destroy(queue); odp_queue_destroy(default_queue); @@ -366,9 +367,10 @@ static void _classification_test_pmr_term_tcp_dport(int num_pkt) CU_ASSERT(sent_queue == recv_queue); CU_ASSERT(sent_default == recv_default); + odp_cls_pmr_destroy(pmr); odp_cos_destroy(cos); + odp_pktio_default_cos_set(pktio, ODP_COS_INVALID); odp_cos_destroy(default_cos); - odp_cls_pmr_destroy(pmr); stop_pktio(pktio); odp_queue_destroy(queue); odp_queue_destroy(default_queue); @@ -457,9 +459,10 @@ static void test_pmr(const odp_pmr_param_t *pmr_param, odp_packet_t pkt, } odp_packet_free(pkt); + odp_cls_pmr_destroy(pmr); odp_cos_destroy(cos); + odp_pktio_default_cos_set(pktio, ODP_COS_INVALID); odp_cos_destroy(default_cos); - odp_cls_pmr_destroy(pmr); /* XXX ordering */ stop_pktio(pktio); odp_pool_destroy(default_pool); odp_pool_destroy(pool); @@ -747,9 +750,10 @@ static void classification_test_pmr_term_dmac(void) CU_ASSERT(recvpool == default_pool); CU_ASSERT(retqueue == default_queue); + odp_cls_pmr_destroy(pmr); odp_cos_destroy(cos); + odp_pktio_default_cos_set(pktio, ODP_COS_INVALID); odp_cos_destroy(default_cos); - odp_cls_pmr_destroy(pmr); odp_packet_free(pkt); stop_pktio(pktio); odp_pool_destroy(default_pool); @@ -1080,9 +1084,10 @@ static void classification_test_pmr_pool_set(void) CU_ASSERT(retqueue == queue); odp_packet_free(pkt); + odp_cls_pmr_destroy(pmr); odp_cos_destroy(cos); + odp_pktio_default_cos_set(pktio, ODP_COS_INVALID); odp_cos_destroy(default_cos); - odp_cls_pmr_destroy(pmr); stop_pktio(pktio); odp_pool_destroy(default_pool); odp_pool_destroy(pool); @@ -1180,9 +1185,10 @@ static void classification_test_pmr_queue_set(void) CU_ASSERT(retqueue == queue_new); odp_packet_free(pkt); + odp_cls_pmr_destroy(pmr); odp_cos_destroy(cos); + odp_pktio_default_cos_set(pktio, ODP_COS_INVALID); odp_cos_destroy(default_cos); - odp_cls_pmr_destroy(pmr); stop_pktio(pktio); odp_pool_destroy(default_pool); odp_pool_destroy(pool); @@ -1603,15 +1609,15 @@ static void test_pmr_series(const int num_udp, int marking) CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); CU_ASSERT(retqueue == default_queue); odp_packet_free(pkt); + odp_cls_pmr_destroy(pmr_ip); for (i = 0; i < num_udp; i++) { - odp_cos_destroy(cos_udp[i]); odp_cls_pmr_destroy(pmr_udp[i]); + odp_cos_destroy(cos_udp[i]); } odp_cos_destroy(cos_ip); - odp_cls_pmr_destroy(pmr_ip); - + odp_pktio_default_cos_set(pktio, ODP_COS_INVALID); odp_cos_destroy(default_cos); stop_pktio(pktio); odp_pool_destroy(default_pool); diff --git a/test/validation/api/classification/odp_classification_tests.c b/test/validation/api/classification/odp_classification_tests.c index 962885c06..002beb2aa 100644 --- a/test/validation/api/classification/odp_classification_tests.c +++ b/test/validation/api/classification/odp_classification_tests.c @@ -162,6 +162,16 @@ static int classification_suite_common_term(odp_bool_t enable_pktv) retcode = -1; } + for (i = 0; i < CLS_ENTRIES; i++) { + if (pmr_list[i] != ODP_PMR_INVALID) + odp_cls_pmr_destroy(pmr_list[i]); + } + + for (i = 0; i < CLS_ENTRIES; i++) { + if (cos_list[i] != ODP_COS_INVALID) + odp_cos_destroy(cos_list[i]); + } + if (0 != odp_pool_destroy(pool_default)) { ODPH_ERR("Pool_default destroy failed\n"); retcode = -1; @@ -175,16 +185,6 @@ static int classification_suite_common_term(odp_bool_t enable_pktv) } for (i = 0; i < CLS_ENTRIES; i++) { - if (cos_list[i] != ODP_COS_INVALID) - odp_cos_destroy(cos_list[i]); - } - - for (i = 0; i < CLS_ENTRIES; i++) { - if (pmr_list[i] != ODP_PMR_INVALID) - odp_cls_pmr_destroy(pmr_list[i]); - } - - for (i = 0; i < CLS_ENTRIES; i++) { if (queue_list[i] != ODP_QUEUE_INVALID) odp_queue_destroy(queue_list[i]); } diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c index 7d5e50c71..c6a7767cc 100644 --- a/test/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/validation/api/crypto/odp_crypto_test_inp.c @@ -6,14 +6,23 @@ */ #include <string.h> +#include <stdlib.h> #include <odp_api.h> #include <odp/helper/odph_api.h> #include <odp_cunit_common.h> #include <packet_common.h> #include "test_vectors.h" +/* + * If nonzero, run time consuming tests too. + * Set through FULL_TEST environment variable. + */ +static int full_test; + +#define MAX_FAILURE_PRINTS 20 + #define PKT_POOL_NUM 64 -#define PKT_POOL_LEN (1 * 1024) +#define PKT_POOL_LEN 1200 /* enough for a test packet and some headroom */ #define UAREA_SIZE 8 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) @@ -40,9 +49,6 @@ static void test_defaults(uint8_t fill) CU_ASSERT_EQUAL(param.op, ODP_CRYPTO_OP_ENCODE); CU_ASSERT_EQUAL(param.op_type, ODP_CRYPTO_OP_TYPE_LEGACY); CU_ASSERT_EQUAL(param.auth_cipher_text, false); -#if ODP_DEPRECATED_API - CU_ASSERT_EQUAL(param.pref_mode, ODP_CRYPTO_SYNC); -#endif CU_ASSERT_EQUAL(param.op_mode, ODP_CRYPTO_SYNC); CU_ASSERT_EQUAL(param.cipher_alg, ODP_CIPHER_ALG_NULL); CU_ASSERT_EQUAL(param.cipher_iv_len, 0); @@ -151,88 +157,6 @@ static const char *cipher_alg_name(odp_cipher_alg_t cipher) } } -#if ODP_DEPRECATED_API -static int alg_op(odp_packet_t pkt, - odp_bool_t *ok, - odp_crypto_session_t session, - uint8_t *cipher_iv_ptr, - uint8_t *auth_iv_ptr, - odp_packet_data_range_t *cipher_range, - odp_packet_data_range_t *auth_range, - uint8_t *aad, - unsigned int hash_result_offset) -{ - int rc; - odp_crypto_op_result_t result; - odp_crypto_op_param_t op_params; - odp_bool_t posted; - odp_event_subtype_t subtype; - - /* Prepare input/output params */ - memset(&op_params, 0, sizeof(op_params)); - op_params.session = session; - op_params.pkt = pkt; - op_params.out_pkt = pkt; - op_params.ctx = (void *)0xdeadbeef; - - op_params.cipher_range = *cipher_range; - op_params.auth_range = *auth_range; - if (cipher_iv_ptr) - op_params.cipher_iv_ptr = cipher_iv_ptr; - if (auth_iv_ptr) - op_params.auth_iv_ptr = auth_iv_ptr; - - op_params.aad_ptr = aad; - - op_params.hash_result_offset = hash_result_offset; - - rc = odp_crypto_operation(&op_params, &posted, &result); - if (rc < 0) { - CU_FAIL("Failed odp_crypto_operation()"); - return rc; - } - - if (posted) { - odp_event_t event; - odp_crypto_compl_t compl_event; - - /* Get crypto completion event from compl_queue. */ - CU_ASSERT_FATAL(NULL != suite_context.compl_queue_deq); - do { - event = suite_context.compl_queue_deq(); - } while (event == ODP_EVENT_INVALID); - - CU_ASSERT(odp_event_is_valid(event) == 1); - CU_ASSERT(ODP_EVENT_CRYPTO_COMPL == odp_event_type(event)); - CU_ASSERT(ODP_EVENT_NO_SUBTYPE == odp_event_subtype(event)); - CU_ASSERT(ODP_EVENT_CRYPTO_COMPL == - odp_event_types(event, &subtype)); - CU_ASSERT(ODP_EVENT_NO_SUBTYPE == subtype); - - compl_event = odp_crypto_compl_from_event(event); - CU_ASSERT(odp_crypto_compl_to_u64(compl_event) == - odp_crypto_compl_to_u64( - odp_crypto_compl_from_event(event))); - odp_crypto_compl_result(compl_event, &result); - odp_crypto_compl_free(compl_event); - } - - CU_ASSERT(result.pkt == pkt); - CU_ASSERT(result.ctx == (void *)0xdeadbeef); - CU_ASSERT(ODP_EVENT_PACKET == - odp_event_type(odp_packet_to_event(result.pkt))); - CU_ASSERT(ODP_EVENT_PACKET_BASIC == - odp_event_subtype(odp_packet_to_event(result.pkt))); - CU_ASSERT(ODP_EVENT_PACKET == - odp_event_types(odp_packet_to_event(result.pkt), &subtype)); - CU_ASSERT(ODP_EVENT_PACKET_BASIC == subtype); - - *ok = result.ok; - - return 0; -} -#endif - static int alg_packet_op(odp_packet_t pkt_in, odp_packet_t *pkt_out, odp_bool_t *ok, @@ -241,8 +165,8 @@ static int alg_packet_op(odp_packet_t pkt_in, int32_t oop_shift, uint8_t *cipher_iv_ptr, uint8_t *auth_iv_ptr, - odp_packet_data_range_t *cipher_range, - odp_packet_data_range_t *auth_range, + const odp_packet_data_range_t *cipher_range, + const odp_packet_data_range_t *auth_range, uint8_t *aad, unsigned int hash_result_offset) { @@ -319,17 +243,21 @@ static int alg_packet_op(odp_packet_t pkt_in, CU_ASSERT(odp_packet_subtype(*pkt_out) == ODP_EVENT_PACKET_CRYPTO); rc = odp_crypto_result(&result, *pkt_out); - if (rc < 0) { + if (rc < -1) { CU_FAIL("Failed odp_crypto_packet_result()"); return rc; } - CU_ASSERT(rc == 0); + CU_ASSERT(rc == 0 || rc == -1); if (op_type == ODP_CRYPTO_OP_TYPE_OOP && suite_context.op_mode == ODP_CRYPTO_ASYNC) CU_ASSERT(result.pkt_in == pkt_in); - *ok = result.ok; + *ok = (rc == 0); + +#if ODP_DEPRECATED_API + CU_ASSERT(*ok == result.ok); +#endif return 0; } @@ -342,30 +270,18 @@ static int crypto_op(odp_packet_t pkt_in, int32_t oop_shift, uint8_t *cipher_iv, uint8_t *auth_iv, - odp_packet_data_range_t *cipher_range, - odp_packet_data_range_t *auth_range, + const odp_packet_data_range_t *cipher_range, + const odp_packet_data_range_t *auth_range, uint8_t *aad, unsigned int hash_result_offset) { int rc; - if (!suite_context.packet) { -#if ODP_DEPRECATED_API - rc = alg_op(pkt_in, ok, session, - cipher_iv, auth_iv, - cipher_range, auth_range, - aad, hash_result_offset); - *pkt_out = pkt_in; -#else - rc = -1; -#endif - } else { - rc = alg_packet_op(pkt_in, pkt_out, ok, session, - op_type, oop_shift, - cipher_iv, auth_iv, - cipher_range, auth_range, - aad, hash_result_offset); - } + rc = alg_packet_op(pkt_in, pkt_out, ok, session, + op_type, oop_shift, + cipher_iv, auth_iv, + cipher_range, auth_range, + aad, hash_result_offset); if (rc < 0) odp_packet_free(pkt_in); @@ -407,8 +323,10 @@ static void adjust_segments(odp_packet_t *pkt, uint32_t first_seg_len) static void fill_with_pattern(uint8_t *buf, uint32_t len) { + static uint8_t value; + for (uint32_t n = 0; n < len; n++) - buf[n] = n; + buf[n] = value++; } static void write_header_and_trailer(odp_packet_t pkt, @@ -435,6 +353,8 @@ typedef struct alg_test_param_t { odp_cipher_alg_t cipher_alg; odp_auth_alg_t auth_alg; crypto_test_reference_t *ref; + odp_packet_data_range_t cipher_range; + odp_packet_data_range_t auth_range; uint32_t digest_offset; odp_bool_t is_bit_mode_cipher; odp_bool_t is_bit_mode_auth; @@ -450,23 +370,14 @@ static void prepare_crypto_ranges(const alg_test_param_t *param, odp_packet_data_range_t *auth_range) { odp_packet_data_range_t zero_range = {.offset = 0, .length = 0}; + uint32_t c_scale = param->is_bit_mode_cipher ? 8 : 1; + uint32_t a_scale = param->is_bit_mode_auth ? 8 : 1; + + *cipher_range = param->cipher_range; + *auth_range = param->auth_range; + cipher_range->offset += c_scale * param->header_len; + auth_range->offset += a_scale * param->header_len; - cipher_range->offset = param->header_len; - cipher_range->length = ref_length_in_bytes(param->ref); - auth_range->offset = param->header_len; - auth_range->length = ref_length_in_bytes(param->ref); - if (param->is_bit_mode_cipher) { - cipher_range->offset *= 8; - cipher_range->length = ref_length_in_bits(param->ref); - } - if (param->is_bit_mode_auth) { - auth_range->offset *= 8; - auth_range->length = ref_length_in_bits(param->ref); - } - /* - * We did not check the bit mode of the null algorithms, so let's - * not pass potentially invalid ranges to them. - */ if (param->cipher_alg == ODP_CIPHER_ALG_NULL) *cipher_range = zero_range; if (param->auth_alg == ODP_AUTH_ALG_NULL) @@ -571,7 +482,7 @@ static int is_in_range(uint32_t offs, uint32_t range_offs, uint32_t range_len) */ typedef struct ignore_t { uint32_t byte_offset; /* offset to a byte which has bits to be ignored */ - uint32_t byte_mask; /* mask of ignored bits in the byte */ + uint8_t byte_mask; /* mask of ignored bits in the byte */ struct { uint32_t offset; uint32_t length; @@ -619,10 +530,13 @@ static void prepare_ignore_info(const alg_test_param_t *param, */ if (param->is_bit_mode_cipher && param->cipher_alg != ODP_CIPHER_ALG_NULL) { - uint8_t leftover_bits = param->ref->length % 8; + uint8_t leftover_bits = ref_length_in_bits(param->ref) % 8; ignore->byte_offset = cipher_offset + cipher_len - 1 + shift; - ignore->byte_mask = ~(0xff << (8 - leftover_bits)); + if (leftover_bits > 0) + ignore->byte_mask = ~(0xff << (8 - leftover_bits)); + else + ignore->byte_mask = 0; } /* @@ -679,11 +593,13 @@ static void prepare_expected_data(const alg_test_param_t *param, const int32_t shift = param->op_type == ODP_CRYPTO_OP_TYPE_OOP ? param->oop_shift : 0; const odp_packet_t base_pkt = param->op_type == ODP_CRYPTO_OP_TYPE_OOP ? pkt_out : pkt_in; int rc; + uint32_t cipher_offset_in_ref = param->cipher_range.offset; if (param->op == ODP_CRYPTO_OP_ENCODE) digest_offset += shift; if (param->is_bit_mode_cipher) { + cipher_offset_in_ref /= 8; cipher_offset /= 8; cipher_len = (cipher_len + 7) / 8; } @@ -725,11 +641,11 @@ static void prepare_expected_data(const alg_test_param_t *param, * text) does not work in any real use case anyway. */ memcpy(ex->data + cipher_offset + shift, - param->ref->ciphertext, + param->ref->ciphertext + cipher_offset_in_ref, cipher_len); } else { memcpy(ex->data + cipher_offset + shift, - param->ref->plaintext, + param->ref->plaintext + cipher_offset_in_ref, cipher_len); } @@ -743,7 +659,7 @@ static void print_data(const char *title, uint8_t *data, uint32_t len) { static uint64_t limit; - if (limit++ > 20) + if (limit++ > MAX_FAILURE_PRINTS) return; printf("%s\n", title); @@ -830,14 +746,7 @@ static void alg_test_execute(const alg_test_param_t *param) param->ref->aad, digest_offset)) return; - /* - * API is not explicit about whether a failed crypto op - * sets the has_error packet flag or leaves it unchanged. - * Let's allow both behaviours. - */ test_packet_get_md(pkt_out, &md_out); - if (param->wrong_digest) - md_out.has_error = 0; if (param->op_type == ODP_CRYPTO_OP_TYPE_OOP) { test_packet_md_t md; @@ -855,15 +764,89 @@ static void alg_test_execute(const alg_test_param_t *param) CU_ASSERT(test_packet_is_md_equal(&md_out, &md_in)); } + if (param->cipher_alg != ODP_CIPHER_ALG_NULL && + param->auth_alg != ODP_AUTH_ALG_NULL && + param->digest_offset >= cipher_range.offset && + param->digest_offset < cipher_range.offset + cipher_range.length) { + /* + * Not all implementations support digest offset in cipher + * range, so allow crypto op failure without further checks + * in this case. + */ + if (!ok) + goto out; + } + if (param->wrong_digest) { CU_ASSERT(!ok); } else { CU_ASSERT(ok); } check_output_packet_data(pkt_out, &expected); +out: odp_packet_free(pkt_out); } +static void print_alg_test_param(const alg_test_param_t *p) +{ + const char *cipher_mode = p->is_bit_mode_cipher ? "bit" : "byte"; + const char *auth_mode = p->is_bit_mode_auth ? "bit" : "byte"; + + switch (p->op_type) { + case ODP_CRYPTO_OP_TYPE_LEGACY: + printf("legacy "); + break; + case ODP_CRYPTO_OP_TYPE_BASIC: + printf("basic "); + break; + case ODP_CRYPTO_OP_TYPE_OOP: + printf("out-of-place "); + break; + } + printf("%s\n", p->op == ODP_CRYPTO_OP_ENCODE ? "encode" : "decode"); + + printf("cipher: %s, %s mode\n", cipher_alg_name(p->cipher_alg), cipher_mode); + printf(" key length: %d, iv length: %d\n", + p->ref->cipher_key_length, p->ref->cipher_iv_length); + printf(" range: offset %d, length %d\n", + p->cipher_range.offset, p->cipher_range.length); + + printf("auth: %s, %s mode\n", auth_alg_name(p->auth_alg), auth_mode); + printf(" key length: %d, iv length: %d\n", + p->ref->auth_key_length, p->ref->auth_iv_length); + printf(" range: offset %d, length %d; aad length: %d\n", + p->auth_range.offset, p->auth_range.length, p->ref->aad_length); + printf(" digest offset: %d, digest length %d\n", + p->digest_offset, p->ref->digest_length); + + if (p->wrong_digest) + printf("wrong digest test\n"); + printf("header length: %d, trailer length: %d\n", p->header_len, p->trailer_len); + if (p->adjust_segmentation) + printf("segmentation adjusted, first_seg_len: %d\n", p->first_seg_len); + if (p->op_type == ODP_CRYPTO_OP_TYPE_OOP) + printf("oop_shift: %d\n", p->oop_shift); +} + +static void alg_test_execute_and_print(alg_test_param_t *param) +{ + static int print_limit = MAX_FAILURE_PRINTS; + unsigned int num = CU_get_number_of_failures(); + + alg_test_execute(param); + + if (CU_get_number_of_failures() > num) { + if (print_limit > 0) { + printf("\nTest failed:\n"); + print_alg_test_param(param); + printf("\n"); + print_limit--; + if (print_limit == 0) + printf("Suppressing further failure output\n"); + } + } +} + static void alg_test_op(alg_test_param_t *param) { int32_t oop_shifts[] = {0, 3, 130, -10}; @@ -877,13 +860,15 @@ static void alg_test_op(alg_test_param_t *param) param->oop_shift = oop_shifts[n]; param->wrong_digest = false; - alg_test_execute(param); - alg_test_execute(param); /* rerun with the same parameters */ + alg_test_execute_and_print(param); + if (full_test) + alg_test_execute_and_print(param); /* rerun with the same parameters */ param->wrong_digest = true; - alg_test_execute(param); + alg_test_execute_and_print(param); } } +static int combo_warning_shown; static int oop_warning_shown; typedef enum { @@ -891,10 +876,16 @@ typedef enum { HASH_OVERLAP, } hash_test_mode_t; +typedef enum { + AUTH_CIPHERTEXT, + AUTH_PLAINTEXT +} alg_order_t; + static odp_crypto_session_t session_create(odp_crypto_op_t op, odp_crypto_op_type_t op_type, odp_cipher_alg_t cipher_alg, odp_auth_alg_t auth_alg, + alg_order_t order, crypto_test_reference_t *ref, hash_test_mode_t hash_mode) { @@ -920,11 +911,8 @@ static odp_crypto_session_t session_create(odp_crypto_op_t op, odp_crypto_session_param_init(&ses_params); ses_params.op = op; ses_params.op_type = op_type; - ses_params.auth_cipher_text = false; + ses_params.auth_cipher_text = (order == AUTH_CIPHERTEXT); ses_params.op_mode = suite_context.op_mode; -#if ODP_DEPRECATED_API - ses_params.pref_mode = suite_context.pref_mode; -#endif ses_params.cipher_alg = cipher_alg; ses_params.auth_alg = auth_alg; ses_params.compl_queue = suite_context.queue; @@ -936,17 +924,29 @@ static odp_crypto_session_t session_create(odp_crypto_op_t op, ses_params.auth_digest_len = ref->digest_length; ses_params.auth_aad_len = ref->aad_length; ses_params.hash_result_in_auth_range = (hash_mode == HASH_OVERLAP); - rc = odp_crypto_session_create(&ses_params, &session, &status); + + if (rc < 0 && status == ODP_CRYPTO_SES_ERR_ALG_COMBO) { + if (!combo_warning_shown) { + combo_warning_shown = 1; + printf("\n Unsupported algorithm combination: %s, %s\n", + cipher_alg_name(cipher_alg), + auth_alg_name(auth_alg)); + } + return ODP_CRYPTO_SESSION_INVALID; + } + /* - * In some cases an individual algorithm cannot be used alone, - * i.e. with the null cipher/auth algorithm. + * Allow ODP_CRYPTO_SES_ERR_ALG_ORDER only in async op mode. + * In sync mode an implementation should be able to support both + * orders without much difficulty. */ - if (rc < 0 && - status == ODP_CRYPTO_SES_ERR_ALG_COMBO) { - printf("\n Unsupported algorithm combination: %s, %s\n", + if (rc < 0 && status == ODP_CRYPTO_SES_ERR_ALG_ORDER && + ses_params.op_mode == ODP_CRYPTO_ASYNC) { + printf("\n Unsupported algorithm order: %s, %s, auth_cipher_text: %d\n", cipher_alg_name(cipher_alg), - auth_alg_name(auth_alg)); + auth_alg_name(auth_alg), + ses_params.auth_cipher_text); return ODP_CRYPTO_SESSION_INVALID; } @@ -959,12 +959,6 @@ static odp_crypto_session_t session_create(odp_crypto_op_t op, return ODP_CRYPTO_SESSION_INVALID; } - /* - * We do not allow ODP_CRYPTO_SES_ERR_ALG_ORDER since we do - * not combine individual non-null crypto and auth algorithms - * with each other in the tests. Both orders should work when - * only one algorithm is used (i.e. the other one is null). - */ CU_ASSERT_FATAL(!rc); CU_ASSERT(status == ODP_CRYPTO_SES_ERR_NONE); CU_ASSERT(odp_crypto_session_to_u64(session) != @@ -985,22 +979,28 @@ static void alg_test_ses(odp_crypto_op_t op, odp_crypto_op_type_t op_type, odp_cipher_alg_t cipher_alg, odp_auth_alg_t auth_alg, + alg_order_t order, crypto_test_reference_t *ref, + odp_packet_data_range_t cipher_range, + odp_packet_data_range_t auth_range, uint32_t digest_offset, odp_bool_t is_bit_mode_cipher, odp_bool_t is_bit_mode_auth) { unsigned int initial_num_failures = CU_get_number_of_failures(); const uint32_t reflength = ref_length_in_bytes(ref); - const hash_test_mode_t hash_mode = digest_offset < reflength ? HASH_OVERLAP - : HASH_NO_OVERLAP; + hash_test_mode_t hash_mode = HASH_NO_OVERLAP; odp_crypto_session_t session; int rc; uint32_t seg_len; uint32_t max_shift; alg_test_param_t test_param; - session = session_create(op, op_type, cipher_alg, auth_alg, ref, hash_mode); + if (digest_offset >= auth_range.offset && + digest_offset < auth_range.offset + auth_range.length) + hash_mode = HASH_OVERLAP; + + session = session_create(op, op_type, cipher_alg, auth_alg, order, ref, hash_mode); if (session == ODP_CRYPTO_SESSION_INVALID) return; @@ -1011,6 +1011,8 @@ static void alg_test_ses(odp_crypto_op_t op, test_param.cipher_alg = cipher_alg; test_param.auth_alg = auth_alg; test_param.ref = ref; + test_param.cipher_range = cipher_range; + test_param.auth_range = auth_range; test_param.is_bit_mode_cipher = is_bit_mode_cipher; test_param.is_bit_mode_auth = is_bit_mode_auth; test_param.digest_offset = digest_offset; @@ -1018,12 +1020,21 @@ static void alg_test_ses(odp_crypto_op_t op, alg_test_op(&test_param); max_shift = reflength + ref->digest_length; + seg_len = 0; + + if (!full_test && + cipher_alg != ODP_CIPHER_ALG_NULL && + auth_alg != ODP_AUTH_ALG_NULL) { + /* run the loop body just once */ + seg_len = max_shift / 2; + max_shift = seg_len; + } /* * Test with segmented packets with all possible segment boundaries * within the packet data */ - for (seg_len = 0; seg_len <= max_shift; seg_len++) { + for (; seg_len <= max_shift; seg_len++) { /* * CUnit chokes on too many assertion failures, so bail * out if this test has already failed. @@ -1052,7 +1063,10 @@ static void alg_test_ses(odp_crypto_op_t op, static void alg_test(odp_crypto_op_t op, odp_cipher_alg_t cipher_alg, odp_auth_alg_t auth_alg, + alg_order_t order, crypto_test_reference_t *ref, + odp_packet_data_range_t cipher_range, + odp_packet_data_range_t auth_range, uint32_t digest_offset, odp_bool_t is_bit_mode_cipher, odp_bool_t is_bit_mode_auth) @@ -1071,7 +1085,10 @@ static void alg_test(odp_crypto_op_t op, op_types[n], cipher_alg, auth_alg, + order, ref, + cipher_range, + auth_range, digest_offset, is_bit_mode_cipher, is_bit_mode_auth); @@ -1131,6 +1148,8 @@ static void check_alg(odp_crypto_op_t op, odp_bool_t is_bit_mode_cipher = false; odp_bool_t is_bit_mode_auth = false; uint32_t digest_offs = ref_length_in_bytes(&ref[idx]); + odp_packet_data_range_t cipher_range = {.offset = 0}; + odp_packet_data_range_t auth_range = {.offset = 0}; if (ref_length_in_bits(&ref[idx]) % 8 != 0) bit_mode_needed = true; @@ -1190,7 +1209,18 @@ static void check_alg(odp_crypto_op_t op, continue; } - alg_test(op, cipher_alg, auth_alg, &ref[idx], digest_offs, + cipher_range.length = is_bit_mode_cipher ? + ref_length_in_bits(&ref[idx]) : + ref_length_in_bytes(&ref[idx]); + auth_range.length = is_bit_mode_auth ? + ref_length_in_bits(&ref[idx]) : + ref_length_in_bytes(&ref[idx]); + + alg_test(op, cipher_alg, auth_alg, AUTH_PLAINTEXT, &ref[idx], + cipher_range, auth_range, digest_offs, + is_bit_mode_cipher, is_bit_mode_auth); + alg_test(op, cipher_alg, auth_alg, AUTH_CIPHERTEXT, &ref[idx], + cipher_range, auth_range, digest_offs, is_bit_mode_cipher, is_bit_mode_auth); cipher_tested[cipher_idx] = true; @@ -1252,14 +1282,12 @@ static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth) return ODP_TEST_INACTIVE; } - if (suite_context.packet) { - if (suite_context.op_mode == ODP_CRYPTO_SYNC && - capability.sync_mode == ODP_SUPPORT_NO) - return ODP_TEST_INACTIVE; - if (suite_context.op_mode == ODP_CRYPTO_ASYNC && - capability.async_mode == ODP_SUPPORT_NO) - return ODP_TEST_INACTIVE; - } + if (suite_context.op_mode == ODP_CRYPTO_SYNC && + capability.sync_mode == ODP_SUPPORT_NO) + return ODP_TEST_INACTIVE; + if (suite_context.op_mode == ODP_CRYPTO_ASYNC && + capability.async_mode == ODP_SUPPORT_NO) + return ODP_TEST_INACTIVE; /* Cipher algorithms */ switch (cipher) { @@ -1498,7 +1526,7 @@ static int create_hash_test_reference(odp_auth_alg_t auth, session = session_create(ODP_CRYPTO_OP_ENCODE, ODP_CRYPTO_OP_TYPE_LEGACY, ODP_CIPHER_ALG_NULL, - auth, ref, HASH_NO_OVERLAP); + auth, AUTH_PLAINTEXT, ref, HASH_NO_OVERLAP); if (session == ODP_CRYPTO_SESSION_INVALID) return -1; @@ -1531,10 +1559,16 @@ static int create_hash_test_reference(odp_auth_alg_t auth, } static void test_auth_hash_in_auth_range(odp_auth_alg_t auth, - const odp_crypto_auth_capability_t *capa) + const odp_crypto_auth_capability_t *capa, + alg_order_t order) { static crypto_test_reference_t ref = {.length = 0}; uint32_t digest_offset = 13; + const odp_packet_data_range_t cipher_range = {.offset = 0, .length = 0}; + odp_packet_data_range_t auth_range; + + if (!full_test && capa->digest_len % 4 != 0) + return; /* * Create test packets with auth hash in the authenticated range and @@ -1543,6 +1577,11 @@ static void test_auth_hash_in_auth_range(odp_auth_alg_t auth, if (create_hash_test_reference(auth, capa, &ref, digest_offset, 0)) return; + auth_range.offset = 0; + auth_range.length = capa->bit_mode ? + ref_length_in_bits(&ref) : + ref_length_in_bytes(&ref); + /* * Decode the ciphertext packet. * @@ -1553,7 +1592,9 @@ static void test_auth_hash_in_auth_range(odp_auth_alg_t auth, alg_test(ODP_CRYPTO_OP_DECODE, ODP_CIPHER_ALG_NULL, auth, + order, &ref, + cipher_range, auth_range, digest_offset, false, capa->bit_mode); @@ -1565,6 +1606,11 @@ static void test_auth_hash_in_auth_range(odp_auth_alg_t auth, if (create_hash_test_reference(auth, capa, &ref, digest_offset, 1)) return; + auth_range.offset = 0; + auth_range.length = capa->bit_mode ? + ref_length_in_bits(&ref) : + ref_length_in_bytes(&ref); + /* * Encode the plaintext packet. * @@ -1575,41 +1621,60 @@ static void test_auth_hash_in_auth_range(odp_auth_alg_t auth, alg_test(ODP_CRYPTO_OP_ENCODE, ODP_CIPHER_ALG_NULL, auth, + order, &ref, + cipher_range, auth_range, digest_offset, false, capa->bit_mode); } +/* + * Cipher algorithms that are not AEAD algorithms + */ +static odp_cipher_alg_t cipher_algs[] = { + ODP_CIPHER_ALG_DES, + ODP_CIPHER_ALG_3DES_CBC, + ODP_CIPHER_ALG_3DES_ECB, + ODP_CIPHER_ALG_AES_CBC, + ODP_CIPHER_ALG_AES_CTR, + ODP_CIPHER_ALG_AES_ECB, + ODP_CIPHER_ALG_AES_CFB128, + ODP_CIPHER_ALG_AES_XTS, + ODP_CIPHER_ALG_KASUMI_F8, + ODP_CIPHER_ALG_SNOW3G_UEA2, + ODP_CIPHER_ALG_AES_EEA2, + ODP_CIPHER_ALG_ZUC_EEA3, +}; + +/* + * Authentication algorithms and hashes that use auth_range + * parameter. AEAD algorithms are excluded. + */ +static odp_auth_alg_t auth_algs[] = { + ODP_AUTH_ALG_MD5_HMAC, + ODP_AUTH_ALG_SHA1_HMAC, + ODP_AUTH_ALG_SHA224_HMAC, + ODP_AUTH_ALG_SHA256_HMAC, + ODP_AUTH_ALG_SHA384_HMAC, + ODP_AUTH_ALG_SHA512_HMAC, + ODP_AUTH_ALG_AES_GMAC, + ODP_AUTH_ALG_AES_CMAC, + ODP_AUTH_ALG_AES_XCBC_MAC, + ODP_AUTH_ALG_KASUMI_F9, + ODP_AUTH_ALG_SNOW3G_UIA2, + ODP_AUTH_ALG_AES_EIA2, + ODP_AUTH_ALG_ZUC_EIA3, + ODP_AUTH_ALG_MD5, + ODP_AUTH_ALG_SHA1, + ODP_AUTH_ALG_SHA224, + ODP_AUTH_ALG_SHA256, + ODP_AUTH_ALG_SHA384, + ODP_AUTH_ALG_SHA512, +}; + static void test_auth_hashes_in_auth_range(void) { - /* - * Authentication algorithms and hashes that use auth_range - * parameter. AEAD algorithms are excluded. - */ - static odp_auth_alg_t auth_algs[] = { - ODP_AUTH_ALG_NULL, - ODP_AUTH_ALG_MD5_HMAC, - ODP_AUTH_ALG_SHA1_HMAC, - ODP_AUTH_ALG_SHA224_HMAC, - ODP_AUTH_ALG_SHA256_HMAC, - ODP_AUTH_ALG_SHA384_HMAC, - ODP_AUTH_ALG_SHA512_HMAC, - ODP_AUTH_ALG_AES_GMAC, - ODP_AUTH_ALG_AES_CMAC, - ODP_AUTH_ALG_AES_XCBC_MAC, - ODP_AUTH_ALG_KASUMI_F9, - ODP_AUTH_ALG_SNOW3G_UIA2, - ODP_AUTH_ALG_AES_EIA2, - ODP_AUTH_ALG_ZUC_EIA3, - ODP_AUTH_ALG_MD5, - ODP_AUTH_ALG_SHA1, - ODP_AUTH_ALG_SHA224, - ODP_AUTH_ALG_SHA256, - ODP_AUTH_ALG_SHA384, - ODP_AUTH_ALG_SHA512, - }; - for (size_t n = 0; n < ARRAY_SIZE(auth_algs); n++) { odp_auth_alg_t auth = auth_algs[n]; int num; @@ -1624,11 +1689,547 @@ static void test_auth_hashes_in_auth_range(void) num = odp_crypto_auth_capability(auth, capa, num); - for (int i = 0; i < num; i++) - test_auth_hash_in_auth_range(auth, &capa[i]); + for (int i = 0; i < num; i++) { + test_auth_hash_in_auth_range(auth, &capa[i], AUTH_PLAINTEXT); + test_auth_hash_in_auth_range(auth, &capa[i], AUTH_CIPHERTEXT); + } } } +/* + * Encode ref->plaintext and save result in ref->ciphertext. + */ +static int crypto_encode_ref(crypto_test_reference_t *ref, + odp_cipher_alg_t cipher, + odp_auth_alg_t auth, + odp_packet_data_range_t cipher_range, + odp_packet_data_range_t auth_range, + uint32_t hash_result_offset) +{ + odp_packet_data_range_t zero_range = {.offset = 0, .length = 0}; + odp_packet_t pkt; + int rc; + odp_crypto_session_t session; + odp_bool_t ok; + + pkt = odp_packet_alloc(suite_context.pool, ref->length); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + + rc = odp_packet_copy_from_mem(pkt, 0, ref->length, ref->plaintext); + CU_ASSERT(rc == 0); + + session = session_create(ODP_CRYPTO_OP_ENCODE, + ODP_CRYPTO_OP_TYPE_LEGACY, + cipher, + auth, + AUTH_PLAINTEXT, + ref, + HASH_OVERLAP); + + if (session == ODP_CRYPTO_SESSION_INVALID) { + odp_packet_free(pkt); + return 1; + } + + if (cipher == ODP_CIPHER_ALG_NULL) + cipher_range = zero_range; + if (auth == ODP_AUTH_ALG_NULL) { + auth_range = zero_range; + hash_result_offset = 0; + } + + CU_ASSERT_FATAL(hash_result_offset + ref->digest_length <= ref->length); + + rc = crypto_op(pkt, &pkt, &ok, session, ODP_CRYPTO_OP_TYPE_LEGACY, 0, + ref->cipher_iv, ref->auth_iv, + &cipher_range, &auth_range, + ref->aad, hash_result_offset); + CU_ASSERT(rc == 0); + CU_ASSERT(ok); + + rc = odp_crypto_session_destroy(session); + CU_ASSERT(rc == 0); + + rc = odp_packet_copy_to_mem(pkt, 0, ref->length, ref->ciphertext); + CU_ASSERT(rc == 0); + + odp_packet_free(pkt); + return 0; +} + +typedef struct crypto_suite_t { + odp_cipher_alg_t cipher; + odp_auth_alg_t auth; + alg_order_t order; + const odp_crypto_cipher_capability_t *cipher_capa; + const odp_crypto_auth_capability_t *auth_capa; +} crypto_suite_t; + +/* + * Create test reference for combined auth & cipher by doing authentication + * and ciphering through separate ODP crypto operations. + */ +static int create_combined_ref(const crypto_suite_t *suite, + crypto_test_reference_t *ref, + odp_packet_data_range_t *cipher_range, + odp_packet_data_range_t *auth_range, + uint32_t digest_offset) +{ + uint32_t total_len; + int rc; + crypto_test_reference_t ref_cipher_only; + crypto_test_reference_t ref_auth_only; + crypto_test_reference_t *first_ref, *second_ref; + odp_auth_alg_t first_auth, second_auth; + odp_cipher_alg_t first_cipher, second_cipher; + + total_len = cipher_range->offset + cipher_range->length; + if (auth_range->offset + auth_range->length > total_len) + total_len = auth_range->offset + auth_range->length; + if (digest_offset + suite->auth_capa->digest_len > total_len) + total_len = digest_offset + suite->auth_capa->digest_len; + + ref->cipher_key_length = suite->cipher_capa->key_len; + ref->cipher_iv_length = suite->cipher_capa->iv_len; + ref->auth_key_length = suite->auth_capa->key_len; + ref->auth_iv_length = suite->auth_capa->iv_len; + ref->digest_length = suite->auth_capa->digest_len; + ref->aad_length = 0; + ref->is_length_in_bits = false; + ref->length = total_len; + + if (suite->cipher_capa->bit_mode) { + cipher_range->offset *= 8; + cipher_range->length *= 8; + } + if (suite->auth_capa->bit_mode) { + auth_range->offset *= 8; + auth_range->length *= 8; + } + + if (ref->auth_key_length > MAX_KEY_LEN || + ref->auth_iv_length > MAX_IV_LEN || + total_len > MAX_DATA_LEN || + digest_offset + ref->digest_length > MAX_DATA_LEN) + CU_FAIL_FATAL("Internal error\n"); + + fill_with_pattern(ref->cipher_key, ref->cipher_key_length); + fill_with_pattern(ref->cipher_iv, ref->cipher_iv_length); + fill_with_pattern(ref->auth_key, ref->auth_key_length); + fill_with_pattern(ref->auth_iv, ref->auth_iv_length); + fill_with_pattern(ref->plaintext, ref->length); + memset(ref->plaintext + digest_offset, 0, ref->digest_length); + + ref_cipher_only = *ref; + ref_cipher_only.auth_key_length = 0; + ref_cipher_only.auth_iv_length = 0; + ref_cipher_only.aad_length = 0; + ref_cipher_only.digest_length = 0; + + ref_auth_only = *ref; + ref_auth_only.cipher_key_length = 0; + ref_auth_only.cipher_iv_length = 0; + + if (suite->order == AUTH_CIPHERTEXT) { + first_ref = &ref_cipher_only; + first_cipher = suite->cipher; + first_auth = ODP_AUTH_ALG_NULL; + second_ref = &ref_auth_only; + second_cipher = ODP_CIPHER_ALG_NULL; + second_auth = suite->auth; + } else { + first_ref = &ref_auth_only; + first_cipher = ODP_CIPHER_ALG_NULL; + first_auth = suite->auth; + second_ref = &ref_cipher_only; + second_cipher = suite->cipher; + second_auth = ODP_AUTH_ALG_NULL; + } + rc = crypto_encode_ref(first_ref, + first_cipher, first_auth, + *cipher_range, *auth_range, + digest_offset); + if (rc) + return 1; + memcpy(second_ref->plaintext, first_ref->ciphertext, ref->length); + rc = crypto_encode_ref(second_ref, + second_cipher, second_auth, + *cipher_range, *auth_range, + digest_offset); + if (rc) + return 1; + memcpy(ref->ciphertext, second_ref->ciphertext, ref->length); + /* + * These may be encrypted bytes, but that is what alg_test wants if + * the digest is encrypted in the input packet. + */ + memcpy(ref->digest, second_ref->ciphertext + digest_offset, ref->digest_length); + + return 0; +} + +/* + * Return cipher range that is at least min_len bytes long, multiple of the + * block size and at least 3 blocks. + */ +static uint32_t get_cipher_range_len(uint32_t min_len) +{ +#define MAX_BLOCK_SIZE 16 + uint32_t bs = MAX_BLOCK_SIZE; + uint32_t len = 3 * bs; + + if (min_len > len) + len = ((min_len + bs - 1) / bs) * bs; + return len; +} + +typedef enum range_overlap_t { + SEPARATE_AUTH_AND_CIPHER_RANGES, + SAME_AUTH_AND_CIPHER_RANGE, + RANGES_PARTIALLY_OVERLAP, + AUTH_RANGE_IN_CIPHER_RANGE, + CIPHER_RANGE_IN_AUTH_RANGE, +} range_overlap_t; +#define NUM_RANGE_OVERLAPS 5 + +typedef enum hash_location_t { + HASH_SEPARATE, + HASH_IN_AUTH_RANGE_ONLY, + HASH_IN_CIPHER_RANGE_ONLY, + HASH_IN_AUTH_AND_CIPHER_RANGE, +} hash_location_t; +#define NUM_HASH_LOCATIONS 4 + +static int make_byte_ranges(range_overlap_t overlap, + hash_location_t hash_location, + uint32_t hash_len, + odp_packet_data_range_t *cipher_range, + odp_packet_data_range_t *auth_range, + uint32_t *digest_offset) +{ + const uint32_t padding = 5; /* padding between parts, could also be zero */ + const uint32_t nonzero_len = 3; + uint32_t c_offs = 0, c_len = 0, a_offs = 0, a_len = 0, digest_offs = 0; + + switch (overlap) { + case SEPARATE_AUTH_AND_CIPHER_RANGES: + switch (hash_location) { + case HASH_SEPARATE: + /* |cccc_aaaa_dd| */ + c_offs = 0; + c_len = get_cipher_range_len(nonzero_len); + a_offs = c_offs + c_len + padding; + a_len = nonzero_len; + digest_offs = a_offs + a_len + padding; + break; + case HASH_IN_AUTH_RANGE_ONLY: + /* + * |cccc_aaaa| + * | _dd_| + */ + c_offs = 0; + c_len = get_cipher_range_len(nonzero_len); + a_offs = c_offs + c_len + padding; + a_len = hash_len + 2 * padding; + digest_offs = a_offs + padding; + break; + case HASH_IN_CIPHER_RANGE_ONLY: + /* + * |cccc_aaaa| + * |_dd_ | + */ + c_offs = 0; + c_len = get_cipher_range_len(hash_len + 2 * padding); + a_offs = c_offs + c_len + padding; + a_len = nonzero_len; + digest_offs = c_offs + padding; + break; + case HASH_IN_AUTH_AND_CIPHER_RANGE: + /* not possible when ranges are separate */ + return 1; + } + break; + case SAME_AUTH_AND_CIPHER_RANGE: + c_offs = 0; + a_offs = 0; + switch (hash_location) { + case HASH_SEPARATE: + /* + * |cccc_dd| + * |aaaa | + */ + c_len = get_cipher_range_len(nonzero_len); + a_len = c_len; + digest_offs = c_len + padding; + break; + case HASH_IN_AUTH_RANGE_ONLY: + case HASH_IN_CIPHER_RANGE_ONLY: + /* not possible when ranges are the same */ + return 1; + case HASH_IN_AUTH_AND_CIPHER_RANGE: + /* + * |cccc| + * |aaaa| + * |_dd_| + */ + c_len = get_cipher_range_len(hash_len + 2 * padding); + a_len = c_len; + digest_offs = padding; + break; + } + break; + case RANGES_PARTIALLY_OVERLAP: + a_offs = 0; + switch (hash_location) { + case HASH_SEPARATE: + /* + * |aaaa | + * | cccc_dd| + */ + a_len = 2 * nonzero_len; + c_offs = nonzero_len; + c_len = get_cipher_range_len(a_len); + digest_offs = c_offs + c_len + padding; + break; + case HASH_IN_AUTH_RANGE_ONLY: + /* + * |aaaaa | + * |_dd_ccc| + */ + digest_offs = padding; + a_len = hash_len + 2 * padding + nonzero_len; + c_offs = hash_len + 2 * padding; + c_len = get_cipher_range_len(2 * nonzero_len); + break; + case HASH_IN_CIPHER_RANGE_ONLY: + /* PDCP case when AUTH_PLAINTEXT */ + /* + * |aaaadd| + * | ccccc| + */ + c_offs = nonzero_len; + c_len = get_cipher_range_len(nonzero_len + hash_len); + a_len = nonzero_len + c_len - hash_len; + digest_offs = c_offs + c_len - hash_len; + break; + case HASH_IN_AUTH_AND_CIPHER_RANGE: + /* + * |aaaaaa | + * | cccccc| + * |¨_dd_ | + */ + c_offs = nonzero_len; + c_len = get_cipher_range_len(hash_len + 2 * padding + nonzero_len); + a_len = c_offs + hash_len + 2 * padding; + digest_offs = c_offs + padding; + break; + } + break; + case AUTH_RANGE_IN_CIPHER_RANGE: + c_offs = 0; + a_offs = nonzero_len; + switch (hash_location) { + case HASH_SEPARATE: + /* + * |cccc_dd| + * | aa_ | + */ + a_len = nonzero_len; + c_len = get_cipher_range_len(a_offs + a_len + padding); + digest_offs = c_len + padding; + break; + case HASH_IN_AUTH_RANGE_ONLY: + /* not possible since auth range is in cipher range */ + return 1; + case HASH_IN_CIPHER_RANGE_ONLY: + /* + * |ccccccc| + * | aa_dd_| + */ + a_len = nonzero_len; + digest_offs = a_offs + a_len + padding; + c_len = get_cipher_range_len(digest_offs + hash_len + padding); + break; + case HASH_IN_AUTH_AND_CIPHER_RANGE: + /* + * |cccccc| + * | aaaa_| + * | _dd_ | + */ + a_len = /**/ hash_len + 2 * padding; + c_len = get_cipher_range_len(a_offs + a_len + padding); + digest_offs = a_offs + /**/ padding; + break; + } + break; + case CIPHER_RANGE_IN_AUTH_RANGE: + a_offs = 0; + c_offs = nonzero_len; + switch (hash_location) { + case HASH_SEPARATE: + /* + * |aaaa_dd| + * | cc_ | + */ + c_len = get_cipher_range_len(nonzero_len); + a_len = c_offs + c_len + padding; + digest_offs = a_len + padding; + break; + case HASH_IN_AUTH_RANGE_ONLY: + /* + * |aaaaaaa| + * | cc_dd_| + */ + c_len = get_cipher_range_len(nonzero_len); + digest_offs = c_offs + c_len + padding; + a_len = digest_offs + hash_len + padding; + break; + case HASH_IN_CIPHER_RANGE_ONLY: + /* not possible since cipher range is in auth range */ + return 1; + case HASH_IN_AUTH_AND_CIPHER_RANGE: + /* + * |aaaaaa| + * | cccc_| + * | _dd_ | + */ + c_len = get_cipher_range_len(hash_len + 2 * padding); + a_len = c_offs + c_len + padding; + digest_offs = c_offs + padding; + break; + } + break; + } + cipher_range->offset = c_offs; + cipher_range->length = c_len; + auth_range->offset = a_offs; + auth_range->length = a_len; + *digest_offset = digest_offs; + return 0; +} + +static void test_combo(const crypto_suite_t *suite, + range_overlap_t overlap, + hash_location_t location) +{ + int rc; + + odp_packet_data_range_t cipher_range = {0, 0}; + odp_packet_data_range_t auth_range = {0, 0}; + uint32_t digest_offset = 0; + crypto_test_reference_t ref; + + rc = make_byte_ranges(overlap, + location, + suite->auth_capa->digest_len, + &cipher_range, + &auth_range, + &digest_offset); + if (rc) + return; + + rc = create_combined_ref(suite, &ref, + &cipher_range, &auth_range, + digest_offset); + if (rc) + return; + + alg_test(ODP_CRYPTO_OP_ENCODE, + suite->cipher, + suite->auth, + suite->order, + &ref, + cipher_range, auth_range, + digest_offset, + suite->cipher_capa->bit_mode, + suite->auth_capa->bit_mode); + + alg_test(ODP_CRYPTO_OP_DECODE, + suite->cipher, + suite->auth, + suite->order, + &ref, + cipher_range, auth_range, + digest_offset, + suite->cipher_capa->bit_mode, + suite->auth_capa->bit_mode); +} + +/* Iterate and test different cipher/auth range and hash locations */ +static void test_combo_ranges(const crypto_suite_t *suite) +{ + if (!full_test && suite->auth_capa->digest_len % 4 != 0) + return; + + for (int overlap = 0; overlap < NUM_RANGE_OVERLAPS; overlap++) + for (int location = 0; location < NUM_HASH_LOCATIONS; location++) { + if (suite->order == AUTH_CIPHERTEXT && + (location == HASH_IN_CIPHER_RANGE_ONLY || + location == HASH_IN_AUTH_AND_CIPHER_RANGE)) { + /* + * This combination Ãs not valid since + * the generated hash would overwrite some + * ciphertext, preventing decryption. + */ + continue; + } + test_combo(suite, overlap, location); + } +} + +/* Iterate and test all variants (key sizes etc) of an alg combo */ +static void test_combo_variants(odp_cipher_alg_t cipher, odp_auth_alg_t auth) +{ + int num, num_ciphers, num_auths; + + /* ODP API says AES-GMAC can be combined with the null cipher only */ + if (auth == ODP_AUTH_ALG_AES_GMAC && + cipher != ODP_CIPHER_ALG_NULL) + return; + + if (check_alg_support(cipher, auth) == ODP_TEST_INACTIVE) + return; + + printf(" %s, %s\n", + cipher_alg_name(cipher), + auth_alg_name(auth)); + + num_ciphers = odp_crypto_cipher_capability(cipher, NULL, 0); + num_auths = odp_crypto_auth_capability(auth, NULL, 0); + CU_ASSERT_FATAL(num_ciphers > 0); + CU_ASSERT_FATAL(num_auths > 0); + + odp_crypto_cipher_capability_t cipher_capa[num_ciphers]; + odp_crypto_auth_capability_t auth_capa[num_auths]; + + num = odp_crypto_cipher_capability(cipher, cipher_capa, num_ciphers); + CU_ASSERT(num == num_ciphers); + num = odp_crypto_auth_capability(auth, auth_capa, num_auths); + CU_ASSERT(num == num_auths); + + combo_warning_shown = 0; + + for (int n = 0; n < num_ciphers; n++) + for (int i = 0; i < num_auths; i++) { + crypto_suite_t suite = {.cipher = cipher, + .auth = auth, + .cipher_capa = &cipher_capa[n], + .auth_capa = &auth_capa[i]}; + suite.order = AUTH_PLAINTEXT; + test_combo_ranges(&suite); + suite.order = AUTH_CIPHERTEXT; + test_combo_ranges(&suite); + } +} + +static void test_all_combinations(void) +{ + printf("\n"); + for (size_t n = 0; n < ARRAY_SIZE(cipher_algs); n++) + for (size_t i = 0; i < ARRAY_SIZE(auth_algs); i++) + test_combo_variants(cipher_algs[n], auth_algs[i]); +} + static int check_alg_null(void) { return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_NULL); @@ -2443,64 +3044,8 @@ static odp_event_t plain_compl_queue_deq(void) return odp_queue_deq(suite_context.queue); } -#if ODP_DEPRECATED_API -static int crypto_suite_sync_init(void) -{ - suite_context.pool = odp_pool_lookup("packet_pool"); - if (suite_context.pool == ODP_POOL_INVALID) - return -1; - - suite_context.queue = ODP_QUEUE_INVALID; - suite_context.pref_mode = ODP_CRYPTO_SYNC; - return 0; -} - -static int crypto_suite_async_plain_init(void) -{ - odp_queue_t out_queue; - - suite_context.pool = odp_pool_lookup("packet_pool"); - if (suite_context.pool == ODP_POOL_INVALID) - return -1; - - out_queue = plain_compl_queue_create(); - if (ODP_QUEUE_INVALID == out_queue) { - fprintf(stderr, "Crypto outq creation failed.\n"); - return -1; - } - suite_context.queue = out_queue; - suite_context.q_type = ODP_QUEUE_TYPE_PLAIN; - suite_context.compl_queue_deq = plain_compl_queue_deq; - suite_context.pref_mode = ODP_CRYPTO_ASYNC; - - return 0; -} - -static int crypto_suite_async_sched_init(void) -{ - odp_queue_t out_queue; - - suite_context.pool = odp_pool_lookup("packet_pool"); - if (suite_context.pool == ODP_POOL_INVALID) - return -1; - - out_queue = sched_compl_queue_create(); - if (ODP_QUEUE_INVALID == out_queue) { - fprintf(stderr, "Crypto outq creation failed.\n"); - return -1; - } - suite_context.queue = out_queue; - suite_context.q_type = ODP_QUEUE_TYPE_SCHED; - suite_context.compl_queue_deq = sched_compl_queue_deq; - suite_context.pref_mode = ODP_CRYPTO_ASYNC; - - return 0; -} -#endif - static int crypto_suite_packet_sync_init(void) { - suite_context.packet = true; suite_context.op_mode = ODP_CRYPTO_SYNC; suite_context.pool = odp_pool_lookup("packet_pool"); @@ -2515,7 +3060,6 @@ static int crypto_suite_packet_async_plain_init(void) { odp_queue_t out_queue; - suite_context.packet = true; suite_context.op_mode = ODP_CRYPTO_ASYNC; suite_context.pool = odp_pool_lookup("packet_pool"); @@ -2538,7 +3082,6 @@ static int crypto_suite_packet_async_sched_init(void) { odp_queue_t out_queue; - suite_context.packet = true; suite_context.op_mode = ODP_CRYPTO_ASYNC; suite_context.pool = odp_pool_lookup("packet_pool"); @@ -2709,18 +3252,11 @@ odp_testinfo_t crypto_suite[] = { ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_sha512, check_alg_sha512), ODP_TEST_INFO(test_auth_hashes_in_auth_range), + ODP_TEST_INFO(test_all_combinations), ODP_TEST_INFO_NULL, }; odp_suiteinfo_t crypto_suites[] = { -#if ODP_DEPRECATED_API - {"odp_crypto_sync_inp", crypto_suite_sync_init, - NULL, crypto_suite}, - {"odp_crypto_async_plain_inp", crypto_suite_async_plain_init, - crypto_suite_term, crypto_suite}, - {"odp_crypto_async_sched_inp", crypto_suite_async_sched_init, - crypto_suite_term, crypto_suite}, -#endif {"odp_crypto_packet_sync_inp", crypto_suite_packet_sync_init, NULL, crypto_suite}, {"odp_crypto_packet_async_plain_inp", @@ -2834,6 +3370,11 @@ static int crypto_term(odp_instance_t inst) int main(int argc, char *argv[]) { int ret; + char *env = getenv("FULL_TEST"); + + if (env && strcmp(env, "0")) + full_test = 1; + printf("Test mode: %s\n", full_test ? "full" : "partial"); /* parse common options: */ if (odp_cunit_parse_options(argc, argv)) diff --git a/test/validation/api/dma/dma.c b/test/validation/api/dma/dma.c index f3e967193..ad42c9bb3 100644 --- a/test/validation/api/dma/dma.c +++ b/test/validation/api/dma/dma.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2021-2022, Nokia +/* Copyright (c) 2021-2023, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -10,9 +10,8 @@ #define COMPL_POOL_NAME "DMA compl pool" -#define SHM_SIZE (1024 * 1024) +#define MIN_SEG_LEN 1024 #define SHM_ALIGN ODP_CACHE_LINE_SIZE -#define NUM_COMPL 10 #define RETRIES 5 #define TIMEOUT 5 #define OFFSET 10 @@ -21,6 +20,8 @@ #define RESULT 1 #define USER_DATA 0xdeadbeef +#define MIN(a, b) (a < b ? a : b) + typedef struct global_t { odp_dma_capability_t dma_capa; odp_shm_t shm; @@ -47,7 +48,7 @@ static int dma_suite_init(void) odp_dma_pool_param_t dma_pool_param; odp_pool_capability_t pool_capa; odp_queue_param_t queue_param; - uint32_t pkt_len; + uint32_t shm_len, pkt_len; void *addr; memset(&global, 0, sizeof(global_t)); @@ -67,7 +68,8 @@ static int dma_suite_init(void) return 0; } - shm = odp_shm_reserve("DMA test", SHM_SIZE, SHM_ALIGN, 0); + shm_len = MIN_SEG_LEN * global.dma_capa.max_segs * global.dma_capa.max_transfers; + shm = odp_shm_reserve("DMA test", shm_len, SHM_ALIGN, 0); if (shm == ODP_SHM_INVALID) { ODPH_ERR("SHM reserve failed\n"); @@ -82,7 +84,7 @@ static int dma_suite_init(void) } global.shm = shm; - global.data_size = SHM_SIZE / 2; + global.data_size = shm_len / 2; global.src_addr = addr; global.dst_addr = (uint8_t *)global.src_addr + global.data_size; global.len = global.data_size - OFFSET - TRAILER; @@ -96,6 +98,7 @@ static int dma_suite_init(void) if (pkt_len == 0) pkt_len = 4000; + pkt_len = MIN(pkt_len, global.dma_capa.max_seg_len); odp_pool_param_init(&pool_param); pool_param.type = ODP_POOL_PACKET; pool_param.pkt.num = 4; @@ -124,13 +127,13 @@ static int dma_suite_init(void) } if (global.dma_capa.compl_mode_mask & ODP_DMA_COMPL_EVENT) { - if (global.dma_capa.pool.max_num < NUM_COMPL) { + if (global.dma_capa.pool.max_num < global.dma_capa.max_transfers) { ODPH_ERR("Too small DMA compl pool %u\n", global.dma_capa.pool.max_num); return -1; } odp_dma_pool_param_init(&dma_pool_param); - dma_pool_param.num = NUM_COMPL; + dma_pool_param.num = global.dma_capa.max_transfers; global.cache_size = dma_pool_param.cache_size; global.compl_pool = odp_dma_pool_create(COMPL_POOL_NAME, &dma_pool_param); @@ -178,7 +181,7 @@ static void test_dma_capability(void) odp_dma_capability_t capa; memset(&capa, 0, sizeof(odp_dma_capability_t)); - CU_ASSERT(odp_dma_capability(&capa) == 0); + CU_ASSERT_FATAL(odp_dma_capability(&capa) == 0); if (capa.max_sessions == 0) return; @@ -193,8 +196,12 @@ static void test_dma_capability(void) CU_ASSERT(capa.compl_mode_mask & ODP_DMA_COMPL_SYNC); if (capa.compl_mode_mask & ODP_DMA_COMPL_EVENT) { + odp_pool_capability_t pool_capa; + + CU_ASSERT_FATAL(odp_pool_capability(&pool_capa) == 0); + CU_ASSERT(capa.queue_type_sched || capa.queue_type_plain); - CU_ASSERT(capa.pool.max_pools > 0); + CU_ASSERT(capa.pool.max_pools > 0 && capa.pool.max_pools <= pool_capa.max_pools); CU_ASSERT(capa.pool.max_num > 0); CU_ASSERT(capa.pool.min_cache_size <= capa.pool.max_cache_size); } @@ -266,9 +273,10 @@ static void test_dma_compl_pool(void) { odp_pool_t pool; odp_pool_info_t pool_info; - odp_dma_compl_t compl; + odp_dma_compl_t compl[global.dma_capa.max_transfers]; uint64_t u64; int ret; + uint32_t i, j; const char *name = COMPL_POOL_NAME; CU_ASSERT_FATAL(global.compl_pool != ODP_POOL_INVALID); @@ -282,17 +290,24 @@ static void test_dma_compl_pool(void) CU_ASSERT(strcmp(pool_info.name, name) == 0); CU_ASSERT(pool_info.pool_ext == 0); CU_ASSERT(pool_info.type == ODP_POOL_DMA_COMPL); - CU_ASSERT(pool_info.dma_pool_param.num == NUM_COMPL); + CU_ASSERT(pool_info.dma_pool_param.num == global.dma_capa.max_transfers); CU_ASSERT(pool_info.dma_pool_param.cache_size == global.cache_size); - compl = odp_dma_compl_alloc(global.compl_pool); + for (i = 0; i < global.dma_capa.max_transfers; i++) { + compl[i] = odp_dma_compl_alloc(global.compl_pool); + + u64 = odp_dma_compl_to_u64(compl[i]); + CU_ASSERT(u64 != odp_dma_compl_to_u64(ODP_DMA_COMPL_INVALID)); + + if (compl[i] == ODP_DMA_COMPL_INVALID) + break; - u64 = odp_dma_compl_to_u64(compl); - CU_ASSERT(u64 != odp_dma_compl_to_u64(ODP_DMA_COMPL_INVALID)); - printf("\n DMA compl handle: 0x%" PRIx64 "\n", u64); - odp_dma_compl_print(compl); + printf("\n DMA compl handle: 0x%" PRIx64 "\n", u64); + odp_dma_compl_print(compl[i]); + } - odp_dma_compl_free(compl); + for (j = 0; j < i; j++) + odp_dma_compl_free(compl[j]); } static void test_dma_compl_pool_same_name(void) @@ -307,7 +322,7 @@ static void test_dma_compl_pool_same_name(void) CU_ASSERT(pool == pool_a); odp_dma_pool_param_init(&dma_pool_param); - dma_pool_param.num = NUM_COMPL; + dma_pool_param.num = global.dma_capa.max_transfers; /* Second pool with the same name */ pool_b = odp_dma_pool_create(name, &dma_pool_param); @@ -319,6 +334,36 @@ static void test_dma_compl_pool_same_name(void) CU_ASSERT_FATAL(odp_pool_destroy(pool_b) == 0); } +static void test_dma_compl_pool_max_pools(void) +{ + odp_dma_pool_param_t dma_pool_param; + /* Max pools minus the ones already created in global init */ + uint32_t num = global.dma_capa.pool.max_pools - 2, i, j; + odp_pool_t pools[num]; + int ret; + + odp_dma_pool_param_init(&dma_pool_param); + dma_pool_param.num = global.dma_capa.max_transfers; + + for (i = 0; i < num; i++) { + pools[i] = odp_dma_pool_create(NULL, &dma_pool_param); + CU_ASSERT(pools[i] != ODP_POOL_INVALID); + + if (pools[i] == ODP_POOL_INVALID) { + ODPH_ERR("DMA completion pool create failed: %u / %u\n", i, num); + break; + } + } + + for (j = 0; j < i; j++) { + ret = odp_pool_destroy(pools[j]); + CU_ASSERT(ret == 0); + + if (ret == -1) + ODPH_ERR("DMA completion pool destroy failed: %u / %u\n", j, i); + } +} + static void init_source(uint8_t *src, uint32_t len) { uint32_t i; @@ -380,126 +425,132 @@ static int do_transfer(odp_dma_t dma, const odp_dma_transfer_param_t *trs_param, return ret; } -static int do_transfer_async(odp_dma_t dma, const odp_dma_transfer_param_t *trs_param, +static int do_transfer_async(odp_dma_t dma, odp_dma_transfer_param_t *trs_param, odp_dma_compl_mode_t compl_mode, int multi) { - odp_dma_compl_param_t compl_param; + int num_trs = multi ? multi : 1; + odp_dma_compl_param_t compl_param[num_trs]; + const odp_dma_compl_param_t *compl_ptr[num_trs]; + const odp_dma_transfer_param_t *trs_ptr[num_trs]; odp_event_t ev; odp_dma_compl_t compl; - int i, ret, done; + int i, j, ret, done; uint32_t user_data = USER_DATA; odp_dma_result_t result; - odp_dma_transfer_id_t transfer_id = ODP_DMA_TRANSFER_ID_INVALID; uint64_t wait_ns = 500 * ODP_TIME_MSEC_IN_NS; uint64_t sched_wait = odp_schedule_wait_time(wait_ns); void *user_ptr = &user_data; - odp_dma_compl_param_init(&compl_param); - compl_param.compl_mode = compl_mode; - - if (compl_mode == ODP_DMA_COMPL_EVENT) { - compl = odp_dma_compl_alloc(global.compl_pool); - - CU_ASSERT(compl != ODP_DMA_COMPL_INVALID); - if (compl == ODP_DMA_COMPL_INVALID) + for (i = 0; i < num_trs; i++) { + odp_dma_compl_param_init(&compl_param[i]); + compl_param[i].compl_mode = compl_mode; + + if (compl_mode == ODP_DMA_COMPL_EVENT) { + compl = odp_dma_compl_alloc(global.compl_pool); + + CU_ASSERT(compl != ODP_DMA_COMPL_INVALID); + if (compl == ODP_DMA_COMPL_INVALID) + return -1; + + compl_param[i].event = odp_dma_compl_to_event(compl); + compl_param[i].queue = global.queue; + } else if (compl_mode == ODP_DMA_COMPL_POLL) { + compl_param[i].transfer_id = odp_dma_transfer_id_alloc(dma); + + CU_ASSERT(compl_param[i].transfer_id != ODP_DMA_TRANSFER_ID_INVALID); + if (compl_param[i].transfer_id == ODP_DMA_TRANSFER_ID_INVALID) + return -1; + } else if (compl_mode != ODP_DMA_COMPL_NONE) { + ODPH_ERR("Wrong compl mode: %u\n", compl_mode); return -1; + } - compl_param.event = odp_dma_compl_to_event(compl); - compl_param.queue = global.queue; - } else if (compl_mode == ODP_DMA_COMPL_POLL) { - transfer_id = odp_dma_transfer_id_alloc(dma); - - CU_ASSERT(transfer_id != ODP_DMA_TRANSFER_ID_INVALID); - if (transfer_id == ODP_DMA_TRANSFER_ID_INVALID) - return -1; + compl_param[i].user_ptr = user_ptr; - compl_param.transfer_id = transfer_id; - } else if (compl_mode != ODP_DMA_COMPL_NONE) { - ODPH_ERR("Wrong compl mode: %u\n", compl_mode); - return -1; + if (multi) { + trs_ptr[i] = &trs_param[i]; + compl_ptr[i] = &compl_param[i]; + } } for (i = 0; i < RETRIES; i++) { - compl_param.user_ptr = user_ptr; - - if (multi) { - const odp_dma_compl_param_t *compl_ptr[1] = {&compl_param}; - const odp_dma_transfer_param_t *trs_ptr[1] = {trs_param}; - - ret = odp_dma_transfer_start_multi(dma, trs_ptr, compl_ptr, 1); - } else { - ret = odp_dma_transfer_start(dma, trs_param, &compl_param); - } + if (multi) + ret = odp_dma_transfer_start_multi(dma, trs_ptr, compl_ptr, num_trs); + else + ret = odp_dma_transfer_start(dma, trs_param, compl_param); if (ret) break; } - CU_ASSERT(ret == 1); + CU_ASSERT(ret == num_trs); if (ret < 1) return ret; - memset(&result, 0, sizeof(odp_dma_result_t)); + for (i = 0; i < ret; i++) { + memset(&result, 0, sizeof(odp_dma_result_t)); - if (compl_mode == ODP_DMA_COMPL_POLL) { - for (i = 0; i < TIMEOUT; i++) { - done = odp_dma_transfer_done(dma, transfer_id, &result); - if (done) - break; + if (compl_mode == ODP_DMA_COMPL_POLL) { + for (j = 0; j < TIMEOUT; j++) { + done = odp_dma_transfer_done(dma, compl_param[i].transfer_id, + &result); + if (done) + break; - odp_time_wait_ns(wait_ns); - } + odp_time_wait_ns(wait_ns); + } - CU_ASSERT(done == 1); - CU_ASSERT(result.success); - CU_ASSERT(result.user_ptr == user_ptr); - CU_ASSERT(user_data == USER_DATA); + CU_ASSERT(done == 1); + CU_ASSERT(result.success); + CU_ASSERT(result.user_ptr == user_ptr); + CU_ASSERT(user_data == USER_DATA); - odp_dma_transfer_id_free(dma, transfer_id); + odp_dma_transfer_id_free(dma, compl_param[i].transfer_id); - return done; + return done; - } else if (compl_mode == ODP_DMA_COMPL_EVENT) { - odp_queue_t from = ODP_QUEUE_INVALID; + } else if (compl_mode == ODP_DMA_COMPL_EVENT) { + odp_queue_t from = ODP_QUEUE_INVALID; - for (i = 0; i < TIMEOUT; i++) { - ev = odp_schedule(&from, sched_wait); - if (ev != ODP_EVENT_INVALID) - break; - } + for (j = 0; j < TIMEOUT; j++) { + ev = odp_schedule(&from, sched_wait); + if (ev != ODP_EVENT_INVALID) + break; + } - CU_ASSERT(ev != ODP_EVENT_INVALID); - if (ev == ODP_EVENT_INVALID) - return -1; + CU_ASSERT(ev != ODP_EVENT_INVALID); + if (ev == ODP_EVENT_INVALID) + return -1; - CU_ASSERT(from == global.queue); - CU_ASSERT(odp_event_type(ev) == ODP_EVENT_DMA_COMPL); + CU_ASSERT(from == global.queue); + CU_ASSERT(odp_event_type(ev) == ODP_EVENT_DMA_COMPL); - compl = odp_dma_compl_from_event(ev); - CU_ASSERT(compl != ODP_DMA_COMPL_INVALID); + compl = odp_dma_compl_from_event(ev); + CU_ASSERT(compl != ODP_DMA_COMPL_INVALID); - CU_ASSERT(odp_dma_compl_result(compl, &result) == 0); - CU_ASSERT(result.success); - CU_ASSERT(result.user_ptr == user_ptr); - CU_ASSERT(user_data == USER_DATA); + CU_ASSERT(odp_dma_compl_result(compl, &result) == 0); + CU_ASSERT(result.success); + CU_ASSERT(result.user_ptr == user_ptr); + CU_ASSERT(user_data == USER_DATA); - /* Test also without result struct output */ - CU_ASSERT(odp_dma_compl_result(compl, NULL) == 0); + /* Test also without result struct output */ + CU_ASSERT(odp_dma_compl_result(compl, NULL) == 0); - /* Test compl event print on the first event */ - if (global.event_count == 0) { - printf("\n\n"); - odp_dma_compl_print(compl); - } + /* Test compl event print on the first event */ + if (global.event_count == 0) { + printf("\n\n"); + odp_dma_compl_print(compl); + } - /* Test both ways to free the event */ - if (global.event_count % 2) - odp_event_free(ev); - else - odp_dma_compl_free(compl); + /* Test both ways to free the event */ + if (global.event_count % 2) + odp_event_free(ev); + else + odp_dma_compl_free(compl); - global.event_count++; + global.event_count++; + } } return 1; @@ -517,8 +568,8 @@ static void test_dma_addr_to_addr(odp_dma_compl_mode_t compl_mode_mask, uint32_t uint32_t i, cur_len; uint8_t *src = global.src_addr + OFFSET; uint8_t *dst = global.dst_addr + OFFSET; - uint32_t len = global.len; - uint32_t seg_len = len / num; + uint32_t seg_len = MIN(global.len / num, global.dma_capa.max_seg_len); + uint32_t len = seg_len * num; uint32_t offset = 0; init_source(global.src_addr, global.data_size); @@ -558,7 +609,7 @@ static void test_dma_addr_to_addr(odp_dma_compl_mode_t compl_mode_mask, uint32_t if (ret > 0) { CU_ASSERT(check_equal(src, dst, len) == 0); CU_ASSERT(check_zero(global.dst_addr, OFFSET) == 0); - CU_ASSERT(check_zero(dst + len, TRAILER) == 0); + CU_ASSERT(check_zero(dst + len, global.len - len + TRAILER) == 0); } CU_ASSERT(odp_dma_destroy(dma) == 0); @@ -577,8 +628,8 @@ static void test_dma_addr_to_addr_trs(odp_dma_compl_mode_t compl_mode_mask, uint odp_dma_compl_mode_t compl_mode; uint8_t *src = global.src_addr + OFFSET; uint8_t *dst = global.dst_addr + OFFSET; - uint32_t len = global.len; - uint32_t trs_len = len / num_trs; + uint32_t trs_len = MIN(global.len / num_trs, global.dma_capa.max_seg_len); + uint32_t len = trs_len * num_trs; uint32_t offset = 0; int ret = -1; @@ -630,7 +681,65 @@ static void test_dma_addr_to_addr_trs(odp_dma_compl_mode_t compl_mode_mask, uint if (ret > 0) { CU_ASSERT(check_equal(src, dst, len) == 0); CU_ASSERT(check_zero(global.dst_addr, OFFSET) == 0); - CU_ASSERT(check_zero(dst + len, TRAILER) == 0); + CU_ASSERT(check_zero(dst + len, global.len - len + TRAILER) == 0); + } + + CU_ASSERT(odp_dma_destroy(dma) == 0); +} + +static void test_dma_addr_to_addr_max_trs(odp_dma_compl_mode_t compl_mode_mask) +{ + odp_dma_param_t dma_param; + uint32_t num_trs = global.dma_capa.max_transfers; + odp_dma_transfer_param_t trs_param[num_trs]; + odp_dma_t dma; + odp_dma_seg_t src_seg[num_trs]; + odp_dma_seg_t dst_seg[num_trs]; + int ret; + uint32_t i, cur_len; + uint8_t *src = global.src_addr + OFFSET; + uint8_t *dst = global.dst_addr + OFFSET; + uint32_t seg_len = MIN(global.len / num_trs, global.dma_capa.max_seg_len); + uint32_t len = seg_len * num_trs; + uint32_t offset = 0; + + init_source(global.src_addr, global.data_size); + memset(global.dst_addr, 0, global.data_size); + + odp_dma_param_init(&dma_param); + dma_param.compl_mode_mask = compl_mode_mask; + dma = odp_dma_create("addr_to_addr", &dma_param); + CU_ASSERT_FATAL(dma != ODP_DMA_INVALID); + + memset(src_seg, 0, sizeof(src_seg)); + memset(dst_seg, 0, sizeof(dst_seg)); + + for (i = 0; i < num_trs; i++) { + cur_len = seg_len; + if (i == num_trs - 1) + cur_len = len - seg_len * i; + + src_seg[i].addr = src + offset; + src_seg[i].len = cur_len; + dst_seg[i].addr = dst + offset; + dst_seg[i].len = cur_len; + offset += cur_len; + } + + for (i = 0; i < num_trs; i++) { + odp_dma_transfer_param_init(&trs_param[i]); + trs_param[i].num_src = 1; + trs_param[i].num_dst = 1; + trs_param[i].src_seg = &src_seg[i]; + trs_param[i].dst_seg = &dst_seg[i]; + } + + ret = do_transfer_async(dma, trs_param, compl_mode_mask, num_trs); + + if (ret > 0) { + CU_ASSERT(check_equal(src, dst, len) == 0); + CU_ASSERT(check_zero(global.dst_addr, OFFSET) == 0); + CU_ASSERT(check_zero(dst + len, global.len - len + TRAILER) == 0); } CU_ASSERT(odp_dma_destroy(dma) == 0); @@ -1000,7 +1109,7 @@ static void test_dma_addr_to_addr_sync(void) static void test_dma_addr_to_addr_sync_mtrs(void) { - test_dma_addr_to_addr_trs(ODP_DMA_COMPL_SYNC, 2, 0, 0); + test_dma_addr_to_addr_trs(ODP_DMA_COMPL_SYNC, global.dma_capa.max_transfers * 2, 0, 0); } static void test_dma_addr_to_addr_sync_mseg(void) @@ -1140,6 +1249,11 @@ static void test_dma_multi_addr_to_addr_poll(void) test_dma_addr_to_addr(ODP_DMA_COMPL_POLL, 1, MULTI, 0); } +static void test_dma_multi_addr_to_addr_poll_max_trs(void) +{ + test_dma_addr_to_addr_max_trs(ODP_DMA_COMPL_POLL); +} + static void test_dma_multi_addr_to_pkt_poll(void) { test_dma_addr_to_pkt(ODP_DMA_COMPL_POLL, MULTI); @@ -1160,6 +1274,11 @@ static void test_dma_multi_addr_to_addr_event(void) test_dma_addr_to_addr(ODP_DMA_COMPL_EVENT, 1, MULTI, 0); } +static void test_dma_multi_addr_to_addr_event_max_trs(void) +{ + test_dma_addr_to_addr_max_trs(ODP_DMA_COMPL_EVENT); +} + static void test_dma_multi_addr_to_pkt_event(void) { test_dma_addr_to_pkt(ODP_DMA_COMPL_EVENT, MULTI); @@ -1181,6 +1300,7 @@ odp_testinfo_t dma_suite[] = { ODP_TEST_INFO_CONDITIONAL(test_dma_debug, check_sync), ODP_TEST_INFO_CONDITIONAL(test_dma_compl_pool, check_event), ODP_TEST_INFO_CONDITIONAL(test_dma_compl_pool_same_name, check_event), + ODP_TEST_INFO_CONDITIONAL(test_dma_compl_pool_max_pools, check_event), ODP_TEST_INFO_CONDITIONAL(test_dma_addr_to_addr_sync, check_sync), ODP_TEST_INFO_CONDITIONAL(test_dma_addr_to_addr_sync_mtrs, check_sync), ODP_TEST_INFO_CONDITIONAL(test_dma_addr_to_addr_sync_mseg, check_sync), @@ -1208,10 +1328,12 @@ odp_testinfo_t dma_suite[] = { ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_addr_sync, check_sync), ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_pkt_sync, check_sync), ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_addr_poll, check_poll), + ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_addr_poll_max_trs, check_poll), ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_pkt_poll, check_poll), ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_addr_poll, check_poll), ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_pkt_poll, check_poll), ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_addr_event, check_scheduled), + ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_addr_event_max_trs, check_scheduled), ODP_TEST_INFO_CONDITIONAL(test_dma_multi_addr_to_pkt_event, check_scheduled), ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_addr_event, check_scheduled), ODP_TEST_INFO_CONDITIONAL(test_dma_multi_pkt_to_pkt_event, check_scheduled), diff --git a/test/validation/api/ipsec/ipsec_test_out.c b/test/validation/api/ipsec/ipsec_test_out.c index bb318edad..1a013289b 100644 --- a/test/validation/api/ipsec/ipsec_test_out.c +++ b/test/validation/api/ipsec/ipsec_test_out.c @@ -475,6 +475,30 @@ static void ipsec_check_out_in_one(const ipsec_test_part *part_outbound, } } +static int sa_creation_failure_ok(const odp_ipsec_sa_param_t *param) +{ + odp_cipher_alg_t cipher = param->crypto.cipher_alg; + odp_auth_alg_t auth = param->crypto.auth_alg; + + /* Single algorithm must not fail */ + if (cipher == ODP_CIPHER_ALG_NULL || auth == ODP_AUTH_ALG_NULL) + return 0; + + /* Combined mode algorithms must not fail */ + if (cipher == ODP_CIPHER_ALG_AES_GCM || + cipher == ODP_CIPHER_ALG_AES_CCM || + cipher == ODP_CIPHER_ALG_CHACHA20_POLY1305) + return 0; + + /* Combination of mandatory algorithms must not fail */ + if (cipher == ODP_CIPHER_ALG_AES_CBC && auth == ODP_AUTH_ALG_SHA1_HMAC) + return 0; + + printf("\n Algorithm combination (%d, %d) maybe not supported.\n", cipher, auth); + printf(" SA creation failed, skipping test.\n"); + return 1; +} + static void test_out_in_common(const ipsec_test_flags *flags, odp_cipher_alg_t cipher, const odp_crypto_key_t *cipher_key, @@ -539,6 +563,9 @@ static void test_out_in_common(const ipsec_test_flags *flags, sa_out = odp_ipsec_sa_create(¶m); + if (sa_out == ODP_IPSEC_SA_INVALID && sa_creation_failure_ok(¶m)) + return; + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa_out); ipsec_sa_param_fill(¶m, diff --git a/test/validation/api/pktio/pktio.c b/test/validation/api/pktio/pktio.c index 446411b22..2f4dda4a4 100644 --- a/test/validation/api/pktio/pktio.c +++ b/test/validation/api/pktio/pktio.c @@ -300,6 +300,8 @@ static void pktio_init_packet_eth_ipv4(odp_packet_t pkt, uint8_t proto) seq = odp_atomic_fetch_inc_u32(&ip_seq); ip->id = odp_cpu_to_be_16(seq); ip->chksum = 0; + ip->frag_offset = 0; + ip->tos = 0; odph_ipv4_csum_update(pkt); } @@ -1681,7 +1683,6 @@ static void pktio_test_lookup(void) pktio_inval = odp_pktio_open(iface_name[0], default_pkt_pool, &pktio_param); - CU_ASSERT(odp_errno() != 0); CU_ASSERT(pktio_inval == ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_close(pktio) == 0); @@ -2039,8 +2040,10 @@ static void pktio_config_flow_control(int pfc, int rx, int tx) if (cos != ODP_COS_INVALID) odp_cos_destroy(cos); - if (default_cos != ODP_COS_INVALID) + if (default_cos != ODP_COS_INVALID) { + odp_pktio_default_cos_set(pktio, ODP_COS_INVALID); odp_cos_destroy(default_cos); + } if (queue != ODP_QUEUE_INVALID) odp_queue_destroy(queue); @@ -4433,7 +4436,7 @@ static int create_pool(const char *iface, int num) pool[num] = odp_pool_create(pool_name, ¶ms); if (ODP_POOL_INVALID == pool[num]) { - ODPH_ERR("failed to create pool: %d", odp_errno()); + ODPH_ERR("failed to create pool: %s\n", pool_name); return -1; } @@ -4463,7 +4466,7 @@ static int create_pktv_pool(const char *iface, int num) pktv_pool[num] = odp_pool_create(pool_name, ¶ms); if (ODP_POOL_INVALID == pktv_pool[num]) { - ODPH_ERR("failed to create pool: %d", odp_errno()); + ODPH_ERR("failed to create pool: %s\n", pool_name); return -1; } diff --git a/test/validation/api/stash/stash.c b/test/validation/api/stash/stash.c index f4ddfa2e1..fd4c04577 100644 --- a/test/validation/api/stash/stash.c +++ b/test/validation/api/stash/stash.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2020-2022, Nokia +/* Copyright (c) 2020-2023, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -7,6 +7,8 @@ #include <odp_api.h> #include "odp_cunit_common.h" +#include <string.h> + #define MAGIC_U64 0x8b7438fa56c82e96 #define MAGIC_U32 0x74a13b94 #define MAGIC_U16 0x25bf @@ -111,10 +113,9 @@ static int stash_suite_init(void) static void stash_capability(void) { odp_stash_capability_t capa; - int ret; memset(&capa, 0, sizeof(odp_stash_capability_t)); - CU_ASSERT(odp_stash_capability(&capa, ODP_STASH_TYPE_DEFAULT) == 0); + CU_ASSERT_FATAL(odp_stash_capability(&capa, ODP_STASH_TYPE_DEFAULT) == 0); CU_ASSERT(capa.max_stashes_any_type > 0); CU_ASSERT(capa.max_stashes > 0); CU_ASSERT(capa.max_num_obj > 0); @@ -122,16 +123,43 @@ static void stash_capability(void) CU_ASSERT(capa.max_get_batch >= 1); CU_ASSERT(capa.max_put_batch >= 1); + CU_ASSERT(capa.max_num.u8 >= capa.max_num_obj); + CU_ASSERT(capa.max_num.u16 >= capa.max_num_obj); + CU_ASSERT(capa.max_num.u32 >= capa.max_num_obj); + CU_ASSERT(capa.max_num.max_obj_size >= capa.max_num_obj); + if (capa.max_obj_size >= 8) + CU_ASSERT(capa.max_num.u64 >= capa.max_num_obj); + if (capa.max_obj_size < 8) + CU_ASSERT(capa.max_num.u64 == 0); + if (capa.max_obj_size >= 16) + CU_ASSERT(capa.max_num.u128 >= capa.max_num_obj); + if (capa.max_obj_size < 16) + CU_ASSERT(capa.max_num.u128 == 0); + memset(&capa, 0, sizeof(odp_stash_capability_t)); - ret = odp_stash_capability(&capa, ODP_STASH_TYPE_FIFO); - CU_ASSERT(ret == 0); + CU_ASSERT_FATAL(odp_stash_capability(&capa, ODP_STASH_TYPE_FIFO) == 0); CU_ASSERT(capa.max_stashes_any_type > 0); - if (ret == 0 && capa.max_stashes) { - CU_ASSERT(capa.max_num_obj > 0); - CU_ASSERT(capa.max_obj_size >= sizeof(uint32_t)); - CU_ASSERT(capa.max_get_batch >= 1); - CU_ASSERT(capa.max_put_batch >= 1); - } + + if (capa.max_stashes == 0) + return; + + CU_ASSERT(capa.max_num_obj > 0); + CU_ASSERT(capa.max_obj_size >= sizeof(uint32_t)); + CU_ASSERT(capa.max_get_batch >= 1); + CU_ASSERT(capa.max_put_batch >= 1); + + CU_ASSERT(capa.max_num.u8 >= capa.max_num_obj); + CU_ASSERT(capa.max_num.u16 >= capa.max_num_obj); + CU_ASSERT(capa.max_num.u32 >= capa.max_num_obj); + CU_ASSERT(capa.max_num.max_obj_size >= capa.max_num_obj); + if (capa.max_obj_size >= 8) + CU_ASSERT(capa.max_num.u64 >= capa.max_num_obj); + if (capa.max_obj_size < 8) + CU_ASSERT(capa.max_num.u64 == 0); + if (capa.max_obj_size >= 16) + CU_ASSERT(capa.max_num.u128 >= capa.max_num_obj); + if (capa.max_obj_size < 16) + CU_ASSERT(capa.max_num.u128 == 0); } static void param_defaults(uint8_t fill) @@ -147,6 +175,7 @@ static void param_defaults(uint8_t fill) CU_ASSERT(param.stats.all == 0); CU_ASSERT(param.stats.bit.count == 0); CU_ASSERT(param.stats.bit.cache_count == 0); + CU_ASSERT(param.strict_size == 0); } static void stash_param_defaults(void) @@ -449,12 +478,13 @@ static void stash_stats_u32(void) CU_ASSERT_FATAL(odp_stash_destroy(stash) == 0); } -static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int batch) +static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int batch, + odp_bool_t strict_size) { odp_stash_t stash; odp_stash_param_t param; int32_t i, ret, retry, num_left; - int32_t num, max_burst; + int32_t num, max_burst, num_stashed; void *input, *output; if (batch) { @@ -505,6 +535,7 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b param.num_obj = num; param.obj_size = size; param.cache_size = global.cache_size_default; + param.strict_size = strict_size; stash = odp_stash_create("test_stash_default", ¶m); @@ -516,6 +547,12 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b retry = MAX_RETRY; num_left = num; max_burst = burst; + num_stashed = 0; + + /* Try to store extra objects if strict mode is not enabled */ + if (!strict_size) + num_left += burst; + while (num_left > 0) { if (op == STASH_GEN) { if (batch) @@ -542,6 +579,9 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b } CU_ASSERT_FATAL(ret >= 0); CU_ASSERT_FATAL(ret <= burst); + + num_stashed += ret; + if (batch) { CU_ASSERT(ret == 0 || ret == burst); if (num_left - ret < burst) @@ -552,6 +592,9 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b num_left -= ret; retry = MAX_RETRY; } else { + /* Stash full */ + if (num_stashed >= num) + break; retry--; CU_ASSERT_FATAL(retry > 0); } @@ -559,7 +602,7 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b burst = max_burst; retry = MAX_RETRY; - num_left = num; + num_left = num_stashed; while (num_left > 0) { memset(output, 0, burst * size); @@ -652,12 +695,13 @@ static void stash_default_put(uint32_t size, int32_t burst, stash_op_t op, int b CU_ASSERT_FATAL(odp_stash_destroy(stash) == 0); } -static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batch) +static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batch, + odp_bool_t strict_size) { odp_stash_t stash; odp_stash_param_t param; int32_t i, ret, retry, num_left; - int32_t num, max_burst; + int32_t num, max_burst, num_stashed; void *input, *output; if (batch) { @@ -701,6 +745,7 @@ static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batc param.type = ODP_STASH_TYPE_FIFO; param.num_obj = num; param.obj_size = size; + param.strict_size = strict_size; stash = odp_stash_create("test_stash_fifo", ¶m); @@ -712,6 +757,12 @@ static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batc retry = MAX_RETRY; num_left = num; max_burst = burst; + num_stashed = 0; + + /* Try to store extra objects if strict mode is not enabled */ + if (!strict_size) + num_left += burst; + while (num_left > 0) { for (i = 0; i < burst; i++) { if (size == sizeof(uint64_t)) @@ -750,6 +801,8 @@ static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batc CU_ASSERT_FATAL(ret >= 0); CU_ASSERT_FATAL(ret <= burst); + num_stashed += ret; + if (batch) { CU_ASSERT(ret == 0 || ret == burst); if (num_left - ret < burst) @@ -760,6 +813,9 @@ static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batc num_left -= ret; retry = MAX_RETRY; } else { + /* Stash full */ + if (num_stashed >= num) + break; retry--; CU_ASSERT_FATAL(retry > 0); } @@ -767,7 +823,7 @@ static void stash_fifo_put(uint32_t size, int32_t burst, stash_op_t op, int batc burst = max_burst; retry = MAX_RETRY; - num_left = num; + num_left = num_stashed; while (num_left > 0) { memset(output, 0, burst * size); @@ -912,282 +968,338 @@ static int check_support_fifo(void) static void stash_default_put_u64_1(void) { - stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 0); + stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 0, false); + stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 0, true); } static void stash_default_put_u64_n(void) { - stash_default_put(sizeof(uint64_t), BURST, STASH_GEN, 0); + stash_default_put(sizeof(uint64_t), BURST, STASH_GEN, 0, false); + stash_default_put(sizeof(uint64_t), BURST, STASH_GEN, 0, true); } static void stash_default_u64_put_u64_1(void) { - stash_default_put(sizeof(uint64_t), 1, STASH_U64, 0); + stash_default_put(sizeof(uint64_t), 1, STASH_U64, 0, false); + stash_default_put(sizeof(uint64_t), 1, STASH_U64, 0, true); } static void stash_default_u64_put_u64_n(void) { - stash_default_put(sizeof(uint64_t), BURST, STASH_U64, 0); + stash_default_put(sizeof(uint64_t), BURST, STASH_U64, 0, false); + stash_default_put(sizeof(uint64_t), BURST, STASH_U64, 0, true); } static void stash_default_put_ptr_1(void) { - stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 0); + stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 0, false); + stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 0, true); } static void stash_default_put_ptr_n(void) { - stash_default_put(sizeof(uintptr_t), BURST, STASH_PTR, 0); + stash_default_put(sizeof(uintptr_t), BURST, STASH_PTR, 0, false); + stash_default_put(sizeof(uintptr_t), BURST, STASH_PTR, 0, true); } static void stash_default_put_u64_1_batch(void) { - stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 1); + stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 1, false); + stash_default_put(sizeof(uint64_t), 1, STASH_GEN, 1, true); } static void stash_default_put_u64_n_batch(void) { - stash_default_put(sizeof(uint64_t), BATCH, STASH_GEN, 1); + stash_default_put(sizeof(uint64_t), BATCH, STASH_GEN, 1, false); + stash_default_put(sizeof(uint64_t), BATCH, STASH_GEN, 1, true); } static void stash_default_u64_put_u64_1_batch(void) { - stash_default_put(sizeof(uint64_t), 1, STASH_U64, 1); + stash_default_put(sizeof(uint64_t), 1, STASH_U64, 1, false); + stash_default_put(sizeof(uint64_t), 1, STASH_U64, 1, true); } static void stash_default_u64_put_u64_n_batch(void) { - stash_default_put(sizeof(uint64_t), BATCH, STASH_U64, 1); + stash_default_put(sizeof(uint64_t), BATCH, STASH_U64, 1, false); + stash_default_put(sizeof(uint64_t), BATCH, STASH_U64, 1, true); } static void stash_default_put_ptr_1_batch(void) { - stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 1); + stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 1, false); + stash_default_put(sizeof(uintptr_t), 1, STASH_PTR, 1, true); } static void stash_default_put_ptr_n_batch(void) { - stash_default_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1); + stash_default_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1, false); + stash_default_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1, true); } static void stash_default_put_u32_1(void) { - stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 0); + stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 0, false); + stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 0, true); } static void stash_default_put_u32_n(void) { - stash_default_put(sizeof(uint32_t), BURST, STASH_GEN, 0); + stash_default_put(sizeof(uint32_t), BURST, STASH_GEN, 0, false); + stash_default_put(sizeof(uint32_t), BURST, STASH_GEN, 0, true); } static void stash_default_u32_put_u32_1(void) { - stash_default_put(sizeof(uint32_t), 1, STASH_U32, 0); + stash_default_put(sizeof(uint32_t), 1, STASH_U32, 0, false); + stash_default_put(sizeof(uint32_t), 1, STASH_U32, 0, true); } static void stash_default_u32_put_u32_n(void) { - stash_default_put(sizeof(uint32_t), BURST, STASH_U32, 0); + stash_default_put(sizeof(uint32_t), BURST, STASH_U32, 0, false); + stash_default_put(sizeof(uint32_t), BURST, STASH_U32, 0, true); } static void stash_default_put_u16_1(void) { - stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 0); + stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 0, false); + stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 0, true); } static void stash_default_put_u16_n(void) { - stash_default_put(sizeof(uint16_t), BURST, STASH_GEN, 0); + stash_default_put(sizeof(uint16_t), BURST, STASH_GEN, 0, false); + stash_default_put(sizeof(uint16_t), BURST, STASH_GEN, 0, true); } static void stash_default_put_u8_1(void) { - stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 0); + stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 0, false); + stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 0, true); } static void stash_default_put_u8_n(void) { - stash_default_put(sizeof(uint8_t), BURST, STASH_GEN, 0); + stash_default_put(sizeof(uint8_t), BURST, STASH_GEN, 0, false); + stash_default_put(sizeof(uint8_t), BURST, STASH_GEN, 0, true); } static void stash_default_put_u32_1_batch(void) { - stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 1); + stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 1, false); + stash_default_put(sizeof(uint32_t), 1, STASH_GEN, 1, true); } static void stash_default_put_u32_n_batch(void) { - stash_default_put(sizeof(uint32_t), BATCH, STASH_GEN, 1); + stash_default_put(sizeof(uint32_t), BATCH, STASH_GEN, 1, false); + stash_default_put(sizeof(uint32_t), BATCH, STASH_GEN, 1, true); } static void stash_default_u32_put_u32_1_batch(void) { - stash_default_put(sizeof(uint32_t), 1, STASH_U32, 1); + stash_default_put(sizeof(uint32_t), 1, STASH_U32, 1, false); + stash_default_put(sizeof(uint32_t), 1, STASH_U32, 1, true); } static void stash_default_u32_put_u32_n_batch(void) { - stash_default_put(sizeof(uint32_t), BATCH, STASH_U32, 1); + stash_default_put(sizeof(uint32_t), BATCH, STASH_U32, 1, false); + stash_default_put(sizeof(uint32_t), BATCH, STASH_U32, 1, true); } static void stash_default_put_u16_1_batch(void) { - stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 1); + stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 1, false); + stash_default_put(sizeof(uint16_t), 1, STASH_GEN, 1, true); } static void stash_default_put_u16_n_batch(void) { - stash_default_put(sizeof(uint16_t), BATCH, STASH_GEN, 1); + stash_default_put(sizeof(uint16_t), BATCH, STASH_GEN, 1, false); + stash_default_put(sizeof(uint16_t), BATCH, STASH_GEN, 1, true); } static void stash_default_put_u8_1_batch(void) { - stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 1); + stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 1, false); + stash_default_put(sizeof(uint8_t), 1, STASH_GEN, 1, true); } static void stash_default_put_u8_n_batch(void) { - stash_default_put(sizeof(uint8_t), BATCH, STASH_GEN, 1); + stash_default_put(sizeof(uint8_t), BATCH, STASH_GEN, 1, false); + stash_default_put(sizeof(uint8_t), BATCH, STASH_GEN, 1, true); } static void stash_fifo_put_u64_1(void) { - stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 0); + stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 0, false); + stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 0, true); } static void stash_fifo_put_u64_n(void) { - stash_fifo_put(sizeof(uint64_t), BURST, STASH_GEN, 0); + stash_fifo_put(sizeof(uint64_t), BURST, STASH_GEN, 0, false); + stash_fifo_put(sizeof(uint64_t), BURST, STASH_GEN, 0, true); } static void stash_fifo_u64_put_u64_1(void) { - stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 0); + stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 0, false); + stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 0, true); } static void stash_fifo_u64_put_u64_n(void) { - stash_fifo_put(sizeof(uint64_t), BURST, STASH_U64, 0); + stash_fifo_put(sizeof(uint64_t), BURST, STASH_U64, 0, false); + stash_fifo_put(sizeof(uint64_t), BURST, STASH_U64, 0, true); } static void stash_fifo_put_ptr_1(void) { - stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 0); + stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 0, false); + stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 0, true); } static void stash_fifo_put_ptr_n(void) { - stash_fifo_put(sizeof(uintptr_t), BURST, STASH_PTR, 0); + stash_fifo_put(sizeof(uintptr_t), BURST, STASH_PTR, 0, false); + stash_fifo_put(sizeof(uintptr_t), BURST, STASH_PTR, 0, true); } static void stash_fifo_put_u32_1(void) { - stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 0); + stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 0, false); + stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 0, true); } static void stash_fifo_put_u32_n(void) { - stash_fifo_put(sizeof(uint32_t), BURST, STASH_GEN, 0); + stash_fifo_put(sizeof(uint32_t), BURST, STASH_GEN, 0, false); + stash_fifo_put(sizeof(uint32_t), BURST, STASH_GEN, 0, true); } static void stash_fifo_u32_put_u32_1(void) { - stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 0); + stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 0, false); + stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 0, true); } static void stash_fifo_u32_put_u32_n(void) { - stash_fifo_put(sizeof(uint32_t), BURST, STASH_U32, 0); + stash_fifo_put(sizeof(uint32_t), BURST, STASH_U32, 0, false); + stash_fifo_put(sizeof(uint32_t), BURST, STASH_U32, 0, true); } static void stash_fifo_put_u16_1(void) { - stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 0); + stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 0, false); + stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 0, true); } static void stash_fifo_put_u16_n(void) { - stash_fifo_put(sizeof(uint16_t), BURST, STASH_GEN, 0); + stash_fifo_put(sizeof(uint16_t), BURST, STASH_GEN, 0, false); + stash_fifo_put(sizeof(uint16_t), BURST, STASH_GEN, 0, true); } static void stash_fifo_put_u8_1(void) { - stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 0); + stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 0, false); + stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 0, true); } static void stash_fifo_put_u8_n(void) { - stash_fifo_put(sizeof(uint8_t), BURST, STASH_GEN, 0); + stash_fifo_put(sizeof(uint8_t), BURST, STASH_GEN, 0, false); + stash_fifo_put(sizeof(uint8_t), BURST, STASH_GEN, 0, true); } static void stash_fifo_put_u64_1_batch(void) { - stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 1); + stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 1, false); + stash_fifo_put(sizeof(uint64_t), 1, STASH_GEN, 1, true); } static void stash_fifo_put_u64_n_batch(void) { - stash_fifo_put(sizeof(uint64_t), BATCH, STASH_GEN, 1); + stash_fifo_put(sizeof(uint64_t), BATCH, STASH_GEN, 1, false); + stash_fifo_put(sizeof(uint64_t), BATCH, STASH_GEN, 1, true); } static void stash_fifo_u64_put_u64_1_batch(void) { - stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 1); + stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 1, false); + stash_fifo_put(sizeof(uint64_t), 1, STASH_U64, 1, true); } static void stash_fifo_u64_put_u64_n_batch(void) { - stash_fifo_put(sizeof(uint64_t), BATCH, STASH_U64, 1); + stash_fifo_put(sizeof(uint64_t), BATCH, STASH_U64, 1, false); + stash_fifo_put(sizeof(uint64_t), BATCH, STASH_U64, 1, true); } static void stash_fifo_put_ptr_1_batch(void) { - stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 1); + stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 1, false); + stash_fifo_put(sizeof(uintptr_t), 1, STASH_PTR, 1, true); } static void stash_fifo_put_ptr_n_batch(void) { - stash_fifo_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1); + stash_fifo_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1, false); + stash_fifo_put(sizeof(uintptr_t), BATCH, STASH_PTR, 1, true); } static void stash_fifo_put_u32_1_batch(void) { - stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 1); + stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 1, false); + stash_fifo_put(sizeof(uint32_t), 1, STASH_GEN, 1, true); } static void stash_fifo_put_u32_n_batch(void) { - stash_fifo_put(sizeof(uint32_t), BATCH, STASH_GEN, 1); + stash_fifo_put(sizeof(uint32_t), BATCH, STASH_GEN, 1, false); + stash_fifo_put(sizeof(uint32_t), BATCH, STASH_GEN, 1, true); } static void stash_fifo_u32_put_u32_1_batch(void) { - stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 1); + stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 1, false); + stash_fifo_put(sizeof(uint32_t), 1, STASH_U32, 1, true); } static void stash_fifo_u32_put_u32_n_batch(void) { - stash_fifo_put(sizeof(uint32_t), BATCH, STASH_U32, 1); + stash_fifo_put(sizeof(uint32_t), BATCH, STASH_U32, 1, false); + stash_fifo_put(sizeof(uint32_t), BATCH, STASH_U32, 1, true); } static void stash_fifo_put_u16_1_batch(void) { - stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 1); + stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 1, false); + stash_fifo_put(sizeof(uint16_t), 1, STASH_GEN, 1, true); } static void stash_fifo_put_u16_n_batch(void) { - stash_fifo_put(sizeof(uint16_t), BATCH, STASH_GEN, 1); + stash_fifo_put(sizeof(uint16_t), BATCH, STASH_GEN, 1, false); + stash_fifo_put(sizeof(uint16_t), BATCH, STASH_GEN, 1, true); } static void stash_fifo_put_u8_1_batch(void) { - stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 1); + stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 1, false); + stash_fifo_put(sizeof(uint8_t), 1, STASH_GEN, 1, true); } static void stash_fifo_put_u8_n_batch(void) { - stash_fifo_put(sizeof(uint8_t), BATCH, STASH_GEN, 1); + stash_fifo_put(sizeof(uint8_t), BATCH, STASH_GEN, 1, false); + stash_fifo_put(sizeof(uint8_t), BATCH, STASH_GEN, 1, true); } odp_testinfo_t stash_suite[] = { diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c index 0e3919b73..eb7f0772a 100644 --- a/test/validation/api/timer/timer.c +++ b/test/validation/api/timer/timer.c @@ -1,5 +1,5 @@ /* Copyright (c) 2015-2018, Linaro Limited - * Copyright (c) 2019-2022, Nokia + * Copyright (c) 2019-2023, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -244,6 +244,14 @@ check_plain_queue_support(void) return ODP_TEST_INACTIVE; } +static int check_periodic_support(void) +{ + if (global_mem->periodic) + return ODP_TEST_ACTIVE; + + return ODP_TEST_INACTIVE; +} + static int check_periodic_sched_support(void) { if (global_mem->periodic && global_mem->param.queue_type_sched) @@ -2377,6 +2385,139 @@ static void timer_test_sched_all(void) timer_test_all(ODP_QUEUE_TYPE_SCHED); } +static void timer_test_periodic_capa(void) +{ + odp_timer_capability_t timer_capa; + odp_timer_periodic_capability_t capa; + odp_fract_u64_t min_fract, max_fract, base_freq; + uint64_t freq_range, freq_step, first_hz, res_ns, max_multiplier; + double freq, min_freq, max_freq; + int ret; + uint32_t i, j; + uint32_t num = 100; + + memset(&timer_capa, 0, sizeof(odp_timer_capability_t)); + CU_ASSERT_FATAL(odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa) == 0); + CU_ASSERT(timer_capa.periodic.max_pools); + CU_ASSERT(timer_capa.periodic.max_timers); + + min_fract = timer_capa.periodic.min_base_freq_hz; + max_fract = timer_capa.periodic.max_base_freq_hz; + + CU_ASSERT_FATAL(min_fract.integer || min_fract.numer); + CU_ASSERT_FATAL(max_fract.integer || max_fract.numer); + + if (min_fract.numer) + CU_ASSERT_FATAL(min_fract.denom); + + if (max_fract.numer) + CU_ASSERT_FATAL(max_fract.denom); + + min_freq = odp_fract_u64_to_dbl(&min_fract); + max_freq = odp_fract_u64_to_dbl(&max_fract); + CU_ASSERT(min_freq <= max_freq); + + memset(&capa, 0, sizeof(odp_timer_periodic_capability_t)); + + /* Min freq, capa fills in resolution */ + capa.base_freq_hz = min_fract; + capa.max_multiplier = 1; + capa.res_ns = 0; + + CU_ASSERT(odp_timer_periodic_capability(ODP_CLOCK_DEFAULT, &capa) == 1); + CU_ASSERT(capa.base_freq_hz.integer == min_fract.integer); + CU_ASSERT(capa.base_freq_hz.numer == min_fract.numer); + CU_ASSERT(capa.base_freq_hz.denom == min_fract.denom); + CU_ASSERT(capa.max_multiplier >= 1); + CU_ASSERT(capa.res_ns > 0); + + /* Max freq, capa fills in resolution */ + capa.base_freq_hz = max_fract; + capa.max_multiplier = 1; + capa.res_ns = 0; + + CU_ASSERT(odp_timer_periodic_capability(ODP_CLOCK_DEFAULT, &capa) == 1); + CU_ASSERT(capa.base_freq_hz.integer == max_fract.integer); + CU_ASSERT(capa.base_freq_hz.numer == max_fract.numer); + CU_ASSERT(capa.base_freq_hz.denom == max_fract.denom); + CU_ASSERT(capa.max_multiplier >= 1); + CU_ASSERT(capa.res_ns > 0); + + freq_range = max_fract.integer - min_fract.integer; + + if (freq_range < 10 * num) + num = freq_range / 10; + + /* Too short frequency range */ + if (num == 0) + return; + + freq_step = freq_range / num; + first_hz = min_fract.integer + 1; + + ODPH_DBG("min %" PRIu64 ", max %" PRIu64 ", range %" PRIu64 ", step %" PRIu64 "\n", + min_fract.integer, max_fract.integer, freq_range, freq_step); + + for (i = 0; i < num; i++) { + base_freq.integer = first_hz + i * freq_step; + base_freq.numer = 0; + base_freq.denom = 0; + + freq = odp_fract_u64_to_dbl(&base_freq); + + if (freq > max_freq) + base_freq = max_fract; + + for (j = 0; j < 4; j++) { + capa.base_freq_hz = base_freq; + + max_multiplier = 1; + res_ns = 0; + + if (j & 0x1) + max_multiplier = 2; + + if (j & 0x2) + res_ns = 1 + (ODP_TIME_SEC_IN_NS / (10 * base_freq.integer)); + + capa.max_multiplier = max_multiplier; + capa.res_ns = res_ns; + + ODPH_DBG("freq %" PRIu64 ", multip %" PRIu64 ", res %" PRIu64 ",\n", + base_freq.integer, max_multiplier, res_ns); + + ret = odp_timer_periodic_capability(ODP_CLOCK_DEFAULT, &capa); + + if (ret == 1) { + CU_ASSERT(capa.base_freq_hz.integer == base_freq.integer); + CU_ASSERT(capa.base_freq_hz.numer == base_freq.numer); + CU_ASSERT(capa.base_freq_hz.denom == base_freq.denom); + } else if (ret == 0) { + CU_ASSERT(capa.base_freq_hz.integer != base_freq.integer || + capa.base_freq_hz.numer != base_freq.numer || + capa.base_freq_hz.denom != base_freq.denom) + + if (capa.base_freq_hz.numer) + CU_ASSERT_FATAL(capa.base_freq_hz.denom); + + CU_ASSERT(odp_fract_u64_to_dbl(&capa.base_freq_hz) >= min_freq); + CU_ASSERT(odp_fract_u64_to_dbl(&capa.base_freq_hz) <= max_freq); + } + + if (ret >= 0) { + CU_ASSERT(capa.max_multiplier >= max_multiplier); + + if (res_ns) { + /* Same or better resolution */ + CU_ASSERT(capa.res_ns <= res_ns); + } else { + CU_ASSERT(capa.res_ns > 0); + } + } + } + } +} + static void timer_test_periodic(odp_queue_type_t queue_type, int use_first) { odp_timer_capability_t timer_capa; @@ -2392,7 +2533,7 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first) odp_event_t ev; odp_timer_t timer; odp_time_t t1, t2; - uint64_t tick, cur_tick, period_ns, duration_ns, diff_ns; + uint64_t tick, cur_tick, period_ns, duration_ns, diff_ns, offset_ns; double freq, freq_out, min_freq, max_freq; int ret; const char *user_ctx = "User context"; @@ -2509,10 +2650,14 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first) memset(&start_param, 0, sizeof(odp_timer_periodic_start_t)); cur_tick = odp_timer_current_tick(timer_pool); - tick = cur_tick + odp_timer_ns_to_tick(timer_pool, period_ns / 2); + offset_ns = period_ns / 2; + tick = cur_tick + odp_timer_ns_to_tick(timer_pool, offset_ns); - if (use_first) + if (use_first) { + /* First tick moves timer to start before the first period */ + duration_ns -= (period_ns - offset_ns); start_param.first_tick = tick; + } start_param.freq_multiplier = multiplier; start_param.tmo_ev = ev; @@ -2521,7 +2666,8 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first) ODPH_DBG(" Current tick: %" PRIu64 "\n", cur_tick); ODPH_DBG(" First tick: %" PRIu64 "\n", start_param.first_tick); ODPH_DBG(" Multiplier: %" PRIu64 "\n", start_param.freq_multiplier); - ODPH_DBG("Test duration ns: %" PRIu64 "\n", duration_ns); + ODPH_DBG(" Period: %" PRIu64 " nsec\n", period_ns); + ODPH_DBG("Expected duration: %" PRIu64 " nsec\n", duration_ns); ret = odp_timer_periodic_start(timer, &start_param); @@ -2576,6 +2722,8 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first) ret = odp_timer_periodic_cancel(timer); CU_ASSERT_FATAL(ret == 0); + ODPH_DBG("Measured duration: %" PRIu64 " nsec\n", diff_ns); + t1 = odp_time_local(); while (1) { if (queue_type == ODP_QUEUE_TYPE_SCHED) @@ -2714,6 +2862,8 @@ odp_testinfo_t timer_suite[] = { check_plain_queue_support), ODP_TEST_INFO_CONDITIONAL(timer_test_sched_all, check_sched_queue_support), + ODP_TEST_INFO_CONDITIONAL(timer_test_periodic_capa, + check_periodic_support), ODP_TEST_INFO_CONDITIONAL(timer_test_periodic_sched, check_periodic_sched_support), ODP_TEST_INFO_CONDITIONAL(timer_test_periodic_sched_first, |