diff options
author | Aakash Sasidharan <asasidharan@marvell.com> | 2021-10-28 16:07:36 +0530 |
---|---|---|
committer | Petri Savolainen <petri.savolainen@nokia.com> | 2022-11-21 13:45:04 +0200 |
commit | 5f552ee01eced74b22a07548cf2402490f747cf7 (patch) | |
tree | f8d0baac5f7801f850e9caba949e581cc6135e4b /test | |
parent | f03818dc9a3428d1be2f418a449c0abc3ac1e08f (diff) |
validation: ipsec: add SA expiry test
Add IPsec SA expiry tests in out suite.
Signed-off-by: Aakash Sasidharan <asasidharan@marvell.com>
Reviewed-by: Anoob Joseph <anoobj@marvell.com>
Reviewed-by: Janne Peltonen <janne.peltonen@nokia.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/validation/api/ipsec/ipsec.c | 118 | ||||
-rw-r--r-- | test/validation/api/ipsec/ipsec.h | 14 | ||||
-rw-r--r-- | test/validation/api/ipsec/ipsec_test_out.c | 136 |
3 files changed, 266 insertions, 2 deletions
diff --git a/test/validation/api/ipsec/ipsec.c b/test/validation/api/ipsec/ipsec.c index cacd704ae..11860bf9b 100644 --- a/test/validation/api/ipsec/ipsec.c +++ b/test/validation/api/ipsec/ipsec.c @@ -27,9 +27,12 @@ static struct buffered_event_s sched_ev_buffer[EVENT_BUFFER_SIZE]; struct suite_context_s suite_context; static odp_ipsec_capability_t capa; static int sched_ev_buffer_tail; +odp_bool_t sa_expiry_notified; + #define PKT_POOL_NUM 64 #define EVENT_WAIT_TIME ODP_TIME_SEC_IN_NS +#define STATUS_EVENT_WAIT_TIME ODP_TIME_MSEC_IN_NS #define SCHED_EVENT_RETRY_COUNT 2 #define PACKET_USER_PTR ((void *)0x1212fefe) @@ -437,6 +440,50 @@ void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param, param->lifetime.hard_limit.packets = 10000 * 1000; } +static void ipsec_status_event_handle(odp_event_t ev_status, + odp_ipsec_sa_t sa, + enum ipsec_test_sa_expiry sa_expiry) +{ + odp_ipsec_status_t status = { + .id = 0, + .sa = ODP_IPSEC_SA_INVALID, + .result = 0, + .warn.all = 0, + }; + + CU_ASSERT_FATAL(ODP_EVENT_INVALID != ev_status); + CU_ASSERT_EQUAL(1, odp_event_is_valid(ev_status)); + CU_ASSERT_EQUAL_FATAL(ODP_EVENT_IPSEC_STATUS, odp_event_type(ev_status)); + + CU_ASSERT_EQUAL(0, odp_ipsec_status(&status, ev_status)); + CU_ASSERT_EQUAL(ODP_IPSEC_STATUS_WARN, status.id); + CU_ASSERT_EQUAL(sa, status.sa); + CU_ASSERT_EQUAL(0, status.result); + + if (IPSEC_TEST_EXPIRY_IGNORED != sa_expiry) { + if (IPSEC_TEST_EXPIRY_SOFT_PKT == sa_expiry) { + CU_ASSERT_EQUAL(1, status.warn.soft_exp_packets); + sa_expiry_notified = true; + } else if (IPSEC_TEST_EXPIRY_SOFT_BYTE == sa_expiry) { + CU_ASSERT_EQUAL(1, status.warn.soft_exp_bytes); + sa_expiry_notified = true; + } + } + + odp_event_free(ev_status); +} + +void ipsec_status_event_get(odp_ipsec_sa_t sa, + enum ipsec_test_sa_expiry sa_expiry) +{ + uint64_t wait_time = (sa_expiry == IPSEC_TEST_EXPIRY_IGNORED) ? 0 : STATUS_EVENT_WAIT_TIME; + odp_event_t ev; + + ev = recv_event(suite_context.queue, wait_time); + if (ODP_EVENT_INVALID != ev) + ipsec_status_event_handle(ev, sa, sa_expiry); +} + void ipsec_sa_destroy(odp_ipsec_sa_t sa) { odp_event_t event; @@ -765,6 +812,45 @@ static int ipsec_process_in(const ipsec_test_part *part, return num_out; } +static int ipsec_check_sa_expiry(enum ipsec_test_sa_expiry sa_expiry, + odp_ipsec_packet_result_t *result) +{ + if (sa_expiry == IPSEC_TEST_EXPIRY_IGNORED) + return 0; + + if (!sa_expiry_notified) { + if (sa_expiry == IPSEC_TEST_EXPIRY_SOFT_PKT) { + if (result->status.warn.soft_exp_packets) + sa_expiry_notified = true; + } else if (sa_expiry == IPSEC_TEST_EXPIRY_SOFT_BYTE) { + if (result->status.warn.soft_exp_bytes) + sa_expiry_notified = true; + } else if (sa_expiry == IPSEC_TEST_EXPIRY_HARD_PKT) { + if (result->status.error.hard_exp_packets) + sa_expiry_notified = true; + + return -1; + } else if (sa_expiry == IPSEC_TEST_EXPIRY_HARD_BYTE) { + if (result->status.error.hard_exp_bytes) + sa_expiry_notified = true; + + return -1; + } + } else { + if (sa_expiry == IPSEC_TEST_EXPIRY_HARD_PKT) { + CU_ASSERT(result->status.error.hard_exp_packets); + + return -1; + } else if (sa_expiry == IPSEC_TEST_EXPIRY_HARD_BYTE) { + CU_ASSERT(result->status.error.hard_exp_bytes); + + return -1; + } + } + + return 0; +} + static int ipsec_send_out_one(const ipsec_test_part *part, odp_ipsec_sa_t sa, odp_packet_t *pkto) @@ -891,18 +977,39 @@ static int ipsec_send_out_one(const ipsec_test_part *part, pkto[i] = odp_packet_from_event(ev); CU_ASSERT_FATAL(pkto[i] != ODP_PACKET_INVALID); + + if (part->out[i].sa_expiry != IPSEC_TEST_EXPIRY_NONE) + ipsec_status_event_get(sa, part->out[i].sa_expiry); + i++; continue; } ev = recv_event(suite_context.queue, 0); if (ODP_EVENT_INVALID != ev) { + odp_event_type_t ev_type; + CU_ASSERT(odp_event_is_valid(ev) == 1); + ev_type = odp_event_types(ev, &subtype); + + if ((ODP_EVENT_IPSEC_STATUS == ev_type) && + part->out[i].sa_expiry != IPSEC_TEST_EXPIRY_NONE) { + ipsec_status_event_handle(ev, sa, part->out[i].sa_expiry); + continue; + } + CU_ASSERT_EQUAL(ODP_EVENT_PACKET, - odp_event_types(ev, &subtype)); + ev_type); CU_ASSERT_EQUAL(ODP_EVENT_PACKET_IPSEC, subtype); - CU_ASSERT(part->out[i].status.error.all); + + /* In the case of SA hard expiry tests, hard expiry error bits are + * expected to be set. The exact error bits expected to be set based + * on sa_expiry is checked eventually in ipsec_check_sa_expiry() + * from the caller of this function. + */ + if (part->out[i].sa_expiry == IPSEC_TEST_EXPIRY_NONE) + CU_ASSERT(part->out[i].status.error.all); pkto[i] = odp_ipsec_packet_from_event(ev); CU_ASSERT_FATAL(pkto[i] != ODP_PACKET_INVALID); @@ -991,6 +1098,8 @@ static void verify_in(const ipsec_test_part *part, ODP_IPSEC_OP_MODE_INLINE, result.flag.inline_mode); CU_ASSERT_EQUAL(sa, result.sa); + CU_ASSERT_EQUAL(part->out[i].status.warn.all, + result.status.warn.all); if (ODP_IPSEC_SA_INVALID != sa) CU_ASSERT_EQUAL(IPSEC_SA_CTX, odp_ipsec_sa_context(sa)); @@ -1066,6 +1175,11 @@ int ipsec_check_out(const ipsec_test_part *part, odp_ipsec_sa_t sa, } else { /* IPsec packet */ CU_ASSERT_EQUAL(0, odp_ipsec_result(&result, pkto[i])); + + if (part->out[i].sa_expiry != IPSEC_TEST_EXPIRY_NONE) + if (ipsec_check_sa_expiry(part->out[i].sa_expiry, &result) != 0) + return num_out; + CU_ASSERT_EQUAL(part->out[i].status.error.all, result.status.error.all); if (0 == result.status.error.all) diff --git a/test/validation/api/ipsec/ipsec.h b/test/validation/api/ipsec/ipsec.h index a2bb478a3..1c17693f7 100644 --- a/test/validation/api/ipsec/ipsec.h +++ b/test/validation/api/ipsec/ipsec.h @@ -72,6 +72,15 @@ enum ipsec_test_stats { IPSEC_TEST_STATS_AUTH_ERR, }; +enum ipsec_test_sa_expiry { + IPSEC_TEST_EXPIRY_NONE = 0, + IPSEC_TEST_EXPIRY_IGNORED, + IPSEC_TEST_EXPIRY_SOFT_BYTE, + IPSEC_TEST_EXPIRY_SOFT_PKT, + IPSEC_TEST_EXPIRY_HARD_BYTE, + IPSEC_TEST_EXPIRY_HARD_PKT, +}; + typedef struct { odp_bool_t lookup; odp_bool_t inline_hdr_in_packet; @@ -101,9 +110,12 @@ typedef struct { * differs from that of input test packet (pkt_in). */ uint32_t orig_ip_len; + enum ipsec_test_sa_expiry sa_expiry; } out[MAX_FRAGS]; } ipsec_test_part; +extern odp_bool_t sa_expiry_notified; + void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param, odp_ipsec_dir_t dir, odp_ipsec_protocol_t proto, @@ -151,5 +163,7 @@ int ipsec_check_test_sa_update_seq_num(void); int ipsec_check_esp_aes_gcm_128_reass_ipv4(void); int ipsec_check_esp_aes_gcm_128_reass_ipv6(void); int ipsec_check_esp_null_aes_xcbc(void); +void ipsec_status_event_get(odp_ipsec_sa_t sa, + enum ipsec_test_sa_expiry sa_expiry); #endif diff --git a/test/validation/api/ipsec/ipsec_test_out.c b/test/validation/api/ipsec/ipsec_test_out.c index 236997735..bb318edad 100644 --- a/test/validation/api/ipsec/ipsec_test_out.c +++ b/test/validation/api/ipsec/ipsec_test_out.c @@ -1593,6 +1593,138 @@ static void test_test_sa_update_seq_num(void) printf("\n "); } +#define SOFT_LIMIT_PKT_CNT 1024 +#define HARD_LIMIT_PKT_CNT 2048 +#define DELTA_PKT_CNT 320 + +static void test_out_ipv4_esp_sa_expiry(enum ipsec_test_sa_expiry expiry) +{ + int byte_count_per_packet = pkt_ipv4_icmp_0.len - pkt_ipv4_icmp_0.l3_offset; + uint32_t src = IPV4ADDR(10, 0, 11, 2); + uint32_t dst = IPV4ADDR(10, 0, 22, 2); + odp_ipsec_tunnel_param_t out_tunnel; + odp_ipsec_sa_param_t param_out; + int i, inc, limit, delta; + uint64_t soft_limit_byte; + uint64_t hard_limit_byte; + uint64_t soft_limit_pkt; + uint64_t hard_limit_pkt; + odp_ipsec_sa_t out_sa; + + switch (expiry) { + case IPSEC_TEST_EXPIRY_SOFT_PKT: + soft_limit_pkt = SOFT_LIMIT_PKT_CNT; + hard_limit_pkt = HARD_LIMIT_PKT_CNT; + soft_limit_byte = 0; + hard_limit_byte = 0; + delta = DELTA_PKT_CNT; + limit = soft_limit_pkt; + inc = 1; + break; + case IPSEC_TEST_EXPIRY_HARD_PKT: + soft_limit_pkt = SOFT_LIMIT_PKT_CNT; + hard_limit_pkt = HARD_LIMIT_PKT_CNT; + soft_limit_byte = 0; + hard_limit_byte = 0; + delta = DELTA_PKT_CNT; + limit = hard_limit_pkt; + inc = 1; + break; + case IPSEC_TEST_EXPIRY_SOFT_BYTE: + soft_limit_pkt = 0; + hard_limit_pkt = 0; + soft_limit_byte = byte_count_per_packet * SOFT_LIMIT_PKT_CNT; + hard_limit_byte = byte_count_per_packet * HARD_LIMIT_PKT_CNT; + delta = byte_count_per_packet * DELTA_PKT_CNT; + limit = soft_limit_byte; + inc = byte_count_per_packet; + break; + case IPSEC_TEST_EXPIRY_HARD_BYTE: + soft_limit_pkt = 0; + hard_limit_pkt = 0; + soft_limit_byte = byte_count_per_packet * SOFT_LIMIT_PKT_CNT; + hard_limit_byte = byte_count_per_packet * HARD_LIMIT_PKT_CNT; + delta = byte_count_per_packet * DELTA_PKT_CNT; + limit = hard_limit_byte; + inc = byte_count_per_packet; + break; + default: + return; + } + + memset(&out_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + + out_tunnel.type = ODP_IPSEC_TUNNEL_IPV4; + out_tunnel.ipv4.src_addr = &src; + out_tunnel.ipv4.dst_addr = &dst; + + ipsec_sa_param_fill(¶m_out, ODP_IPSEC_DIR_OUTBOUND, ODP_IPSEC_ESP, + 0x4a2cbfe7, &out_tunnel, + ODP_CIPHER_ALG_AES_CBC, &key_a5_128, + ODP_AUTH_ALG_SHA1_HMAC, &key_5a_160, + NULL, NULL); + + param_out.lifetime.soft_limit.bytes = soft_limit_byte; + param_out.lifetime.hard_limit.bytes = hard_limit_byte; + param_out.lifetime.soft_limit.packets = soft_limit_pkt; + param_out.lifetime.hard_limit.packets = hard_limit_pkt; + + out_sa = odp_ipsec_sa_create(¶m_out); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, out_sa); + + ipsec_test_part test_out = { + .pkt_in = &pkt_ipv4_icmp_0, + .num_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .l3_type = ODP_PROTO_L3_TYPE_IPV4, + .l4_type = ODP_PROTO_L4_TYPE_ESP, + }, + }, + }; + + test_out.out[0].sa_expiry = IPSEC_TEST_EXPIRY_IGNORED; + + for (i = 0; i < limit - delta; i += inc) + ipsec_check_out_one(&test_out, out_sa); + + sa_expiry_notified = false; + test_out.out[0].sa_expiry = expiry; + + for (; i <= limit && !sa_expiry_notified; i += inc) + ipsec_check_out_one(&test_out, out_sa); + + CU_ASSERT(sa_expiry_notified); + + for (; i <= limit + delta; i += inc) + ipsec_check_out_one(&test_out, out_sa); + + ipsec_sa_destroy(out_sa); +} + +static void test_out_ipv4_esp_sa_pkt_expiry(void) +{ + printf("\n IPv4 IPsec SA packet soft expiry"); + test_out_ipv4_esp_sa_expiry(IPSEC_TEST_EXPIRY_SOFT_PKT); + + printf("\n IPv4 IPsec SA packet hard expiry"); + test_out_ipv4_esp_sa_expiry(IPSEC_TEST_EXPIRY_HARD_PKT); + + printf("\n"); +} + +static void test_out_ipv4_esp_sa_byte_expiry(void) +{ + printf("\n IPv4 IPsec SA byte soft expiry"); + test_out_ipv4_esp_sa_expiry(IPSEC_TEST_EXPIRY_SOFT_BYTE); + + printf("\n IPv4 IPsec SA byte hard expiry"); + test_out_ipv4_esp_sa_expiry(IPSEC_TEST_EXPIRY_HARD_BYTE); + + printf("\n"); +} + static void ipsec_test_capability(void) { odp_ipsec_capability_t capa; @@ -1900,6 +2032,10 @@ odp_testinfo_t ipsec_out_suite[] = { ipsec_check_esp_null_aes_xcbc), ODP_TEST_INFO_CONDITIONAL(test_sa_info, ipsec_check_esp_aes_cbc_128_sha1), + ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_sa_pkt_expiry, + ipsec_check_esp_aes_cbc_128_sha1), + ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_sa_byte_expiry, + ipsec_check_esp_aes_cbc_128_sha1), ODP_TEST_INFO_CONDITIONAL(test_test_sa_update_seq_num, ipsec_check_test_sa_update_seq_num), ODP_TEST_INFO(test_esp_out_in_all_basic), |