From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A17DEA0471 for ; Tue, 13 Aug 2019 17:13:50 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id B43EE1BEA2; Tue, 13 Aug 2019 17:13:19 +0200 (CEST) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by dpdk.org (Postfix) with ESMTP id A6A4D1BE8F for ; Tue, 13 Aug 2019 17:13:15 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Aug 2019 08:13:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,381,1559545200"; d="scan'208";a="200508206" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by fmsmga004.fm.intel.com with ESMTP; 13 Aug 2019 08:13:13 -0700 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, bernard.iremonger@intel.com Date: Tue, 13 Aug 2019 16:13:05 +0100 Message-Id: <1565709186-273340-5-git-send-email-vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1565709186-273340-1-git-send-email-vladimir.medvedkin@intel.com> References: <1565709186-273340-1-git-send-email-vladimir.medvedkin@intel.com> Subject: [dpdk-dev] [RFC 4/5] test/ipsec: add ipsec SAD autotests X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Signed-off-by: Vladimir Medvedkin --- app/test/Makefile | 1 + app/test/autotest_data.py | 6 + app/test/meson.build | 1 + app/test/test_ipsec_sad.c | 874 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 882 insertions(+) create mode 100644 app/test/test_ipsec_sad.c diff --git a/app/test/Makefile b/app/test/Makefile index 26ba6fe..e4da070 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -223,6 +223,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BPF) += test_bpf.c SRCS-$(CONFIG_RTE_LIBRTE_RCU) += test_rcu_qsbr.c test_rcu_qsbr_perf.c SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c +SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec_sad.c ifeq ($(CONFIG_RTE_LIBRTE_IPSEC),y) LDLIBS += -lrte_ipsec endif diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py index 7405149..a4f2882 100644 --- a/app/test/autotest_data.py +++ b/app/test/autotest_data.py @@ -518,6 +518,12 @@ "Func": default_autotest, "Report": None, }, + { + "Name": "IPsec_SAD", + "Command": "ipsec_sad_autotest", + "Func": default_autotest, + "Report": None, + }, # #Please always keep all dump tests at the end and together! # diff --git a/app/test/meson.build b/app/test/meson.build index ec40943..b13ec74 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -57,6 +57,7 @@ test_sources = files('commands.c', 'test_hash_readwrite_lf.c', 'test_interrupts.c', 'test_ipsec.c', + 'test_ipsec_sad.c', 'test_kni.c', 'test_kvargs.c', 'test_latencystats.c', diff --git a/app/test/test_ipsec_sad.c b/app/test/test_ipsec_sad.c new file mode 100644 index 0000000..79d6673 --- /dev/null +++ b/app/test/test_ipsec_sad.c @@ -0,0 +1,874 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include +#include + +#include +#include + +#include "test.h" +#include "test_xmmt_ops.h" + +typedef int32_t (*rte_ipsec_sad_test)(void); + +static int32_t test_create_invalid(void); +static int32_t test_multiple_create(void); +static int32_t test_add_invalid(void); +static int32_t test_delete_invalid(void); +static int32_t test_lookup_invalid(void); +static int32_t test_lookup_basic(void); +static int32_t test_lookup_adv(void); +static int32_t test_lookup_order(void); + +#define MAX_SA 100000 +#define PASS 0 +#define SPI 0xdead /* spi to install */ +#define DIP 0xbeef /* dip to install */ +#define SIP 0xf00d /* sip to install */ +#define BAD 0xbad /* some random value not installed into the table */ + +/* + * Check that rte_ipsec_sad_create fails gracefully for incorrect user input + * arguments + */ +int32_t +test_create_invalid(void) +{ + struct rte_ipsec_sad *sad = NULL; + struct rte_ipsec_sad_conf config; + + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA; + config.socket_id = SOCKET_ID_ANY; + config.flags = RTE_IPSEC_SAD_FLAG_IPV4; + + /* name == NULL */ + sad = rte_ipsec_sad_create(NULL, &config); + RTE_TEST_ASSERT(sad == NULL, + "Call succeeded with invalid parameters\n"); + + /* max_sa[SPI_ONLY] = 0 */ + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = 0; + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT(sad == NULL, + "Call succeeded with invalid parameters\n"); + + /* max_sa[SPI_DIP] = 0 */ + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = 0; + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT(sad == NULL, + "Call succeeded with invalid parameters\n"); + + /* max_sa[SPI_DIP_SIP] = 0 */ + config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = 0; + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT(sad == NULL, + "Call succeeded with invalid parameters\n"); + config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA; + + /* socket_id < -1 is invalid */ + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA; + config.socket_id = -2; + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT(sad == NULL, + "Call succeeded with invalid parameters\n"); + config.socket_id = SOCKET_ID_ANY; + + /* invalid flags */ + config.flags = 0; + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT(sad == NULL, + "Call succeeded with invalid parameters\n"); + config.flags = RTE_IPSEC_SAD_FLAG_IPV4|RTE_IPSEC_SAD_FLAG_IPV6; + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT(sad == NULL, + "Call succeeded with invalid parameters\n"); + + return TEST_SUCCESS; +} + +/* + * Create ipsec sad then delete it 10 times + * Use a slightly different max_sa each time + */ +int32_t +test_multiple_create(void) +{ + int i; + struct rte_ipsec_sad *sad = NULL; + struct rte_ipsec_sad_conf config; + + config.socket_id = SOCKET_ID_ANY; + config.flags = RTE_IPSEC_SAD_FLAG_IPV4; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA; + + for (i = 0; i < 10; i++) { + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA - i; + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n"); + rte_ipsec_sad_free(sad); + } + return TEST_SUCCESS; +} + +static int32_t +__test_add_invalid(int ipv4, union rte_ipsec_sad_key *tuple) +{ + int status; + struct rte_ipsec_sad *sad = NULL; + struct rte_ipsec_sad_conf config; + uint64_t tmp; + void *sa = &tmp; + + /* sad == NULL*/ + status = rte_ipsec_sad_add(NULL, tuple, + RTE_IPSEC_SAD_SPI_DIP_SIP, sa); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA; + config.socket_id = SOCKET_ID_ANY; + if (ipv4) + config.flags = RTE_IPSEC_SAD_FLAG_IPV4; + else + config.flags = RTE_IPSEC_SAD_FLAG_IPV6; + + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n"); + + /* key == NULL*/ + status = rte_ipsec_sad_add(sad, NULL, RTE_IPSEC_SAD_SPI_DIP_SIP, sa); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + /* len is incorrect*/ + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP_SIP + 1, sa); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + /* sa == NULL*/ + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP_SIP, NULL); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + /* sa is not aligned*/ + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP_SIP, (void *)((uint8_t *)sa + 1)); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + rte_ipsec_sad_free(sad); + + return TEST_SUCCESS; +} + +/* + * Check that rte_ipsec_sad_add fails gracefully + * for incorrect user input arguments + */ +int32_t +test_add_invalid(void) +{ + int status; + struct rte_ipsec_sadv4_key tuple_v4 = {10, 20, 30}; + struct rte_ipsec_sadv6_key tuple_v6 = {10, {20, }, {30, } }; + + status = __test_add_invalid(1, (union rte_ipsec_sad_key *)&tuple_v4); + if (status != TEST_SUCCESS) + return status; + + status = __test_add_invalid(0, (union rte_ipsec_sad_key *)&tuple_v6); + + return status; + +} + +static int32_t +__test_delete_invalid(int ipv4, union rte_ipsec_sad_key *tuple) +{ + int status; + struct rte_ipsec_sad *sad = NULL; + struct rte_ipsec_sad_conf config; + + /* sad == NULL*/ + status = rte_ipsec_sad_del(NULL, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA; + config.socket_id = SOCKET_ID_ANY; + if (ipv4) + config.flags = RTE_IPSEC_SAD_FLAG_IPV4; + else + config.flags = RTE_IPSEC_SAD_FLAG_IPV6; + + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n"); + + /* key == NULL*/ + status = rte_ipsec_sad_del(sad, NULL, RTE_IPSEC_SAD_SPI_DIP_SIP); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + /* len is incorrect */ + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP + 1); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + rte_ipsec_sad_free(sad); + + return TEST_SUCCESS; +} + +/* + * Check that rte_ipsec_sad_delete fails gracefully for incorrect user input + * arguments + */ +int32_t +test_delete_invalid(void) +{ + int status; + struct rte_ipsec_sadv4_key tuple_v4 = {SPI, DIP, SIP}; + struct rte_ipsec_sadv6_key tuple_v6 = {SPI, {0xbe, 0xef, }, + {0xf0, 0x0d, } }; + + status = __test_delete_invalid(1, (union rte_ipsec_sad_key *)&tuple_v4); + if (status != TEST_SUCCESS) + return status; + + status = __test_delete_invalid(0, (union rte_ipsec_sad_key *)&tuple_v6); + + return status; +} + +static int32_t +__test_lookup_invalid(int ipv4, union rte_ipsec_sad_key *tuple) +{ + int status; + struct rte_ipsec_sad *sad = NULL; + struct rte_ipsec_sad_conf config; + const union rte_ipsec_sad_key *key_arr[] = {tuple}; + void *sa[1]; + + status = rte_ipsec_sad_lookup(NULL, key_arr, 1, sa); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA; + config.socket_id = SOCKET_ID_ANY; + if (ipv4) + config.flags = RTE_IPSEC_SAD_FLAG_IPV4; + else + config.flags = RTE_IPSEC_SAD_FLAG_IPV6; + + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n"); + + status = rte_ipsec_sad_lookup(sad, NULL, 1, sa); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 1, NULL); + RTE_TEST_ASSERT(status < 0, + "Call succeeded with invalid parameters\n"); + + rte_ipsec_sad_free(sad); + + return TEST_SUCCESS; +} + +/* + * Check that rte_ipsec_sad_lookup fails gracefully for incorrect user input + * arguments + */ +int32_t +test_lookup_invalid(void) +{ + int status; + struct rte_ipsec_sadv4_key tuple_v4 = {10, 20, 30}; + struct rte_ipsec_sadv6_key tuple_v6 = {10, {20, }, {30, } }; + + status = __test_lookup_invalid(1, + (union rte_ipsec_sad_key *)&tuple_v4); + if (status != TEST_SUCCESS) + return status; + + status = __test_lookup_invalid(0, + (union rte_ipsec_sad_key *)&tuple_v6); + + return status; +} + +static int32_t +__test_lookup_basic(int ipv4, union rte_ipsec_sad_key *tuple, + union rte_ipsec_sad_key *tuple_1) +{ + int status; + struct rte_ipsec_sad *sad = NULL; + struct rte_ipsec_sad_conf config; + const union rte_ipsec_sad_key *key_arr[] = {tuple}; + + uint64_t tmp; + void *sa[1]; + + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA; + config.socket_id = SOCKET_ID_ANY; + if (ipv4) + config.flags = RTE_IPSEC_SAD_FLAG_IPV4; + else + config.flags = RTE_IPSEC_SAD_FLAG_IPV6; + + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 1, sa); + RTE_TEST_ASSERT((status == 0) && (sa[0] == NULL), + "Lookup returns an unexpected result\n"); + + sa[0] = &tmp; + status = rte_ipsec_sad_add(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY, sa[0]); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 1, sa); + RTE_TEST_ASSERT((status == 1) && (sa[0] == &tmp), + "Lookup returns an unexpected result\n"); + + key_arr[0] = tuple_1; + status = rte_ipsec_sad_lookup(sad, key_arr, 1, sa); + RTE_TEST_ASSERT((status == 1) && (sa[0] == &tmp), + "Lookup returns an unexpected result\n"); + key_arr[0] = tuple; + + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 1, sa); + RTE_TEST_ASSERT((status == 0) && (sa[0] == NULL), + "Lookup returns an unexpected result\n"); + + rte_ipsec_sad_free(sad); + + return TEST_SUCCESS; +} + +/* + * Lookup missing key, then add it as RTE_IPSEC_SAD_SPI_ONLY, lookup it again, + * lookup different key with the same SPI, then delete it and repeat lookup + */ +int32_t +test_lookup_basic(void) +{ + int status; + struct rte_ipsec_sadv4_key tuple_v4 = {SPI, DIP, SIP}; + struct rte_ipsec_sadv4_key tuple_v4_1 = {SPI, BAD, BAD}; + struct rte_ipsec_sadv6_key tuple_v6 = {SPI, {0xbe, 0xef, }, + {0xf0, 0x0d, } }; + struct rte_ipsec_sadv6_key tuple_v6_1 = {SPI, {0x0b, 0xad, }, + {0x0b, 0xad, } }; + + status = __test_lookup_basic(1, (union rte_ipsec_sad_key *)&tuple_v4, + (union rte_ipsec_sad_key *)&tuple_v4_1); + if (status != TEST_SUCCESS) + return status; + + status = __test_lookup_basic(0, (union rte_ipsec_sad_key *)&tuple_v6, + (union rte_ipsec_sad_key *)&tuple_v6_1); + + return status; +} + +static int32_t +__test_lookup_adv(int ipv4, union rte_ipsec_sad_key *tuple, + const union rte_ipsec_sad_key **key_arr) +{ + int status; + struct rte_ipsec_sad *sad = NULL; + struct rte_ipsec_sad_conf config; + uint64_t tmp1, tmp2, tmp3; + void *install_sa; + void *sa[4]; + + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA; + config.socket_id = SOCKET_ID_ANY; + if (ipv4) + config.flags = RTE_IPSEC_SAD_FLAG_IPV4; + else + config.flags = RTE_IPSEC_SAD_FLAG_IPV6; + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n"); + + /* lookup with empty table */ + status = rte_ipsec_sad_lookup(sad, key_arr, 4, sa); + RTE_TEST_ASSERT(status == 0, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[3] == NULL, + "Lookup returns an unexpected result\n"); + + /* lookup with one RTE_IPSEC_SAD_SPI_ONLY rule */ + install_sa = &tmp1; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_ONLY, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 4, sa); + RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp1, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp1, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == &tmp1, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[3] == NULL, + "Lookup returns an unexpected result\n"); + + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY); + RTE_TEST_ASSERT(status == 0, "Failde to delete a rule\n"); + + /* lookup with one RTE_IPSEC_SAD_SPI_DIP rule */ + install_sa = &tmp2; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP, install_sa); + RTE_TEST_ASSERT(status == 0, "failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 4, sa); + RTE_TEST_ASSERT(status == 2, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[3] == NULL, + "Lookup returns an unexpected result\n"); + + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + + /* lookup with one RTE_IPSEC_SAD_SPI_DIP_SIP rule */ + install_sa = &tmp3; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 4, sa); + RTE_TEST_ASSERT(status == 1, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp3, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[3] == NULL, + "Lookup returns an unexpected result\n"); + + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + + /* lookup with two RTE_IPSEC_SAD_ONLY and RTE_IPSEC_SAD_DIP rules */ + install_sa = &tmp1; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_ONLY, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + install_sa = &tmp2; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 4, sa); + RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == &tmp1, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[3] == NULL, + "Lookup returns an unexpected result\n"); + + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + + /* lookup with two RTE_IPSEC_SAD_ONLY and RTE_IPSEC_SAD_DIP_SIP rules */ + install_sa = &tmp1; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_ONLY, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + install_sa = &tmp3; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 4, sa); + RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp3, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp1, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == &tmp1, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[3] == NULL, + "Lookup returns an unexpected result\n"); + + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + + /* lookup with two RTE_IPSEC_SAD_DIP and RTE_IPSEC_SAD_DIP_SIP rules */ + install_sa = &tmp2; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + install_sa = &tmp3; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 4, sa); + RTE_TEST_ASSERT(status == 2, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp3, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[3] == NULL, + "Lookup returns an unexpected result\n"); + + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + + /* + * lookup with three RTE_IPSEC_SAD_DIP, RTE_IPSEC_SAD_DIP and + * RTE_IPSEC_SAD_DIP_SIP rules + */ + install_sa = &tmp1; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_ONLY, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + install_sa = &tmp2; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + install_sa = &tmp3; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 4, sa); + RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp3, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == &tmp1, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[3] == NULL, + "Lookup returns an unexpected result\n"); + + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + + rte_ipsec_sad_free(sad); + + return TEST_SUCCESS; +} + +/* + * Lookup different keys in a table with: + * - RTE_IPSEC_SAD_SPI_ONLY + * - RTE_IPSEC_SAD_SPI_DIP + * - RTE_IPSEC_SAD_SPI_SIP + * - RTE_IPSEC_SAD_SPI_ONLY/RTE_IPSEC_SAD_SPI_DIP + * - RTE_IPSEC_SAD_SPI_ONLY/RTE_IPSEC_SAD_SPI_DIP_SIP + * - RTE_IPSEC_SAD_SPI_DIP/RTE_IPSEC_SAD_SPI_DIP_SIP + * - RTE_IPSEC_SAD_SPI_ONLY/RTE_IPSEC_SAD_SPI_DIP/RTE_IPSEC_SAD_SPI_DIP_SIP + * length of rule installed. + */ +int32_t +test_lookup_adv(void) +{ + int status; + /* key to install*/ + struct rte_ipsec_sadv4_key tuple_v4 = {SPI, DIP, SIP}; + struct rte_ipsec_sadv4_key tuple_v4_1 = {SPI, DIP, BAD}; + struct rte_ipsec_sadv4_key tuple_v4_2 = {SPI, BAD, SIP}; + struct rte_ipsec_sadv4_key tuple_v4_3 = {BAD, DIP, SIP}; + + /* key to install*/ + struct rte_ipsec_sadv6_key tuple_v6 = {SPI, {0xbe, 0xef, }, + {0xf0, 0x0d, } }; + struct rte_ipsec_sadv6_key tuple_v6_1 = {SPI, {0xbe, 0xef, }, + {0x0b, 0xad, } }; + struct rte_ipsec_sadv6_key tuple_v6_2 = {SPI, {0x0b, 0xad, }, + {0xf0, 0x0d, } }; + struct rte_ipsec_sadv6_key tuple_v6_3 = {BAD, {0xbe, 0xef, }, + {0xf0, 0x0d, } }; + + const union rte_ipsec_sad_key *key_arr[] = { + (union rte_ipsec_sad_key *)&tuple_v4, + (union rte_ipsec_sad_key *)&tuple_v4_1, + (union rte_ipsec_sad_key *)&tuple_v4_2, + (union rte_ipsec_sad_key *)&tuple_v4_3 + }; + + status = __test_lookup_adv(1, (union rte_ipsec_sad_key *)&tuple_v4, + key_arr); + if (status != TEST_SUCCESS) + return status; + + key_arr[0] = (union rte_ipsec_sad_key *)&tuple_v6; + key_arr[1] = (union rte_ipsec_sad_key *)&tuple_v6_1; + key_arr[2] = (union rte_ipsec_sad_key *)&tuple_v6_2; + key_arr[3] = (union rte_ipsec_sad_key *)&tuple_v6_3; + status = __test_lookup_adv(0, (union rte_ipsec_sad_key *)&tuple_v6, + key_arr); + + return status; +} + + +static int32_t +__test_lookup_order(int ipv4, union rte_ipsec_sad_key *tuple, + union rte_ipsec_sad_key *tuple_1, union rte_ipsec_sad_key *tuple_2) +{ + int status; + struct rte_ipsec_sad *sad = NULL; + struct rte_ipsec_sad_conf config; + const union rte_ipsec_sad_key *key_arr[] = {tuple, tuple_1, tuple_2,}; + uint64_t tmp1, tmp2, tmp3; + void *install_sa; + void *sa[3]; + + config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA; + config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA; + config.socket_id = SOCKET_ID_ANY; + if (ipv4) + config.flags = RTE_IPSEC_SAD_FLAG_IPV4; + else + config.flags = RTE_IPSEC_SAD_FLAG_IPV6; + sad = rte_ipsec_sad_create(__func__, &config); + RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n"); + + /* install RTE_IPSEC_SAD_SPI_ONLY */ + install_sa = &tmp1; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_ONLY, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 3, sa); + RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp1, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp1, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == &tmp1, + "Lookup returns an unexpected result\n"); + + /* add RTE_IPSEC_SAD_SPI_DIP */ + install_sa = &tmp2; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 3, sa); + RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == &tmp1, + "Lookup returns an unexpected result\n"); + + /* add RTE_IPSEC_SAD_SPI_DIP_SIP */ + install_sa = &tmp3; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 3, sa); + RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp3, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == &tmp1, + "Lookup returns an unexpected result\n"); + + /* delete RTE_IPSEC_SAD_SPI_ONLY */ + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 3, sa); + RTE_TEST_ASSERT(status == 2, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp3, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == NULL, + "Lookup returns an unexpected result\n"); + + /* delete RTE_IPSEC_SAD_SPI_DIP */ + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 3, sa); + RTE_TEST_ASSERT(status == 1, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp3, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == NULL, + "Lookup returns an unexpected result\n"); + + /* delete RTE_IPSEC_SAD_SPI_DIP_SIP */ + status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP); + RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 3, sa); + RTE_TEST_ASSERT(status == 0, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == NULL, + "Lookup returns an unexpected result\n"); + + /* add RTE_IPSEC_SAD_SPI_DIP_SIP */ + install_sa = &tmp3; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 3, sa); + RTE_TEST_ASSERT(status == 1, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp3, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == NULL, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == NULL, + "Lookup returns an unexpected result\n"); + + /* add RTE_IPSEC_SAD_SPI_DIP */ + install_sa = &tmp2; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_DIP, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 3, sa); + RTE_TEST_ASSERT(status == 2, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp3, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == NULL, + "Lookup returns an unexpected result\n"); + + /* add RTE_IPSEC_SAD_SPI_ONLY */ + install_sa = &tmp1; + status = rte_ipsec_sad_add(sad, tuple, + RTE_IPSEC_SAD_SPI_ONLY, install_sa); + RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n"); + + status = rte_ipsec_sad_lookup(sad, key_arr, 3, sa); + RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[0] == &tmp3, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[1] == &tmp2, + "Lookup returns an unexpected result\n"); + RTE_TEST_ASSERT(sa[2] == &tmp1, + "Lookup returns an unexpected result\n"); + + rte_ipsec_sad_free(sad); + return TEST_SUCCESS; +} + +/* + * Check an order of add and delete + */ +int32_t +test_lookup_order(void) +{ + int status; + /* key to install*/ + struct rte_ipsec_sadv4_key tuple_v4 = {SPI, DIP, SIP}; + struct rte_ipsec_sadv4_key tuple_v4_1 = {SPI, DIP, BAD}; + struct rte_ipsec_sadv4_key tuple_v4_2 = {SPI, BAD, SIP}; + /* key to install*/ + struct rte_ipsec_sadv6_key tuple_v6 = {SPI, {0xbe, 0xef, }, + {0xf0, 0x0d, } }; + struct rte_ipsec_sadv6_key tuple_v6_1 = {SPI, {0xbe, 0xef, }, + {0x0b, 0xad, } }; + struct rte_ipsec_sadv6_key tuple_v6_2 = {SPI, {0x0b, 0xad, }, + {0xf0, 0x0d, } }; + + status = __test_lookup_order(1, (union rte_ipsec_sad_key *)&tuple_v4, + (union rte_ipsec_sad_key *)&tuple_v4_1, + (union rte_ipsec_sad_key *)&tuple_v4_2); + if (status != TEST_SUCCESS) + return status; + + status = __test_lookup_order(0, (union rte_ipsec_sad_key *)&tuple_v6, + (union rte_ipsec_sad_key *)&tuple_v6_1, + (union rte_ipsec_sad_key *)&tuple_v6_2); + return status; +} + +static struct unit_test_suite ipsec_sad_tests = { + .suite_name = "ipsec sad autotest", + .setup = NULL, + .teardown = NULL, + .unit_test_cases = { + TEST_CASE(test_create_invalid), + TEST_CASE(test_multiple_create), + TEST_CASE(test_add_invalid), + TEST_CASE(test_delete_invalid), + TEST_CASE(test_lookup_invalid), + TEST_CASE(test_lookup_basic), + TEST_CASE(test_lookup_adv), + TEST_CASE(test_lookup_order), + TEST_CASES_END() + } +}; + +static int +test_ipsec_sad(void) +{ + return unit_test_suite_runner(&ipsec_sad_tests); +} + +REGISTER_TEST_COMMAND(ipsec_sad_autotest, test_ipsec_sad); -- 2.7.4