aboutsummaryrefslogtreecommitdiff
path: root/test/validation/api/ipsec/ipsec.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/validation/api/ipsec/ipsec.c')
-rw-r--r--test/validation/api/ipsec/ipsec.c227
1 files changed, 189 insertions, 38 deletions
diff --git a/test/validation/api/ipsec/ipsec.c b/test/validation/api/ipsec/ipsec.c
index 5bbc9c025..c6fbe6f91 100644
--- a/test/validation/api/ipsec/ipsec.c
+++ b/test/validation/api/ipsec/ipsec.c
@@ -20,6 +20,7 @@ struct suite_context_s suite_context;
static odp_ipsec_capability_t capa;
#define PKT_POOL_NUM 64
+#define EVENT_WAIT_TIME ODP_TIME_SEC_IN_NS
#define PACKET_USER_PTR ((void *)0x1212fefe)
#define IPSEC_SA_CTX ((void *)0xfefefafa)
@@ -100,6 +101,41 @@ static int pktio_start(odp_pktio_t pktio, odp_bool_t in, odp_bool_t out)
return 1;
}
+static odp_event_t sched_queue_deq(uint64_t wait_ns)
+{
+ uint64_t wait = odp_schedule_wait_time(wait_ns);
+
+ return odp_schedule(NULL, wait);
+}
+
+static odp_event_t plain_queue_deq(odp_queue_t queue, uint64_t wait_ns)
+{
+ odp_time_t cur, wait, next;
+ odp_event_t event;
+
+ wait = odp_time_local_from_ns(wait_ns);
+ next = odp_time_sum(odp_time_local(), wait);
+
+ do {
+ event = odp_queue_deq(queue);
+ cur = odp_time_local();
+ } while (event == ODP_EVENT_INVALID && odp_time_cmp(next, cur) >= 0);
+
+ return event;
+}
+
+static odp_event_t recv_event(odp_queue_t queue, uint64_t wait_ns)
+{
+ odp_event_t event;
+
+ if (odp_queue_type(queue) == ODP_QUEUE_TYPE_PLAIN)
+ event = plain_queue_deq(queue, wait_ns);
+ else
+ event = sched_queue_deq(wait_ns);
+
+ return event;
+}
+
static void pktio_stop(odp_pktio_t pktio)
{
odp_queue_t queue = ODP_QUEUE_INVALID;
@@ -110,7 +146,7 @@ static void pktio_stop(odp_pktio_t pktio)
fprintf(stderr, "IPsec pktio stop failed.\n");
while (1) {
- odp_event_t ev = odp_queue_deq(queue);
+ odp_event_t ev = recv_event(queue, 0);
if (ev != ODP_EVENT_INVALID)
odp_event_free(ev);
@@ -139,6 +175,17 @@ int ipsec_check(odp_bool_t ah,
ODP_SUPPORT_NO == capa.op_mode_inline_out))
return ODP_TEST_INACTIVE;
+ if (!(ODP_IPSEC_OP_MODE_SYNC == suite_context.inbound_op_mode &&
+ ODP_IPSEC_OP_MODE_SYNC == suite_context.outbound_op_mode) &&
+ ODP_QUEUE_INVALID != suite_context.queue) {
+ if (suite_context.q_type == ODP_QUEUE_TYPE_PLAIN &&
+ !capa.queue_type_plain)
+ return ODP_TEST_INACTIVE;
+ if (suite_context.q_type == ODP_QUEUE_TYPE_SCHED &&
+ !capa.queue_type_sched)
+ return ODP_TEST_INACTIVE;
+ }
+
/* suite_context.pktio is set to ODP_PKTIO_INVALID in ipsec_suite_init()
* if the pktio device doesn't support inline IPsec processing. */
if (suite_context.pktio == ODP_PKTIO_INVALID &&
@@ -356,9 +403,7 @@ void ipsec_sa_destroy(odp_ipsec_sa_t sa)
CU_ASSERT_EQUAL(ODP_IPSEC_OK, odp_ipsec_sa_disable(sa));
if (ODP_QUEUE_INVALID != suite_context.queue) {
- do {
- event = odp_queue_deq(suite_context.queue);
- } while (event == ODP_EVENT_INVALID);
+ event = recv_event(suite_context.queue, EVENT_WAIT_TIME);
CU_ASSERT(odp_event_is_valid(event) == 1);
CU_ASSERT_EQUAL(ODP_EVENT_IPSEC_STATUS, odp_event_type(event));
@@ -516,12 +561,27 @@ static int send_pkts(const ipsec_test_part part[], int num_part)
return num_part;
}
+/* Receive async inbound packet */
+static odp_event_t recv_pkt_async_inbound(odp_ipsec_op_status_t status)
+{
+ odp_queue_t queue;
+
+ /*
+ * In case of SA lookup failure, the event is enqueued to the default
+ * queue specified during odp_ipsec_config()
+ */
+ if (status.error.sa_lookup == 0)
+ queue = suite_context.queue;
+ else
+ queue = suite_context.default_queue;
+
+ return recv_event(queue, EVENT_WAIT_TIME);
+}
+
/* Receive inline processed packets */
static int recv_pkts_inline(const ipsec_test_part *part,
odp_packet_t *pkto)
{
- odp_packet_reass_partial_state_t reass_state;
- odp_packet_reass_status_t reass_status;
odp_queue_t queue = ODP_QUEUE_INVALID;
int i;
@@ -532,7 +592,7 @@ static int recv_pkts_inline(const ipsec_test_part *part,
odp_event_t ev;
odp_event_subtype_t subtype;
- ev = odp_queue_deq(queue);
+ ev = recv_event(queue, 0);
if (ODP_EVENT_INVALID != ev) {
CU_ASSERT(odp_event_is_valid(ev) == 1);
CU_ASSERT_EQUAL(ODP_EVENT_PACKET,
@@ -547,10 +607,15 @@ static int recv_pkts_inline(const ipsec_test_part *part,
continue;
}
- ev = odp_queue_deq(suite_context.queue);
+ ev = recv_event(suite_context.queue, 0);
if (ODP_EVENT_INVALID != ev) {
odp_packet_t pkt;
int num_pkts = 0;
+ odp_packet_reass_status_t reass_status;
+ odp_packet_reass_info_t reass = {0};
+ odp_packet_reass_partial_state_t reass_state;
+ odp_packet_t frags[MAX_FRAGS];
+ int j;
CU_ASSERT(odp_event_is_valid(ev) == 1);
CU_ASSERT_EQUAL(ODP_EVENT_PACKET, odp_event_type(ev));
@@ -559,13 +624,18 @@ static int recv_pkts_inline(const ipsec_test_part *part,
CU_ASSERT(!part->out[i].status.error.sa_lookup);
reass_status = odp_packet_reass_status(pkt);
- if (ODP_PACKET_REASS_INCOMPLETE != reass_status) {
+ CU_ASSERT(reass_status == part->out[i].reass_status);
+
+ switch (reass_status) {
+ case ODP_PACKET_REASS_COMPLETE:
+ CU_ASSERT(odp_packet_reass_info(pkt, &reass) == 0);
+ CU_ASSERT(part->out[i].num_frags == reass.num_frags);
+ /* FALLTHROUGH */
+ case ODP_PACKET_REASS_NONE:
pkto[i] = pkt;
num_pkts = 1;
- } else {
- odp_packet_t frags[MAX_FRAGS];
- int j;
-
+ break;
+ case ODP_PACKET_REASS_INCOMPLETE:
CU_ASSERT(0 ==
odp_packet_reass_partial_state(pkt, frags, &reass_state));
num_pkts = reass_state.num_frags;
@@ -573,6 +643,10 @@ static int recv_pkts_inline(const ipsec_test_part *part,
CU_ASSERT_FATAL(i + num_pkts <= part->num_pkt);
for (j = 0; j < num_pkts; j++)
pkto[i + j] = frags[j];
+ break;
+ default:
+ CU_FAIL("Unknown reassembly status");
+ break;
}
for (; num_pkts > 0; num_pkts--)
@@ -625,9 +699,7 @@ static int ipsec_process_in(const ipsec_test_part *part,
odp_event_t event;
odp_event_subtype_t subtype;
- do {
- event = odp_queue_deq(suite_context.queue);
- } while (event == ODP_EVENT_INVALID);
+ event = recv_pkt_async_inbound(part->out[i].status);
CU_ASSERT(odp_event_is_valid(event) == 1);
CU_ASSERT_EQUAL(ODP_EVENT_PACKET,
@@ -680,9 +752,7 @@ static int ipsec_send_out_one(const ipsec_test_part *part,
odp_event_t event;
odp_event_subtype_t subtype;
- do {
- event = odp_queue_deq(suite_context.queue);
- } while (event == ODP_EVENT_INVALID);
+ event = recv_event(suite_context.queue, EVENT_WAIT_TIME);
CU_ASSERT(odp_event_is_valid(event) == 1);
CU_ASSERT_EQUAL(ODP_EVENT_PACKET,
@@ -764,7 +834,7 @@ static int ipsec_send_out_one(const ipsec_test_part *part,
odp_event_t ev;
odp_event_subtype_t subtype;
- ev = odp_queue_deq(queue);
+ ev = recv_event(queue, 0);
if (ODP_EVENT_INVALID != ev) {
CU_ASSERT(odp_event_is_valid(ev) == 1);
CU_ASSERT_EQUAL(ODP_EVENT_PACKET,
@@ -779,7 +849,7 @@ static int ipsec_send_out_one(const ipsec_test_part *part,
continue;
}
- ev = odp_queue_deq(suite_context.queue);
+ ev = recv_event(suite_context.queue, 0);
if (ODP_EVENT_INVALID != ev) {
CU_ASSERT(odp_event_is_valid(ev) == 1);
CU_ASSERT_EQUAL(ODP_EVENT_PACKET,
@@ -878,6 +948,11 @@ static void verify_in(const ipsec_test_part *part,
if (ODP_IPSEC_SA_INVALID != sa)
CU_ASSERT_EQUAL(IPSEC_SA_CTX,
odp_ipsec_sa_context(sa));
+ if (suite_context.inbound_op_mode != ODP_IPSEC_OP_MODE_SYNC) {
+ uint32_t len = part->pkt_in->len - part->pkt_in->l3_offset;
+
+ CU_ASSERT(result.orig_ip_len == len);
+ }
}
ipsec_check_packet(part->out[i].pkt_res,
pkto[i],
@@ -1005,7 +1080,7 @@ void ipsec_check_out_one(const ipsec_test_part *part, odp_ipsec_sa_t sa)
odp_packet_free(pkto[i]);
}
-int ipsec_suite_init(void)
+static int ipsec_suite_init(void)
{
int rc = 0;
@@ -1033,11 +1108,16 @@ void ipsec_test_packet_from_pkt(ipsec_test_packet *test_pkt, odp_packet_t *pkt)
odp_packet_free(*pkt);
}
-static int ipsec_suite_term(void)
+int ipsec_suite_term(void)
{
if (suite_context.pktio != ODP_PKTIO_INVALID)
pktio_stop(suite_context.pktio);
+ if (ODP_QUEUE_INVALID != suite_context.queue) {
+ if (odp_queue_destroy(suite_context.queue))
+ fprintf(stderr, "IPsec destq destroy failed.\n");
+ }
+
if (odp_cunit_print_inactive())
return -1;
@@ -1054,19 +1134,80 @@ int ipsec_out_term(void)
return ipsec_suite_term();
}
+static odp_queue_t sched_queue_create(const char *name)
+{
+ odp_queue_param_t qparam;
+
+ odp_queue_param_init(&qparam);
+ qparam.type = ODP_QUEUE_TYPE_SCHED;
+ qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT;
+ qparam.sched.sync = ODP_SCHED_SYNC_PARALLEL;
+ qparam.sched.group = ODP_SCHED_GROUP_ALL;
+
+ return odp_queue_create(name, &qparam);
+}
+
+static odp_queue_t plain_queue_create(const char *name)
+{
+ return odp_queue_create(name, NULL);
+}
+
+int ipsec_suite_sync_init(void)
+{
+ suite_context.queue = ODP_QUEUE_INVALID;
+
+ /* q_type doesn't matter when queue handle is invalid. */
+ suite_context.q_type = ODP_QUEUE_TYPE_PLAIN;
+
+ return ipsec_suite_init();
+}
+
+int ipsec_suite_plain_init(void)
+{
+ odp_queue_t dest_queue;
+
+ dest_queue = plain_queue_create("ipsec-out");
+ if (ODP_QUEUE_INVALID == dest_queue) {
+ fprintf(stderr, "IPsec destq creation failed.\n");
+ return -1;
+ }
+
+ suite_context.queue = dest_queue;
+ suite_context.q_type = ODP_QUEUE_TYPE_PLAIN;
+
+ return ipsec_suite_init();
+}
+
+int ipsec_suite_sched_init(void)
+{
+ odp_queue_t dest_queue;
+
+ dest_queue = sched_queue_create("ipsec-out");
+ if (ODP_QUEUE_INVALID == dest_queue) {
+ fprintf(stderr, "IPsec destq creation failed.\n");
+ return -1;
+ }
+
+ suite_context.queue = dest_queue;
+ suite_context.q_type = ODP_QUEUE_TYPE_SCHED;
+
+ return ipsec_suite_init();
+}
+
int ipsec_init(odp_instance_t *inst, odp_ipsec_op_mode_t mode)
{
odp_pool_param_t params;
odp_pool_t pool;
- odp_queue_t out_queue;
odp_pool_capability_t pool_capa;
odp_pktio_t pktio;
odp_init_t init_param;
odph_helper_options_t helper_options;
+ suite_context.reass_ipv4 = false;
+ suite_context.reass_ipv6 = false;
suite_context.pool = ODP_POOL_INVALID;
- suite_context.queue = ODP_QUEUE_INVALID;
suite_context.pktio = ODP_PKTIO_INVALID;
+ suite_context.default_queue = ODP_QUEUE_INVALID;
if (odph_options(&helper_options)) {
fprintf(stderr, "error: odph_options() failed.\n");
@@ -1086,6 +1227,11 @@ int ipsec_init(odp_instance_t *inst, odp_ipsec_op_mode_t mode)
return -1;
}
+ if (odp_schedule_config(NULL)) {
+ fprintf(stderr, "odp_schedule_config() failed.\n");
+ return -1;
+ }
+
if (odp_pool_capability(&pool_capa) < 0) {
fprintf(stderr, "error: odp_pool_capability() failed.\n");
return -1;
@@ -1115,14 +1261,6 @@ int ipsec_init(odp_instance_t *inst, odp_ipsec_op_mode_t mode)
fprintf(stderr, "Packet pool creation failed.\n");
return -1;
}
- if (mode == ODP_IPSEC_OP_MODE_ASYNC ||
- mode == ODP_IPSEC_OP_MODE_INLINE) {
- out_queue = odp_queue_create("ipsec-out", NULL);
- if (ODP_QUEUE_INVALID == out_queue) {
- fprintf(stderr, "IPsec outq creation failed.\n");
- return -1;
- }
- }
if (mode == ODP_IPSEC_OP_MODE_INLINE) {
pktio = pktio_create(pool);
@@ -1159,6 +1297,19 @@ int ipsec_config(odp_instance_t ODP_UNUSED inst)
ODP_SUPPORT_NO == capa.op_mode_inline_out))
return 0;
+ if (suite_context.inbound_op_mode == ODP_IPSEC_OP_MODE_ASYNC ||
+ suite_context.inbound_op_mode == ODP_IPSEC_OP_MODE_INLINE) {
+ if (capa.queue_type_plain)
+ suite_context.default_queue = plain_queue_create("ipsec-default");
+ else if (capa.queue_type_sched)
+ suite_context.default_queue = sched_queue_create("ipsec-default");
+
+ if (ODP_QUEUE_INVALID == suite_context.default_queue) {
+ fprintf(stderr, "IPsec defaultq creation failed.\n");
+ return -1;
+ }
+ }
+
reass_test_vectors_init();
odp_ipsec_config_init(&ipsec_config);
@@ -1166,7 +1317,7 @@ int ipsec_config(odp_instance_t ODP_UNUSED inst)
ipsec_config.inbound_mode = suite_context.inbound_op_mode;
ipsec_config.outbound_mode = suite_context.outbound_op_mode;
ipsec_config.outbound.all_chksum = ~0;
- ipsec_config.inbound.default_queue = suite_context.queue;
+ ipsec_config.inbound.default_queue = suite_context.default_queue;
ipsec_config.inbound.parse_level = ODP_PROTO_LAYER_ALL;
ipsec_config.inbound.chksums.all_chksum = ~0;
ipsec_config.stats_en = true;
@@ -1242,7 +1393,7 @@ int ipsec_config(odp_instance_t ODP_UNUSED inst)
int ipsec_term(odp_instance_t inst)
{
odp_pool_t pool = suite_context.pool;
- odp_queue_t out_queue = suite_context.queue;
+ odp_queue_t default_queue = suite_context.default_queue;
/* suite_context.pktio is set to ODP_PKTIO_INVALID by ipsec_suite_init()
if inline processing is not supported. */
odp_pktio_t pktio = odp_pktio_lookup("loop");
@@ -1252,9 +1403,9 @@ int ipsec_term(odp_instance_t inst)
fprintf(stderr, "IPsec pktio close failed.\n");
}
- if (ODP_QUEUE_INVALID != out_queue) {
- if (odp_queue_destroy(out_queue))
- fprintf(stderr, "IPsec outq destroy failed.\n");
+ if (ODP_QUEUE_INVALID != default_queue) {
+ if (odp_queue_destroy(default_queue))
+ fprintf(stderr, "IPsec defaultq destroy failed.\n");
}
if (ODP_POOL_INVALID != pool) {