diff options
author | Anoob Joseph <anoobj@marvell.com> | 2021-03-08 10:28:52 +0000 |
---|---|---|
committer | Matias Elo <matias.elo@nokia.com> | 2021-05-05 10:33:29 +0300 |
commit | 9dee565e2a1ceb23f33f3dd2bfa0b5206b6b24ab (patch) | |
tree | a20d4fdd4b932e257f494d6d7ea657e314574880 | |
parent | 28863bfc18c9948d7209dede54a6faab145bff34 (diff) |
validation: ipsec: add test cases for reassembly of IPv4 pkts
Add test cases to verify IPsec reassembly. The tests cases would work on
large packets which are fragmented.
Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Sachin Yaligar <syaligar@marvell.com>
Signed-off-by: Subrahmanyam Nilla <snilla@marvell.com>
Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Reviewed-by: Janne Peltonen <janne.peltonen@nokia.com>
-rw-r--r-- | test/validation/api/ipsec/ipsec.c | 72 | ||||
-rw-r--r-- | test/validation/api/ipsec/ipsec.h | 10 | ||||
-rw-r--r-- | test/validation/api/ipsec/ipsec_test_in.c | 300 | ||||
-rw-r--r-- | test/validation/api/ipsec/ipsec_test_out.c | 5 |
4 files changed, 379 insertions, 8 deletions
diff --git a/test/validation/api/ipsec/ipsec.c b/test/validation/api/ipsec/ipsec.c index 7ddc79c74..390e7e4ff 100644 --- a/test/validation/api/ipsec/ipsec.c +++ b/test/validation/api/ipsec/ipsec.c @@ -1,6 +1,6 @@ /* Copyright (c) 2017-2018, Linaro Limited * Copyright (c) 2018-2021, Nokia - * Copyright (c) 2020, Marvell + * Copyright (c) 2020-2021, Marvell * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -269,6 +269,14 @@ int ipsec_check_test_sa_update_seq_num(void) return ODP_TEST_ACTIVE; } +int ipsec_check_esp_aes_gcm_128_reass_ipv4(void) +{ + if (suite_context.reass_ipv4) + return ipsec_check_esp(ODP_CIPHER_ALG_AES_GCM, 128, + ODP_AUTH_ALG_AES_GCM, 0); + return ODP_TEST_INACTIVE; +} + void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param, odp_bool_t in, odp_bool_t ah, @@ -1158,6 +1166,68 @@ int ipsec_config(odp_instance_t ODP_UNUSED inst) ipsec_config.inbound.chksums.all_chksum = ~0; ipsec_config.stats_en = true; + ipsec_config.inbound.reassembly.max_wait_time = 100 * ODP_TIME_MSEC_IN_NS; + if (ipsec_config.inbound.reassembly.max_wait_time > capa.reassembly.max_wait_time) + ipsec_config.inbound.reassembly.max_wait_time = capa.reassembly.max_wait_time; + + ipsec_config.inbound.reassembly.max_num_frags = capa.reassembly.max_num_frags; + + if (capa.reassembly.ip) { + ipsec_config.inbound.reassembly.en_ipv4 = true; + ipsec_config.inbound.reassembly.en_ipv6 = true; + } + + if (capa.reassembly.ipv4) + ipsec_config.inbound.reassembly.en_ipv4 = true; + + if (capa.reassembly.ipv6) + ipsec_config.inbound.reassembly.en_ipv6 = true; + + if (ODP_IPSEC_OP_MODE_INLINE == suite_context.inbound_op_mode && + !capa.reass_inline) { + ipsec_config.inbound.reassembly.en_ipv4 = false; + ipsec_config.inbound.reassembly.en_ipv6 = false; + } + + if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.inbound_op_mode && + !capa.reass_async) { + ipsec_config.inbound.reassembly.en_ipv4 = false; + ipsec_config.inbound.reassembly.en_ipv6 = false; + } + + if (ODP_IPSEC_OP_MODE_SYNC == suite_context.inbound_op_mode) { + ipsec_config.inbound.reassembly.en_ipv4 = false; + ipsec_config.inbound.reassembly.en_ipv6 = false; + } + + if (ipsec_config.inbound.reassembly.max_num_frags > MAX_FRAGS) { + ipsec_config.inbound.reassembly.en_ipv4 = false; + ipsec_config.inbound.reassembly.en_ipv6 = false; + } + + if (ipsec_config.inbound.reassembly.en_ipv4) + suite_context.reass_ipv4 = true; + else + suite_context.reass_ipv4 = false; + + if (ipsec_config.inbound.reassembly.en_ipv6) + suite_context.reass_ipv6 = true; + else + suite_context.reass_ipv6 = false; + + if (suite_context.reass_ipv4 || suite_context.reass_ipv6) { + if (ODP_IPSEC_OP_MODE_INLINE == suite_context.inbound_op_mode) + ipsec_config.inbound.reass_inline = true; + + if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.inbound_op_mode) { + ipsec_config.inbound.reass_async = true; + + /* Reassembly with ASYNC not supported */ + suite_context.reass_ipv4 = false; + suite_context.reass_ipv6 = false; + } + } + if (ODP_IPSEC_OK != odp_ipsec_config(&ipsec_config)) return -1; diff --git a/test/validation/api/ipsec/ipsec.h b/test/validation/api/ipsec/ipsec.h index fc5192aab..96404ba9b 100644 --- a/test/validation/api/ipsec/ipsec.h +++ b/test/validation/api/ipsec/ipsec.h @@ -11,6 +11,11 @@ #include <odp_cunit_common.h> +#define IPV4ADDR(a, b, c, d) odp_cpu_to_be_32(((a) << 24) | \ + ((b) << 16) | \ + ((c) << 8) | \ + ((d) << 0)) + /* test arrays: */ extern odp_testinfo_t ipsec_in_suite[]; extern odp_testinfo_t ipsec_out_suite[]; @@ -27,6 +32,8 @@ int ipsec_in_term(void); int ipsec_out_term(void); struct suite_context_s { + odp_bool_t reass_ipv4; + odp_bool_t reass_ipv6; odp_ipsec_op_mode_t inbound_op_mode; odp_ipsec_op_mode_t outbound_op_mode; odp_pool_t pool; @@ -80,7 +87,7 @@ typedef struct { odp_proto_l3_type_t l3_type; odp_proto_l4_type_t l4_type; uint32_t seq_num; - } out[1]; + } out[MAX_FRAGS]; } ipsec_test_part; void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param, @@ -131,5 +138,6 @@ int ipsec_check_esp_null_aes_gmac_192(void); int ipsec_check_esp_null_aes_gmac_256(void); int ipsec_check_esp_chacha20_poly1305(void); int ipsec_check_test_sa_update_seq_num(void); +int ipsec_check_esp_aes_gcm_128_reass_ipv4(void); #endif diff --git a/test/validation/api/ipsec/ipsec_test_in.c b/test/validation/api/ipsec/ipsec_test_in.c index 0e9125664..0a844025d 100644 --- a/test/validation/api/ipsec/ipsec_test_in.c +++ b/test/validation/api/ipsec/ipsec_test_in.c @@ -1,5 +1,5 @@ /* Copyright (c) 2017-2018, Linaro Limited - * Copyright (c) 2020, Marvell + * Copyright (c) 2020-2021, Marvell * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -7,8 +7,45 @@ #include "ipsec.h" +#include "reass_test_vectors.h" #include "test_vectors.h" +static void part_prep_esp(ipsec_test_part part[], int num_part, bool v6_tunnel) +{ + int i; + + memset(part, 0, sizeof(ipsec_test_part) * num_part); + + for (i = 0; i < num_part; i++) { + part[i].num_pkt = 1; + + if (v6_tunnel) + part[i].out[0].l3_type = ODP_PROTO_L3_TYPE_IPV6; + else + part[i].out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; + + part[i].out[0].l4_type = ODP_PROTO_L4_TYPE_ESP; + } +} + +static void part_prep_plain(ipsec_test_part *part, int num_pkt, bool v6, bool udp) +{ + int i; + + part->num_pkt = num_pkt; + for (i = 0; i < num_pkt; i++) { + part->out[i].l4_type = _ODP_PROTO_L4_TYPE_UNDEF; + + if (v6) + part->out[i].l3_type = ODP_PROTO_L3_TYPE_IPV6; + else + part->out[i].l3_type = ODP_PROTO_L3_TYPE_IPV4; + + if (udp) + part->out[i].l4_type = ODP_PROTO_L4_TYPE_UDP; + } +} + static void test_in_ipv4_ah_sha256(void) { odp_ipsec_sa_param_t param; @@ -1727,6 +1764,263 @@ static void test_ipsec_sa_print(void) ipsec_sa_destroy(in_sa); } +static void test_in_ipv4_esp_reass_success_two_frags(odp_ipsec_sa_t out_sa, + odp_ipsec_sa_t in_sa) +{ + ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS]; + int i; + + memset(test_in, 0, sizeof(test_in)); + + CU_ASSERT(MAX_FRAGS >= 2); + + part_prep_esp(test_out, 2, false); + + test_out[0].pkt_in = &pkt_ipv4_udp_p1_f1; + test_out[1].pkt_in = &pkt_ipv4_udp_p1_f2; + + part_prep_plain(&test_in[1], 1, false, true); + test_in[1].out[0].pkt_res = &pkt_ipv4_udp_p1; + + for (i = 0; i < 2; i++) { + ipsec_test_packet test_pkt; + odp_packet_t pkt; + + CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1); + + ipsec_test_packet_from_pkt(&test_pkt, &pkt); + test_in[i].pkt_in = &test_pkt; + + ipsec_check_in_one(&test_in[i], in_sa); + } +} + +static void test_in_ipv4_esp_reass_success_four_frags(odp_ipsec_sa_t out_sa, + odp_ipsec_sa_t in_sa) +{ + ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS]; + int i; + + memset(test_in, 0, sizeof(test_in)); + + CU_ASSERT(MAX_FRAGS >= 4); + + part_prep_esp(test_out, 4, false); + + test_out[0].pkt_in = &pkt_ipv4_udp_p2_f1; + test_out[1].pkt_in = &pkt_ipv4_udp_p2_f2; + test_out[2].pkt_in = &pkt_ipv4_udp_p2_f3; + test_out[3].pkt_in = &pkt_ipv4_udp_p2_f4; + + part_prep_plain(&test_in[3], 1, false, true); + test_in[3].out[0].pkt_res = &pkt_ipv4_udp_p2; + + for (i = 0; i < 4; i++) { + ipsec_test_packet test_pkt; + odp_packet_t pkt; + + CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1); + + ipsec_test_packet_from_pkt(&test_pkt, &pkt); + test_in[i].pkt_in = &test_pkt; + + ipsec_check_in_one(&test_in[i], in_sa); + } +} + +static void test_in_ipv4_esp_reass_success_two_frags_ooo(odp_ipsec_sa_t out_sa, + odp_ipsec_sa_t in_sa) +{ + ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS]; + int i; + + memset(test_in, 0, sizeof(test_in)); + + CU_ASSERT(MAX_FRAGS >= 2); + + part_prep_esp(test_out, 2, false); + + test_out[0].pkt_in = &pkt_ipv4_udp_p1_f2; + test_out[1].pkt_in = &pkt_ipv4_udp_p1_f1; + + part_prep_plain(&test_in[1], 1, false, true); + test_in[1].out[0].pkt_res = &pkt_ipv4_udp_p1; + + for (i = 0; i < 2; i++) { + ipsec_test_packet test_pkt; + odp_packet_t pkt; + + CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1); + + ipsec_test_packet_from_pkt(&test_pkt, &pkt); + test_in[i].pkt_in = &test_pkt; + + ipsec_check_in_one(&test_in[i], in_sa); + } +} + +static void test_in_ipv4_esp_reass_success_four_frags_ooo(odp_ipsec_sa_t out_sa, + odp_ipsec_sa_t in_sa) +{ + ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS]; + int i; + + memset(test_in, 0, sizeof(test_in)); + + CU_ASSERT(MAX_FRAGS >= 4); + + part_prep_esp(test_out, 4, false); + + test_out[0].pkt_in = &pkt_ipv4_udp_p2_f4; + test_out[1].pkt_in = &pkt_ipv4_udp_p2_f1; + test_out[2].pkt_in = &pkt_ipv4_udp_p2_f2; + test_out[3].pkt_in = &pkt_ipv4_udp_p2_f3; + + part_prep_plain(&test_in[3], 1, false, true); + test_in[3].out[0].pkt_res = &pkt_ipv4_udp_p2; + + for (i = 0; i < 4; i++) { + ipsec_test_packet test_pkt; + odp_packet_t pkt; + + CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1); + + ipsec_test_packet_from_pkt(&test_pkt, &pkt); + test_in[i].pkt_in = &test_pkt; + + ipsec_check_in_one(&test_in[i], in_sa); + } +} + +static void test_in_ipv4_esp_reass_incomp_missing(odp_ipsec_sa_t out_sa, + odp_ipsec_sa_t in_sa) +{ + ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS]; + ipsec_test_packet test_pkt; + odp_packet_t pkt; + + memset(test_in, 0, sizeof(test_in)); + + CU_ASSERT(MAX_FRAGS >= 1); + + part_prep_esp(test_out, 1, false); + + test_out[0].pkt_in = &pkt_ipv4_udp_p1_f1; + + part_prep_plain(&test_in[0], 1, false, true); + test_in[0].out[0].pkt_res = &pkt_ipv4_udp_p1_f1; + + CU_ASSERT_EQUAL(ipsec_check_out(&test_out[0], out_sa, &pkt), 1); + + ipsec_test_packet_from_pkt(&test_pkt, &pkt); + test_in[0].pkt_in = &test_pkt; + + ipsec_check_in_one(&test_in[0], in_sa); +} + +static void test_in_ipv4_esp_reass_success(void) +{ + odp_ipsec_tunnel_param_t in_tunnel, out_tunnel; + odp_ipsec_sa_param_t param_in, param_out; + uint32_t src = IPV4ADDR(10, 0, 11, 2); + uint32_t dst = IPV4ADDR(10, 0, 22, 2); + odp_ipsec_sa_t out_sa, in_sa; + odp_ipsec_capability_t capa; + + memset(&in_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + 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; + + CU_ASSERT(odp_ipsec_capability(&capa) == 0); + + ipsec_sa_param_fill(¶m_out, + false, false, 0x4a2cbfe7, &out_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + + ipsec_sa_param_fill(¶m_in, + true, false, 0x4a2cbfe7, &in_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + + param_in.inbound.reassembly_en = 1; + + out_sa = odp_ipsec_sa_create(¶m_out); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, out_sa); + + in_sa = odp_ipsec_sa_create(¶m_in); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, in_sa); + + printf("\n IPv4 two frags"); + test_in_ipv4_esp_reass_success_two_frags(out_sa, in_sa); + + printf("\n IPv4 four frags"); + test_in_ipv4_esp_reass_success_four_frags(out_sa, in_sa); + + printf("\n IPv4 two frags out of order"); + test_in_ipv4_esp_reass_success_two_frags_ooo(out_sa, in_sa); + + printf("\n IPv4 four frags out of order"); + test_in_ipv4_esp_reass_success_four_frags_ooo(out_sa, in_sa); + + printf("\n"); + + ipsec_sa_destroy(in_sa); + ipsec_sa_destroy(out_sa); +} + +static void test_in_ipv4_esp_reass_incomp(void) +{ + odp_ipsec_tunnel_param_t in_tunnel, out_tunnel; + odp_ipsec_sa_param_t param_in, param_out; + uint32_t src = IPV4ADDR(10, 0, 11, 2); + uint32_t dst = IPV4ADDR(10, 0, 22, 2); + odp_ipsec_sa_t out_sa, in_sa; + odp_ipsec_capability_t capa; + + memset(&in_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + 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; + + CU_ASSERT(odp_ipsec_capability(&capa) == 0); + + ipsec_sa_param_fill(¶m_out, + false, false, 0x4a2cbfe7, &out_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + + ipsec_sa_param_fill(¶m_in, + true, false, 0x4a2cbfe7, &in_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + + param_in.inbound.reassembly_en = 1; + + out_sa = odp_ipsec_sa_create(¶m_out); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, out_sa); + + in_sa = odp_ipsec_sa_create(¶m_in); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, in_sa); + + printf("\n IPv4 missing frag"); + test_in_ipv4_esp_reass_incomp_missing(out_sa, in_sa); + + printf("\n"); + + ipsec_sa_destroy(in_sa); + ipsec_sa_destroy(out_sa); +} + static void ipsec_test_capability(void) { odp_ipsec_capability_t capa; @@ -1839,5 +2133,9 @@ odp_testinfo_t ipsec_in_suite[] = { ODP_TEST_INFO(test_ipsec_print), ODP_TEST_INFO_CONDITIONAL(test_ipsec_sa_print, ipsec_check_esp_aes_cbc_128_sha1), + ODP_TEST_INFO_CONDITIONAL(test_in_ipv4_esp_reass_success, + ipsec_check_esp_aes_gcm_128_reass_ipv4), + ODP_TEST_INFO_CONDITIONAL(test_in_ipv4_esp_reass_incomp, + ipsec_check_esp_aes_gcm_128_reass_ipv4), ODP_TEST_INFO_NULL, }; diff --git a/test/validation/api/ipsec/ipsec_test_out.c b/test/validation/api/ipsec/ipsec_test_out.c index 1aa6b8409..b48dd0d6c 100644 --- a/test/validation/api/ipsec/ipsec_test_out.c +++ b/test/validation/api/ipsec/ipsec_test_out.c @@ -151,11 +151,6 @@ static void test_out_ipv4_ah_sha256(void) ipsec_sa_destroy(sa); } -#define IPV4ADDR(a, b, c, d) odp_cpu_to_be_32((a << 24) | \ - (b << 16) | \ - (c << 8) | \ - (d << 0)) - static void test_out_ipv4_ah_sha256_tun_ipv4(void) { odp_ipsec_tunnel_param_t tunnel; |