aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAakash Sasidharan <asasidharan@marvell.com>2021-10-28 16:07:36 +0530
committerPetri Savolainen <petri.savolainen@nokia.com>2022-11-21 13:45:04 +0200
commit5f552ee01eced74b22a07548cf2402490f747cf7 (patch)
treef8d0baac5f7801f850e9caba949e581cc6135e4b /test
parentf03818dc9a3428d1be2f418a449c0abc3ac1e08f (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.c118
-rw-r--r--test/validation/api/ipsec/ipsec.h14
-rw-r--r--test/validation/api/ipsec/ipsec_test_out.c136
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(&param_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(&param_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),