From patchwork Mon Sep 25 22:00:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 114189 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp3107156qgf; Mon, 25 Sep 2017 15:05:49 -0700 (PDT) X-Google-Smtp-Source: AOwi7QBSG6+Dm02Q+HKCZQWSgxKzTZdnl0xTnzvKufUOiCwcC6j8c2lRudDvEiRcXYK4VJljfci2 X-Received: by 10.36.13.82 with SMTP id 79mr2910635itx.129.1506377148944; Mon, 25 Sep 2017 15:05:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506377148; cv=none; d=google.com; s=arc-20160816; b=J9DsJPN9eujDKh/1u6/3sBEuh6Kt9Sc5sb981Rt/bMR3xQr6fhPdpwskSqtTKfpANX 9WF8+OV14WHuvDqH+NbLUGGhjfXSDVvd2owry0/znGrhORRrxUaOzXffznCZVAZtmoME j5KlgPHvFBwcMUpYTDso5RxDh34r4/1f1XquVYc9tZKXfLz6fCfiil6w7mfX+9UHqasW wXB+GxEDgqtiFugmcwoGREZC0dOLJrldbp6SqjBHgIUINEkfAlJboGyFK2rhCTQm/REa ZyY5hudCaGdXtkVkROWgaLliNffq6sGdEQlqzNZoQMDQfW3zZd/9vLCPwBUfK7FqPSVf MgTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=6ZnbFudft4dLHAwOCfzFFB1Nzpdtg2ax3w/sbuPbyvs=; b=XOKmGjDUPBwFwWUJhsRwzeAG2F4kdHw9dw2Wb+lZQQ+M5gXri1goZm6j8yUd3t513Z d5GDLvBf4O5Sz7VNyhMJwEcAmbAwa3627umiv8ML1DkwYJ9/sAz3kL24MsScH3hSLG4m zarTRQ2wkPsucGN7b5WBALDyrneoOYGM/GoEZgCNTfJ45leol2971SyRjYXyOp8IpZ5c 6hH3rUl3eSQKCNycD54CqRCXhwpa0Hnk5BwM1N7jl1lv3c6K73GmB7ZZmdQAY2ypmdWt FCsglimwgdG37HWvOIyRHzlxwYbPf17tsT96dYzc1XhrBBKS1xW14if3vSqn58SNxbOp 4LDA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id 15si5742701iob.321.2017.09.25.15.05.48; Mon, 25 Sep 2017 15:05:48 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id 65DC460B45; Mon, 25 Sep 2017 22:05:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 7257360B3F; Mon, 25 Sep 2017 22:02:39 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id CECF560C71; Mon, 25 Sep 2017 22:02:08 +0000 (UTC) Received: from forward104o.mail.yandex.net (forward104o.mail.yandex.net [37.140.190.179]) by lists.linaro.org (Postfix) with ESMTPS id 2B02F60AEF for ; Mon, 25 Sep 2017 22:00:39 +0000 (UTC) Received: from mxback3o.mail.yandex.net (mxback3o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::1d]) by forward104o.mail.yandex.net (Yandex) with ESMTP id C7C83701A80 for ; Tue, 26 Sep 2017 01:00:37 +0300 (MSK) Received: from smtp2o.mail.yandex.net (smtp2o.mail.yandex.net [2a02:6b8:0:1a2d::26]) by mxback3o.mail.yandex.net (nwsmtp/Yandex) with ESMTP id bfUyBGfLql-0bde6Ej1; Tue, 26 Sep 2017 01:00:37 +0300 Received: by smtp2o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id y0gxWEywlF-0a4auvLm; Tue, 26 Sep 2017 01:00:36 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 26 Sep 2017 01:00:19 +0300 Message-Id: <1506376827-27848-2-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> References: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 81 Subject: [lng-odp] [PATCH API-NEXT v19 1/9] test: validation: add IPsec API testsuite X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Dmitry Eremin-Solenikov Add several basic tests for IPsec API. Signed-off-by: Dmitry Eremin-Solenikov --- /** Email created from pull request 81 (lumag:ipsec-packet-impl-2) ** https://github.com/Linaro/odp/pull/81 ** Patch: https://github.com/Linaro/odp/pull/81.patch ** Base sha: 13322ca632f8ffba292bec058e597719bc54142d ** Merge commit sha: 04f37d8f29d26df3744151a85a19ef9b55b3d1f7 **/ test/common_plat/validation/api/ipsec/Makefile.am | 27 +- test/common_plat/validation/api/ipsec/ipsec.c | 879 ++++++++++++++++++- test/common_plat/validation/api/ipsec/ipsec.h | 81 +- .../common_plat/validation/api/ipsec/ipsec_async.c | 55 ++ .../validation/api/ipsec/ipsec_inline_in.c | 56 ++ .../validation/api/ipsec/ipsec_inline_out.c | 56 ++ test/common_plat/validation/api/ipsec/ipsec_main.c | 12 - test/common_plat/validation/api/ipsec/ipsec_sync.c | 53 ++ .../validation/api/ipsec/ipsec_sync_in.c | 27 + .../validation/api/ipsec/ipsec_test_in.c | 815 +++++++++++++++++ .../validation/api/ipsec/ipsec_test_out.c | 348 ++++++++ .../validation/api/ipsec/test_vectors.h | 965 +++++++++++++++++++++ test/linux-generic/Makefile.am | 5 +- 13 files changed, 3335 insertions(+), 44 deletions(-) create mode 100644 test/common_plat/validation/api/ipsec/ipsec_async.c create mode 100644 test/common_plat/validation/api/ipsec/ipsec_inline_in.c create mode 100644 test/common_plat/validation/api/ipsec/ipsec_inline_out.c delete mode 100644 test/common_plat/validation/api/ipsec/ipsec_main.c create mode 100644 test/common_plat/validation/api/ipsec/ipsec_sync.c create mode 100644 test/common_plat/validation/api/ipsec/ipsec_sync_in.c create mode 100644 test/common_plat/validation/api/ipsec/ipsec_test_in.c create mode 100644 test/common_plat/validation/api/ipsec/ipsec_test_out.c create mode 100644 test/common_plat/validation/api/ipsec/test_vectors.h diff --git a/test/common_plat/validation/api/ipsec/Makefile.am b/test/common_plat/validation/api/ipsec/Makefile.am index 106b8dcea..5a4652f5f 100644 --- a/test/common_plat/validation/api/ipsec/Makefile.am +++ b/test/common_plat/validation/api/ipsec/Makefile.am @@ -1,10 +1,27 @@ include ../Makefile.inc +AM_CPPFLAGS += -Wno-error=missing-field-initializers + noinst_LTLIBRARIES = libtestipsec.la -libtestipsec_la_SOURCES = ipsec.c +libtestipsec_la_SOURCES = \ + test_vectors.h \ + ipsec_test_in.c \ + ipsec_test_out.c \ + ipsec.h \ + ipsec.c + +test_PROGRAMS = \ + ipsec_sync$(EXEEXT) \ + ipsec_async$(EXEEXT) \ + ipsec_inline_in$(EXEEXT) \ + ipsec_inline_out$(EXEEXT) -test_PROGRAMS = ipsec_main$(EXEEXT) -dist_ipsec_main_SOURCES = ipsec_main.c -ipsec_main_LDADD = libtestipsec.la $(LIBCUNIT_COMMON) $(LIBODP) +ipsec_sync_SOURCES = ipsec_sync.c +ipsec_async_SOURCES = ipsec_async.c +ipsec_inline_in_SOURCES = ipsec_inline_in.c +ipsec_inline_out_SOURCES = ipsec_inline_out.c -EXTRA_DIST = ipsec.h +ipsec_sync_LDADD = libtestipsec.la $(LIBCUNIT_COMMON) $(LIBODP) +ipsec_async_LDADD = libtestipsec.la $(LIBCUNIT_COMMON) $(LIBODP) +ipsec_inline_in_LDADD = libtestipsec.la $(LIBCUNIT_COMMON) $(LIBODP) +ipsec_inline_out_LDADD = libtestipsec.la $(LIBCUNIT_COMMON) $(LIBODP) diff --git a/test/common_plat/validation/api/ipsec/ipsec.c b/test/common_plat/validation/api/ipsec/ipsec.c index 783480325..a8fdf2b14 100644 --- a/test/common_plat/validation/api/ipsec/ipsec.c +++ b/test/common_plat/validation/api/ipsec/ipsec.c @@ -4,41 +4,884 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "config.h" + #include #include #include #include "ipsec.h" -void ipsec_test_capability(void) +#include "test_vectors.h" + +struct suite_context_s suite_context; + +#define PKT_POOL_NUM 64 +#define PKT_POOL_LEN (1 * 1024) + +static odp_pktio_t pktio_create(odp_pool_t pool) +{ + odp_pktio_t pktio; + odp_pktio_param_t pktio_param; + odp_pktin_queue_param_t pktin_param; + odp_pktio_capability_t capa; + + int ret; + + if (pool == ODP_POOL_INVALID) + return ODP_PKTIO_INVALID; + + odp_pktio_param_init(&pktio_param); + pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE; + + pktio = odp_pktio_open("loop", pool, &pktio_param); + if (pktio == ODP_PKTIO_INVALID) { + ret = odp_pool_destroy(pool); + if (ret) + fprintf(stderr, "unable to destroy pool.\n"); + return ODP_PKTIO_INVALID; + } + + if (odp_pktio_capability(pktio, &capa)) { + fprintf(stderr, "pktio capabilities failed.\n"); + return ODP_PKTIO_INVALID; + } + + odp_pktin_queue_param_init(&pktin_param); + pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; + + if (odp_pktin_queue_config(pktio, &pktin_param)) { + fprintf(stderr, "pktin queue config failed.\n"); + return ODP_PKTIO_INVALID; + } + + if (odp_pktout_queue_config(pktio, NULL)) { + fprintf(stderr, "pktout queue config failed.\n"); + return ODP_PKTIO_INVALID; + } + + return pktio; +} + +static int pktio_start(odp_pktio_t pktio, odp_bool_t in, odp_bool_t out) +{ + odp_pktio_capability_t capa; + odp_pktio_config_t config; + + if (ODP_PKTIO_INVALID == pktio) + return -1; + + if (odp_pktio_capability(pktio, &capa)) + return -1; + /* If inline is not supported, return here. Tests will be marked as + * inactive when testing for IPsec capabilities. */ + if (in && !capa.config.inbound_ipsec) + return 0; + if (out && !capa.config.outbound_ipsec) + return 0; + + odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; + config.inbound_ipsec = in; + config.outbound_ipsec = out; + + if (odp_pktio_config(pktio, &config)) + return -1; + if (odp_pktio_start(pktio)) + return -1; + + suite_context.pktio = pktio; + + return 1; +} + +static void pktio_stop(odp_pktio_t pktio) +{ + odp_queue_t queue = ODP_QUEUE_INVALID; + + odp_pktin_event_queue(pktio, &queue, 1); + + if (odp_pktio_stop(pktio)) + fprintf(stderr, "IPsec pktio stop failed.\n"); + + while (1) { + odp_event_t ev = odp_queue_deq(queue); + + if (ev != ODP_EVENT_INVALID) + odp_event_free(ev); + else + break; + } +} + +#define MAX_ALG_CAPA 32 + +int ipsec_check(odp_bool_t ah, + odp_cipher_alg_t cipher, + uint32_t cipher_bits, + odp_auth_alg_t auth) { odp_ipsec_capability_t capa; + odp_crypto_cipher_capability_t cipher_capa[MAX_ALG_CAPA]; + odp_crypto_auth_capability_t auth_capa[MAX_ALG_CAPA]; + int i, num; + odp_bool_t found = false; + + if (odp_ipsec_capability(&capa) < 0) + return ODP_TEST_INACTIVE; + + if ((ODP_IPSEC_OP_MODE_SYNC == suite_context.inbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_sync) || + (ODP_IPSEC_OP_MODE_ASYNC == suite_context.outbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_sync) || + (ODP_IPSEC_OP_MODE_ASYNC == suite_context.inbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_async) || + (ODP_IPSEC_OP_MODE_ASYNC == suite_context.outbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_async) || + (ODP_IPSEC_OP_MODE_INLINE == suite_context.inbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_inline_in) || + (ODP_IPSEC_OP_MODE_INLINE == suite_context.outbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_inline_out)) + return ODP_TEST_INACTIVE; - CU_ASSERT(odp_ipsec_capability(&capa) == 0); + if (ah && (ODP_SUPPORT_NO == capa.proto_ah)) + return ODP_TEST_INACTIVE; + + /* Cipher algorithms */ + switch (cipher) { + case ODP_CIPHER_ALG_NULL: + if (!capa.ciphers.bit.null) + return ODP_TEST_INACTIVE; + break; + case ODP_CIPHER_ALG_DES: + if (!capa.ciphers.bit.des) + return ODP_TEST_INACTIVE; + break; + case ODP_CIPHER_ALG_3DES_CBC: + if (!capa.ciphers.bit.trides_cbc) + return ODP_TEST_INACTIVE; + break; + case ODP_CIPHER_ALG_AES_CBC: + if (!capa.ciphers.bit.aes_cbc) + return ODP_TEST_INACTIVE; + break; + case ODP_CIPHER_ALG_AES_GCM: + if (!capa.ciphers.bit.aes_gcm) + return ODP_TEST_INACTIVE; + break; + default: + fprintf(stderr, "Unsupported cipher algorithm\n"); + return ODP_TEST_INACTIVE; + } + + /* Authentication algorithms */ + switch (auth) { + case ODP_AUTH_ALG_NULL: + if (!capa.auths.bit.null) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_MD5_HMAC: + if (!capa.auths.bit.md5_hmac) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_SHA1_HMAC: + if (!capa.auths.bit.sha1_hmac) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_SHA256_HMAC: + if (!capa.auths.bit.sha256_hmac) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_SHA512_HMAC: + if (!capa.auths.bit.sha512_hmac) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_AES_GCM: + if (!capa.auths.bit.aes_gcm) + return ODP_TEST_INACTIVE; + break; + default: + fprintf(stderr, "Unsupported authentication algorithm\n"); + return ODP_TEST_INACTIVE; + } + + num = odp_ipsec_cipher_capability(cipher, cipher_capa, MAX_ALG_CAPA); + if (num <= 0) { + fprintf(stderr, "Wrong cipher capabilities\n"); + return ODP_TEST_INACTIVE; + } + + /* Search for the test case */ + for (i = 0; i < num; i++) { + if (cipher_capa[i].key_len == cipher_bits / 8) { + found = 1; + break; + } + } + + if (!found) { + fprintf(stderr, "Unsupported key length\n"); + return ODP_TEST_INACTIVE; + } + + num = odp_ipsec_auth_capability(auth, auth_capa, MAX_ALG_CAPA); + if (num <= 0) { + fprintf(stderr, "Wrong auth capabilities\n"); + return ODP_TEST_INACTIVE; + } + + return ODP_TEST_ACTIVE; } -odp_testinfo_t ipsec_suite[] = { - ODP_TEST_INFO(ipsec_test_capability), - ODP_TEST_INFO_NULL -}; +int ipsec_check_ah_sha256(void) +{ + return ipsec_check_ah(ODP_AUTH_ALG_SHA256_HMAC); +} -odp_suiteinfo_t ipsec_suites[] = { - {"IPsec", NULL, NULL, ipsec_suite}, - ODP_SUITE_INFO_NULL, -}; +int ipsec_check_esp_null_sha256(void) +{ + return ipsec_check_esp(ODP_CIPHER_ALG_NULL, 0, + ODP_AUTH_ALG_SHA256_HMAC); +} -int ipsec_main(int argc, char *argv[]) +int ipsec_check_esp_aes_cbc_128_null(void) { - int ret; + return ipsec_check_esp(ODP_CIPHER_ALG_AES_CBC, 128, + ODP_AUTH_ALG_NULL); +} + +int ipsec_check_esp_aes_cbc_128_sha256(void) +{ + return ipsec_check_esp(ODP_CIPHER_ALG_AES_CBC, 128, + ODP_AUTH_ALG_SHA256_HMAC); +} + +int ipsec_check_esp_aes_gcm_128(void) +{ + return ipsec_check_esp(ODP_CIPHER_ALG_AES_GCM, 128, + ODP_AUTH_ALG_AES_GCM); +} + +int ipsec_check_esp_aes_gcm_256(void) +{ + return ipsec_check_esp(ODP_CIPHER_ALG_AES_GCM, 256, + ODP_AUTH_ALG_AES_GCM); +} + +void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param, + odp_bool_t in, + odp_bool_t ah, + uint32_t spi, + odp_ipsec_tunnel_param_t *tun, + odp_cipher_alg_t cipher_alg, + const odp_crypto_key_t *cipher_key, + odp_auth_alg_t auth_alg, + const odp_crypto_key_t *auth_key, + const odp_crypto_key_t *extra_key) +{ + odp_ipsec_sa_param_init(param); + param->dir = in ? ODP_IPSEC_DIR_INBOUND : + ODP_IPSEC_DIR_OUTBOUND; + if (in) + param->inbound.lookup_mode = ODP_IPSEC_LOOKUP_SPI; + + param->proto = ah ? ODP_IPSEC_AH : + ODP_IPSEC_ESP; + + if (tun) { + param->mode = ODP_IPSEC_MODE_TUNNEL; + if (!in) + param->outbound.tunnel = *tun; + } else { + param->mode = ODP_IPSEC_MODE_TRANSPORT; + } + + param->spi = spi; + + param->dest_queue = suite_context.queue; + + param->crypto.cipher_alg = cipher_alg; + if (cipher_key) + param->crypto.cipher_key = *cipher_key; + + param->crypto.auth_alg = auth_alg; + if (auth_key) + param->crypto.auth_key = *auth_key; + + if (extra_key) + param->crypto.cipher_key_extra = *extra_key; +} + +void ipsec_sa_destroy(odp_ipsec_sa_t sa) +{ + odp_event_t event; + odp_ipsec_status_t status; + + 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); + + CU_ASSERT_EQUAL(ODP_EVENT_IPSEC_STATUS, odp_event_type(event)); + + CU_ASSERT_EQUAL(ODP_IPSEC_OK, odp_ipsec_status(&status, event)); + + CU_ASSERT_EQUAL(ODP_IPSEC_STATUS_SA_DISABLE, status.id); + CU_ASSERT_EQUAL(sa, status.sa); + CU_ASSERT_EQUAL(0, status.result); + CU_ASSERT_EQUAL(0, status.warn.all); + + odp_event_free(event); + } + + CU_ASSERT_EQUAL(ODP_IPSEC_OK, odp_ipsec_sa_destroy(sa)); +} + +#define PACKET_USER_PTR ((void *)0x1212fefe) + +odp_packet_t ipsec_packet(const ipsec_test_packet *itp) +{ + odp_packet_t pkt = odp_packet_alloc(suite_context.pool, itp->len); + + CU_ASSERT_NOT_EQUAL(ODP_PACKET_INVALID, pkt); + if (ODP_PACKET_INVALID == pkt) + return pkt; + + CU_ASSERT_EQUAL(0, odp_packet_copy_from_mem(pkt, 0, itp->len, + itp->data)); + if (itp->l2_offset != ODP_PACKET_OFFSET_INVALID) + CU_ASSERT_EQUAL(0, odp_packet_l2_offset_set(pkt, + itp->l2_offset)); + if (itp->l3_offset != ODP_PACKET_OFFSET_INVALID) + CU_ASSERT_EQUAL(0, odp_packet_l3_offset_set(pkt, + itp->l3_offset)); + if (itp->l4_offset != ODP_PACKET_OFFSET_INVALID) + CU_ASSERT_EQUAL(0, odp_packet_l4_offset_set(pkt, + itp->l4_offset)); + + odp_packet_user_ptr_set(pkt, PACKET_USER_PTR); + + return pkt; +} + +/* + * Compare packages ignoring everything before L3 header + */ +static void ipsec_check_packet(const ipsec_test_packet *itp, odp_packet_t pkt) +{ + uint32_t len = (ODP_PACKET_INVALID == pkt) ? 1 : odp_packet_len(pkt); + uint32_t l3, l4; + uint8_t data[len]; + + if (NULL == itp) + return; + + CU_ASSERT_NOT_EQUAL(ODP_PACKET_INVALID, pkt); + if (ODP_PACKET_INVALID == pkt) + return; + + CU_ASSERT_EQUAL(PACKET_USER_PTR, odp_packet_user_ptr(pkt)); + + l3 = odp_packet_l3_offset(pkt); + l4 = odp_packet_l4_offset(pkt); + odp_packet_copy_to_mem(pkt, 0, len, data); + + if (l3 == ODP_PACKET_OFFSET_INVALID) { + CU_ASSERT_EQUAL(itp->l3_offset, ODP_PACKET_OFFSET_INVALID); + CU_ASSERT_EQUAL(l4, ODP_PACKET_OFFSET_INVALID); + + return; + } + + CU_ASSERT_EQUAL(len - l3, itp->len - itp->l3_offset); + if (len - l3 != itp->len - itp->l3_offset) + return; + + CU_ASSERT_EQUAL(l4 - l3, itp->l4_offset - itp->l3_offset); + if (l4 - l3 != itp->l4_offset - itp->l3_offset) + return; + + CU_ASSERT_EQUAL(0, memcmp(data + l3, + itp->data + itp->l3_offset, + len - l3)); +} + +static int ipsec_send_in_one(const ipsec_test_part *part, + odp_ipsec_sa_t sa, + odp_packet_t *pkto) +{ + odp_ipsec_in_param_t param; + int num_out = part->out_pkt; + odp_packet_t pkt; + int i; + + pkt = ipsec_packet(part->pkt_in); - /* parse common options: */ - if (odp_cunit_parse_options(argc, argv)) + memset(¶m, 0, sizeof(param)); + if (!part->lookup) { + param.num_sa = 1; + param.sa = &sa; + } else { + param.num_sa = 0; + param.sa = NULL; + } + + if (ODP_IPSEC_OP_MODE_SYNC == suite_context.inbound_op_mode) { + CU_ASSERT_EQUAL(part->out_pkt, odp_ipsec_in(&pkt, 1, + pkto, &num_out, + ¶m)); + CU_ASSERT_EQUAL(num_out, part->out_pkt); + } else if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.inbound_op_mode) { + CU_ASSERT_EQUAL(1, odp_ipsec_in_enq(&pkt, 1, ¶m)); + + for (i = 0; i < num_out; i++) { + odp_event_t event; + odp_event_subtype_t subtype; + + do { + event = odp_queue_deq(suite_context.queue); + } while (event == ODP_EVENT_INVALID); + + CU_ASSERT_EQUAL(ODP_EVENT_PACKET, + odp_event_types(event, &subtype)); + CU_ASSERT_EQUAL(ODP_EVENT_PACKET_IPSEC, subtype); + pkto[i] = odp_ipsec_packet_from_event(event); + } + } else { + odp_queue_t queue; + odp_pktout_queue_t pktout; + + CU_ASSERT_EQUAL_FATAL(1, odp_pktout_queue(suite_context.pktio, + &pktout, 1)); + + CU_ASSERT_EQUAL(1, odp_pktout_send(pktout, &pkt, 1)); + CU_ASSERT_EQUAL_FATAL(1, + odp_pktin_event_queue(suite_context. + pktio, + &queue, 1)); + + for (i = 0; i < num_out;) { + odp_event_t ev; + odp_event_subtype_t subtype; + + ev = odp_queue_deq(queue); + if (ODP_EVENT_INVALID != ev) { + CU_ASSERT_EQUAL(ODP_EVENT_PACKET, + odp_event_types(ev, &subtype)); + CU_ASSERT_EQUAL(ODP_EVENT_PACKET_BASIC, + subtype); + CU_ASSERT(part->out[i].status.error.sa_lookup); + + pkto[i++] = odp_ipsec_packet_from_event(ev); + continue; + } + + ev = odp_queue_deq(suite_context.queue); + if (ODP_EVENT_INVALID != ev) { + CU_ASSERT_EQUAL(ODP_EVENT_PACKET, + odp_event_types(ev, &subtype)); + CU_ASSERT_EQUAL(ODP_EVENT_PACKET_IPSEC, + subtype); + CU_ASSERT(!part->out[i].status.error.sa_lookup); + + pkto[i++] = odp_ipsec_packet_from_event(ev); + continue; + } + } + } + + return num_out; +} + +static int ipsec_send_out_one(const ipsec_test_part *part, + odp_ipsec_sa_t sa, + odp_packet_t *pkto) +{ + odp_ipsec_out_param_t param; + int num_out = part->out_pkt; + odp_packet_t pkt; + int i; + + pkt = ipsec_packet(part->pkt_in); + + memset(¶m, 0, sizeof(param)); + param.num_sa = 1; + param.sa = &sa; + param.num_opt = 0; + param.opt = NULL; + + if (ODP_IPSEC_OP_MODE_SYNC == suite_context.outbound_op_mode) { + CU_ASSERT_EQUAL(part->out_pkt, odp_ipsec_out(&pkt, 1, + pkto, &num_out, + ¶m)); + CU_ASSERT_EQUAL(num_out, part->out_pkt); + } else if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.outbound_op_mode) { + CU_ASSERT_EQUAL(1, odp_ipsec_out_enq(&pkt, 1, ¶m)); + + for (i = 0; i < num_out; i++) { + odp_event_t event; + odp_event_subtype_t subtype; + + do { + event = odp_queue_deq(suite_context.queue); + } while (event == ODP_EVENT_INVALID); + + CU_ASSERT_EQUAL(ODP_EVENT_PACKET, + odp_event_types(event, &subtype)); + CU_ASSERT_EQUAL(ODP_EVENT_PACKET_IPSEC, subtype); + pkto[i] = odp_ipsec_packet_from_event(event); + } + } else { + struct odp_ipsec_out_inline_param_t inline_param; + odp_queue_t queue; + uint32_t hdr_len = part->out[0].pkt_out->l3_offset; + uint8_t hdr[hdr_len]; + + memcpy(hdr, part->out[0].pkt_out->data, hdr_len); + inline_param.pktio = suite_context.pktio; + inline_param.outer_hdr.ptr = hdr; + inline_param.outer_hdr.len = hdr_len; + + CU_ASSERT_EQUAL(1, odp_ipsec_out_inline(&pkt, 1, ¶m, + &inline_param)); + CU_ASSERT_EQUAL_FATAL(1, + odp_pktin_event_queue(suite_context. + pktio, + &queue, 1)); + + for (i = 0; i < num_out;) { + odp_event_t ev; + odp_event_subtype_t subtype; + + ev = odp_queue_deq(queue); + if (ODP_EVENT_INVALID != ev) { + CU_ASSERT_EQUAL(ODP_EVENT_PACKET, + odp_event_types(ev, &subtype)); + CU_ASSERT_EQUAL(ODP_EVENT_PACKET_BASIC, + subtype); + CU_ASSERT(!part->out[i].status.error.all); + + pkto[i++] = odp_ipsec_packet_from_event(ev); + continue; + } + + ev = odp_queue_deq(suite_context.queue); + if (ODP_EVENT_INVALID != ev) { + CU_ASSERT_EQUAL(ODP_EVENT_PACKET, + odp_event_types(ev, &subtype)); + CU_ASSERT_EQUAL(ODP_EVENT_PACKET_IPSEC, + subtype); + CU_ASSERT(part->out[i].status.error.all); + + pkto[i++] = odp_ipsec_packet_from_event(ev); + continue; + } + } + } + + return num_out; +} + +void ipsec_check_in_one(const ipsec_test_part *part, odp_ipsec_sa_t sa) +{ + int num_out = part->out_pkt; + odp_packet_t pkto[num_out]; + int i; + + num_out = ipsec_send_in_one(part, sa, pkto); + + for (i = 0; i < num_out; i++) { + odp_ipsec_packet_result_t result; + + if (ODP_PACKET_INVALID == pkto[i]) { + CU_FAIL("ODP_PACKET_INVALID received"); + continue; + } + + if (ODP_EVENT_PACKET_IPSEC != + odp_event_subtype(odp_packet_to_event(pkto[i]))) { + /* Inline packet went through loop */ + CU_ASSERT_EQUAL(1, part->out[i].status.error.sa_lookup); + } else { + CU_ASSERT_EQUAL(0, odp_ipsec_result(&result, pkto[i])); + CU_ASSERT_EQUAL(part->out[i].status.error.all, + result.status.error.all); + CU_ASSERT_EQUAL(sa, result.sa); + } + ipsec_check_packet(part->out[i].pkt_out, + pkto[i]); + odp_packet_free(pkto[i]); + } +} + +void ipsec_check_out_one(const ipsec_test_part *part, odp_ipsec_sa_t sa) +{ + int num_out = part->out_pkt; + odp_packet_t pkto[num_out]; + int i; + + num_out = ipsec_send_out_one(part, sa, pkto); + + for (i = 0; i < num_out; i++) { + odp_ipsec_packet_result_t result; + + if (ODP_PACKET_INVALID == pkto[i]) { + CU_FAIL("ODP_PACKET_INVALID received"); + continue; + } + + if (ODP_EVENT_PACKET_IPSEC != + odp_event_subtype(odp_packet_to_event(pkto[i]))) { + /* Inline packet went through loop */ + CU_ASSERT_EQUAL(0, part->out[i].status.error.all); + } else { + /* IPsec packet */ + CU_ASSERT_EQUAL(0, odp_ipsec_result(&result, pkto[i])); + CU_ASSERT_EQUAL(part->out[i].status.error.all, + result.status.error.all); + CU_ASSERT_EQUAL(sa, result.sa); + } + ipsec_check_packet(part->out[i].pkt_out, + pkto[i]); + odp_packet_free(pkto[i]); + } +} + +void ipsec_check_out_in_one(const ipsec_test_part *part, + odp_ipsec_sa_t sa, + odp_ipsec_sa_t sa_in) +{ + int num_out = part->out_pkt; + odp_packet_t pkto[num_out]; + int i; + + num_out = ipsec_send_out_one(part, sa, pkto); + + for (i = 0; i < num_out; i++) { + ipsec_test_part part_in = *part; + ipsec_test_packet pkt_in; + odp_ipsec_packet_result_t result; + + if (ODP_PACKET_INVALID == pkto[i]) { + CU_FAIL("ODP_PACKET_INVALID received"); + continue; + } + + if (ODP_EVENT_PACKET_IPSEC != + odp_event_subtype(odp_packet_to_event(pkto[i]))) { + /* Inline packet went through loop */ + CU_ASSERT_EQUAL(0, part->out[i].status.error.all); + } else { + /* IPsec packet */ + CU_ASSERT_EQUAL(0, odp_ipsec_result(&result, pkto[i])); + CU_ASSERT_EQUAL(part->out[i].status.error.all, + result.status.error.all); + CU_ASSERT_EQUAL(sa, result.sa); + } + CU_ASSERT_FATAL(odp_packet_len(pkto[i]) <= + sizeof(pkt_in.data)); + + pkt_in.len = odp_packet_len(pkto[i]); + pkt_in.l2_offset = odp_packet_l2_offset(pkto[i]); + pkt_in.l3_offset = odp_packet_l3_offset(pkto[i]); + pkt_in.l4_offset = odp_packet_l4_offset(pkto[i]); + odp_packet_copy_to_mem(pkto[i], 0, + pkt_in.len, + pkt_in.data); + part_in.pkt_in = &pkt_in; + ipsec_check_in_one(&part_in, sa_in); + odp_packet_free(pkto[i]); + } +} + +int ipsec_suite_init(void) +{ + int rc = 0; + + if (suite_context.pktio != ODP_PKTIO_INVALID) + rc = pktio_start(suite_context.pktio, + suite_context.inbound_op_mode == + ODP_IPSEC_OP_MODE_INLINE, + suite_context.outbound_op_mode == + ODP_IPSEC_OP_MODE_INLINE); + if (rc == 0) + suite_context.pktio = ODP_PKTIO_INVALID; + + return rc < 0 ? -1 : 0; +} + +static int ipsec_suite_term(odp_testinfo_t *suite) +{ + int i; + int first = 1; + + if (suite_context.pktio != ODP_PKTIO_INVALID) + pktio_stop(suite_context.pktio); + + for (i = 0; suite[i].pName; i++) { + if (suite[i].check_active && + suite[i].check_active() == ODP_TEST_INACTIVE) { + if (first) { + first = 0; + printf("\n\n Inactive tests:\n"); + } + printf(" %s\n", suite[i].pName); + } + } + + return 0; +} + +int ipsec_in_term(void) +{ + return ipsec_suite_term(ipsec_in_suite); +} + +int ipsec_out_term(void) +{ + return ipsec_suite_term(ipsec_out_suite); +} + +int ipsec_init(odp_instance_t *inst) +{ + odp_pool_param_t params; + odp_pool_t pool; + odp_queue_t out_queue; + odp_pool_capability_t pool_capa; + odp_pktio_t pktio; + + if (0 != odp_init_global(inst, NULL, NULL)) { + fprintf(stderr, "error: odp_init_global() failed.\n"); + return -1; + } + + if (0 != odp_init_local(*inst, ODP_THREAD_CONTROL)) { + fprintf(stderr, "error: odp_init_local() failed.\n"); + return -1; + } + + if (odp_pool_capability(&pool_capa) < 0) { + fprintf(stderr, "error: odp_pool_capability() failed.\n"); + return -1; + } + + odp_pool_param_init(¶ms); + params.pkt.seg_len = PKT_POOL_LEN; + params.pkt.len = PKT_POOL_LEN; + params.pkt.num = PKT_POOL_NUM; + params.type = ODP_POOL_PACKET; + + if (pool_capa.pkt.max_seg_len && + PKT_POOL_LEN > pool_capa.pkt.max_seg_len) { + fprintf(stderr, "Warning: small packet segment length\n"); + params.pkt.seg_len = pool_capa.pkt.max_seg_len; + } + + if (pool_capa.pkt.max_len && + PKT_POOL_LEN > pool_capa.pkt.max_len) { + fprintf(stderr, "Pool max packet length too small\n"); return -1; + } - ret = odp_cunit_register(ipsec_suites); + pool = odp_pool_create("packet_pool", ¶ms); - if (ret == 0) - ret = odp_cunit_run(); + if (ODP_POOL_INVALID == pool) { + fprintf(stderr, "Packet pool creation failed.\n"); + return -1; + } + out_queue = odp_queue_create("ipsec-out", NULL); + if (ODP_QUEUE_INVALID == out_queue) { + fprintf(stderr, "IPsec outq creation failed.\n"); + return -1; + } + + pktio = pktio_create(pool); + if (ODP_PKTIO_INVALID == pktio) { + fprintf(stderr, "IPsec pktio creation failed.\n"); + return -1; + } + + return 0; +} + +int ipsec_config(odp_instance_t ODP_UNUSED inst) +{ + odp_ipsec_capability_t capa; + odp_ipsec_config_t ipsec_config; + + if (odp_ipsec_capability(&capa) < 0) + return -1; + + /* If we can not setup IPsec due to mode being unsupported, don't + * return an error here. It is easier (and more correct) to filter that + * in test checking function and just say that the test is inactive. */ + if ((ODP_IPSEC_OP_MODE_SYNC == suite_context.inbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_sync) || + (ODP_IPSEC_OP_MODE_ASYNC == suite_context.outbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_sync) || + (ODP_IPSEC_OP_MODE_ASYNC == suite_context.inbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_async) || + (ODP_IPSEC_OP_MODE_ASYNC == suite_context.outbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_async) || + (ODP_IPSEC_OP_MODE_INLINE == suite_context.inbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_inline_in) || + (ODP_IPSEC_OP_MODE_INLINE == suite_context.outbound_op_mode && + ODP_SUPPORT_NO == capa.op_mode_inline_out)) + return 0; + + odp_ipsec_config_init(&ipsec_config); + ipsec_config.inbound_mode = suite_context.inbound_op_mode; + ipsec_config.outbound_mode = suite_context.outbound_op_mode; + ipsec_config.inbound.default_queue = suite_context.queue; + ipsec_config.inbound.parse = ODP_IPSEC_LAYER_ALL; + + if (ODP_IPSEC_OK != odp_ipsec_config(&ipsec_config)) + return -1; + + return 0; +} + +int ipsec_term(odp_instance_t inst) +{ + odp_pool_t pool; + odp_queue_t out_queue; + odp_pktio_t pktio; + + pktio = odp_pktio_lookup("loop"); + if (ODP_PKTIO_INVALID != pktio) { + if (odp_pktio_close(pktio)) + fprintf(stderr, "IPsec pktio close failed.\n"); + } else { + fprintf(stderr, "IPsec pktio not found.\n"); + } + + out_queue = odp_queue_lookup("ipsec-out"); + if (ODP_QUEUE_INVALID != out_queue) { + if (odp_queue_destroy(out_queue)) + fprintf(stderr, "IPsec outq destroy failed.\n"); + } else { + fprintf(stderr, "IPsec outq not found.\n"); + } + + pool = odp_pool_lookup("packet_pool"); + if (ODP_POOL_INVALID != pool) { + if (odp_pool_destroy(pool)) + fprintf(stderr, "Packet pool destroy failed.\n"); + } else { + fprintf(stderr, "Packet pool not found.\n"); + } + + if (0 != odp_term_local()) { + fprintf(stderr, "error: odp_term_local() failed.\n"); + return -1; + } + + if (0 != odp_term_global(inst)) { + fprintf(stderr, "error: odp_term_global() failed.\n"); + return -1; + } - return ret; + return 0; } diff --git a/test/common_plat/validation/api/ipsec/ipsec.h b/test/common_plat/validation/api/ipsec/ipsec.h index 290a186f7..d1c6854b7 100644 --- a/test/common_plat/validation/api/ipsec/ipsec.h +++ b/test/common_plat/validation/api/ipsec/ipsec.h @@ -9,16 +9,81 @@ #include -/* test functions: */ -void ipsec_test_capability(void); - /* test arrays: */ -extern odp_testinfo_t ipsec_suite[]; +extern odp_testinfo_t ipsec_in_suite[]; +extern odp_testinfo_t ipsec_out_suite[]; + +int ipsec_init(odp_instance_t *inst); +int ipsec_term(odp_instance_t inst); +int ipsec_config(odp_instance_t inst); + +int ipsec_in_inline_init(void); +int ipsec_out_inline_init(void); + +int ipsec_suite_init(void); +int ipsec_in_term(void); +int ipsec_out_term(void); + +struct suite_context_s { + odp_ipsec_op_mode_t inbound_op_mode; + odp_ipsec_op_mode_t outbound_op_mode; + odp_pool_t pool; + odp_queue_t queue; + odp_pktio_t pktio; +}; + +extern struct suite_context_s suite_context; + +typedef struct { + uint32_t len; + uint32_t l2_offset; + uint32_t l3_offset; + uint32_t l4_offset; + uint8_t data[256]; +} ipsec_test_packet; + +typedef struct { + const ipsec_test_packet *pkt_in; + odp_bool_t lookup; + int out_pkt; + struct { + odp_ipsec_op_status_t status; + const ipsec_test_packet *pkt_out; + } out[1]; +} ipsec_test_part; + +void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param, + odp_bool_t in, + odp_bool_t ah, + uint32_t spi, + odp_ipsec_tunnel_param_t *tun, + odp_cipher_alg_t cipher_alg, + const odp_crypto_key_t *cipher_key, + odp_auth_alg_t auth_alg, + const odp_crypto_key_t *auth_key, + const odp_crypto_key_t *extra_key); -/* test registry: */ -extern odp_suiteinfo_t ipsec_suites[]; +void ipsec_sa_destroy(odp_ipsec_sa_t sa); +odp_packet_t ipsec_packet(const ipsec_test_packet *itp); +void ipsec_check_in_one(const ipsec_test_part *part, odp_ipsec_sa_t sa); +void ipsec_check_out_one(const ipsec_test_part *part, odp_ipsec_sa_t sa); +void ipsec_check_out_in_one(const ipsec_test_part *part, + odp_ipsec_sa_t sa, + odp_ipsec_sa_t sa_in); -/* main test program: */ -int ipsec_main(int argc, char *argv[]); +int ipsec_check(odp_bool_t ah, + odp_cipher_alg_t cipher, + uint32_t cipher_bits, + odp_auth_alg_t auth); +#define ipsec_check_ah(auth) \ + ipsec_check(true, ODP_CIPHER_ALG_NULL, 0, auth) +#define ipsec_check_esp(cipher, cipher_bits, auth) \ + ipsec_check(false, cipher, cipher_bits, auth) +int ipsec_check_ah_sha256(void); +int ipsec_check_esp_null_sha256(void); +int ipsec_check_esp_aes_cbc_128_null(void); +int ipsec_check_esp_aes_cbc_128_sha256(void); +int ipsec_check_esp_aes_gcm_128(void); +int ipsec_check_esp_aes_gcm_256(void); #endif diff --git a/test/common_plat/validation/api/ipsec/ipsec_async.c b/test/common_plat/validation/api/ipsec/ipsec_async.c new file mode 100644 index 000000000..0de463a48 --- /dev/null +++ b/test/common_plat/validation/api/ipsec/ipsec_async.c @@ -0,0 +1,55 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#include "ipsec.h" + +static int ipsec_sync_init(odp_instance_t *inst) +{ + int rc; + + rc = ipsec_init(inst); + if (rc != 0) + return rc; + + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + suite_context.queue = odp_queue_lookup("ipsec-out"); + if (suite_context.queue == ODP_QUEUE_INVALID) + return -1; + + suite_context.pktio = ODP_PKTIO_INVALID; + suite_context.inbound_op_mode = ODP_IPSEC_OP_MODE_ASYNC; + suite_context.outbound_op_mode = ODP_IPSEC_OP_MODE_ASYNC; + + return ipsec_config(*inst); +} + +odp_suiteinfo_t ipsec_suites[] = { + {"IPsec-in", ipsec_suite_init, ipsec_in_term, ipsec_in_suite}, + {"IPsec-out", ipsec_suite_init, ipsec_out_term, ipsec_out_suite}, + ODP_SUITE_INFO_NULL, +}; + +int main(int argc, char *argv[]) +{ + int ret; + + /* parse common options: */ + if (odp_cunit_parse_options(argc, argv)) + return -1; + + odp_cunit_register_global_init(ipsec_sync_init); + odp_cunit_register_global_term(ipsec_term); + + ret = odp_cunit_register(ipsec_suites); + if (ret == 0) + ret = odp_cunit_run(); + + return ret; +} diff --git a/test/common_plat/validation/api/ipsec/ipsec_inline_in.c b/test/common_plat/validation/api/ipsec/ipsec_inline_in.c new file mode 100644 index 000000000..2a595353d --- /dev/null +++ b/test/common_plat/validation/api/ipsec/ipsec_inline_in.c @@ -0,0 +1,56 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#include "ipsec.h" + +static int ipsec_sync_init(odp_instance_t *inst) +{ + int rc; + + rc = ipsec_init(inst); + if (rc != 0) + return rc; + + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + suite_context.queue = odp_queue_lookup("ipsec-out"); + if (suite_context.queue == ODP_QUEUE_INVALID) + return -1; + suite_context.pktio = odp_pktio_lookup("loop"); + if (suite_context.pktio == ODP_PKTIO_INVALID) + return -1; + + suite_context.inbound_op_mode = ODP_IPSEC_OP_MODE_INLINE; + suite_context.outbound_op_mode = ODP_IPSEC_OP_MODE_ASYNC; + + return ipsec_config(*inst); +} + +odp_suiteinfo_t ipsec_suites[] = { + {"IPsec-in", ipsec_suite_init, ipsec_in_term, ipsec_in_suite}, + ODP_SUITE_INFO_NULL, +}; + +int main(int argc, char *argv[]) +{ + int ret; + + /* parse common options: */ + if (odp_cunit_parse_options(argc, argv)) + return -1; + + odp_cunit_register_global_init(ipsec_sync_init); + odp_cunit_register_global_term(ipsec_term); + + ret = odp_cunit_register(ipsec_suites); + if (ret == 0) + ret = odp_cunit_run(); + + return ret; +} diff --git a/test/common_plat/validation/api/ipsec/ipsec_inline_out.c b/test/common_plat/validation/api/ipsec/ipsec_inline_out.c new file mode 100644 index 000000000..0a34e03ad --- /dev/null +++ b/test/common_plat/validation/api/ipsec/ipsec_inline_out.c @@ -0,0 +1,56 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#include "ipsec.h" + +static int ipsec_sync_init(odp_instance_t *inst) +{ + int rc; + + rc = ipsec_init(inst); + if (rc != 0) + return rc; + + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + suite_context.queue = odp_queue_lookup("ipsec-out"); + if (suite_context.queue == ODP_QUEUE_INVALID) + return -1; + suite_context.pktio = odp_pktio_lookup("loop"); + if (suite_context.pktio == ODP_PKTIO_INVALID) + return -1; + + suite_context.inbound_op_mode = ODP_IPSEC_OP_MODE_ASYNC; + suite_context.outbound_op_mode = ODP_IPSEC_OP_MODE_INLINE; + + return ipsec_config(*inst); +} + +odp_suiteinfo_t ipsec_suites[] = { + {"IPsec-out", ipsec_suite_init, ipsec_out_term, ipsec_out_suite}, + ODP_SUITE_INFO_NULL, +}; + +int main(int argc, char *argv[]) +{ + int ret; + + /* parse common options: */ + if (odp_cunit_parse_options(argc, argv)) + return -1; + + odp_cunit_register_global_init(ipsec_sync_init); + odp_cunit_register_global_term(ipsec_term); + + ret = odp_cunit_register(ipsec_suites); + if (ret == 0) + ret = odp_cunit_run(); + + return ret; +} diff --git a/test/common_plat/validation/api/ipsec/ipsec_main.c b/test/common_plat/validation/api/ipsec/ipsec_main.c deleted file mode 100644 index 63a7a55fd..000000000 --- a/test/common_plat/validation/api/ipsec/ipsec_main.c +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright (c) 2017, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "ipsec.h" - -int main(int argc, char *argv[]) -{ - return ipsec_main(argc, argv); -} diff --git a/test/common_plat/validation/api/ipsec/ipsec_sync.c b/test/common_plat/validation/api/ipsec/ipsec_sync.c new file mode 100644 index 000000000..c22980a83 --- /dev/null +++ b/test/common_plat/validation/api/ipsec/ipsec_sync.c @@ -0,0 +1,53 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#include "ipsec.h" + +static int ipsec_sync_init(odp_instance_t *inst) +{ + int rc; + + rc = ipsec_init(inst); + if (rc != 0) + return rc; + + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + + suite_context.queue = ODP_QUEUE_INVALID; + suite_context.pktio = ODP_PKTIO_INVALID; + suite_context.inbound_op_mode = ODP_IPSEC_OP_MODE_SYNC; + suite_context.outbound_op_mode = ODP_IPSEC_OP_MODE_SYNC; + + return ipsec_config(*inst); +} + +odp_suiteinfo_t ipsec_suites[] = { + {"IPsec-in", ipsec_suite_init, ipsec_in_term, ipsec_in_suite}, + {"IPsec-out", ipsec_suite_init, ipsec_out_term, ipsec_out_suite}, + ODP_SUITE_INFO_NULL, +}; + +int main(int argc, char *argv[]) +{ + int ret; + + /* parse common options: */ + if (odp_cunit_parse_options(argc, argv)) + return -1; + + odp_cunit_register_global_init(ipsec_sync_init); + odp_cunit_register_global_term(ipsec_term); + + ret = odp_cunit_register(ipsec_suites); + if (ret == 0) + ret = odp_cunit_run(); + + return ret; +} diff --git a/test/common_plat/validation/api/ipsec/ipsec_sync_in.c b/test/common_plat/validation/api/ipsec/ipsec_sync_in.c new file mode 100644 index 000000000..8a7fc4680 --- /dev/null +++ b/test/common_plat/validation/api/ipsec/ipsec_sync_in.c @@ -0,0 +1,27 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#include "ipsec.h" + +int main(int argc, char *argv[]) +{ + int ret; + + /* parse common options: */ + if (odp_cunit_parse_options(argc, argv)) + return -1; + + odp_cunit_register_global_init(ipsec_init); + odp_cunit_register_global_term(ipsec_term); + + ret = odp_cunit_register(ipsec_suites); + if (ret == 0) + ret = odp_cunit_run(); + + return ret; +} diff --git a/test/common_plat/validation/api/ipsec/ipsec_test_in.c b/test/common_plat/validation/api/ipsec/ipsec_test_in.c new file mode 100644 index 000000000..25fc00e11 --- /dev/null +++ b/test/common_plat/validation/api/ipsec/ipsec_test_in.c @@ -0,0 +1,815 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#include "ipsec.h" + +#include "test_vectors.h" + +static void test_in_ah_sha256(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, true, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_ah_sha256_1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_ah_sha256_tun(void) +{ + odp_ipsec_tunnel_param_t tunnel = {}; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, true, 123, &tunnel, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_ah_tun_sha256_1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_ah_sha256_tun_notun(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, true, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_ah_tun_sha256_1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0_ipip }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_esp_null_sha256(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_esp_null_sha256_1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_esp_aes_cbc_null(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_AES_CBC, &key_a5_128, + ODP_AUTH_ALG_NULL, NULL, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_esp_aes_cbc_null_1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_esp_aes_cbc_sha256(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_AES_CBC, &key_a5_128, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_esp_aes_cbc_sha256_1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_lookup_ah_sha256(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, true, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_ah_sha256_1, + .lookup = 1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_lookup_esp_null_sha256(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_esp_null_sha256_1, + .lookup = 1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_esp_null_sha256_tun(void) +{ + odp_ipsec_tunnel_param_t tunnel = {}; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 123, &tunnel, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_esp_tun_null_sha256_1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_ah_esp_pkt(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + /* This test will not work properly inbound inline mode. + * test_in_lookup_ah_esp_pkt will be used instead. */ + if (suite_context.inbound_op_mode == ODP_IPSEC_OP_MODE_INLINE) + return; + + ipsec_sa_param_fill(¶m, + true, true, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_esp_null_sha256_1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.proto = 1, + .pkt_out = NULL }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_esp_ah_pkt(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + /* This test will not work properly inbound inline mode. + * test_in_lookup_esp_ah_pkt will be used instead. */ + if (suite_context.inbound_op_mode == ODP_IPSEC_OP_MODE_INLINE) + return; + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_ah_sha256_1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.proto = 1, + .pkt_out = NULL }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_lookup_ah_esp_pkt(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, true, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_esp_null_sha256_1, + .lookup = 1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.sa_lookup = 1, + .pkt_out = NULL }, + }, + }; + + ipsec_check_in_one(&test, ODP_IPSEC_SA_INVALID); + + ipsec_sa_destroy(sa); +} + +static void test_in_lookup_esp_ah_pkt(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_ah_sha256_1, + .lookup = 1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.sa_lookup = 1, + .pkt_out = NULL }, + }, + }; + + ipsec_check_in_one(&test, ODP_IPSEC_SA_INVALID); + + ipsec_sa_destroy(sa); +} + +static void test_in_ah_sha256_bad1(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, true, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_ah_sha256_1_bad1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.auth = 1, + .pkt_out = NULL }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_ah_sha256_bad2(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, true, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_ah_sha256_1_bad2, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.auth = 1, + .pkt_out = NULL }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_esp_null_sha256_bad1(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0_esp_null_sha256_1_bad1, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.auth = 1, + .pkt_out = NULL }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_rfc3602_5_esp(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 0x4321, NULL, + ODP_CIPHER_ALG_AES_CBC, &key_rfc3602, + ODP_AUTH_ALG_NULL, NULL, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_rfc3602_5_esp, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_rfc3602_5 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_rfc3602_6_esp(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 0x4321, NULL, + ODP_CIPHER_ALG_AES_CBC, &key_rfc3602, + ODP_AUTH_ALG_NULL, NULL, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_rfc3602_6_esp, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_rfc3602_6 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_rfc3602_7_esp(void) +{ + odp_ipsec_tunnel_param_t tunnel = {}; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 0x8765, &tunnel, + ODP_CIPHER_ALG_AES_CBC, &key_rfc3602_2, + ODP_AUTH_ALG_NULL, NULL, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_rfc3602_7_esp, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_rfc3602_7 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_rfc3602_8_esp(void) +{ + odp_ipsec_tunnel_param_t tunnel = {}; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 0x8765, &tunnel, + ODP_CIPHER_ALG_AES_CBC, &key_rfc3602_2, + ODP_AUTH_ALG_NULL, NULL, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_rfc3602_8_esp, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_rfc3602_8 }, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_mcgrew_gcm_2_esp(void) +{ + odp_ipsec_tunnel_param_t tunnel = {}; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 0xa5f8, &tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_2, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_2); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_mcgrew_gcm_test_2_esp, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_mcgrew_gcm_test_2}, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_mcgrew_gcm_3_esp(void) +{ + odp_ipsec_tunnel_param_t tunnel = {}; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 0x4a2cbfe3, &tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_3, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_3); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_mcgrew_gcm_test_3_esp, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_mcgrew_gcm_test_3}, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_mcgrew_gcm_4_esp(void) +{ + odp_ipsec_tunnel_param_t tunnel = {}; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 0x00000000, &tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_mcgrew_gcm_test_4_esp, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_mcgrew_gcm_test_4}, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_in_mcgrew_gcm_12_esp(void) +{ + odp_ipsec_tunnel_param_t tunnel = {}; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 0x335467ae, &tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_12, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_12); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_mcgrew_gcm_test_12_esp, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_mcgrew_gcm_test_12}, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void ipsec_test_capability(void) +{ + odp_ipsec_capability_t capa; + + CU_ASSERT(odp_ipsec_capability(&capa) == 0); +} + +odp_testinfo_t ipsec_in_suite[] = { + ODP_TEST_INFO(ipsec_test_capability), + ODP_TEST_INFO_CONDITIONAL(test_in_rfc3602_5_esp, + ipsec_check_esp_aes_cbc_128_null), + ODP_TEST_INFO_CONDITIONAL(test_in_rfc3602_6_esp, + ipsec_check_esp_aes_cbc_128_null), + ODP_TEST_INFO_CONDITIONAL(test_in_rfc3602_7_esp, + ipsec_check_esp_aes_cbc_128_null), + ODP_TEST_INFO_CONDITIONAL(test_in_rfc3602_8_esp, + ipsec_check_esp_aes_cbc_128_null), + /* test 1, 5, 6, 8 -- 11 -- ESN */ + /* test 7 -- invalid, plaintext packet includes trl into IP length */ + ODP_TEST_INFO_CONDITIONAL(test_in_mcgrew_gcm_2_esp, + ipsec_check_esp_aes_gcm_128), + ODP_TEST_INFO_CONDITIONAL(test_in_mcgrew_gcm_3_esp, + ipsec_check_esp_aes_gcm_256), + ODP_TEST_INFO_CONDITIONAL(test_in_mcgrew_gcm_4_esp, + ipsec_check_esp_aes_gcm_128), + ODP_TEST_INFO_CONDITIONAL(test_in_mcgrew_gcm_12_esp, + ipsec_check_esp_aes_gcm_128), + ODP_TEST_INFO_CONDITIONAL(test_in_ah_sha256, + ipsec_check_ah_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_ah_sha256_tun, + ipsec_check_ah_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_ah_sha256_tun_notun, + ipsec_check_ah_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_esp_null_sha256, + ipsec_check_esp_null_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_esp_aes_cbc_null, + ipsec_check_esp_aes_cbc_128_null), + ODP_TEST_INFO_CONDITIONAL(test_in_esp_aes_cbc_sha256, + ipsec_check_esp_aes_cbc_128_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_lookup_ah_sha256, + ipsec_check_ah_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_lookup_esp_null_sha256, + ipsec_check_esp_null_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_esp_null_sha256_tun, + ipsec_check_esp_null_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_ah_esp_pkt, + ipsec_check_ah_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_esp_ah_pkt, + ipsec_check_esp_null_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_lookup_ah_esp_pkt, + ipsec_check_ah_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_lookup_esp_ah_pkt, + ipsec_check_esp_null_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_ah_sha256_bad1, + ipsec_check_ah_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_ah_sha256_bad2, + ipsec_check_ah_sha256), + ODP_TEST_INFO_CONDITIONAL(test_in_esp_null_sha256_bad1, + ipsec_check_esp_null_sha256), + ODP_TEST_INFO_NULL, +}; diff --git a/test/common_plat/validation/api/ipsec/ipsec_test_out.c b/test/common_plat/validation/api/ipsec/ipsec_test_out.c new file mode 100644 index 000000000..39a3c30ff --- /dev/null +++ b/test/common_plat/validation/api/ipsec/ipsec_test_out.c @@ -0,0 +1,348 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#include "ipsec.h" + +#include "test_vectors.h" + +static void test_out_ah_sha256(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + false, true, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0_ah_sha256_1 }, + }, + }; + + ipsec_check_out_one(&test, sa); + + 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_ah_sha256_tun(void) +{ + uint32_t src = IPV4ADDR(10, 0, 111, 2); + uint32_t dst = IPV4ADDR(10, 0, 222, 2); + odp_ipsec_tunnel_param_t tunnel = { + .type = ODP_IPSEC_TUNNEL_IPV4, + .ipv4.src_addr = &src, + .ipv4.dst_addr = &dst, + .ipv4.ttl = 64, + }; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + false, true, 123, &tunnel, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0_ah_tun_sha256_1 }, + }, + }; + + ipsec_check_out_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_out_esp_null_sha256_out(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + false, false, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0_esp_null_sha256_1 }, + }, + }; + + ipsec_check_out_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_out_esp_null_sha256_tun_out(void) +{ + uint32_t src = IPV4ADDR(10, 0, 111, 2); + uint32_t dst = IPV4ADDR(10, 0, 222, 2); + odp_ipsec_tunnel_param_t tunnel = { + .type = ODP_IPSEC_TUNNEL_IPV4, + .ipv4.src_addr = &src, + .ipv4.dst_addr = &dst, + .ipv4.ttl = 64, + }; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + false, false, 123, &tunnel, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0_esp_tun_null_sha256_1 }, + }, + }; + + ipsec_check_out_one(&test, sa); + + ipsec_sa_destroy(sa); +} + +static void test_out_esp_null_sha256(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + odp_ipsec_sa_t sa2; + + ipsec_sa_param_fill(¶m, + false, false, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_NULL, NULL, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa2 = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_out_in_one(&test, sa, sa2); + + ipsec_sa_destroy(sa2); + ipsec_sa_destroy(sa); +} + +static void test_out_esp_aes_cbc_null(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + odp_ipsec_sa_t sa2; + + ipsec_sa_param_fill(¶m, + false, false, 123, NULL, + ODP_CIPHER_ALG_AES_CBC, &key_a5_128, + ODP_AUTH_ALG_NULL, NULL, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_AES_CBC, &key_a5_128, + ODP_AUTH_ALG_NULL, NULL, + NULL); + + sa2 = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_out_in_one(&test, sa, sa2); + + ipsec_sa_destroy(sa2); + ipsec_sa_destroy(sa); +} + +static void test_out_esp_aes_cbc_sha256(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + odp_ipsec_sa_t sa2; + + ipsec_sa_param_fill(¶m, + false, false, 123, NULL, + ODP_CIPHER_ALG_AES_CBC, &key_a5_128, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_AES_CBC, &key_a5_128, + ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, + NULL); + + sa2 = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_out_in_one(&test, sa, sa2); + + ipsec_sa_destroy(sa2); + ipsec_sa_destroy(sa); +} + +static void test_out_esp_aes_gcm128(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + odp_ipsec_sa_t sa2; + + ipsec_sa_param_fill(¶m, + false, false, 123, NULL, + ODP_CIPHER_ALG_AES_GCM, &key_a5_128, + ODP_AUTH_ALG_AES_GCM, &key_a5_128, + &key_mcgrew_gcm_salt_2); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_AES_GCM, &key_a5_128, + ODP_AUTH_ALG_AES_GCM, &key_a5_128, + &key_mcgrew_gcm_salt_2); + + sa2 = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2); + + ipsec_test_part test = { + .pkt_in = &pkt_icmp_0, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_icmp_0 }, + }, + }; + + ipsec_check_out_in_one(&test, sa, sa2); + + ipsec_sa_destroy(sa2); + ipsec_sa_destroy(sa); +} + +static void ipsec_test_capability(void) +{ + odp_ipsec_capability_t capa; + + CU_ASSERT(odp_ipsec_capability(&capa) == 0); +} + +odp_testinfo_t ipsec_out_suite[] = { + ODP_TEST_INFO(ipsec_test_capability), + ODP_TEST_INFO_CONDITIONAL(test_out_ah_sha256, + ipsec_check_ah_sha256), + ODP_TEST_INFO_CONDITIONAL(test_out_ah_sha256_tun, + ipsec_check_ah_sha256), + ODP_TEST_INFO_CONDITIONAL(test_out_esp_null_sha256_out, + ipsec_check_esp_null_sha256), + ODP_TEST_INFO_CONDITIONAL(test_out_esp_null_sha256_tun_out, + ipsec_check_esp_null_sha256), + ODP_TEST_INFO_CONDITIONAL(test_out_esp_null_sha256, + ipsec_check_esp_null_sha256), + ODP_TEST_INFO_CONDITIONAL(test_out_esp_aes_cbc_null, + ipsec_check_esp_aes_cbc_128_null), + ODP_TEST_INFO_CONDITIONAL(test_out_esp_aes_cbc_sha256, + ipsec_check_esp_aes_cbc_128_sha256), + ODP_TEST_INFO_CONDITIONAL(test_out_esp_aes_gcm128, + ipsec_check_esp_aes_gcm_128), + ODP_TEST_INFO_NULL, +}; diff --git a/test/common_plat/validation/api/ipsec/test_vectors.h b/test/common_plat/validation/api/ipsec/test_vectors.h new file mode 100644 index 000000000..2fb06b2b7 --- /dev/null +++ b/test/common_plat/validation/api/ipsec/test_vectors.h @@ -0,0 +1,965 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ODP_TEST_IPSEC_VECTORS_H_ +#define _ODP_TEST_IPSEC_VECTORS_H_ + +#define KEY(name, ...) \ + static uint8_t name ## _data[] = { __VA_ARGS__ }; \ + static const ODP_UNUSED odp_crypto_key_t name = { \ + .data = name ## _data, \ + .length = sizeof(name ## _data), \ + } + +KEY(key_a5_128, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, + 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5); +KEY(key_5a_128, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, + 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a); +KEY(key_a5_256, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, + 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, + 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, + 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5); +KEY(key_5a_256, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, + 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, + 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, + 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a); + +KEY(key_rfc3602, 0x90, 0xd3, 0x82, 0xb4, 0x10, 0xee, 0xba, 0x7a, + 0xd9, 0x38, 0xc4, 0x6c, 0xec, 0x1a, 0x82, 0xbf); +KEY(key_rfc3602_2, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef); +KEY(key_mcgrew_gcm_2, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08); +KEY(key_mcgrew_gcm_salt_2, 0xca, 0xfe, 0xba, 0xbe); +KEY(key_mcgrew_gcm_3, 0xab, 0xbc, 0xcd, 0xde, 0xf0, 0x01, 0x12, 0x23, + 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x9a, 0xab, + 0xab, 0xbc, 0xcd, 0xde, 0xf0, 0x01, 0x12, 0x23, + 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x9a, 0xab); +KEY(key_mcgrew_gcm_salt_3, 0x11, 0x22, 0x33, 0x44); +KEY(key_mcgrew_gcm_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); +KEY(key_mcgrew_gcm_salt_4, 0x00, 0x00, 0x00, 0x00); +KEY(key_mcgrew_gcm_12, 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47); +KEY(key_mcgrew_gcm_salt_12, 0xd9, 0x66, 0x42, 0x67); + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0 = { + .len = 142, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0xac, 0x27, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_ipip = { + .len = 162, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x04, 0x19, 0x62, 0x0a, 0x00, 0x6f, 0x02, + 0x0a, 0x00, 0xde, 0x02, + + /* Inner IP */ + 0x45, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0xac, 0x27, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_ah_sha256_1 = { + .len = 170, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x33, 0xab, 0xd9, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* AH */ + 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x01, + 0x6c, 0x2e, 0xf7, 0x1f, 0x7c, 0x70, 0x39, 0xa3, + 0x4a, 0x77, 0x01, 0x47, 0x9e, 0x45, 0x73, 0x51, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_ah_tun_sha256_1 = { + .len = 190, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x33, 0x19, 0x17, 0x0a, 0x00, 0x6f, 0x02, + 0x0a, 0x00, 0xde, 0x02, + + /* AH */ + 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x01, + 0xd5, 0x35, 0x9b, 0x21, 0xe6, 0x14, 0x9b, 0x42, + 0x1f, 0x00, 0xfa, 0x36, 0x73, 0x4c, 0x53, 0xcf, + + /* Inner IP */ + 0x45, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0xac, 0x27, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_ah_sha256_1_bad1 = { + .len = 168, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x33, 0xab, 0xd9, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* AH */ + 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x01, + 0x6c, 0x2e, 0xf7, 0x1f, 0x7c, 0x70, 0x39, 0xa3, + 0x4a, 0x77, 0x01, 0x47, 0x9e, 0x45, 0x73, 0x51, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_ah_sha256_1_bad2 = { + .len = 170, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x33, 0xab, 0xd9, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* AH */ + 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x01, + 0x6c, 0x2e, 0xf7, 0x1f, 0x7c, 0x70, 0x39, 0xa3, + 0x4a, 0x77, 0x01, 0x47, 0x9e, 0x45, 0x73, 0x51, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5d, + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_esp_null_sha256_1 = { + .len = 170, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x32, 0xab, 0xda, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* ESP */ + 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + + /* ESP TRL */ + 0x01, 0x02, 0x02, 0x01, + + /* ICV */ + 0xe9, 0x81, 0xcd, 0x65, 0x9b, 0x25, 0x0b, 0x33, + 0xe2, 0xf3, 0x83, 0xf1, 0x6d, 0x14, 0xb4, 0x1f, + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_esp_tun_null_sha256_1 = { + .len = 190, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x32, 0x19, 0x18, 0x0a, 0x00, 0x6f, 0x02, + 0x0a, 0x00, 0xde, 0x02, + + /* ESP */ + 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + + /* Inner IP */ + 0x45, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0xac, 0x27, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + + /* ESP TRL */ + 0x01, 0x02, 0x02, 0x04, + + /* ICV */ + 0x73, 0x8d, 0xf6, 0x9a, 0x26, 0x06, 0x4d, 0xa1, + 0x88, 0x37, 0x65, 0xab, 0x0d, 0xe9, 0x95, 0x3b, + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_esp_null_sha256_1_bad1 = { + .len = 170, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x32, 0xab, 0xda, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* ESP */ + 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + + /* ESP TRL */ + 0x01, 0x02, 0x02, 0x01, + + /* ICV */ + 0x18, 0x00, 0x14, 0x3a, 0x54, 0x72, 0x98, 0xe8, + 0xc7, 0x2d, 0xfa, 0xeb, 0x70, 0xe0, 0x24, 0xdf, + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_esp_aes_cbc_null_1 = { + .len = 170, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x32, 0xab, 0xca, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* ESP */ + 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + + /* IV */ + 0x96, 0xfa, 0x74, 0x56, 0x78, 0xe4, 0xbb, 0x0c, + 0x9e, 0x6e, 0x4a, 0xeb, 0x44, 0xd9, 0xf2, 0xe6, + + /* data */ + 0x2f, 0xb3, 0xa6, 0xfe, 0x2c, 0x2e, 0xce, 0x65, + 0x3a, 0x57, 0xe3, 0x09, 0x5d, 0x66, 0x36, 0x32, + 0xb1, 0xc2, 0x59, 0x58, 0xb6, 0xe5, 0x9e, 0xa2, + 0x07, 0xf8, 0x26, 0x4a, 0x64, 0xf5, 0x16, 0x01, + 0x51, 0x8e, 0xe5, 0x4b, 0x07, 0x2c, 0x4b, 0x23, + 0xfa, 0x4e, 0x6e, 0xdb, 0x35, 0xc7, 0x1d, 0x30, + 0x42, 0xd9, 0x0f, 0xba, 0x8a, 0x69, 0x7e, 0x29, + 0xe7, 0xbd, 0x15, 0xe9, 0x35, 0x9e, 0x81, 0xe7, + 0x9e, 0xc9, 0x7d, 0x66, 0x99, 0x58, 0xec, 0x45, + 0x29, 0xd0, 0xa4, 0xfd, 0xf1, 0xe7, 0x5b, 0x3e, + 0x2a, 0x77, 0x1d, 0x8f, 0x2b, 0x73, 0xba, 0xf8, + 0x72, 0xd2, 0xa0, 0x0b, 0x90, 0xb9, 0x73, 0x9c, + 0xde, 0x3c, 0xc3, 0xb8, 0x91, 0x97, 0xc4, 0x28, + 0xfa, 0x6d, 0xa8, 0x41, 0xb6, 0x83, 0xc8, 0xaa, + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_esp_aes_cbc_sha256_1 = { + .len = 186, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x32, 0xab, 0xca, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* ESP */ + 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + + /* IV */ + 0x96, 0xfa, 0x74, 0x56, 0x78, 0xe4, 0xbb, 0x0c, + 0x9e, 0x6e, 0x4a, 0xeb, 0x44, 0xd9, 0xf2, 0xe6, + + /* data */ + 0x2f, 0xb3, 0xa6, 0xfe, 0x2c, 0x2e, 0xce, 0x65, + 0x3a, 0x57, 0xe3, 0x09, 0x5d, 0x66, 0x36, 0x32, + 0xb1, 0xc2, 0x59, 0x58, 0xb6, 0xe5, 0x9e, 0xa2, + 0x07, 0xf8, 0x26, 0x4a, 0x64, 0xf5, 0x16, 0x01, + 0x51, 0x8e, 0xe5, 0x4b, 0x07, 0x2c, 0x4b, 0x23, + 0xfa, 0x4e, 0x6e, 0xdb, 0x35, 0xc7, 0x1d, 0x30, + 0x42, 0xd9, 0x0f, 0xba, 0x8a, 0x69, 0x7e, 0x29, + 0xe7, 0xbd, 0x15, 0xe9, 0x35, 0x9e, 0x81, 0xe7, + 0x9e, 0xc9, 0x7d, 0x66, 0x99, 0x58, 0xec, 0x45, + 0x29, 0xd0, 0xa4, 0xfd, 0xf1, 0xe7, 0x5b, 0x3e, + 0x2a, 0x77, 0x1d, 0x8f, 0x2b, 0x73, 0xba, 0xf8, + 0x72, 0xd2, 0xa0, 0x0b, 0x90, 0xb9, 0x73, 0x9c, + 0xde, 0x3c, 0xc3, 0xb8, 0x91, 0x97, 0xc4, 0x28, + 0xfa, 0x6d, 0xa8, 0x41, 0xb6, 0x83, 0xc8, 0xaa, + + /* IV */ + 0x8a, 0x39, 0x10, 0x07, 0x02, 0x97, 0xbb, 0x1c, + 0x59, 0xb7, 0x70, 0x33, 0xa4, 0x26, 0xa2, 0xb8 + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_rfc3602_5 = { + .len = 98, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x54, 0x08, 0xf2, 0x00, 0x00, + 0x40, 0x01, 0xf9, 0xfe, 0xc0, 0xa8, 0x7b, 0x03, + 0xc0, 0xa8, 0x7b, 0x64, + + /* ICMP */ + 0x08, 0x00, 0x0e, 0xbd, 0xa7, 0x0a, 0x00, 0x00, + 0x8e, 0x9c, 0x08, 0x3d, 0xb9, 0x5b, 0x07, 0x00, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_rfc3602_5_esp = { + .len = 138, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x7c, 0x08, 0xf2, 0x00, 0x00, + 0x40, 0x32, 0xf9, 0xa5, 0xc0, 0xa8, 0x7b, 0x03, + 0xc0, 0xa8, 0x7b, 0x64, + + /* ESP */ + 0x00, 0x00, 0x43, 0x21, 0x00, 0x00, 0x00, 0x01, + + /* IV */ + 0xe9, 0x6e, 0x8c, 0x08, 0xab, 0x46, 0x57, 0x63, + 0xfd, 0x09, 0x8d, 0x45, 0xdd, 0x3f, 0xf8, 0x93, + + /* data */ + 0xf6, 0x63, 0xc2, 0x5d, 0x32, 0x5c, 0x18, 0xc6, + 0xa9, 0x45, 0x3e, 0x19, 0x4e, 0x12, 0x08, 0x49, + 0xa4, 0x87, 0x0b, 0x66, 0xcc, 0x6b, 0x99, 0x65, + 0x33, 0x00, 0x13, 0xb4, 0x89, 0x8d, 0xc8, 0x56, + 0xa4, 0x69, 0x9e, 0x52, 0x3a, 0x55, 0xdb, 0x08, + 0x0b, 0x59, 0xec, 0x3a, 0x8e, 0x4b, 0x7e, 0x52, + 0x77, 0x5b, 0x07, 0xd1, 0xdb, 0x34, 0xed, 0x9c, + 0x53, 0x8a, 0xb5, 0x0c, 0x55, 0x1b, 0x87, 0x4a, + 0xa2, 0x69, 0xad, 0xd0, 0x47, 0xad, 0x2d, 0x59, + 0x13, 0xac, 0x19, 0xb7, 0xcf, 0xba, 0xd4, 0xa6, + }, +}; + +static const ipsec_test_packet pkt_rfc3602_6 = { + .len = 62, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x30, 0x08, 0xfe, 0x00, 0x00, + 0x40, 0x01, 0xfa, 0x16, 0xc0, 0xa8, 0x7b, 0x03, + 0xc0, 0xa8, 0x7b, 0x64, + + /* ICMP */ + 0x08, 0x00, 0xb5, 0xe8, 0xa8, 0x0a, 0x05, 0x00, + 0xa6, 0x9c, 0x08, 0x3d, 0x0b, 0x66, 0x0e, 0x00, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x77, 0x77, 0x77, 0x77, + }, +}; + +static const ipsec_test_packet pkt_rfc3602_6_esp = { + .len = 90, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x4c, 0x08, 0xfe, 0x00, 0x00, + 0x40, 0x32, 0xf9, 0xc9, 0xc0, 0xa8, 0x7b, 0x03, + 0xc0, 0xa8, 0x7b, 0x64, + + /* ESP */ + 0x00, 0x00, 0x43, 0x21, 0x00, 0x00, 0x00, 0x08, + + /* IV */ + 0x69, 0xd0, 0x8d, 0xf7, 0xd2, 0x03, 0x32, 0x9d, + 0xb0, 0x93, 0xfc, 0x49, 0x24, 0xe5, 0xbd, 0x80, + + /* data */ + 0xf5, 0x19, 0x95, 0x88, 0x1e, 0xc4, 0xe0, 0xc4, + 0x48, 0x89, 0x87, 0xce, 0x74, 0x2e, 0x81, 0x09, + 0x68, 0x9b, 0xb3, 0x79, 0xd2, 0xd7, 0x50, 0xc0, + 0xd9, 0x15, 0xdc, 0xa3, 0x46, 0xa8, 0x9f, 0x75, + }, +}; + +static const ipsec_test_packet pkt_rfc3602_7 = { + .len = 98, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x54, 0x09, 0x04, 0x00, 0x00, + 0x40, 0x01, 0xf9, 0x88, 0xc0, 0xa8, 0x7b, 0x03, + 0xc0, 0xa8, 0x7b, 0xc8, + + /* ICMP */ + 0x08, 0x00, 0x9f, 0x76, 0xa9, 0x0a, 0x01, 0x00, + 0xb4, 0x9c, 0x08, 0x3d, 0x02, 0xa2, 0x04, 0x00, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + }, +}; + +static const ipsec_test_packet pkt_rfc3602_7_esp = { + .len = 154, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x8c, 0x09, 0x05, 0x00, 0x00, + 0x40, 0x32, 0xf9, 0x1e, 0xc0, 0xa8, 0x7b, 0x03, + 0xc0, 0xa8, 0x7b, 0xc8, + + /* ESP */ + 0x00, 0x00, 0x87, 0x65, 0x00, 0x00, 0x00, 0x02, + + /* IV */ + 0xf4, 0xe7, 0x65, 0x24, 0x4f, 0x64, 0x07, 0xad, + 0xf1, 0x3d, 0xc1, 0x38, 0x0f, 0x67, 0x3f, 0x37, + + /* data */ + 0x77, 0x3b, 0x52, 0x41, 0xa4, 0xc4, 0x49, 0x22, + 0x5e, 0x4f, 0x3c, 0xe5, 0xed, 0x61, 0x1b, 0x0c, + 0x23, 0x7c, 0xa9, 0x6c, 0xf7, 0x4a, 0x93, 0x01, + 0x3c, 0x1b, 0x0e, 0xa1, 0xa0, 0xcf, 0x70, 0xf8, + 0xe4, 0xec, 0xae, 0xc7, 0x8a, 0xc5, 0x3a, 0xad, + 0x7a, 0x0f, 0x02, 0x2b, 0x85, 0x92, 0x43, 0xc6, + 0x47, 0x75, 0x2e, 0x94, 0xa8, 0x59, 0x35, 0x2b, + 0x8a, 0x4d, 0x4d, 0x2d, 0xec, 0xd1, 0x36, 0xe5, + 0xc1, 0x77, 0xf1, 0x32, 0xad, 0x3f, 0xbf, 0xb2, + 0x20, 0x1a, 0xc9, 0x90, 0x4c, 0x74, 0xee, 0x0a, + 0x10, 0x9e, 0x0c, 0xa1, 0xe4, 0xdf, 0xe9, 0xd5, + 0xa1, 0x00, 0xb8, 0x42, 0xf1, 0xc2, 0x2f, 0x0d, + }, +}; + +static const ipsec_test_packet pkt_rfc3602_8 = { + .len = 82, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x44, 0x09, 0x0c, 0x00, 0x00, + 0x40, 0x01, 0xf9, 0x90, 0xc0, 0xa8, 0x7b, 0x03, + 0xc0, 0xa8, 0x7b, 0xc8, + + /* ICMP */ + 0x08, 0x00, 0xd6, 0x3c, 0xaa, 0x0a, 0x02, 0x00, + 0xc6, 0x9c, 0x08, 0x3d, 0xa3, 0xde, 0x03, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }, +}; + +static const ipsec_test_packet pkt_rfc3602_8_esp = { + .len = 138, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x7c, 0x09, 0x0d, 0x00, 0x00, + 0x40, 0x32, 0xf9, 0x26, 0xc0, 0xa8, 0x7b, 0x03, + 0xc0, 0xa8, 0x7b, 0xc8, + + /* ESP */ + 0x00, 0x00, 0x87, 0x65, 0x00, 0x00, 0x00, 0x05, + + /* IV */ + 0x85, 0xd4, 0x72, 0x24, 0xb5, 0xf3, 0xdd, 0x5d, + 0x21, 0x01, 0xd4, 0xea, 0x8d, 0xff, 0xab, 0x22, + + /* data */ + 0x15, 0xb9, 0x26, 0x83, 0x81, 0x95, 0x96, 0xa8, + 0x04, 0x72, 0x32, 0xcc, 0x00, 0xf7, 0x04, 0x8f, + 0xe4, 0x53, 0x18, 0xe1, 0x1f, 0x8a, 0x0f, 0x62, + 0xed, 0xe3, 0xc3, 0xfc, 0x61, 0x20, 0x3b, 0xb5, + 0x0f, 0x98, 0x0a, 0x08, 0xc9, 0x84, 0x3f, 0xd3, + 0xa1, 0xb0, 0x6d, 0x5c, 0x07, 0xff, 0x96, 0x39, + 0xb7, 0xeb, 0x7d, 0xfb, 0x35, 0x12, 0xe5, 0xde, + 0x43, 0x5e, 0x72, 0x07, 0xed, 0x97, 0x1e, 0xf3, + 0xd2, 0x72, 0x6d, 0x9b, 0x5e, 0xf6, 0xaf, 0xfc, + 0x6d, 0x17, 0xa0, 0xde, 0xcb, 0xb1, 0x38, 0x92, + }, +}; + +/* + * Several tests from draft-mcgrew-gcm-test-01. It was never completed as an + * RFC, but serves good purpopse anyway. + * + * Note: plaintext texts also contain ESP trailers, which we + * do not include here into plaintext packets. + */ +static const ipsec_test_packet pkt_mcgrew_gcm_test_2 = { + .len = 76, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x3e, 0x69, 0x8f, 0x00, 0x00, + 0x80, 0x11, 0x4d, 0xcc, 0xc0, 0xa8, 0x01, 0x02, + 0xc0, 0xa8, 0x01, 0x01, + + /* UDP */ + 0x0a, 0x98, 0x00, 0x35, 0x00, 0x2a, 0x23, 0x43, + 0xb2, 0xd0, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x73, 0x69, 0x70, + 0x09, 0x63, 0x79, 0x62, 0x65, 0x72, 0x63, 0x69, + 0x74, 0x79, 0x02, 0x64, 0x6b, 0x00, 0x00, 0x01, + 0x00, 0x01, + }, +}; + +static const ipsec_test_packet pkt_mcgrew_gcm_test_2_esp = { + .len = 130, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP - not a part of RFC, added for simplicity */ + 0x45, 0x00, 0x00, 0x74, 0x69, 0x8f, 0x00, 0x00, + 0x80, 0x32, 0x4d, 0x76, 0xc0, 0xa8, 0x01, 0x02, + 0xc0, 0xa8, 0x01, 0x01, + + /* ESP */ + 0x00, 0x00, 0xa5, 0xf8, 0x00, 0x00, 0x00, 0x0a, + + /* IV */ + 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88, + + /* Data */ + 0xde, 0xb2, 0x2c, 0xd9, 0xb0, 0x7c, 0x72, 0xc1, + 0x6e, 0x3a, 0x65, 0xbe, 0xeb, 0x8d, 0xf3, 0x04, + 0xa5, 0xa5, 0x89, 0x7d, 0x33, 0xae, 0x53, 0x0f, + 0x1b, 0xa7, 0x6d, 0x5d, 0x11, 0x4d, 0x2a, 0x5c, + 0x3d, 0xe8, 0x18, 0x27, 0xc1, 0x0e, 0x9a, 0x4f, + 0x51, 0x33, 0x0d, 0x0e, 0xec, 0x41, 0x66, 0x42, + 0xcf, 0xbb, 0x85, 0xa5, 0xb4, 0x7e, 0x48, 0xa4, + 0xec, 0x3b, 0x9b, 0xa9, 0x5d, 0x91, 0x8b, 0xd1, + 0x83, 0xb7, 0x0d, 0x3a, 0xa8, 0xbc, 0x6e, 0xe4, + 0xc3, 0x09, 0xe9, 0xd8, 0x5a, 0x41, 0xad, 0x4a, + }, +}; + +static const ipsec_test_packet pkt_mcgrew_gcm_test_3 = { + .len = 62, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x30, 0x69, 0xa6, 0x40, 0x00, + 0x80, 0x06, 0x26, 0x90, 0xc0, 0xa8, 0x01, 0x02, + 0x93, 0x89, 0x15, 0x5e, + + /* TCP */ + 0x0a, 0x9e, 0x00, 0x8b, 0x2d, 0xc5, 0x7e, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x02, 0x40, 0x00, + 0x20, 0xbf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, + 0x01, 0x01, 0x04, 0x02, + }, +}; + +static const ipsec_test_packet pkt_mcgrew_gcm_test_3_esp = { + .len = 118, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP - not a part of RFC, added for simplicity */ + 0x45, 0x00, 0x00, 0x68, 0x69, 0x8f, 0x00, 0x00, + 0x80, 0x32, 0x4d, 0x82, 0xc0, 0xa8, 0x01, 0x02, + 0xc0, 0xa8, 0x01, 0x01, + + /* ESP */ + 0x4a, 0x2c, 0xbf, 0xe3, 0x00, 0x00, 0x00, 0x02, + + /* IV */ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + + /* Data */ + 0xff, 0x42, 0x5c, 0x9b, 0x72, 0x45, 0x99, 0xdf, + 0x7a, 0x3b, 0xcd, 0x51, 0x01, 0x94, 0xe0, 0x0d, + 0x6a, 0x78, 0x10, 0x7f, 0x1b, 0x0b, 0x1c, 0xbf, + 0x06, 0xef, 0xae, 0x9d, 0x65, 0xa5, 0xd7, 0x63, + 0x74, 0x8a, 0x63, 0x79, 0x85, 0x77, 0x1d, 0x34, + 0x7f, 0x05, 0x45, 0x65, 0x9f, 0x14, 0xe9, 0x9d, + 0xef, 0x84, 0x2d, 0x8e, 0xb3, 0x35, 0xf4, 0xee, + 0xcf, 0xdb, 0xf8, 0x31, 0x82, 0x4b, 0x4c, 0x49, + 0x15, 0x95, 0x6c, 0x96, + }, +}; + +static const ipsec_test_packet pkt_mcgrew_gcm_test_4 = { + .len = 74, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x3c, 0x99, 0xc5, 0x00, 0x00, + 0x80, 0x01, 0xcb, 0x7a, 0x40, 0x67, 0x93, 0x18, + 0x01, 0x01, 0x01, 0x01, + + /* ICMP */ + 0x08, 0x00, 0x07, 0x5c, 0x02, 0x00, 0x44, 0x00, + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + }, +}; + +static const ipsec_test_packet pkt_mcgrew_gcm_test_4_esp = { + .len = 130, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP - not a part of RFC, added for simplicity */ + 0x45, 0x00, 0x00, 0x74, 0x69, 0x8f, 0x00, 0x00, + 0x80, 0x32, 0x4d, 0x76, 0xc0, 0xa8, 0x01, 0x02, + 0xc0, 0xa8, 0x01, 0x01, + + /* ESP */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + + /* IV */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* Data */ + 0x46, 0x88, 0xda, 0xf2, 0xf9, 0x73, 0xa3, 0x92, + 0x73, 0x29, 0x09, 0xc3, 0x31, 0xd5, 0x6d, 0x60, + 0xf6, 0x94, 0xab, 0xaa, 0x41, 0x4b, 0x5e, 0x7f, + 0xf5, 0xfd, 0xcd, 0xff, 0xf5, 0xe9, 0xa2, 0x84, + 0x45, 0x64, 0x76, 0x49, 0x27, 0x19, 0xff, 0xb6, + 0x4d, 0xe7, 0xd9, 0xdc, 0xa1, 0xe1, 0xd8, 0x94, + 0xbc, 0x3b, 0xd5, 0x78, 0x73, 0xed, 0x4d, 0x18, + 0x1d, 0x19, 0xd4, 0xd5, 0xc8, 0xc1, 0x8a, 0xf3, + 0xf8, 0x21, 0xd4, 0x96, 0xee, 0xb0, 0x96, 0xe9, + 0x8a, 0xd2, 0xb6, 0x9e, 0x47, 0x99, 0xc7, 0x1d, + }, +}; + +static const ipsec_test_packet pkt_mcgrew_gcm_test_12 = { + .len = 14, + .l2_offset = 0, + .l3_offset = ODP_PACKET_OFFSET_INVALID, + .l4_offset = ODP_PACKET_OFFSET_INVALID, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + }, +}; + +static const ipsec_test_packet pkt_mcgrew_gcm_test_12_esp = { + .len = 70, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP - not a part of RFC, added for simplicity */ + 0x45, 0x00, 0x00, 0x38, 0x69, 0x8f, 0x00, 0x00, + 0x80, 0x32, 0x4d, 0xb2, 0xc0, 0xa8, 0x01, 0x02, + 0xc0, 0xa8, 0x01, 0x01, + + /* ESP */ + 0x33, 0x54, 0x67, 0xae, 0xff, 0xff, 0xff, 0xff, + + /* IV */ + 0x43, 0x45, 0x7e, 0x91, 0x82, 0x44, 0x3b, 0xc6, + + /* Data */ + 0x43, 0x7f, 0x86, 0x6b, 0xcb, 0x3f, 0x69, 0x9f, + 0xe9, 0xb0, 0x82, 0x2b, 0xac, 0x96, 0x1c, 0x45, + 0x04, 0xbe, 0xf2, 0x70, + }, +}; + +#endif diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile.am index 4be5d94e9..b637c8b48 100644 --- a/test/linux-generic/Makefile.am +++ b/test/linux-generic/Makefile.am @@ -21,7 +21,10 @@ TESTS = validation/api/pktio/pktio_run.sh \ $(ALL_API_VALIDATION_DIR)/init/init_main_ok$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/init/init_main_abort$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/init/init_main_log$(EXEEXT) \ - $(ALL_API_VALIDATION_DIR)/ipsec/ipsec_main$(EXEEXT) \ + $(ALL_API_VALIDATION_DIR)/ipsec/ipsec_sync$(EXEEXT) \ + $(ALL_API_VALIDATION_DIR)/ipsec/ipsec_async$(EXEEXT) \ + $(ALL_API_VALIDATION_DIR)/ipsec/ipsec_inline_in$(EXEEXT) \ + $(ALL_API_VALIDATION_DIR)/ipsec/ipsec_inline_out$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/lock/lock_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/packet/packet_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/pool/pool_main$(EXEEXT) \ From patchwork Mon Sep 25 22:00:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 114190 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp3112012qgf; Mon, 25 Sep 2017 15:11:06 -0700 (PDT) X-Google-Smtp-Source: AOwi7QCx/sGSpPAoA0rmXgrzB2mdgvHApL5pupbHR8qdBz5hi4/c9x2PrgkqeoViQLfIrLLpY8vZ X-Received: by 10.36.82.145 with SMTP id d139mr2816149itb.86.1506377466709; Mon, 25 Sep 2017 15:11:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506377466; cv=none; d=google.com; s=arc-20160816; b=LyfOHmUOS7x/MW+p4z4htzd8n9MzWPBej9OPYuO2qWETZvuT49gUPnKjqNQNInQgbg f7vP5vcIFonr+L0ZWlDs1YVPPKK4OlhzRo8a8G35w43tWH8ZoOa0zvGF6AtUsM2EBmci dSfLJFzNWkECXzp4eNZDyxlWGAHfVQwsHQdDLsM5NoTKNn5un+yYDZmUfcqGaVroZzs7 BXavIIXfZXlRqI6ra3CNwOq/6CHdRSU1z07HEPxTTLX7j8tuc/H1FIxmJIlGaC2G2pUR XYfHubHBCxWEhO3fqLNDOOmPaBO4NIgkka8JLUOIklZ6OxpNDs67gTrQv0hg7sbLa+s7 QsDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=9wrhiOWUC1whT8eJklsm+ztgzEJuqt/Hs8H6VDoqr68=; b=MOO+YOZZs4qOnMj6LLob6l/Ots87YSUvQFAkGsJiwOMWbGBZD+bhqyITN8KLzWKJ8F /ecGPFDoW+4HI8ooeqmuc2gnWsCKdaGIlLJuMK5Z482kBbasKK1magAJK1aD/iwXIIWb FSDHyRAdOGkmSapKobHTCvKZie5fjXeTQsS+p6u8o14aEWLBeFUED3z1XQQ6VIlkQ3mt kBUuZsoxljnRhUa+RlLu1v72mpAZ8D8HW78+fU0QiaZFVlgHhFgwuqrMNpf8VKHvqb3Z g2CjbSQA5WgmS/1ZvlI8cAkP0i1jVP5WZGD6S/YYfHtD14Ne5rVOUR8pzIuQm5r9LUbo srxQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id a198si437349itc.70.2017.09.25.15.11.06; Mon, 25 Sep 2017 15:11:06 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id 2418560D79; Mon, 25 Sep 2017 22:11:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id D783960CA0; Mon, 25 Sep 2017 22:02:42 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 45C2A60BDB; Mon, 25 Sep 2017 22:02:28 +0000 (UTC) Received: from forward101o.mail.yandex.net (forward101o.mail.yandex.net [37.140.190.181]) by lists.linaro.org (Postfix) with ESMTPS id C509E60BE3 for ; Mon, 25 Sep 2017 22:01:03 +0000 (UTC) Received: from mxback1g.mail.yandex.net (mxback1g.mail.yandex.net [IPv6:2a02:6b8:0:1472:2741:0:8b7:162]) by forward101o.mail.yandex.net (Yandex) with ESMTP id 4BA551343A11 for ; Tue, 26 Sep 2017 01:01:02 +0300 (MSK) Received: from smtp2o.mail.yandex.net (smtp2o.mail.yandex.net [2a02:6b8:0:1a2d::26]) by mxback1g.mail.yandex.net (nwsmtp/Yandex) with ESMTP id eCviJh4cLY-0cQahepT; Tue, 26 Sep 2017 01:00:38 +0300 Received: by smtp2o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id y0gxWEywlF-0b4KrL4Q; Tue, 26 Sep 2017 01:00:37 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 26 Sep 2017 01:00:20 +0300 Message-Id: <1506376827-27848-3-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> References: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 81 Subject: [lng-odp] [PATCH API-NEXT v19 2/9] linux-gen: pktio: loop: support IPsec outbound inline X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Dmitry Eremin-Solenikov Add support for outbound inline IPsec packet processing on loop interface. Signed-off-by: Dmitry Eremin-Solenikov --- /** Email created from pull request 81 (lumag:ipsec-packet-impl-2) ** https://github.com/Linaro/odp/pull/81 ** Patch: https://github.com/Linaro/odp/pull/81.patch ** Base sha: 13322ca632f8ffba292bec058e597719bc54142d ** Merge commit sha: 04f37d8f29d26df3744151a85a19ef9b55b3d1f7 **/ platform/linux-generic/pktio/loop.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index 428b6cebd..6cc86e6af 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -164,6 +164,22 @@ static int loopback_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED, bytes += odp_packet_len(pkt_tbl[i]); } + if (pktio_entry->s.config.outbound_ipsec) + for (i = 0; i < len; ++i) { + odp_buffer_t buf = buf_from_buf_hdr(hdr_tbl[i]); + odp_ipsec_packet_result_t result; + + if (_odp_buffer_event_subtype(buf) != + ODP_EVENT_PACKET_IPSEC) + continue; + + /* Possibly postprocessing packet */ + odp_ipsec_result(&result, pkt_tbl[i]); + + _odp_buffer_event_subtype_set(buf, + ODP_EVENT_PACKET_BASIC); + } + odp_ticketlock_lock(&pktio_entry->s.txl); queue = queue_fn->from_ext(pktio_entry->s.pkt_loop.loopq); @@ -213,6 +229,8 @@ static int loopback_capability(pktio_entry_t *pktio_entry ODP_UNUSED, odp_pktio_config_init(&capa->config); capa->config.pktin.bit.ts_all = 1; capa->config.pktin.bit.ts_ptp = 1; + capa->config.outbound_ipsec = 1; + return 0; } From patchwork Mon Sep 25 22:00:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 114191 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp3114526qgf; Mon, 25 Sep 2017 15:14:04 -0700 (PDT) X-Google-Smtp-Source: AOwi7QDvxzfSdos9flSB5qXxguRNgq/qpcTX8ATVhVGau43ddWyMlenj9ss8oshhL3GE9l4fvcJv X-Received: by 10.36.98.10 with SMTP id d10mr2711153itc.110.1506377644239; Mon, 25 Sep 2017 15:14:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506377644; cv=none; d=google.com; s=arc-20160816; b=KP++Z05o5GSIQ+mrhAwnJlvU6BUGgNUcrsM3fH1t6uxIHUyvNbgjUcCDOG1ZsUIFY+ ZIoWXXviBEqDTzZ68jnpdSOg+6p09ZckJefjznsAJqmgMDnDVwMpWGCpmnrLmbloxtMg jHPOuVKCpevcrPitCjf34YCl3uUMGNf9v1euXu8Rlp5H79uSIiVojeqn5Qj1/4R3PuBm VwV8h3KA+5aLqNo4fyq4C3R6kbwNrNf7iNeQiBesdNJPjPqtX6+MxStWoqE+KdSbzyZV 9i/0TSYwYLq7fEb28jOMSyMwQszy8PfVg3Hex4fr6gZlgPHFWR3z0wr9FMcL+x1erTG4 1IjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=iD9NiRrdvA8uuTlNQkHdBFEs9bsl6SOF++xrdPy7r3Q=; b=CM8yH4KcIEJe5zIg8pejitl0rsxXa3Mb2/K85UrNNlbeLkDgZj3lscKkWBTBVy6/qP T4U0gxM0NxzxryEOgFb559fwy7CIJ38PW972wQKaz/NoZGiKjqW/GrnYpaP5qrv+f+4T JkgFCR5fK49L162YlE3QQW0EGfswetnMmzvw9pz8JZdh0EKvU+4n0R1kBYxNVSNneYov YjdUNpwcoDIbGOkP/tVO2XmpSn4RXUteqwegVj3Yhuf150ZyWRP5P6XK2dd9uQfqWuRF cWVo6jGoGWZvdFQ9CHlP1fE0Xm7mQr9XDSwhSG2l7kVDMs6eUmgqa9gjRaXqO79WiLPN 3CjQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id u186si462885itc.9.2017.09.25.15.14.03; Mon, 25 Sep 2017 15:14:04 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id B306B60D3D; Mon, 25 Sep 2017 22:14:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 722B460CD1; Mon, 25 Sep 2017 22:02:52 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id E919660CD1; Mon, 25 Sep 2017 22:02:48 +0000 (UTC) Received: from forward104o.mail.yandex.net (forward104o.mail.yandex.net [37.140.190.179]) by lists.linaro.org (Postfix) with ESMTPS id EBAF7607F1 for ; Mon, 25 Sep 2017 22:01:03 +0000 (UTC) Received: from mxback12j.mail.yandex.net (mxback12j.mail.yandex.net [IPv6:2a02:6b8:0:1619::87]) by forward104o.mail.yandex.net (Yandex) with ESMTP id DF6E6703756 for ; Tue, 26 Sep 2017 01:01:02 +0300 (MSK) Received: from smtp2o.mail.yandex.net (smtp2o.mail.yandex.net [2a02:6b8:0:1a2d::26]) by mxback12j.mail.yandex.net (nwsmtp/Yandex) with ESMTP id RlQco5qLVA-12oqT6fO; Tue, 26 Sep 2017 01:01:02 +0300 Received: by smtp2o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id y0gxWEywlF-124Odidc; Tue, 26 Sep 2017 01:01:02 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 26 Sep 2017 01:00:21 +0300 Message-Id: <1506376827-27848-4-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> References: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 81 Subject: [lng-odp] [PATCH API-NEXT v19 3/9] linux-gen: pktio: loop: support IPsec inbound inline X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Dmitry Eremin-Solenikov Add support for inbound inline IPsec packet processing on loop interface. Signed-off-by: Dmitry Eremin-Solenikov --- /** Email created from pull request 81 (lumag:ipsec-packet-impl-2) ** https://github.com/Linaro/odp/pull/81 ** Patch: https://github.com/Linaro/odp/pull/81.patch ** Base sha: 13322ca632f8ffba292bec058e597719bc54142d ** Merge commit sha: 04f37d8f29d26df3744151a85a19ef9b55b3d1f7 **/ platform/linux-generic/pktio/loop.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index 6cc86e6af..1b36034fd 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -135,6 +135,13 @@ static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, packet_set_ts(pkt_hdr, ts); pkt_hdr->input = pktio_entry->s.handle; + + /* Try IPsec inline processing */ + if (pktio_entry->s.config.inbound_ipsec && + odp_packet_has_ipsec(pkt) && + _odp_ipsec_try_inline(pkt) == 0) + continue; + pktio_entry->s.stats.in_octets += pkt_len; pkts[num_rx++] = pkt; } @@ -229,6 +236,7 @@ static int loopback_capability(pktio_entry_t *pktio_entry ODP_UNUSED, odp_pktio_config_init(&capa->config); capa->config.pktin.bit.ts_all = 1; capa->config.pktin.bit.ts_ptp = 1; + capa->config.inbound_ipsec = 1; capa->config.outbound_ipsec = 1; return 0; From patchwork Mon Sep 25 22:00:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 114192 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp3115356qgf; Mon, 25 Sep 2017 15:15:06 -0700 (PDT) X-Google-Smtp-Source: AOwi7QAkxFg2SHge9kItSR7kTIlIlEf9scKDrM9DQgtt5OEZj4YRsglKShpJIUtfpXXr9HEoYE7I X-Received: by 10.107.81.10 with SMTP id f10mr11067447iob.22.1506377706229; Mon, 25 Sep 2017 15:15:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506377706; cv=none; d=google.com; s=arc-20160816; b=d/Fp5tWE8aBcvRXuXR8p9kgu1+5lb2l7G3fKfxUDYZ5z72Ys0iWVR1RLE2OVlXa3dp n9yJ268ObMbKWbJvpdE45aeZXKjJgNZE+0RCvNl4T2HrmaPljKZ1fyK4EpQqlVQ2wubM nuy6DQ9h5icXy8LQ4Ylz5vLUsm7D5QQ+ZX9effmyTQLtz0FUy5OAmSMi3Kr7ufgItavz d1HTSrtcS5KruHSWUxVDALmf6tP9qfS/mIyTqA/+mocmxk4VrY//q3m3cAvlVC0Iu7Lv SaKEaTOiDa79GrX2+5FEAcbbWIjRd+aguf+0p9vaBec66J1EomatU10bp2fHPZ1uyzv2 li7g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=OyFL7CGh8swSCwsxtSVGsWHDevLVKUDFSd5U0i1Hfb0=; b=MzQw3ju0B9dR9ZJcExI/KJSih5K0g7QCtfpO4TP5EoZ1+mQxw4M8/Quc6un2nfR7WP 4DC0vdrh6MvrWLxf74F7+1m7oGKuCuN1qtQ3UY7Du3a545F9cGnJM2InNhoXxq80A8Xa LoxZTW9wt0kZqhvC+a2UBa4N64+8hMuVcH4TNC16EeUxhE5FJqUqn5+rdBwix9deq4VA 49GYyiQk9jT6MBOYLlKEUMOmUQKi6WAqmXAjtDdjvO92i7TCLga4w9m9iJTY6k5M11RJ zduHh2AVwJSnODC7a322HNRSyz8aHjEK/Y3uAzvuYbkLzTJodOrEGkxf/vuoPQ7zWhJn +dLA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id s64si442757its.19.2017.09.25.15.15.05; Mon, 25 Sep 2017 15:15:06 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id A6B5E60D2D; Mon, 25 Sep 2017 22:15:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 0534660A59; Mon, 25 Sep 2017 22:03:32 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 559D360B59; Mon, 25 Sep 2017 22:03:26 +0000 (UTC) Received: from forward106j.mail.yandex.net (forward106j.mail.yandex.net [5.45.198.249]) by lists.linaro.org (Postfix) with ESMTPS id A0F776067D for ; Mon, 25 Sep 2017 22:01:28 +0000 (UTC) Received: from mxback1j.mail.yandex.net (mxback1j.mail.yandex.net [IPv6:2a02:6b8:0:1619::10a]) by forward106j.mail.yandex.net (Yandex) with ESMTP id 6F2CD1803848 for ; Tue, 26 Sep 2017 01:01:27 +0300 (MSK) Received: from smtp2o.mail.yandex.net (smtp2o.mail.yandex.net [2a02:6b8:0:1a2d::26]) by mxback1j.mail.yandex.net (nwsmtp/Yandex) with ESMTP id 8cLGkJfMJ2-13ruaAF8; Tue, 26 Sep 2017 01:01:03 +0300 Received: by smtp2o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id y0gxWEywlF-124eG8wu; Tue, 26 Sep 2017 01:01:03 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 26 Sep 2017 01:00:22 +0300 Message-Id: <1506376827-27848-5-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> References: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 81 Subject: [lng-odp] [PATCH API-NEXT v19 4/9] linux-gen: packet: factor out L2 header parsing X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Dmitry Eremin-Solenikov Function parse_packet_common() now becomes just a multiplexer calling other low-level parsing functions. Signed-off-by: Dmitry Eremin-Solenikov --- /** Email created from pull request 81 (lumag:ipsec-packet-impl-2) ** https://github.com/Linaro/odp/pull/81 ** Patch: https://github.com/Linaro/odp/pull/81.patch ** Base sha: 13322ca632f8ffba292bec058e597719bc54142d ** Merge commit sha: 04f37d8f29d26df3744151a85a19ef9b55b3d1f7 **/ platform/linux-generic/odp_packet.c | 139 ++++++++++++++++++++---------------- 1 file changed, 77 insertions(+), 62 deletions(-) diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index ff0cb8fe5..515a5e169 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -1794,6 +1794,78 @@ int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt) return dsthdr->buf_hdr.uarea_size < srchdr->buf_hdr.uarea_size; } +/** Parser helper function for Ethernet packets */ +static inline uint16_t parse_eth(packet_parser_t *prs, const uint8_t **parseptr, + uint32_t *offset, uint32_t frame_len) +{ + uint16_t ethtype; + const _odp_ethhdr_t *eth; + uint16_t macaddr0, macaddr2, macaddr4; + const _odp_vlanhdr_t *vlan; + + /* Detect jumbo frames */ + if (frame_len > _ODP_ETH_LEN_MAX) + prs->input_flags.jumbo = 1; + + eth = (const _odp_ethhdr_t *)*parseptr; + + /* Handle Ethernet broadcast/multicast addresses */ + macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); + prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; + + if (macaddr0 == 0xffff) { + macaddr2 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 1)); + macaddr4 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 2)); + prs->input_flags.eth_bcast = + (macaddr2 == 0xffff) && (macaddr4 == 0xffff); + } else { + prs->input_flags.eth_bcast = 0; + } + + /* Get Ethertype */ + ethtype = odp_be_to_cpu_16(eth->type); + *offset += sizeof(*eth); + *parseptr += sizeof(*eth); + + /* Check for SNAP vs. DIX */ + if (ethtype < _ODP_ETH_LEN_MAX) { + prs->input_flags.snap = 1; + if (ethtype > frame_len - *offset) { + prs->error_flags.snap_len = 1; + return 0; + } + ethtype = odp_be_to_cpu_16(*((const uint16_t *)(uintptr_t) + (parseptr + 6))); + *offset += 8; + *parseptr += 8; + } + + /* Parse the VLAN header(s), if present */ + if (ethtype == _ODP_ETHTYPE_VLAN_OUTER) { + prs->input_flags.vlan_qinq = 1; + prs->input_flags.vlan = 1; + + vlan = (const _odp_vlanhdr_t *)*parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + *offset += sizeof(_odp_vlanhdr_t); + *parseptr += sizeof(_odp_vlanhdr_t); + } + + if (ethtype == _ODP_ETHTYPE_VLAN) { + prs->input_flags.vlan = 1; + vlan = (const _odp_vlanhdr_t *)*parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + *offset += sizeof(_odp_vlanhdr_t); + *parseptr += sizeof(_odp_vlanhdr_t); + } + + return ethtype; +} + /** * Parser helper function for IPv4 */ @@ -1948,9 +2020,9 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, uint16_t ethtype; const uint8_t *parseptr; uint8_t ip_proto; - const _odp_ethhdr_t *eth; - uint16_t macaddr0, macaddr2, macaddr4; - const _odp_vlanhdr_t *vlan; + + parseptr = ptr; + offset = 0; if (layer == ODP_PKTIO_PARSER_LAYER_NONE) return 0; @@ -1959,65 +2031,8 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, prs->input_flags.eth = 1; /* Assume valid L2 header, no CRC/FCS check in SW */ prs->input_flags.l2 = 1; - /* Detect jumbo frames */ - if (frame_len > _ODP_ETH_LEN_MAX) - prs->input_flags.jumbo = 1; - - offset = sizeof(_odp_ethhdr_t); - eth = (const _odp_ethhdr_t *)ptr; - /* Handle Ethernet broadcast/multicast addresses */ - macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); - prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; - - if (macaddr0 == 0xffff) { - macaddr2 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 1)); - macaddr4 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 2)); - prs->input_flags.eth_bcast = - (macaddr2 == 0xffff) && (macaddr4 == 0xffff); - } else { - prs->input_flags.eth_bcast = 0; - } - - /* Get Ethertype */ - ethtype = odp_be_to_cpu_16(eth->type); - parseptr = (const uint8_t *)(eth + 1); - - /* Check for SNAP vs. DIX */ - if (ethtype < _ODP_ETH_LEN_MAX) { - prs->input_flags.snap = 1; - if (ethtype > frame_len - offset) { - prs->error_flags.snap_len = 1; - goto parse_exit; - } - ethtype = odp_be_to_cpu_16(*((const uint16_t *)(uintptr_t) - (parseptr + 6))); - offset += 8; - parseptr += 8; - } - - /* Parse the VLAN header(s), if present */ - if (ethtype == _ODP_ETHTYPE_VLAN_OUTER) { - prs->input_flags.vlan_qinq = 1; - prs->input_flags.vlan = 1; - - vlan = (const _odp_vlanhdr_t *)parseptr; - ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } - - if (ethtype == _ODP_ETHTYPE_VLAN) { - prs->input_flags.vlan = 1; - vlan = (const _odp_vlanhdr_t *)parseptr; - ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } + ethtype = parse_eth(prs, &parseptr, &offset, frame_len); if (layer == ODP_PKTIO_PARSER_LAYER_L2) return prs->error_flags.all != 0; @@ -2099,7 +2114,7 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, prs->l4_offset = ODP_PACKET_OFFSET_INVALID; break; } -parse_exit: + return prs->error_flags.all != 0; } From patchwork Mon Sep 25 22:00:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 114193 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp3116026qgf; Mon, 25 Sep 2017 15:15:59 -0700 (PDT) X-Google-Smtp-Source: AOwi7QDjQXyJSWDF+4z4F0hGKk2fS804BgabrqD7gRNvGmYc67aOW0Ec7esPblAPQgnWEqrkd4iR X-Received: by 10.107.181.196 with SMTP id e187mr11515108iof.178.1506377758956; Mon, 25 Sep 2017 15:15:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506377758; cv=none; d=google.com; s=arc-20160816; b=hVYU92zhA8sogOWbPNECOpeD9mIlOCUWc2Q7B9gzKZ2k0KFPCfskms9DSy84GYg1nd srU4Vc40hOIDfhzfXEZ9hcReUZK3sRSA/haUidMYM7cc9lbs0xbFEoeVqQ2olSTFO7QM sGkR81EknbUR1IXSHQh46nSYL/89Iox/lKta8FffKbHZQDkqUGPcZlSkZSJ+1VvMR6kf Bgs5OhyJbQMN7kNSSTDmk0iTGkVuuzWBsYJYjtkrCm0PWUIr5mChS7LQQiUvvdFsA159 CLFjLZR6ODsgPdTfJbDS8982U8hTV3Je+YR57447TZFC4QT22RC1Jd204jBt9oQ7gnmn FBvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=7uB44XJzvGvfZd7ojKHRO0HxZ5QXvRSb4gfZaxKHOFw=; b=alSczguThBGWOsQ6lWdHflVX05ojahOprOJ9HcIkNzmUD3Sbhvw9gNxUJISv6sQwO0 ak4bcULbtYarzxfzsTlI/Xeb3Xdfjy52ZRRiBUi3rr0YVB8xVYAzPqIiIrsiv6yQrer9 tFl7fDiTb6MjhJr6y5f4AvxF5sh1SrsFIS1p1WXA6ZkXr9aGWzcDDc0HTdDZMDGy4uBf Zc/HWDf46xTrQUztQtDWYns7p0tgU6/6uUf8+ROWV4mX1EQn4G8JOU80lW8wupwqu96I 0xn3iwrbE4S4KCSEEYXYP9XBfx29cSEwaSUIZl5z/UomrFD5f7D6obTax8+7sOaRVdvU 3nwQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id t125si423927itg.166.2017.09.25.15.15.55; Mon, 25 Sep 2017 15:15:58 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id AF6BE60B59; Mon, 25 Sep 2017 22:15:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 49FB360AF4; Mon, 25 Sep 2017 22:03:36 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id D4AEE607E6; Mon, 25 Sep 2017 22:03:26 +0000 (UTC) Received: from forward106p.mail.yandex.net (forward106p.mail.yandex.net [77.88.28.109]) by lists.linaro.org (Postfix) with ESMTPS id 828D06071B for ; Mon, 25 Sep 2017 22:01:29 +0000 (UTC) Received: from mxback18j.mail.yandex.net (mxback18j.mail.yandex.net [IPv6:2a02:6b8:0:1619::94]) by forward106p.mail.yandex.net (Yandex) with ESMTP id 065B52D83959 for ; Tue, 26 Sep 2017 01:01:28 +0300 (MSK) Received: from smtp2o.mail.yandex.net (smtp2o.mail.yandex.net [2a02:6b8:0:1a2d::26]) by mxback18j.mail.yandex.net (nwsmtp/Yandex) with ESMTP id aUiPcOoGZI-1R4eHgRV; Tue, 26 Sep 2017 01:01:27 +0300 Received: by smtp2o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id y0gxWEywlF-1R4OOiUh; Tue, 26 Sep 2017 01:01:27 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 26 Sep 2017 01:00:23 +0300 Message-Id: <1506376827-27848-6-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> References: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 81 Subject: [lng-odp] [PATCH API-NEXT v19 5/9] linux-gen: packet: support parsing of just L3/L4 headers X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Dmitry Eremin-Solenikov IPsec packet postprocessing needs parsing of packets which guarantee only L3/L4 headers. Separate parsing function doing L3/L4 headers parsing. Signed-off-by: Dmitry Eremin-Solenikov --- /** Email created from pull request 81 (lumag:ipsec-packet-impl-2) ** https://github.com/Linaro/odp/pull/81 ** Patch: https://github.com/Linaro/odp/pull/81.patch ** Base sha: 13322ca632f8ffba292bec058e597719bc54142d ** Merge commit sha: 04f37d8f29d26df3744151a85a19ef9b55b3d1f7 **/ .../linux-generic/include/odp_packet_internal.h | 6 ++ platform/linux-generic/odp_packet.c | 83 +++++++++++++++------- 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 097264236..e29e7e85f 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -279,6 +279,12 @@ int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, odp_pktio_parser_layer_t layer); +/* Perform L3 and L4 parsing up to a given protocol layer */ +int packet_parse_l3_l4(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer, + uint32_t l3_offset, + uint16_t ethtype); + /* Reset parser metadata for a new parse */ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr); diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 515a5e169..2208614c6 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -330,7 +330,7 @@ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) pkt_hdr->p.error_flags.all = 0; pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; - pkt_hdr->p.l2_offset = 0; + pkt_hdr->p.l2_offset = ODP_PACKET_OFFSET_INVALID; pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID; pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID; } @@ -2006,35 +2006,16 @@ static inline void parse_udp(packet_parser_t *prs, *parseptr += sizeof(_odp_udphdr_t); } -/** - * Parse common packet headers up to given layer - * - * The function expects at least PACKET_PARSE_SEG_LEN bytes of data to be - * available from the ptr. - */ -int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, - uint32_t frame_len, uint32_t seg_len, - odp_pktio_parser_layer_t layer) +static inline +int packet_parse_common_l3_l4(packet_parser_t *prs, const uint8_t *parseptr, + uint32_t offset, + uint32_t frame_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer, + uint16_t ethtype) { - uint32_t offset; - uint16_t ethtype; - const uint8_t *parseptr; uint8_t ip_proto; - parseptr = ptr; - offset = 0; - - if (layer == ODP_PKTIO_PARSER_LAYER_NONE) - return 0; - - /* We only support Ethernet for now */ - prs->input_flags.eth = 1; - /* Assume valid L2 header, no CRC/FCS check in SW */ - prs->input_flags.l2 = 1; - - ethtype = parse_eth(prs, &parseptr, &offset, frame_len); - - if (layer == ODP_PKTIO_PARSER_LAYER_L2) + if (layer <= ODP_PKTIO_PARSER_LAYER_L2) return prs->error_flags.all != 0; /* Set l3_offset+flag only for known ethtypes */ @@ -2119,6 +2100,38 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, } /** + * Parse common packet headers up to given layer + * + * The function expects at least PACKET_PARSE_SEG_LEN bytes of data to be + * available from the ptr. + */ +int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, + uint32_t frame_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer) +{ + uint32_t offset; + uint16_t ethtype; + const uint8_t *parseptr; + + parseptr = ptr; + offset = 0; + + if (layer == ODP_PKTIO_PARSER_LAYER_NONE) + return 0; + + /* Assume valid L2 header, no CRC/FCS check in SW */ + prs->l2_offset = offset; + prs->input_flags.l2 = 1; + /* We only support Ethernet for now */ + prs->input_flags.eth = 1; + + ethtype = parse_eth(prs, &parseptr, &offset, frame_len); + + return packet_parse_common_l3_l4(prs, parseptr, offset, frame_len, + seg_len, layer, ethtype); +} + +/** * Simple packet parser */ int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, @@ -2131,6 +2144,22 @@ int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, seg_len, layer); } +int packet_parse_l3_l4(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer, + uint32_t l3_offset, + uint16_t ethtype) +{ + uint32_t seg_len = 0; + void *base = packet_map(pkt_hdr, l3_offset, &seg_len, NULL); + + if (seg_len == 0) + return -1; + + return packet_parse_common_l3_l4(&pkt_hdr->p, base, l3_offset, + pkt_hdr->frame_len, seg_len, + layer, ethtype); +} + uint64_t odp_packet_to_u64(odp_packet_t hdl) { return _odp_pri(hdl); From patchwork Mon Sep 25 22:00:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 114198 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp3119955qgf; Mon, 25 Sep 2017 15:20:23 -0700 (PDT) X-Google-Smtp-Source: AOwi7QB5ucgACnO4qb1+A29p6Vll7TL3I7pp3HKj84H3PDkNformIkq98HKkOTG4eQ+/vAyi+Z5p X-Received: by 10.107.27.149 with SMTP id b143mr10989223iob.2.1506378023593; Mon, 25 Sep 2017 15:20:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506378023; cv=none; d=google.com; s=arc-20160816; b=tq8qMe7sd66zh4gYLQ3yupXFskvu+As9oD+aV1UclLL9JorWdpwojILTGQombCzgTo JqryL+5Npw2LJ9KrVuLKQymlUqJ6dtgP6cE6MxkuQqOrwR6MExdXMclgb7xEjsrm0uVF g/epkO6vSlnS7OxM8PQv85SyqtMzzA7GROzsDqHmqpVnEyjWye0dAp/dRv+jg7Fkdrl0 fWQp6Mr3R+QZbucw4xQMVTfSkFwbw3xPTw+z08M6uXAQqVhftQp65pPA1QuISo05psfW TqbFPrdF2S4dDhrt/Ri7EhyE1BlSx4PvWiflwrVcQ1BAKMHUvWFkfKyBdyaTLBOvTxUt Hhew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=WNBKIPG05D3AYWRFZK7w2mBD2SLVzTFy2cxKUmhxoIU=; b=D6jOGU+oxDBB4o0JIDtxgwo3R/fi6WeQCADtEjwLR46K5/pFjrbKUYoZRdQa/hkv/P 9d4ZFReZQ1HLJvDgmnPEUtrkFFaKbysnSQ9xOA64XMTmvRO7vrVbeNJ05a+G+VbuXFcS rbRQx2H5lEbCqD5cE9L7sLCXge5nyN+M0TRIY0cSD538nlKmNc9WOumyz+NifmSr3Xjg oTl8wp/E8jS8sl3QuVC7dqIZy0NOeGSMHolIGhRtylpzBFPvXXQZWyqEUysvxP1gwIxk 6zjbOuG42wy9dNcJgR0OjzkzA++LqlA/ejojqS16geaztHU+VhXcfC2Nh2+DvjuQRRKh pC7w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id j141si6112349ioe.277.2017.09.25.15.20.23; Mon, 25 Sep 2017 15:20:23 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id 18B4660CDE; Mon, 25 Sep 2017 22:20:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 348ED60D2C; Mon, 25 Sep 2017 22:04:11 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 8092360A4A; Mon, 25 Sep 2017 22:04:02 +0000 (UTC) Received: from forward104p.mail.yandex.net (forward104p.mail.yandex.net [77.88.28.107]) by lists.linaro.org (Postfix) with ESMTPS id 5B88B60A4A for ; Mon, 25 Sep 2017 22:01:35 +0000 (UTC) Received: from mxback3g.mail.yandex.net (mxback3g.mail.yandex.net [IPv6:2a02:6b8:0:1472:2741:0:8b7:164]) by forward104p.mail.yandex.net (Yandex) with ESMTP id AB444180D38 for ; Tue, 26 Sep 2017 01:01:28 +0300 (MSK) Received: from smtp2o.mail.yandex.net (smtp2o.mail.yandex.net [2a02:6b8:0:1a2d::26]) by mxback3g.mail.yandex.net (nwsmtp/Yandex) with ESMTP id D2sFigKpAZ-1SjucAWT; Tue, 26 Sep 2017 01:01:28 +0300 Received: by smtp2o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id y0gxWEywlF-1S4mm8qY; Tue, 26 Sep 2017 01:01:28 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 26 Sep 2017 01:00:24 +0300 Message-Id: <1506376827-27848-7-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> References: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 81 Subject: [lng-odp] [PATCH API-NEXT v19 6/9] linux-gen: packet: add support for IP-in-IP (RFC 2003) encap X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Dmitry Eremin-Solenikov Don't barf on IP-in-IP packets parsing, just ignore L4 (=L3) header. Signed-off-by: Dmitry Eremin-Solenikov --- /** Email created from pull request 81 (lumag:ipsec-packet-impl-2) ** https://github.com/Linaro/odp/pull/81 ** Patch: https://github.com/Linaro/odp/pull/81.patch ** Base sha: 13322ca632f8ffba292bec058e597719bc54142d ** Merge commit sha: 04f37d8f29d26df3744151a85a19ef9b55b3d1f7 **/ platform/linux-generic/include/protocols/ip.h | 1 + platform/linux-generic/odp_packet.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/platform/linux-generic/include/protocols/ip.h b/platform/linux-generic/include/protocols/ip.h index 2b34a753f..0fc391abe 100644 --- a/platform/linux-generic/include/protocols/ip.h +++ b/platform/linux-generic/include/protocols/ip.h @@ -158,6 +158,7 @@ typedef struct ODP_PACKED { * @{*/ #define _ODP_IPPROTO_HOPOPTS 0x00 /**< IPv6 hop-by-hop options */ #define _ODP_IPPROTO_ICMPv4 0x01 /**< Internet Control Message Protocol (1) */ +#define _ODP_IPPROTO_IPIP 0x04 /**< IP Encapsulation within IP (4) */ #define _ODP_IPPROTO_TCP 0x06 /**< Transmission Control Protocol (6) */ #define _ODP_IPPROTO_UDP 0x11 /**< User Datagram Protocol (17) */ #define _ODP_IPPROTO_ROUTE 0x2B /**< IPv6 Routing header (43) */ diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 2208614c6..cc8af211e 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -2062,6 +2062,10 @@ int packet_parse_common_l3_l4(packet_parser_t *prs, const uint8_t *parseptr, prs->input_flags.icmp = 1; break; + case _ODP_IPPROTO_IPIP: + /* Do nothing */ + break; + case _ODP_IPPROTO_TCP: if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) return -1; From patchwork Mon Sep 25 22:00:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 114194 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp3116742qgf; Mon, 25 Sep 2017 15:16:43 -0700 (PDT) X-Google-Smtp-Source: AOwi7QBNnVeC8iT78DkrxqXegilRf8dWk4RHHoCaaeO9u03vE7XcIq2y8Nx+IBLyBCG1VXpyIEG9 X-Received: by 10.36.82.145 with SMTP id d139mr2838219itb.86.1506377802888; Mon, 25 Sep 2017 15:16:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506377802; cv=none; d=google.com; s=arc-20160816; b=Xb3P693CaYBQK2c+83Pdtk+uqyGdqgQgvcA/6d5rylCBqDqt9H7+cpzaGqz9ryCNiy kgM3LWo1+tLrwsEii7H++P57NKx1/Twp07R9AJj06T7NAnN8qMlf4JQMsB6Mjxt/bnJD bCQ+cjvM4vl5lc81GVAOkdqmhnM9YpTsR8QeSv9i0itXKaHFDzfrw2JRRyhGl9gqb30G 4hzPXSeCrZONZqhlLq7kQbj+nleK0gNZv1Lshb57cAXigW1hp9f7bLIYbtcWtXVBo8P4 s0RQydEnD7f3vDEMdKdf+h/oP4bh8PwTFDn2Xe9wb6hTXatHya36gT3+JWl9J+147n7v CUww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=4iDTunq1Bpi05NtDXn1N3zl8J2lc9pIe/CRgudSWL/o=; b=exeh7JpFWXDPtlMluhIdS6ZTqsorKxIi2u8ib5v2OJiFErjsSJJFwKswPrk5BNXq9N BIFBuie9j/pMk0xBBEE60ODt+d5Yk3VSzqNoIg59kybgkqKKrqQ/sFC9ec50Sc55P8bc pgexE2QwRvRWvgd/gxFepjwnEulBh92Uc5+8lOwwf8AnjFkxVgXVAZJfaJ8lQf7Ws3le 5MamEJJbaqnEDFAefq8IM1ryMy9oR0kmw+o8VM5kuf68/uiHacMSy8c9YgHcCn+/7+Jw BHTmYcL4S+DHs87RlPjWhLIoEnPIfJr2kkMGdpu16sQULUO5TXVKNNvGa/HS/4KVbr3O +yYA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id o143si6126120ioo.68.2017.09.25.15.16.42; Mon, 25 Sep 2017 15:16:42 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id 6D3DD60B4E; Mon, 25 Sep 2017 22:16:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 0743A60CE4; Mon, 25 Sep 2017 22:03:54 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 06C1D60D1F; Mon, 25 Sep 2017 22:03:45 +0000 (UTC) Received: from forward106o.mail.yandex.net (forward106o.mail.yandex.net [37.140.190.187]) by lists.linaro.org (Postfix) with ESMTPS id A171860455 for ; Mon, 25 Sep 2017 22:01:30 +0000 (UTC) Received: from mxback7o.mail.yandex.net (mxback7o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::21]) by forward106o.mail.yandex.net (Yandex) with ESMTP id 3E52C7840F0 for ; Tue, 26 Sep 2017 01:01:29 +0300 (MSK) Received: from smtp2o.mail.yandex.net (smtp2o.mail.yandex.net [2a02:6b8:0:1a2d::26]) by mxback7o.mail.yandex.net (nwsmtp/Yandex) with ESMTP id dVp42vEBz4-1TO49V0i; Tue, 26 Sep 2017 01:01:29 +0300 Received: by smtp2o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id y0gxWEywlF-1S4WZMRP; Tue, 26 Sep 2017 01:01:28 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 26 Sep 2017 01:00:25 +0300 Message-Id: <1506376827-27848-8-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> References: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 81 Subject: [lng-odp] [PATCH API-NEXT v19 7/9] linux-generic: ipsec: implement events handling X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Dmitry Eremin-Solenikov Add functions implementing IPsec events support. Signed-off-by: Dmitry Eremin-Solenikov --- /** Email created from pull request 81 (lumag:ipsec-packet-impl-2) ** https://github.com/Linaro/odp/pull/81 ** Patch: https://github.com/Linaro/odp/pull/81.patch ** Base sha: 13322ca632f8ffba292bec058e597719bc54142d ** Merge commit sha: 04f37d8f29d26df3744151a85a19ef9b55b3d1f7 **/ platform/linux-generic/Makefile.am | 2 + platform/linux-generic/include/odp_internal.h | 4 + .../linux-generic/include/odp_ipsec_internal.h | 84 +++++++++++ platform/linux-generic/odp_event.c | 4 + platform/linux-generic/odp_init.c | 13 ++ platform/linux-generic/odp_ipsec.c | 10 +- platform/linux-generic/odp_ipsec_events.c | 156 +++++++++++++++++++++ 7 files changed, 265 insertions(+), 8 deletions(-) create mode 100644 platform/linux-generic/include/odp_ipsec_internal.h create mode 100644 platform/linux-generic/odp_ipsec_events.c diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 3e26aab4c..c3c24ba1a 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -174,6 +174,7 @@ noinst_HEADERS = \ ${srcdir}/include/odp_errno_define.h \ ${srcdir}/include/odp_forward_typedefs_internal.h \ ${srcdir}/include/odp_internal.h \ + ${srcdir}/include/odp_ipsec_internal.h \ ${srcdir}/include/odp_llqueue.h \ ${srcdir}/include/odp_name_table_internal.h \ ${srcdir}/include/odp_packet_internal.h \ @@ -246,6 +247,7 @@ __LIB__libodp_linux_la_SOURCES = \ odp_init.c \ odp_impl.c \ odp_ipsec.c \ + odp_ipsec_events.c \ odp_name_table.c \ odp_packet.c \ odp_packet_flags.c \ diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index a3516ded1..47ead0773 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -74,6 +74,7 @@ enum init_stage { CLASSIFICATION_INIT, TRAFFIC_MNGR_INIT, NAME_TABLE_INIT, + IPSEC_EVENTS_INIT, MODULES_INIT, ALL_INIT /* All init stages completed */ }; @@ -133,6 +134,9 @@ int _odp_ishm_init_local(void); int _odp_ishm_term_global(void); int _odp_ishm_term_local(void); +int _odp_ipsec_events_init_global(void); +int _odp_ipsec_events_term_global(void); + int _odp_modules_init_global(void); int cpuinfo_parser(FILE *file, system_info_t *sysinfo); diff --git a/platform/linux-generic/include/odp_ipsec_internal.h b/platform/linux-generic/include/odp_ipsec_internal.h new file mode 100644 index 000000000..b31f048ff --- /dev/null +++ b/platform/linux-generic/include/odp_ipsec_internal.h @@ -0,0 +1,84 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP internal IPsec routines + */ + +#ifndef ODP_IPSEC_INTERNAL_H_ +#define ODP_IPSEC_INTERNAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include + +/** @ingroup odp_ipsec + * @{ + */ + +typedef ODP_HANDLE_T(ipsec_status_t); + +#define ODP_IPSEC_STATUS_INVALID \ + _odp_cast_scalar(ipsec_status_t, 0xffffffff) + +/** + * @internal Get ipsec_status handle from event + * + * Converts an ODP_EVENT_IPSEC_STATUS type event to an IPsec status event. + * + * @param ev Event handle + * + * @return IPsec status handle + * + * @see odp_event_type() + */ +ipsec_status_t _odp_ipsec_status_from_event(odp_event_t ev); + +/** + * @internal Free IPsec status event + * + * Frees the ipsec_status into the ipsec_status pool it was allocated from. + * + * @param res IPsec status handle + */ +void _odp_ipsec_status_free(ipsec_status_t status); + +/** + * @internal Send ODP_IPSEC_STATUS event + * + * Sends the ipsec_status event using provided information + * + * @param queue destination queue + * @param id status id + * @param sa SA respective to the operation + * @param result status value + * @param warn generated warning + * + * @retval 0 on success + * @retval <0 on failure + */ +int _odp_ipsec_status_send(odp_queue_t queue, + odp_ipsec_status_id_t id, + odp_ipsec_sa_t sa, + int result, + odp_ipsec_warn_t warn); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/odp_event.c b/platform/linux-generic/odp_event.c index 991d0e17d..66bc11fe4 100644 --- a/platform/linux-generic/odp_event.c +++ b/platform/linux-generic/odp_event.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,9 @@ void odp_event_free(odp_event_t event) case ODP_EVENT_CRYPTO_COMPL: odp_crypto_compl_free(odp_crypto_compl_from_event(event)); break; + case ODP_EVENT_IPSEC_STATUS: + _odp_ipsec_status_free(_odp_ipsec_status_from_event(event)); + break; default: ODP_ABORT("Invalid event type: %d\n", odp_event_type(event)); } diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c index fdccac7cd..8234df974 100644 --- a/platform/linux-generic/odp_init.c +++ b/platform/linux-generic/odp_init.c @@ -223,6 +223,12 @@ int odp_init_global(odp_instance_t *instance, } stage = NAME_TABLE_INIT; + if (_odp_ipsec_events_init_global()) { + ODP_ERR("ODP IPsec events init failed.\n"); + goto init_failed; + } + stage = IPSEC_EVENTS_INIT; + if (_odp_modules_init_global()) { ODP_ERR("ODP modules init failed\n"); goto init_failed; @@ -253,6 +259,13 @@ int _odp_term_global(enum init_stage stage) switch (stage) { case ALL_INIT: case MODULES_INIT: + case IPSEC_EVENTS_INIT: + if (_odp_ipsec_events_term_global()) { + ODP_ERR("ODP IPsec events term failed.\n"); + rc = -1; + } + /* Fall through */ + case NAME_TABLE_INIT: if (_odp_int_name_tbl_term_global()) { ODP_ERR("Name table term failed.\n"); diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 04757e788..e42b488f5 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -6,6 +6,8 @@ #include +#include + #include int odp_ipsec_capability(odp_ipsec_capability_t *capa) @@ -139,14 +141,6 @@ int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t packet) return -1; } -int odp_ipsec_status(odp_ipsec_status_t *status, odp_event_t event) -{ - (void)status; - (void)event; - - return -1; -} - int odp_ipsec_sa_mtu_update(odp_ipsec_sa_t sa, uint32_t mtu) { (void)sa; diff --git a/platform/linux-generic/odp_ipsec_events.c b/platform/linux-generic/odp_ipsec_events.c new file mode 100644 index 000000000..3a7ebd6e8 --- /dev/null +++ b/platform/linux-generic/odp_ipsec_events.c @@ -0,0 +1,156 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include + +typedef struct { + /* common buffer header */ + odp_buffer_hdr_t buf_hdr; + + odp_ipsec_status_t status; +} ipsec_status_hdr_t; + +static odp_pool_t ipsec_status_pool = ODP_POOL_INVALID; + +#define IPSEC_EVENTS_POOL_BUF_COUNT 1024 + +int _odp_ipsec_events_init_global(void) +{ + odp_pool_param_t param; + + odp_pool_param_init(¶m); + + param.buf.size = sizeof(ipsec_status_hdr_t); + param.buf.align = 0; + param.buf.num = IPSEC_EVENTS_POOL_BUF_COUNT; + param.type = ODP_POOL_BUFFER; + + ipsec_status_pool = odp_pool_create("ipsec_status_pool", ¶m); + if (ODP_POOL_INVALID == ipsec_status_pool) { + ODP_ERR("Error: status pool create failed.\n"); + goto err_status; + } + + return 0; + +err_status: + return -1; +} + +int _odp_ipsec_events_term_global(void) +{ + int ret = 0; + int rc = 0; + + ret = odp_pool_destroy(ipsec_status_pool); + if (ret < 0) { + ODP_ERR("status pool destroy failed"); + rc = -1; + } + + return rc; +} + +ipsec_status_t _odp_ipsec_status_from_event(odp_event_t ev) +{ + ODP_ASSERT(ODP_EVENT_INVALID != ev); + ODP_ASSERT(ODP_EVENT_IPSEC_STATUS == odp_event_type(ev)); + + return (ipsec_status_t)ev; +} + +static odp_event_t ipsec_status_to_event(ipsec_status_t status) +{ + ODP_ASSERT(ODP_IPSEC_STATUS_INVALID != status); + + return (odp_event_t)status; +} + +static ipsec_status_hdr_t *ipsec_status_hdr_from_buf(odp_buffer_t buf) +{ + return (ipsec_status_hdr_t *)(void *)buf_hdl_to_hdr(buf); +} + +static ipsec_status_hdr_t *ipsec_status_hdr(ipsec_status_t status) +{ + odp_buffer_t buf = odp_buffer_from_event(ipsec_status_to_event(status)); + + return ipsec_status_hdr_from_buf(buf); +} + +static ipsec_status_t odp_ipsec_status_alloc(void) +{ + odp_buffer_t buf = odp_buffer_alloc(ipsec_status_pool); + + if (odp_unlikely(buf == ODP_BUFFER_INVALID)) + return ODP_IPSEC_STATUS_INVALID; + + _odp_buffer_event_type_set(buf, ODP_EVENT_IPSEC_STATUS); + + return _odp_ipsec_status_from_event(odp_buffer_to_event(buf)); +} + +void _odp_ipsec_status_free(ipsec_status_t status) +{ + odp_event_t ev = ipsec_status_to_event(status); + + odp_buffer_free(odp_buffer_from_event(ev)); +} + +int _odp_ipsec_status_send(odp_queue_t queue, + odp_ipsec_status_id_t id, + odp_ipsec_sa_t sa, + int result, + odp_ipsec_warn_t warn) +{ + ipsec_status_t ipsec_ev = odp_ipsec_status_alloc(); + ipsec_status_hdr_t *status_hdr; + + if (ODP_IPSEC_STATUS_INVALID == ipsec_ev) + return -1; + + status_hdr = ipsec_status_hdr(ipsec_ev); + + status_hdr->status.id = id; + status_hdr->status.sa = sa; + status_hdr->status.result = result; + status_hdr->status.warn = warn; + + if (odp_queue_enq(queue, ipsec_status_to_event(ipsec_ev))) { + _odp_ipsec_status_free(ipsec_ev); + return -1; + } + + return 0; +} + +int odp_ipsec_status(odp_ipsec_status_t *status, odp_event_t event) +{ + ipsec_status_t ipsec_ev; + ipsec_status_hdr_t *status_hdr; + + if (odp_unlikely(ODP_EVENT_INVALID == event)) + return -1; + + ipsec_ev = _odp_ipsec_status_from_event(event); + if (odp_unlikely(ODP_IPSEC_STATUS_INVALID == ipsec_ev)) + return -1; + + status_hdr = ipsec_status_hdr(ipsec_ev); + + *status = status_hdr->status; + + return 0; +} From patchwork Mon Sep 25 22:00:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 114195 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp3117841qgf; Mon, 25 Sep 2017 15:18:03 -0700 (PDT) X-Google-Smtp-Source: AOwi7QB/VPcAbHt6I+l/fsMic5/SUUezvuBjQfgk+ovC4rKoL3rg8E99eDQl3bXMP9ytbtIPQy74 X-Received: by 10.107.88.22 with SMTP id m22mr11230086iob.284.1506377882661; Mon, 25 Sep 2017 15:18:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506377882; cv=none; d=google.com; s=arc-20160816; b=bM+4m+I3oEdtt9DOZp0+02lIh9SeGUMPuxzKY3T9P18gFT1m3mUTURERtB5TErEGqF 7GNugoQcPwFYtkElKHjiGpQaQelzanScYjOWW8IMZOOoPw1S1JpMSQXVLjtMYC2ivGrh l7peuSY5TUctm0yy9Hc2bOwfM59pwoSaTMIWWBF7VQsZ//CgoSSZCetPj+sHiKTZNv3F 6Dbk+2Irk8WYiB0rvYNXfBxRJcStLNPO43NbRcDfVqwW95Esw93Pgb6v+y9DobQunrLa ufWwi4BhLY6UtQDeEl5vW+5+/8gN7nv4dHEXkVhuZTOFtk+9b1CNI99ceFx70PutR7Yb nPEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=Pegs15Yf3noRo6JQY1pw836Sjp6c0A8gGG0hdldBUKQ=; b=aSPEuw5qY7uFTt6c+wZ/O9K18OQAr8U73QVX6x9dPGI85EV8jUfjAE80gDh3mPpVOl 6HNrZTilNTk5RQ5aFjttiAF9En1lGvIuwBfL9B8jDMezOSbdeMbsVLfAx/+yeIzoVkL8 ysPVDOWQzEq7Kw/2KvjgnxzbkNZUSTZRqUa9e0nZXycZupEt0T0be8XFdfgqna0Z8Per SguVoAj1HJyTPNe4+e0I+FYSSTtTlodg4+/RNiO3T3uF1d7ch7eYOt7Dmn+XF4OATwn1 3/RSetRnXWJG1S/LXnLb5c1qEaxV3FqlKdkZVzf5F4z1HEtypsriNy6KpObIiAs/VxN8 ZI3w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id d202si450842itd.121.2017.09.25.15.18.02; Mon, 25 Sep 2017 15:18:02 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id 306C460C4B; Mon, 25 Sep 2017 22:18:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 6C4CD60D1F; Mon, 25 Sep 2017 22:04:01 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id AEC3D60BF6; Mon, 25 Sep 2017 22:03:45 +0000 (UTC) Received: from forward104j.mail.yandex.net (forward104j.mail.yandex.net [5.45.198.247]) by lists.linaro.org (Postfix) with ESMTPS id DBEEF6080B for ; Mon, 25 Sep 2017 22:01:31 +0000 (UTC) Received: from mxback10o.mail.yandex.net (mxback10o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::24]) by forward104j.mail.yandex.net (Yandex) with ESMTP id 1575843D1C for ; Tue, 26 Sep 2017 01:01:30 +0300 (MSK) Received: from smtp2o.mail.yandex.net (smtp2o.mail.yandex.net [2a02:6b8:0:1a2d::26]) by mxback10o.mail.yandex.net (nwsmtp/Yandex) with ESMTP id h9qpA0omqN-1TJCDRCT; Tue, 26 Sep 2017 01:01:30 +0300 Received: by smtp2o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id y0gxWEywlF-1T4e7th9; Tue, 26 Sep 2017 01:01:29 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 26 Sep 2017 01:00:26 +0300 Message-Id: <1506376827-27848-9-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> References: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 81 Subject: [lng-odp] [PATCH API-NEXT v19 8/9] linux-generic: ipsec: implement IPsec SAD X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Dmitry Eremin-Solenikov Implement SA database and SA handling. - only IPv4 is supported for now Signed-off-by: Dmitry Eremin-Solenikov --- /** Email created from pull request 81 (lumag:ipsec-packet-impl-2) ** https://github.com/Linaro/odp/pull/81 ** Patch: https://github.com/Linaro/odp/pull/81.patch ** Base sha: 13322ca632f8ffba292bec058e597719bc54142d ** Merge commit sha: 04f37d8f29d26df3744151a85a19ef9b55b3d1f7 **/ platform/linux-generic/Makefile.am | 1 + platform/linux-generic/include/odp_internal.h | 4 + .../linux-generic/include/odp_ipsec_internal.h | 109 +++++ platform/linux-generic/odp_init.c | 13 + platform/linux-generic/odp_ipsec.c | 46 -- platform/linux-generic/odp_ipsec_sad.c | 502 +++++++++++++++++++++ 6 files changed, 629 insertions(+), 46 deletions(-) create mode 100644 platform/linux-generic/odp_ipsec_sad.c diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index c3c24ba1a..5721f3b9b 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -248,6 +248,7 @@ __LIB__libodp_linux_la_SOURCES = \ odp_impl.c \ odp_ipsec.c \ odp_ipsec_events.c \ + odp_ipsec_sad.c \ odp_name_table.c \ odp_packet.c \ odp_packet_flags.c \ diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index 47ead0773..ef9733c83 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -75,6 +75,7 @@ enum init_stage { TRAFFIC_MNGR_INIT, NAME_TABLE_INIT, IPSEC_EVENTS_INIT, + IPSEC_SAD_INIT, MODULES_INIT, ALL_INIT /* All init stages completed */ }; @@ -134,6 +135,9 @@ int _odp_ishm_init_local(void); int _odp_ishm_term_global(void); int _odp_ishm_term_local(void); +int _odp_ipsec_sad_init_global(void); +int _odp_ipsec_sad_term_global(void); + int _odp_ipsec_events_init_global(void); int _odp_ipsec_events_term_global(void); diff --git a/platform/linux-generic/include/odp_ipsec_internal.h b/platform/linux-generic/include/odp_ipsec_internal.h index b31f048ff..64ef8ab78 100644 --- a/platform/linux-generic/include/odp_ipsec_internal.h +++ b/platform/linux-generic/include/odp_ipsec_internal.h @@ -20,7 +20,9 @@ extern "C" { #include #include +#include #include +#include /** @ingroup odp_ipsec * @{ @@ -31,6 +33,8 @@ typedef ODP_HANDLE_T(ipsec_status_t); #define ODP_IPSEC_STATUS_INVALID \ _odp_cast_scalar(ipsec_status_t, 0xffffffff) +typedef struct ipsec_sa_s ipsec_sa_t; + /** * @internal Get ipsec_status handle from event * @@ -73,6 +77,111 @@ int _odp_ipsec_status_send(odp_queue_t queue, int result, odp_ipsec_warn_t warn); +#define IPSEC_MAX_IV_LEN 32 /**< Maximum IV length in bytes */ + +#define IPSEC_MAX_SALT_LEN 4 /**< Maximum salt length in bytes */ + +/** + * Maximum number of available SAs + */ +#define ODP_CONFIG_IPSEC_SAS 8 + +struct ipsec_sa_s { + odp_atomic_u32_t state ODP_ALIGNED_CACHE; + + uint32_t ipsec_sa_idx; + odp_ipsec_sa_t ipsec_sa_hdl; + + odp_ipsec_protocol_t proto; + uint32_t spi; + + odp_ipsec_mode_t mode; + + /* Limits */ + uint64_t soft_limit_bytes; + uint64_t soft_limit_packets; + uint64_t hard_limit_bytes; + uint64_t hard_limit_packets; + + /* Statistics for soft/hard expiration */ + odp_atomic_u64_t bytes; + odp_atomic_u64_t packets; + + odp_crypto_session_t session; + void *context; + odp_queue_t queue; + + uint32_t icv_len; + uint32_t esp_iv_len; + uint32_t esp_block_len; + + uint8_t salt[IPSEC_MAX_SALT_LEN]; + uint32_t salt_length; + + unsigned dec_ttl : 1; + unsigned copy_dscp : 1; + unsigned copy_df : 1; + + union { + struct { + odp_ipsec_lookup_mode_t lookup_mode; + odp_u32be_t lookup_dst_ip; + } in; + + struct { + odp_u32be_t tun_src_ip; + odp_u32be_t tun_dst_ip; + + /* 32-bit from which low 16 are used */ + odp_atomic_u32_t tun_hdr_id; + odp_atomic_u32_t seq; + + uint8_t tun_ttl; + uint8_t tun_dscp; + uint8_t tun_df; + } out; + }; +}; + +/** + * IPSEC Security Association (SA) lookup parameters + */ +typedef struct odp_ipsec_sa_lookup_s { + /** IPSEC protocol: ESP or AH */ + odp_ipsec_protocol_t proto; + + /** SPI value */ + uint32_t spi; + + /* FIXME: IPv4 vs IPv6 */ + + /** IP destination address (NETWORK ENDIAN) */ + void *dst_addr; +} ipsec_sa_lookup_t; + +/** + * Obtain SA reference + */ +ipsec_sa_t *_odp_ipsec_sa_use(odp_ipsec_sa_t sa); + +/** + * Release SA reference + */ +void _odp_ipsec_sa_unuse(ipsec_sa_t *ipsec_sa); + +/** + * Lookup SA corresponding to inbound packet pkt + */ +ipsec_sa_t *_odp_ipsec_sa_lookup(const ipsec_sa_lookup_t *lookup); + +/** + * Update SA usage statistics, filling respective status for the packet. + * + * @retval <0 if hard limits were breached + */ +int _odp_ipsec_sa_update_stats(ipsec_sa_t *ipsec_sa, uint32_t len, + odp_ipsec_op_status_t *status); + /** * @} */ diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c index 8234df974..1412c03a0 100644 --- a/platform/linux-generic/odp_init.c +++ b/platform/linux-generic/odp_init.c @@ -229,6 +229,12 @@ int odp_init_global(odp_instance_t *instance, } stage = IPSEC_EVENTS_INIT; + if (_odp_ipsec_sad_init_global()) { + ODP_ERR("ODP IPsec SAD init failed.\n"); + goto init_failed; + } + stage = IPSEC_SAD_INIT; + if (_odp_modules_init_global()) { ODP_ERR("ODP modules init failed\n"); goto init_failed; @@ -259,6 +265,13 @@ int _odp_term_global(enum init_stage stage) switch (stage) { case ALL_INIT: case MODULES_INIT: + case IPSEC_SAD_INIT: + if (_odp_ipsec_sad_term_global()) { + ODP_ERR("ODP IPsec SAD term failed.\n"); + rc = -1; + } + /* Fall through */ + case IPSEC_EVENTS_INIT: if (_odp_ipsec_events_term_global()) { ODP_ERR("ODP IPsec events term failed.\n"); diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index e42b488f5..d0ca027cb 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -49,32 +49,6 @@ int odp_ipsec_config(const odp_ipsec_config_t *config) return -1; } -void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param) -{ - memset(param, 0, sizeof(odp_ipsec_sa_param_t)); -} - -odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param) -{ - (void)param; - - return ODP_IPSEC_SA_INVALID; -} - -int odp_ipsec_sa_disable(odp_ipsec_sa_t sa) -{ - (void)sa; - - return -1; -} - -int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa) -{ - (void)sa; - - return -1; -} - int odp_ipsec_in(const odp_packet_t pkt_in[], int num_in, odp_packet_t pkt_out[], int *num_out, const odp_ipsec_in_param_t *param) @@ -141,21 +115,6 @@ int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t packet) return -1; } -int odp_ipsec_sa_mtu_update(odp_ipsec_sa_t sa, uint32_t mtu) -{ - (void)sa; - (void)mtu; - - return -1; -} - -void *odp_ipsec_sa_context(odp_ipsec_sa_t sa) -{ - (void)sa; - - return NULL; -} - odp_packet_t odp_ipsec_packet_from_event(odp_event_t ev) { (void)ev; @@ -169,8 +128,3 @@ odp_event_t odp_ipsec_packet_to_event(odp_packet_t pkt) return ODP_EVENT_INVALID; } - -uint64_t odp_ipsec_sa_to_u64(odp_ipsec_sa_t sa) -{ - return _odp_pri(sa); -} diff --git a/platform/linux-generic/odp_ipsec_sad.c b/platform/linux-generic/odp_ipsec_sad.c new file mode 100644 index 000000000..896e6a4a4 --- /dev/null +++ b/platform/linux-generic/odp_ipsec_sad.c @@ -0,0 +1,502 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include + +#include + +#define IPSEC_SA_STATE_DISABLE 0x40000000 +#define IPSEC_SA_STATE_FREE 0xc0000000 /* This includes disable !!! */ + +typedef struct ipsec_sa_table_t { + ipsec_sa_t ipsec_sa[ODP_CONFIG_IPSEC_SAS]; + odp_shm_t shm; +} ipsec_sa_table_t; + +static ipsec_sa_table_t *ipsec_sa_tbl; + +static inline ipsec_sa_t *ipsec_sa_entry(uint32_t ipsec_sa_idx) +{ + return &ipsec_sa_tbl->ipsec_sa[ipsec_sa_idx]; +} + +static inline ipsec_sa_t *ipsec_sa_entry_from_hdl(odp_ipsec_sa_t ipsec_sa_hdl) +{ + return ipsec_sa_entry(_odp_typeval(ipsec_sa_hdl)); +} + +static inline odp_ipsec_sa_t ipsec_sa_index_to_handle(uint32_t ipsec_sa_idx) +{ + return _odp_cast_scalar(odp_ipsec_sa_t, ipsec_sa_idx); +} + +int _odp_ipsec_sad_init_global(void) +{ + odp_shm_t shm; + unsigned i; + + shm = odp_shm_reserve("ipsec_sa_table", + sizeof(ipsec_sa_table_t), + ODP_CACHE_LINE_SIZE, 0); + + ipsec_sa_tbl = odp_shm_addr(shm); + if (ipsec_sa_tbl == NULL) + return -1; + + memset(ipsec_sa_tbl, 0, sizeof(ipsec_sa_table_t)); + ipsec_sa_tbl->shm = shm; + + for (i = 0; i < ODP_CONFIG_IPSEC_SAS; i++) { + ipsec_sa_t *ipsec_sa = ipsec_sa_entry(i); + + ipsec_sa->ipsec_sa_hdl = ipsec_sa_index_to_handle(i); + ipsec_sa->ipsec_sa_idx = i; + odp_atomic_init_u32(&ipsec_sa->state, IPSEC_SA_STATE_FREE); + odp_atomic_init_u64(&ipsec_sa->bytes, 0); + odp_atomic_init_u64(&ipsec_sa->packets, 0); + } + + return 0; +} + +int _odp_ipsec_sad_term_global(void) +{ + int i; + ipsec_sa_t *ipsec_sa; + int ret = 0; + int rc = 0; + + for (i = 0; i < ODP_CONFIG_IPSEC_SAS; i++) { + ipsec_sa = ipsec_sa_entry(i); + + if (odp_atomic_load_u32(&ipsec_sa->state) != + IPSEC_SA_STATE_FREE) { + ODP_ERR("Not destroyed ipsec_sa: %u\n", + ipsec_sa->ipsec_sa_idx); + rc = -1; + } + odp_atomic_store_u32(&ipsec_sa->state, IPSEC_SA_STATE_FREE); + } + + ret = odp_shm_free(ipsec_sa_tbl->shm); + if (ret < 0) { + ODP_ERR("shm free failed"); + rc = -1; + } + + return rc; +} + +static ipsec_sa_t *ipsec_sa_reserve(void) +{ + int i; + ipsec_sa_t *ipsec_sa; + + for (i = 0; i < ODP_CONFIG_IPSEC_SAS; i++) { + uint32_t state = IPSEC_SA_STATE_FREE; + + ipsec_sa = ipsec_sa_entry(i); + + if (odp_atomic_cas_acq_u32(&ipsec_sa->state, &state, 0)) + return ipsec_sa; + } + + return NULL; +} + +static void ipsec_sa_release(ipsec_sa_t *ipsec_sa) +{ + odp_atomic_store_rel_u32(&ipsec_sa->state, IPSEC_SA_STATE_FREE); +} + +static int ipsec_sa_lock(ipsec_sa_t *ipsec_sa) +{ + int cas = 0; + uint32_t state = odp_atomic_load_u32(&ipsec_sa->state); + + while (0 == cas) { + /* + * This can be called from lookup path, so we really need this + * check + */ + if (state & IPSEC_SA_STATE_DISABLE) + return -1; + + cas = odp_atomic_cas_acq_u32(&ipsec_sa->state, &state, + state + 1); + } + + return 0; +} + +/* Do not call directly, use _odp_ipsec_sa_unuse */ +static odp_bool_t ipsec_sa_unlock(ipsec_sa_t *ipsec_sa) +{ + int cas = 0; + uint32_t state = odp_atomic_load_u32(&ipsec_sa->state); + + while (0 == cas) + cas = odp_atomic_cas_rel_u32(&ipsec_sa->state, &state, + state - 1); + + return state == IPSEC_SA_STATE_DISABLE; +} + +ipsec_sa_t *_odp_ipsec_sa_use(odp_ipsec_sa_t sa) +{ + ipsec_sa_t *ipsec_sa; + + ODP_ASSERT(ODP_IPSEC_SA_INVALID != sa); + + ipsec_sa = ipsec_sa_entry_from_hdl(sa); + + if (ipsec_sa_lock(ipsec_sa) < 0) + return NULL; + + return ipsec_sa; +} + +void _odp_ipsec_sa_unuse(ipsec_sa_t *ipsec_sa) +{ + odp_queue_t queue; + odp_ipsec_sa_t sa; + odp_ipsec_warn_t warn = { .all = 0 }; + + ODP_ASSERT(NULL != ipsec_sa); + + queue = ipsec_sa->queue; + sa = ipsec_sa->ipsec_sa_hdl; + + if (ipsec_sa_unlock(ipsec_sa) && ODP_QUEUE_INVALID != queue) + _odp_ipsec_status_send(queue, + ODP_IPSEC_STATUS_SA_DISABLE, + sa, 0, warn); +} + +void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param) +{ + memset(param, 0, sizeof(odp_ipsec_sa_param_t)); + param->dest_queue = ODP_QUEUE_INVALID; +} + +odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param) +{ + ipsec_sa_t *ipsec_sa; + odp_crypto_session_param_t crypto_param; + odp_crypto_ses_create_err_t ses_create_rc; + + ipsec_sa = ipsec_sa_reserve(); + if (NULL == ipsec_sa) { + ODP_ERR("No more free SA\n"); + return ODP_IPSEC_SA_INVALID; + } + + ipsec_sa->proto = param->proto; + ipsec_sa->spi = param->spi; + ipsec_sa->context = param->context; + ipsec_sa->queue = param->dest_queue; + ipsec_sa->mode = param->mode; + if (ODP_IPSEC_DIR_INBOUND == param->dir) { + ipsec_sa->in.lookup_mode = param->inbound.lookup_mode; + if (ODP_IPSEC_LOOKUP_DSTADDR_SPI == ipsec_sa->in.lookup_mode) + memcpy(&ipsec_sa->in.lookup_dst_ip, + param->inbound.lookup_param.dst_addr, + sizeof(ipsec_sa->in.lookup_dst_ip)); + + } else { + odp_atomic_store_u32(&ipsec_sa->out.seq, 1); + } + ipsec_sa->dec_ttl = param->opt.dec_ttl; + ipsec_sa->copy_dscp = param->opt.copy_dscp; + ipsec_sa->copy_df = param->opt.copy_df; + + odp_atomic_store_u64(&ipsec_sa->bytes, 0); + odp_atomic_store_u64(&ipsec_sa->packets, 0); + ipsec_sa->soft_limit_bytes = param->lifetime.soft_limit.bytes; + ipsec_sa->soft_limit_packets = param->lifetime.soft_limit.packets; + ipsec_sa->hard_limit_bytes = param->lifetime.hard_limit.bytes; + ipsec_sa->hard_limit_packets = param->lifetime.hard_limit.packets; + + if (ODP_IPSEC_MODE_TUNNEL == ipsec_sa->mode && + ODP_IPSEC_DIR_OUTBOUND == param->dir) { + if (param->outbound.tunnel.type != ODP_IPSEC_TUNNEL_IPV4) { + ipsec_sa_release(ipsec_sa); + + return ODP_IPSEC_SA_INVALID; + } + memcpy(&ipsec_sa->out.tun_src_ip, + param->outbound.tunnel.ipv4.src_addr, + sizeof(ipsec_sa->out.tun_src_ip)); + memcpy(&ipsec_sa->out.tun_dst_ip, + param->outbound.tunnel.ipv4.dst_addr, + sizeof(ipsec_sa->out.tun_dst_ip)); + odp_atomic_init_u32(&ipsec_sa->out.tun_hdr_id, 0); + ipsec_sa->out.tun_ttl = param->outbound.tunnel.ipv4.ttl; + ipsec_sa->out.tun_dscp = param->outbound.tunnel.ipv4.dscp; + ipsec_sa->out.tun_df = param->outbound.tunnel.ipv4.df; + } + + odp_crypto_session_param_init(&crypto_param); + + /* Setup parameters and call crypto library to create session */ + crypto_param.op = (ODP_IPSEC_DIR_INBOUND == param->dir) ? + ODP_CRYPTO_OP_DECODE : + ODP_CRYPTO_OP_ENCODE; + crypto_param.auth_cipher_text = 1; + + crypto_param.op_mode = ODP_CRYPTO_SYNC; + crypto_param.compl_queue = ODP_QUEUE_INVALID; + crypto_param.output_pool = ODP_POOL_INVALID; + + crypto_param.cipher_alg = param->crypto.cipher_alg; + crypto_param.cipher_key = param->crypto.cipher_key; + crypto_param.auth_alg = param->crypto.auth_alg; + crypto_param.auth_key = param->crypto.auth_key; + + switch (crypto_param.auth_alg) { + case ODP_AUTH_ALG_NULL: + ipsec_sa->icv_len = 0; + break; +#if ODP_DEPRECATED_API + case ODP_AUTH_ALG_MD5_96: +#endif + case ODP_AUTH_ALG_MD5_HMAC: + ipsec_sa->icv_len = 12; + break; + case ODP_AUTH_ALG_SHA1_HMAC: + ipsec_sa->icv_len = 12; + break; +#if ODP_DEPRECATED_API + case ODP_AUTH_ALG_SHA256_128: +#endif + case ODP_AUTH_ALG_SHA256_HMAC: + ipsec_sa->icv_len = 16; + break; + case ODP_AUTH_ALG_SHA512_HMAC: + ipsec_sa->icv_len = 32; + break; +#if ODP_DEPRECATED_API + case ODP_AUTH_ALG_AES128_GCM: +#endif + case ODP_AUTH_ALG_AES_GCM: + ipsec_sa->icv_len = 16; + break; + default: + return ODP_IPSEC_SA_INVALID; + } + + switch (crypto_param.cipher_alg) { + case ODP_CIPHER_ALG_NULL: + ipsec_sa->esp_iv_len = 0; + ipsec_sa->esp_block_len = 1; + break; + case ODP_CIPHER_ALG_DES: + case ODP_CIPHER_ALG_3DES_CBC: + ipsec_sa->esp_iv_len = 8; + ipsec_sa->esp_block_len = 8; + break; +#if ODP_DEPRECATED_API + case ODP_CIPHER_ALG_AES128_CBC: +#endif + case ODP_CIPHER_ALG_AES_CBC: + ipsec_sa->esp_iv_len = 16; + ipsec_sa->esp_block_len = 16; + break; +#if ODP_DEPRECATED_API + case ODP_CIPHER_ALG_AES128_GCM: +#endif + case ODP_CIPHER_ALG_AES_GCM: + ipsec_sa->esp_iv_len = 8; + ipsec_sa->esp_block_len = 16; + crypto_param.iv.length = 12; + break; + default: + return ODP_IPSEC_SA_INVALID; + } + + crypto_param.auth_digest_len = ipsec_sa->icv_len; + + if (param->crypto.cipher_key_extra.length) { + if (param->crypto.cipher_key_extra.length > + IPSEC_MAX_SALT_LEN) + goto error; + + ipsec_sa->salt_length = param->crypto.cipher_key_extra.length; + memcpy(ipsec_sa->salt, + param->crypto.cipher_key_extra.data, + param->crypto.cipher_key_extra.length); + } else { + ipsec_sa->salt_length = 0; + } + + if (odp_crypto_session_create(&crypto_param, &ipsec_sa->session, + &ses_create_rc)) + goto error; + + return ipsec_sa->ipsec_sa_hdl; + +error: + ipsec_sa_release(ipsec_sa); + + return ODP_IPSEC_SA_INVALID; +} + +int odp_ipsec_sa_disable(odp_ipsec_sa_t sa) +{ + ipsec_sa_t *ipsec_sa = ipsec_sa_entry_from_hdl(sa); + uint32_t state; + int cas = 0; + + /* This is a custom rwlock implementation. It is not possible to use + * original rwlock, because there is no way to test if current code is + * the last reader when disable operation is pending. */ + state = odp_atomic_load_u32(&ipsec_sa->state); + + while (0 == cas) { + if (state & IPSEC_SA_STATE_DISABLE) + return -1; + + cas = odp_atomic_cas_acq_u32(&ipsec_sa->state, &state, + state | IPSEC_SA_STATE_DISABLE); + } + + if (ODP_QUEUE_INVALID != ipsec_sa->queue) { + odp_ipsec_warn_t warn = { .all = 0 }; + + /* + * If there were not active state when we disabled SA, + * send the event. + */ + if (0 == state) + _odp_ipsec_status_send(ipsec_sa->queue, + ODP_IPSEC_STATUS_SA_DISABLE, + ipsec_sa->ipsec_sa_hdl, + 0, warn); + + return 0; + } + + while (IPSEC_SA_STATE_DISABLE != state) { + odp_cpu_pause(); + state = odp_atomic_load_u32(&ipsec_sa->state); + } + + return 0; +} + +int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa) +{ + ipsec_sa_t *ipsec_sa = ipsec_sa_entry_from_hdl(sa); + int rc = 0; + uint32_t state = odp_atomic_load_u32(&ipsec_sa->state); + + if (IPSEC_SA_STATE_DISABLE != state) { + ODP_ERR("Distroying not disabled ipsec_sa: %u\n", + ipsec_sa->ipsec_sa_idx); + return -1; + } + + if (odp_crypto_session_destroy(ipsec_sa->session) < 0) { + ODP_ERR("Error destroying crypto session for ipsec_sa: %u\n", + ipsec_sa->ipsec_sa_idx); + rc = -1; + } + + ipsec_sa_release(ipsec_sa); + + return rc; +} + +void *odp_ipsec_sa_context(odp_ipsec_sa_t sa) +{ + ipsec_sa_t *ipsec_sa = ipsec_sa_entry_from_hdl(sa); + + return ipsec_sa->context; +} + +uint64_t odp_ipsec_sa_to_u64(odp_ipsec_sa_t sa) +{ + return _odp_pri(sa); +} + +int odp_ipsec_sa_mtu_update(odp_ipsec_sa_t sa, uint32_t mtu) +{ + (void)sa; + (void)mtu; + + return -1; +} + +ipsec_sa_t *_odp_ipsec_sa_lookup(const ipsec_sa_lookup_t *lookup) +{ + (void)lookup; + + int i; + ipsec_sa_t *ipsec_sa; + ipsec_sa_t *best = NULL; + + for (i = 0; i < ODP_CONFIG_IPSEC_SAS; i++) { + ipsec_sa = ipsec_sa_entry(i); + + if (ipsec_sa_lock(ipsec_sa) < 0) + continue; + + if (ODP_IPSEC_LOOKUP_DSTADDR_SPI == ipsec_sa->in.lookup_mode && + lookup->proto == ipsec_sa->proto && + lookup->spi == ipsec_sa->spi && + !memcmp(lookup->dst_addr, &ipsec_sa->in.lookup_dst_ip, + sizeof(ipsec_sa->in.lookup_dst_ip))) { + if (NULL != best) + _odp_ipsec_sa_unuse(best); + return ipsec_sa; + } else if (ODP_IPSEC_LOOKUP_SPI == ipsec_sa->in.lookup_mode && + lookup->proto == ipsec_sa->proto && + lookup->spi == ipsec_sa->spi) { + best = ipsec_sa; + } else { + _odp_ipsec_sa_unuse(ipsec_sa); + } + } + + return best; +} + +int _odp_ipsec_sa_update_stats(ipsec_sa_t *ipsec_sa, uint32_t len, + odp_ipsec_op_status_t *status) +{ + uint64_t bytes = odp_atomic_fetch_add_u64(&ipsec_sa->bytes, len) + len; + uint64_t packets = odp_atomic_fetch_add_u64(&ipsec_sa->packets, 1) + 1; + int rc = 0; + + if (ipsec_sa->soft_limit_bytes > 0 && + bytes > ipsec_sa->soft_limit_bytes) + status->warn.soft_exp_bytes = 1; + + if (ipsec_sa->soft_limit_packets > 0 && + packets > ipsec_sa->soft_limit_packets) + status->warn.soft_exp_packets = 1; + + if (ipsec_sa->hard_limit_bytes > 0 && + bytes > ipsec_sa->hard_limit_bytes) { + status->error.hard_exp_bytes = 1; + rc = -1; + } + if (ipsec_sa->hard_limit_packets > 0 && + packets > ipsec_sa->hard_limit_packets) { + status->error.hard_exp_packets = 1; + rc = -1; + } + + return rc; +} From patchwork Mon Sep 25 22:00:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 114199 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp3120684qgf; Mon, 25 Sep 2017 15:21:09 -0700 (PDT) X-Google-Smtp-Source: AOwi7QAxjYEP0S4NUDm0neMeEWlnYhLbW9NsZeYBJ/ws9bvRjHuc1bpQHpBWxeu8BhKQkX3Dzrwb X-Received: by 10.36.127.146 with SMTP id r140mr2712245itc.79.1506378069565; Mon, 25 Sep 2017 15:21:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506378069; cv=none; d=google.com; s=arc-20160816; b=AkJKdSVUnXJlXUPjQatAeMsk2xeb8aUXeYffaqLGtgX/DjoqlQPFT0Msuu3ml6rM9c L1dfQg0+X75fa6w4deCKKYmpMitb+Z9RVSxroxOjOW6nd5PuxPSnfxDM/lM0GNnsYHEP MFWWFk4LlktVLdGuDYWHWYNpSlxYGZk8oS+zL064PzKC7R2LSCPrgLLjX5SB+jv/uYY6 NERMqf2wXQAn5KOnkumZQZ24ElxiKrg8DOGwsav8UTWVF/VnYj39VaoCU+yinO0vznd0 q8MOkz+nC1cJUIOlngbKZ2Mav+tjWFFy3sqslPLDASRTUwzyvpF7BDZJXnr0G3ZpNdU4 cFXA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=ESs7pnrvXHTfi8orOxOXhovhlwk1CNkSFSSKuDfiAyE=; b=jLZ54KnhGow7wzsKaNY0SYvj+2g85TF5WJNEgguNIDhzEd0iELP+HZMSqGBrmvCxw4 URD6yxyqC2dnMQgHKr1slaQ15pqYeP1cntGlir/MnBYae9kmRW7bgRnHWqoXfJ7WDJjK auD+B5V5vXegZsvPBxVEpptyd86STaopGWRvwMCKoZnXihfbcHysrwN8hL1xxkYQtj9Q 1eJM+dranWHhHdcXb71QfsbypbgwHEbPZMn+8Q1tViTPgAIUKHW7WYhlMI+cviNdQ9nx NMTQMiqXnXw4fwOSJuZM19X6HIPTJJ9Qlpu12j5m9VT8Ef/IkbcLwlEBra87fCEBPPHr vcTA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id r22si444496itc.159.2017.09.25.15.21.09; Mon, 25 Sep 2017 15:21:09 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id 0A7DC60CA9; Mon, 25 Sep 2017 22:21:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id AAE4C60D3E; Mon, 25 Sep 2017 22:04:22 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 891E4609D5; Mon, 25 Sep 2017 22:04:10 +0000 (UTC) Received: from forward103p.mail.yandex.net (forward103p.mail.yandex.net [77.88.28.106]) by lists.linaro.org (Postfix) with ESMTPS id A8AAA609D5 for ; Mon, 25 Sep 2017 22:01:32 +0000 (UTC) Received: from mxback5j.mail.yandex.net (mxback5j.mail.yandex.net [IPv6:2a02:6b8:0:1619::10e]) by forward103p.mail.yandex.net (Yandex) with ESMTP id 488C62183BD9 for ; Tue, 26 Sep 2017 01:01:31 +0300 (MSK) Received: from smtp2o.mail.yandex.net (smtp2o.mail.yandex.net [2a02:6b8:0:1a2d::26]) by mxback5j.mail.yandex.net (nwsmtp/Yandex) with ESMTP id Enw4ebTroN-1Vh4mjhS; Tue, 26 Sep 2017 01:01:31 +0300 Received: by smtp2o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id y0gxWEywlF-1U4OOPHh; Tue, 26 Sep 2017 01:01:30 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 26 Sep 2017 01:00:27 +0300 Message-Id: <1506376827-27848-10-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> References: <1506376827-27848-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 81 Subject: [lng-odp] [PATCH API-NEXT v19 9/9] linux-generic: ipsec: draft IPsec implementation X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Dmitry Eremin-Solenikov For now it's only a preview with the following limitation: - Only IPv4 support - No pipeline_cls and outer header retaining support - No zeroing of mutable IPv4 options for AH ICV calculation - No replay protection - No ESN support - No UDP encapsulation support Signed-off-by: Dmitry Eremin-Solenikov --- /** Email created from pull request 81 (lumag:ipsec-packet-impl-2) ** https://github.com/Linaro/odp/pull/81 ** Patch: https://github.com/Linaro/odp/pull/81.patch ** Base sha: 13322ca632f8ffba292bec058e597719bc54142d ** Merge commit sha: 04f37d8f29d26df3744151a85a19ef9b55b3d1f7 **/ .../linux-generic/include/odp_ipsec_internal.h | 7 + .../linux-generic/include/odp_packet_internal.h | 4 + platform/linux-generic/odp_ipsec.c | 1235 +++++++++++++++++++- 3 files changed, 1197 insertions(+), 49 deletions(-) diff --git a/platform/linux-generic/include/odp_ipsec_internal.h b/platform/linux-generic/include/odp_ipsec_internal.h index 64ef8ab78..74085c95c 100644 --- a/platform/linux-generic/include/odp_ipsec_internal.h +++ b/platform/linux-generic/include/odp_ipsec_internal.h @@ -183,6 +183,13 @@ int _odp_ipsec_sa_update_stats(ipsec_sa_t *ipsec_sa, uint32_t len, odp_ipsec_op_status_t *status); /** + * Try inline IPsec processing of provided packet. + * + * @retval 0 if packet was processed and sent using IPsec inline processing + */ +int _odp_ipsec_try_inline(odp_packet_t pkt); + +/** * @} */ diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index e29e7e85f..a07223b63 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -26,6 +26,7 @@ extern "C" { #include #include #include +#include #include #include @@ -152,6 +153,9 @@ typedef struct { uint8_t extra[PKT_EXTRA_LEN] ODP_ALIGNED_CACHE; #endif + /* Context for IPsec */ + odp_ipsec_packet_result_t ipsec_ctx; + /* Packet data storage */ uint8_t data[0]; } odp_packet_hdr_t; diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index d0ca027cb..a156eeb40 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -4,127 +4,1264 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "config.h" + #include +#include + +#include +#include #include +#include +#include +#include + #include +typedef struct ODP_PACKED { + odp_u32be_t spi; /**< Security Parameter Index */ + odp_u32be_t seq_no; /**< Sequence Number */ +} ipsec_aad_t; + int odp_ipsec_capability(odp_ipsec_capability_t *capa) { + int rc; + odp_crypto_capability_t crypto_capa; + odp_queue_capability_t queue_capa; + memset(capa, 0, sizeof(odp_ipsec_capability_t)); + capa->op_mode_sync = ODP_SUPPORT_PREFERRED; + capa->op_mode_async = ODP_SUPPORT_PREFERRED; + capa->op_mode_inline_in = ODP_SUPPORT_PREFERRED; + capa->op_mode_inline_out = ODP_SUPPORT_PREFERRED; + + capa->proto_ah = ODP_SUPPORT_YES; + + capa->max_num_sa = ODP_CONFIG_IPSEC_SAS; + + rc = odp_crypto_capability(&crypto_capa); + if (rc < 0) + return rc; + + capa->ciphers = crypto_capa.ciphers; + capa->auths = crypto_capa.auths; + + rc = odp_queue_capability(&queue_capa); + if (rc < 0) + return rc; + + capa->max_queues = queue_capa.max_queues; + return 0; } int odp_ipsec_cipher_capability(odp_cipher_alg_t cipher, odp_crypto_cipher_capability_t capa[], int num) { - (void)cipher; - (void)capa; - (void)num; - - return -1; + return odp_crypto_cipher_capability(cipher, capa, num); } int odp_ipsec_auth_capability(odp_auth_alg_t auth, odp_crypto_auth_capability_t capa[], int num) { - (void)auth; - (void)capa; - (void)num; - - return -1; + return odp_crypto_auth_capability(auth, capa, num); } void odp_ipsec_config_init(odp_ipsec_config_t *config) { memset(config, 0, sizeof(odp_ipsec_config_t)); + config->inbound_mode = ODP_IPSEC_OP_MODE_SYNC; + config->outbound_mode = ODP_IPSEC_OP_MODE_SYNC; + config->max_num_sa = ODP_CONFIG_IPSEC_SAS; + config->inbound.default_queue = ODP_QUEUE_INVALID; + config->inbound.lookup.min_spi = 0; + config->inbound.lookup.max_spi = UINT32_MAX; } +static odp_ipsec_config_t ipsec_config; + int odp_ipsec_config(const odp_ipsec_config_t *config) { - (void)config; + if (ODP_CONFIG_IPSEC_SAS > config->max_num_sa) + return -1; + + ipsec_config = *config; + + return 0; +} + +static odp_ipsec_packet_result_t *ipsec_pkt_result(odp_packet_t packet) +{ + ODP_ASSERT(ODP_EVENT_PACKET_IPSEC == + odp_event_subtype(odp_packet_to_event(packet))); + + return &odp_packet_hdr(packet)->ipsec_ctx; +} + +/** + * Checksum + * + * @param buffer calculate chksum for buffer + * @param len buffer length + * + * @return checksum value in network order + */ +static inline +odp_u16sum_t _odp_chksum(void *buffer, int len) +{ + uint16_t *buf = (uint16_t *)buffer; + uint32_t sum = 0; + uint16_t result; + + for (sum = 0; len > 1; len -= 2) + sum += *buf++; + + if (len == 1) + sum += *(unsigned char *)buf; + + sum = (sum >> 16) + (sum & 0xFFFF); + sum += (sum >> 16); + result = ~sum; + + return (__odp_force odp_u16sum_t) result; +} + +static inline int _odp_ipv4_csum(odp_packet_t pkt, + uint32_t offset, + _odp_ipv4hdr_t *ip, + odp_u16sum_t *chksum) +{ + unsigned nleft = _ODP_IPV4HDR_IHL(ip->ver_ihl) * 4; + uint16_t buf[nleft / 2]; + int res; + + if (odp_unlikely(nleft < sizeof(*ip))) + return -1; + ip->chksum = 0; + memcpy(buf, ip, sizeof(*ip)); + res = odp_packet_copy_to_mem(pkt, offset + sizeof(*ip), + nleft - sizeof(*ip), + buf + sizeof(*ip) / 2); + if (odp_unlikely(res < 0)) + return res; + + *chksum = _odp_chksum(buf, nleft); + + return 0; +} + +/** @internal Checksum offset in IPv4 header */ +#define _ODP_IPV4HDR_CSUM_OFFSET 10 + +/** + * Calculate and fill in IPv4 checksum + * + * @param pkt ODP packet + * + * @retval 0 on success + * @retval <0 on failure + */ +static inline int _odp_ipv4_csum_update(odp_packet_t pkt) +{ + uint32_t offset; + _odp_ipv4hdr_t ip; + odp_u16sum_t chksum; + int res; + + offset = odp_packet_l3_offset(pkt); + if (offset == ODP_PACKET_OFFSET_INVALID) + return -1; + + res = odp_packet_copy_to_mem(pkt, offset, sizeof(ip), &ip); + if (odp_unlikely(res < 0)) + return res; + + res = _odp_ipv4_csum(pkt, offset, &ip, &chksum); + if (odp_unlikely(res < 0)) + return res; + + return odp_packet_copy_from_mem(pkt, + offset + _ODP_IPV4HDR_CSUM_OFFSET, + 2, &chksum); +} + +#define ipv4_hdr_len(ip) (_ODP_IPV4HDR_IHL(ip->ver_ihl) * 4) +static inline +void ipv4_adjust_len(_odp_ipv4hdr_t *ip, int adj) +{ + ip->tot_len = odp_cpu_to_be_16(odp_be_to_cpu_16(ip->tot_len) + adj); +} + +static const uint8_t ipsec_padding[255] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +static inline odp_pktio_parser_layer_t parse_layer(odp_ipsec_proto_layer_t l) +{ + switch (l) { + case ODP_IPSEC_LAYER_NONE: + return ODP_PKTIO_PARSER_LAYER_NONE; + case ODP_IPSEC_LAYER_L2: + return ODP_PKTIO_PARSER_LAYER_L2; + case ODP_IPSEC_LAYER_L3: + return ODP_PKTIO_PARSER_LAYER_L3; + case ODP_IPSEC_LAYER_L4: + return ODP_PKTIO_PARSER_LAYER_L4; + case ODP_IPSEC_LAYER_ALL: + return ODP_PKTIO_PARSER_LAYER_ALL; + } + + return ODP_PKTIO_PARSER_LAYER_NONE; +} + +static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt, + odp_ipsec_sa_t sa, + odp_packet_t *pkt_out, + odp_ipsec_op_status_t *status) +{ + ipsec_sa_t *ipsec_sa = NULL; + uint32_t ip_offset = odp_packet_l3_offset(pkt); + _odp_ipv4hdr_t *ip = odp_packet_l3_ptr(pkt, NULL); + uint16_t ip_hdr_len = ipv4_hdr_len(ip); + odp_crypto_packet_op_param_t param; + int rc; + unsigned stats_length; + uint16_t ipsec_offset; /**< Offset of IPsec header from + buffer start */ + uint8_t iv[MAX_IV_LEN]; /**< ESP IV storage */ + ipsec_aad_t aad; /**< AAD, note ESN is not fully supported */ + unsigned hdr_len; /**< Length of IPsec headers */ + unsigned trl_len; /**< Length of IPsec trailers */ + uint8_t ip_tos; /**< Saved IP TOS value */ + uint8_t ip_ttl; /**< Saved IP TTL value */ + uint16_t ip_frag_offset; /**< Saved IP flags value */ + odp_crypto_packet_result_t crypto; /**< Crypto operation result */ + + ODP_ASSERT(ODP_PACKET_OFFSET_INVALID != ip_offset); + ODP_ASSERT(NULL != ip); - return -1; + ip_tos = 0; + ip_ttl = 0; + ip_frag_offset = 0; + + /* Initialize parameters block */ + memset(¶m, 0, sizeof(param)); + + ipsec_offset = ip_offset + ip_hdr_len; + + if (_ODP_IPV4HDR_IS_FRAGMENT(odp_be_to_cpu_16(ip->frag_offset))) { + status->error.proto = 1; + goto out; + } + + /* Check IP header for IPSec protocols and look it up */ + if (_ODP_IPPROTO_ESP == ip->proto) { + _odp_esphdr_t esp; + + if (odp_packet_copy_to_mem(pkt, ipsec_offset, + sizeof(esp), &esp) < 0) { + status->error.alg = 1; + goto out; + } + + if (ODP_IPSEC_SA_INVALID == sa) { + ipsec_sa_lookup_t lookup; + + lookup.proto = ODP_IPSEC_ESP; + lookup.spi = odp_be_to_cpu_32(esp.spi); + lookup.dst_addr = &ip->dst_addr; + + ipsec_sa = _odp_ipsec_sa_lookup(&lookup); + if (NULL == ipsec_sa) { + status->error.sa_lookup = 1; + goto out; + } + } else { + ipsec_sa = _odp_ipsec_sa_use(sa); + ODP_ASSERT(NULL != ipsec_sa); + if (ipsec_sa->proto != ODP_IPSEC_ESP || + ipsec_sa->spi != odp_be_to_cpu_32(esp.spi)) { + status->error.proto = 1; + goto out; + } + } + + memcpy(iv, ipsec_sa->salt, ipsec_sa->salt_length); + if (odp_packet_copy_to_mem(pkt, + ipsec_offset + _ODP_ESPHDR_LEN, + ipsec_sa->esp_iv_len, + iv + ipsec_sa->salt_length) < 0) { + status->error.alg = 1; + goto out; + } + + hdr_len = _ODP_ESPHDR_LEN + ipsec_sa->esp_iv_len; + trl_len = _ODP_ESPTRL_LEN + ipsec_sa->icv_len; + + param.cipher_range.offset = ipsec_offset + hdr_len; + param.cipher_range.length = odp_be_to_cpu_16(ip->tot_len) - + ip_hdr_len - + hdr_len - + ipsec_sa->icv_len; + param.override_iv_ptr = iv; + + aad.spi = esp.spi; + aad.seq_no = esp.seq_no; + + param.aad.ptr = (uint8_t *)&aad; + param.aad.length = sizeof(aad); + + param.auth_range.offset = ipsec_offset; + param.auth_range.length = odp_be_to_cpu_16(ip->tot_len) - + ip_hdr_len - + ipsec_sa->icv_len; + param.hash_result_offset = ip_offset + + odp_be_to_cpu_16(ip->tot_len) - + ipsec_sa->icv_len; + + stats_length = param.cipher_range.length; + } else if (_ODP_IPPROTO_AH == ip->proto) { + _odp_ahhdr_t ah; + + if (odp_packet_copy_to_mem(pkt, ipsec_offset, + sizeof(ah), &ah) < 0) { + status->error.alg = 1; + goto out; + } + + if (ODP_IPSEC_SA_INVALID == sa) { + ipsec_sa_lookup_t lookup; + + lookup.proto = ODP_IPSEC_AH; + lookup.spi = odp_be_to_cpu_32(ah.spi); + lookup.dst_addr = &ip->dst_addr; + + ipsec_sa = _odp_ipsec_sa_lookup(&lookup); + if (NULL == ipsec_sa) { + status->error.sa_lookup = 1; + goto out; + } + } else { + ipsec_sa = _odp_ipsec_sa_use(sa); + ODP_ASSERT(NULL != ipsec_sa); + if (ipsec_sa->proto != ODP_IPSEC_AH || + ipsec_sa->spi != odp_be_to_cpu_32(ah.spi)) { + status->error.proto = 1; + goto out; + } + } + + hdr_len = (ah.ah_len + 2) * 4; + trl_len = 0; + + /* Save everything to context */ + ip_tos = ip->tos; + ip_frag_offset = odp_be_to_cpu_16(ip->frag_offset); + ip_ttl = ip->ttl; + + /* FIXME: zero copy of header, passing it to crypto! */ + /* + * If authenticating, zero the mutable fields build the request + */ + ip->chksum = 0; + ip->tos = 0; + ip->frag_offset = 0; + ip->ttl = 0; + + param.auth_range.offset = ip_offset; + param.auth_range.length = odp_be_to_cpu_16(ip->tot_len); + param.hash_result_offset = ipsec_offset + _ODP_AHHDR_LEN; + + stats_length = param.auth_range.length; + } else { + status->error.proto = 1; + goto out; + } + + if (_odp_ipsec_sa_update_stats(ipsec_sa, + stats_length, + status) < 0) + goto out; + + param.session = ipsec_sa->session; + + rc = odp_crypto_op(&pkt, &pkt, ¶m, 1); + if (rc < 0) { + ODP_DBG("Crypto failed\n"); + status->error.alg = 1; + goto out; + } + + rc = odp_crypto_result(&crypto, pkt); + if (rc < 0) { + ODP_DBG("Crypto failed\n"); + status->error.alg = 1; + goto out; + } + + if (!crypto.ok) { + if ((crypto.cipher_status.alg_err != + ODP_CRYPTO_ALG_ERR_NONE) || + (crypto.cipher_status.hw_err != + ODP_CRYPTO_HW_ERR_NONE)) + status->error.alg = 1; + + if ((crypto.auth_status.alg_err != + ODP_CRYPTO_ALG_ERR_NONE) || + (crypto.auth_status.hw_err != + ODP_CRYPTO_HW_ERR_NONE)) + status->error.auth = 1; + + goto out; + } + + ip_offset = odp_packet_l3_offset(pkt); + ip = odp_packet_l3_ptr(pkt, NULL); + ip_hdr_len = ipv4_hdr_len(ip); + + if (_ODP_IPPROTO_ESP == ip->proto) { + /* + * Finish cipher by finding ESP trailer and processing + */ + _odp_esptrl_t esptrl; + uint32_t esptrl_offset = ip_offset + + odp_be_to_cpu_16(ip->tot_len) - + trl_len; + + if (odp_packet_copy_to_mem(pkt, esptrl_offset, + sizeof(esptrl), &esptrl) < 0) { + status->error.proto = 1; + goto out; + } + + if (ip_offset + esptrl.pad_len > esptrl_offset) { + status->error.proto = 1; + goto out; + } + + if (_odp_packet_cmp_data(pkt, esptrl_offset - esptrl.pad_len, + ipsec_padding, esptrl.pad_len) != 0) { + status->error.proto = 1; + goto out; + } + + ip->proto = esptrl.next_header; + trl_len += esptrl.pad_len; + } else if (_ODP_IPPROTO_AH == ip->proto) { + /* + * Finish auth + */ + _odp_ahhdr_t ah; + + if (odp_packet_copy_to_mem(pkt, ipsec_offset, + sizeof(ah), &ah) < 0) { + status->error.alg = 1; + goto out; + } + + ip->proto = ah.next_header; + + /* Restore mutable fields */ + ip->ttl = ip_ttl; + ip->tos = ip_tos; + ip->frag_offset = odp_cpu_to_be_16(ip_frag_offset); + } else { + status->error.proto = 1; + goto out; + } + + if (odp_packet_trunc_tail(&pkt, trl_len, NULL, NULL) < 0) { + status->error.alg = 1; + goto out; + } + + if (ODP_IPSEC_MODE_TUNNEL == ipsec_sa->mode) { + /* We have a tunneled IPv4 packet, strip outer and IPsec + * headers */ + odp_packet_move_data(pkt, ip_hdr_len + hdr_len, 0, + ip_offset); + if (odp_packet_trunc_head(&pkt, ip_hdr_len + hdr_len, + NULL, NULL) < 0) { + status->error.alg = 1; + goto out; + } + } else { + odp_packet_move_data(pkt, hdr_len, 0, + ip_offset + ip_hdr_len); + if (odp_packet_trunc_head(&pkt, hdr_len, + NULL, NULL) < 0) { + status->error.alg = 1; + goto out; + } + } + + /* Finalize the IPv4 header */ + if (odp_packet_len(pkt) > sizeof(*ip)) { + ip = odp_packet_l3_ptr(pkt, NULL); + + if (ODP_IPSEC_MODE_TRANSPORT == ipsec_sa->mode) + ipv4_adjust_len(ip, -(hdr_len + trl_len)); + + ip->ttl -= ipsec_sa->dec_ttl; + _odp_ipv4_csum_update(pkt); + } + + if (!status->error.all) { + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + + packet_parse_reset(pkt_hdr); + + packet_parse_l3_l4(pkt_hdr, parse_layer(ipsec_config.inbound.parse), + ip_offset, _ODP_ETHTYPE_IPV4); + } +out: + *pkt_out = pkt; + + return ipsec_sa; +} + +/* Generate sequence number */ +static inline +uint32_t ipsec_seq_no(ipsec_sa_t *ipsec_sa) +{ + return odp_atomic_fetch_add_u32(&ipsec_sa->out.seq, 1); +} + +/* Helper for calculating encode length using data length and block size */ +#define ESP_ENCODE_LEN(x, b) ((((x) + ((b) - 1)) / (b)) * (b)) + +static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt, + odp_ipsec_sa_t sa, + odp_packet_t *pkt_out, + odp_ipsec_out_opt_t *opt ODP_UNUSED, + odp_ipsec_op_status_t *status) +{ + ipsec_sa_t *ipsec_sa = NULL; + uint32_t ip_offset = odp_packet_l3_offset(pkt); + _odp_ipv4hdr_t *ip = odp_packet_l3_ptr(pkt, NULL); + uint16_t ip_hdr_len = ipv4_hdr_len(ip); + odp_crypto_packet_op_param_t param; + unsigned stats_length; + int rc; + uint16_t ipsec_offset; /**< Offset of IPsec header from + buffer start */ + uint8_t iv[MAX_IV_LEN]; /**< ESP IV storage */ + ipsec_aad_t aad; /**< AAD, note ESN is not fully supported */ + unsigned hdr_len; /**< Length of IPsec headers */ + unsigned trl_len; /**< Length of IPsec trailers */ + uint8_t ip_tos; /**< Saved IP TOS value */ + uint8_t ip_ttl; /**< Saved IP TTL value */ + uint16_t ip_frag_offset; /**< Saved IP flags value */ + odp_crypto_packet_result_t crypto; /**< Crypto operation result */ + + ODP_ASSERT(ODP_PACKET_OFFSET_INVALID != ip_offset); + ODP_ASSERT(NULL != ip); + + ip_tos = 0; + ip_ttl = 0; + ip_frag_offset = 0; + + ipsec_sa = _odp_ipsec_sa_use(sa); + ODP_ASSERT(NULL != ipsec_sa); + + /* Initialize parameters block */ + memset(¶m, 0, sizeof(param)); + + if (ODP_IPSEC_MODE_TRANSPORT == ipsec_sa->mode && + _ODP_IPV4HDR_IS_FRAGMENT(odp_be_to_cpu_16(ip->frag_offset))) { + status->error.alg = 1; + goto out; + } + + if (ODP_IPSEC_MODE_TUNNEL == ipsec_sa->mode) { + _odp_ipv4hdr_t out_ip; + uint16_t tot_len; + + ip->ttl -= ipsec_sa->dec_ttl; + + out_ip.ver_ihl = 0x45; + if (ipsec_sa->copy_dscp) + out_ip.tos = ip->tos; + else + out_ip.tos = (ip->tos & ~_ODP_IP_TOS_DSCP_MASK) | + (ipsec_sa->out.tun_dscp << + _ODP_IP_TOS_DSCP_SHIFT); + tot_len = odp_be_to_cpu_16(ip->tot_len) + _ODP_IPV4HDR_LEN; + out_ip.tot_len = odp_cpu_to_be_16(tot_len); + /* No need to convert to BE: ID just should not be duplicated */ + out_ip.id = odp_atomic_fetch_add_u32(&ipsec_sa->out.tun_hdr_id, + 1); + if (ipsec_sa->copy_df) + out_ip.frag_offset = ip->frag_offset; + else + out_ip.frag_offset = (ip->frag_offset & ~0x4000) | + (ipsec_sa->out.tun_df << 14); + out_ip.ttl = ipsec_sa->out.tun_ttl; + out_ip.proto = _ODP_IPV4; + /* Will be filled later by packet checksum update */ + out_ip.chksum = 0; + out_ip.src_addr = ipsec_sa->out.tun_src_ip; + out_ip.dst_addr = ipsec_sa->out.tun_dst_ip; + + if (odp_packet_extend_head(&pkt, _ODP_IPV4HDR_LEN, + NULL, NULL) < 0) { + status->error.alg = 1; + goto out; + } + + odp_packet_move_data(pkt, 0, _ODP_IPV4HDR_LEN, ip_offset); + + odp_packet_copy_from_mem(pkt, ip_offset, + _ODP_IPV4HDR_LEN, &out_ip); + + odp_packet_l4_offset_set(pkt, ip_offset + _ODP_IPV4HDR_LEN); + + ip = odp_packet_l3_ptr(pkt, NULL); + ip_hdr_len = _ODP_IPV4HDR_LEN; + } + + ipsec_offset = ip_offset + ip_hdr_len; + + if (ipsec_sa->proto == ODP_IPSEC_ESP) { + _odp_esphdr_t esp; + _odp_esptrl_t esptrl; + uint32_t encrypt_len; + uint16_t ip_data_len = odp_be_to_cpu_16(ip->tot_len) - + ip_hdr_len; + uint32_t pad_block = ipsec_sa->esp_block_len; + + /* ESP trailer should be 32-bit right aligned */ + if (pad_block < 4) + pad_block = 4; + + encrypt_len = ESP_ENCODE_LEN(ip_data_len + _ODP_ESPTRL_LEN, + pad_block); + + hdr_len = _ODP_ESPHDR_LEN + ipsec_sa->esp_iv_len; + trl_len = encrypt_len - + ip_data_len + + ipsec_sa->icv_len; + + if (ipsec_sa->esp_iv_len) { + uint32_t len; + + len = odp_random_data(iv + ipsec_sa->salt_length, + ipsec_sa->esp_iv_len, + ODP_RANDOM_CRYPTO); + + if (len != ipsec_sa->esp_iv_len) { + status->error.alg = 1; + goto out; + } + + memcpy(iv, ipsec_sa->salt, ipsec_sa->salt_length); + + param.override_iv_ptr = iv; + } + + if (odp_packet_extend_tail(&pkt, trl_len, NULL, NULL) < 0) { + status->error.alg = 1; + goto out; + } + + if (odp_packet_extend_head(&pkt, hdr_len, NULL, NULL) < 0) { + status->error.alg = 1; + goto out; + } + + odp_packet_move_data(pkt, 0, hdr_len, ipsec_offset); + + ip = odp_packet_l3_ptr(pkt, NULL); + + /* Set IPv4 length before authentication */ + ipv4_adjust_len(ip, hdr_len + trl_len); + + uint32_t esptrl_offset = ip_offset + + ip_hdr_len + + hdr_len + + encrypt_len - + _ODP_ESPTRL_LEN; + + memset(&esp, 0, sizeof(esp)); + esp.spi = odp_cpu_to_be_32(ipsec_sa->spi); + esp.seq_no = odp_cpu_to_be_32(ipsec_seq_no(ipsec_sa)); + + aad.spi = esp.spi; + aad.seq_no = esp.seq_no; + + param.aad.ptr = (uint8_t *)&aad; + param.aad.length = sizeof(aad); + + memset(&esptrl, 0, sizeof(esptrl)); + esptrl.pad_len = encrypt_len - ip_data_len - _ODP_ESPTRL_LEN; + esptrl.next_header = ip->proto; + ip->proto = _ODP_IPPROTO_ESP; + + odp_packet_copy_from_mem(pkt, + ipsec_offset, _ODP_ESPHDR_LEN, + &esp); + memcpy(iv, ipsec_sa->salt, ipsec_sa->salt_length); + odp_packet_copy_from_mem(pkt, + ipsec_offset + _ODP_ESPHDR_LEN, + ipsec_sa->esp_iv_len, + iv + ipsec_sa->salt_length); + odp_packet_copy_from_mem(pkt, + esptrl_offset - esptrl.pad_len, + esptrl.pad_len, ipsec_padding); + odp_packet_copy_from_mem(pkt, + esptrl_offset, _ODP_ESPTRL_LEN, + &esptrl); + + param.cipher_range.offset = ipsec_offset + hdr_len; + param.cipher_range.length = odp_be_to_cpu_16(ip->tot_len) - + ip_hdr_len - + hdr_len - + ipsec_sa->icv_len; + + param.auth_range.offset = ipsec_offset; + param.auth_range.length = odp_be_to_cpu_16(ip->tot_len) - + ip_hdr_len - + ipsec_sa->icv_len; + param.hash_result_offset = ip_offset + + odp_be_to_cpu_16(ip->tot_len) - + ipsec_sa->icv_len; + + stats_length = param.cipher_range.length; + } else if (ipsec_sa->proto == ODP_IPSEC_AH) { + _odp_ahhdr_t ah; + + hdr_len = _ODP_AHHDR_LEN + ipsec_sa->icv_len; + trl_len = 0; + + /* Save IPv4 stuff */ + ip_tos = ip->tos; + ip_frag_offset = odp_be_to_cpu_16(ip->frag_offset); + ip_ttl = ip->ttl; + + if (odp_packet_extend_tail(&pkt, trl_len, NULL, NULL) < 0) { + status->error.alg = 1; + goto out; + } + + if (odp_packet_extend_head(&pkt, hdr_len, NULL, NULL) < 0) { + status->error.alg = 1; + goto out; + } + + odp_packet_move_data(pkt, 0, hdr_len, ipsec_offset); + + ip = odp_packet_l3_ptr(pkt, NULL); + + /* Set IPv4 length before authentication */ + ipv4_adjust_len(ip, hdr_len + trl_len); + + memset(&ah, 0, sizeof(ah)); + ah.spi = odp_cpu_to_be_32(ipsec_sa->spi); + ah.ah_len = 1 + (ipsec_sa->icv_len / 4); + ah.seq_no = odp_cpu_to_be_32(ipsec_seq_no(ipsec_sa)); + ah.next_header = ip->proto; + ip->proto = _ODP_IPPROTO_AH; + + odp_packet_copy_from_mem(pkt, + ipsec_offset, _ODP_AHHDR_LEN, + &ah); + _odp_packet_set_data(pkt, + ipsec_offset + _ODP_AHHDR_LEN, + 0, ipsec_sa->icv_len); + + ip->chksum = 0; + ip->tos = 0; + ip->frag_offset = 0; + ip->ttl = 0; + + param.auth_range.offset = ip_offset; + param.auth_range.length = odp_be_to_cpu_16(ip->tot_len); + param.hash_result_offset = ipsec_offset + _ODP_AHHDR_LEN; + + stats_length = param.auth_range.length; + } else { + status->error.alg = 1; + goto out; + } + + if (_odp_ipsec_sa_update_stats(ipsec_sa, + stats_length, + status) < 0) + goto out; + + param.session = ipsec_sa->session; + + rc = odp_crypto_op(&pkt, &pkt, ¶m, 1); + if (rc < 0) { + ODP_DBG("Crypto failed\n"); + status->error.alg = 1; + goto out; + } + + rc = odp_crypto_result(&crypto, pkt); + if (rc < 0) { + ODP_DBG("Crypto failed\n"); + status->error.alg = 1; + goto out; + } + + if (!crypto.ok) { + if ((crypto.cipher_status.alg_err != + ODP_CRYPTO_ALG_ERR_NONE) || + (crypto.cipher_status.hw_err != + ODP_CRYPTO_HW_ERR_NONE)) + status->error.alg = 1; + + if ((crypto.auth_status.alg_err != + ODP_CRYPTO_ALG_ERR_NONE) || + (crypto.auth_status.hw_err != + ODP_CRYPTO_HW_ERR_NONE)) + status->error.auth = 1; + + goto out; + } + + ip = odp_packet_l3_ptr(pkt, NULL); + + /* Finalize the IPv4 header */ + if (ip->proto == _ODP_IPPROTO_AH) { + ip->ttl = ip_ttl; + ip->tos = ip_tos; + ip->frag_offset = odp_cpu_to_be_16(ip_frag_offset); + } + + _odp_ipv4_csum_update(pkt); + +out: + + *pkt_out = pkt; + return ipsec_sa; } int odp_ipsec_in(const odp_packet_t pkt_in[], int num_in, odp_packet_t pkt_out[], int *num_out, const odp_ipsec_in_param_t *param) { - (void)pkt_in; - (void)num_in; - (void)pkt_out; - (void)num_out; - (void)param; + int in_pkt = 0; + int out_pkt = 0; + int max_out = *num_out; + unsigned sa_idx = 0; + unsigned sa_inc = (param->num_sa > 1) ? 1 : 0; + + while (in_pkt < num_in && out_pkt < max_out) { + odp_packet_t pkt = pkt_in[in_pkt]; + odp_ipsec_op_status_t status; + odp_ipsec_sa_t sa; + ipsec_sa_t *ipsec_sa; + odp_ipsec_packet_result_t *result; + + memset(&status, 0, sizeof(status)); + + if (0 == param->num_sa) { + sa = ODP_IPSEC_SA_INVALID; + } else { + sa = param->sa[sa_idx++]; + ODP_ASSERT(ODP_IPSEC_SA_INVALID != sa); + } + + ipsec_sa = ipsec_in_single(pkt, sa, &pkt, &status); + + _odp_buffer_event_subtype_set(packet_to_buffer(pkt), + ODP_EVENT_PACKET_IPSEC); + result = ipsec_pkt_result(pkt); + memset(result, 0, sizeof(*result)); + result->status = status; + if (NULL != ipsec_sa) + result->sa = ipsec_sa->ipsec_sa_hdl; + else + result->sa = ODP_IPSEC_SA_INVALID; + + pkt_out[out_pkt] = pkt; + in_pkt++; + out_pkt++; + sa_idx += sa_inc; + + /* Last thing */ + if (NULL != ipsec_sa) + _odp_ipsec_sa_unuse(ipsec_sa); + } - return -1; + *num_out = out_pkt; + + return in_pkt; } +static odp_ipsec_out_opt_t default_opt = { + .mode = ODP_IPSEC_FRAG_DISABLED, +}; + int odp_ipsec_out(const odp_packet_t pkt_in[], int num_in, odp_packet_t pkt_out[], int *num_out, const odp_ipsec_out_param_t *param) { - (void)pkt_in; - (void)num_in; - (void)pkt_out; - (void)num_out; - (void)param; + int in_pkt = 0; + int out_pkt = 0; + int max_out = *num_out; + unsigned sa_idx = 0; + unsigned opt_idx = 0; + unsigned sa_inc = (param->num_sa > 1) ? 1 : 0; + unsigned opt_inc = (param->num_opt > 1) ? 1 : 0; + + ODP_ASSERT(param->num_sa != 0); + + while (in_pkt < num_in && out_pkt < max_out) { + odp_packet_t pkt = pkt_in[in_pkt]; + odp_ipsec_op_status_t status; + odp_ipsec_sa_t sa; + ipsec_sa_t *ipsec_sa; + odp_ipsec_packet_result_t *result; + odp_ipsec_out_opt_t *opt; + + memset(&status, 0, sizeof(status)); + + sa = param->sa[sa_idx++]; + ODP_ASSERT(ODP_IPSEC_SA_INVALID != sa); + + if (0 == param->num_opt) + opt = &default_opt; + else + opt = ¶m->opt[opt_idx]; + + ipsec_sa = ipsec_out_single(pkt, sa, &pkt, opt, &status); + ODP_ASSERT(NULL != ipsec_sa); - return -1; + _odp_buffer_event_subtype_set(packet_to_buffer(pkt), + ODP_EVENT_PACKET_IPSEC); + result = ipsec_pkt_result(pkt); + memset(result, 0, sizeof(*result)); + result->status = status; + result->sa = ipsec_sa->ipsec_sa_hdl; + + pkt_out[out_pkt] = pkt; + in_pkt++; + out_pkt++; + sa_idx += sa_inc; + opt_idx += opt_inc; + + /* Last thing */ + _odp_ipsec_sa_unuse(ipsec_sa); + } + + *num_out = out_pkt; + + return in_pkt; } -int odp_ipsec_in_enq(const odp_packet_t pkt[], int num, +int odp_ipsec_in_enq(const odp_packet_t pkt_in[], int num_in, const odp_ipsec_in_param_t *param) { - (void)pkt; - (void)num; - (void)param; + int in_pkt = 0; + unsigned sa_idx = 0; + unsigned sa_inc = (param->num_sa > 1) ? 1 : 0; + + while (in_pkt < num_in) { + odp_packet_t pkt = pkt_in[in_pkt]; + odp_ipsec_op_status_t status; + odp_ipsec_sa_t sa; + ipsec_sa_t *ipsec_sa; + odp_ipsec_packet_result_t *result; + odp_queue_t queue; + + memset(&status, 0, sizeof(status)); + + if (0 == param->num_sa) { + sa = ODP_IPSEC_SA_INVALID; + } else { + sa = param->sa[sa_idx++]; + ODP_ASSERT(ODP_IPSEC_SA_INVALID != sa); + } + + ipsec_sa = ipsec_in_single(pkt, sa, &pkt, &status); - return -1; + _odp_buffer_event_subtype_set(packet_to_buffer(pkt), + ODP_EVENT_PACKET_IPSEC); + result = ipsec_pkt_result(pkt); + memset(result, 0, sizeof(*result)); + result->status = status; + if (NULL != ipsec_sa) { + result->sa = ipsec_sa->ipsec_sa_hdl; + queue = ipsec_sa->queue; + } else { + result->sa = ODP_IPSEC_SA_INVALID; + queue = ipsec_config.inbound.default_queue; + } + + if (odp_queue_enq(queue, odp_ipsec_packet_to_event(pkt))) { + odp_packet_free(pkt); + break; + } + in_pkt++; + sa_idx += sa_inc; + + /* Last thing */ + if (NULL != ipsec_sa) + _odp_ipsec_sa_unuse(ipsec_sa); + } + + return in_pkt; } -int odp_ipsec_out_enq(const odp_packet_t pkt[], int num, +int odp_ipsec_out_enq(const odp_packet_t pkt_in[], int num_in, const odp_ipsec_out_param_t *param) { - (void)pkt; - (void)num; - (void)param; + int in_pkt = 0; + unsigned sa_idx = 0; + unsigned opt_idx = 0; + unsigned sa_inc = (param->num_sa > 1) ? 1 : 0; + unsigned opt_inc = (param->num_opt > 1) ? 1 : 0; + + ODP_ASSERT(param->num_sa != 0); + + while (in_pkt < num_in) { + odp_packet_t pkt = pkt_in[in_pkt]; + odp_ipsec_op_status_t status; + odp_ipsec_sa_t sa; + ipsec_sa_t *ipsec_sa; + odp_ipsec_packet_result_t *result; + odp_ipsec_out_opt_t *opt; + odp_queue_t queue; + + memset(&status, 0, sizeof(status)); + + sa = param->sa[sa_idx++]; + ODP_ASSERT(ODP_IPSEC_SA_INVALID != sa); + + if (0 == param->num_opt) + opt = &default_opt; + else + opt = ¶m->opt[opt_idx]; - return -1; + ipsec_sa = ipsec_out_single(pkt, sa, &pkt, opt, &status); + ODP_ASSERT(NULL != ipsec_sa); + + _odp_buffer_event_subtype_set(packet_to_buffer(pkt), + ODP_EVENT_PACKET_IPSEC); + result = ipsec_pkt_result(pkt); + memset(result, 0, sizeof(*result)); + result->status = status; + result->sa = ipsec_sa->ipsec_sa_hdl; + queue = ipsec_sa->queue; + + if (odp_queue_enq(queue, odp_ipsec_packet_to_event(pkt))) { + odp_packet_free(pkt); + break; + } + in_pkt++; + sa_idx += sa_inc; + opt_idx += opt_inc; + + /* Last thing */ + _odp_ipsec_sa_unuse(ipsec_sa); + } + + return in_pkt; } -int odp_ipsec_out_inline(const odp_packet_t pkt[], int num, +int _odp_ipsec_try_inline(odp_packet_t pkt) +{ + odp_ipsec_op_status_t status; + ipsec_sa_t *ipsec_sa; + odp_ipsec_packet_result_t *result; + odp_queue_t queue; + + memset(&status, 0, sizeof(status)); + + ipsec_sa = ipsec_in_single(pkt, ODP_IPSEC_SA_INVALID, &pkt, &status); + /* + * Route packet back in case of lookup failure or early error before + * lookup + */ + if (NULL == ipsec_sa) + return -1; + + _odp_buffer_event_subtype_set(packet_to_buffer(pkt), + ODP_EVENT_PACKET_IPSEC); + result = ipsec_pkt_result(pkt); + memset(result, 0, sizeof(*result)); + result->status = status; + result->sa = ipsec_sa->ipsec_sa_hdl; + queue = ipsec_sa->queue; + + if (odp_queue_enq(queue, odp_ipsec_packet_to_event(pkt))) + odp_packet_free(pkt); + + /* Last thing */ + _odp_ipsec_sa_unuse(ipsec_sa); + + return 0; +} + +int odp_ipsec_out_inline(const odp_packet_t pkt_in[], int num_in, const odp_ipsec_out_param_t *param, const odp_ipsec_out_inline_param_t *inline_param) { - (void)pkt; - (void)num; - (void)param; - (void)inline_param; + int in_pkt = 0; + unsigned sa_idx = 0; + unsigned opt_idx = 0; + unsigned sa_inc = (param->num_sa > 1) ? 1 : 0; + unsigned opt_inc = (param->num_opt > 1) ? 1 : 0; + + ODP_ASSERT(param->num_sa != 0); + + while (in_pkt < num_in) { + odp_packet_t pkt = pkt_in[in_pkt]; + odp_ipsec_op_status_t status; + odp_ipsec_sa_t sa; + ipsec_sa_t *ipsec_sa; + odp_ipsec_packet_result_t *result; + odp_ipsec_out_opt_t *opt; + uint32_t hdr_len, offset; + const void *ptr; + + memset(&status, 0, sizeof(status)); + + if (0 == param->num_sa) { + sa = ODP_IPSEC_SA_INVALID; + } else { + sa = param->sa[sa_idx++]; + ODP_ASSERT(ODP_IPSEC_SA_INVALID != sa); + } + + if (0 == param->num_opt) + opt = &default_opt; + else + opt = ¶m->opt[opt_idx]; + + hdr_len = inline_param[in_pkt].outer_hdr.len; + ptr = inline_param[in_pkt].outer_hdr.ptr; + offset = odp_packet_l3_offset(pkt); + if (offset >= hdr_len) { + if (odp_packet_trunc_head(&pkt, offset - hdr_len, + NULL, NULL) < 0) + status.error.alg = 1; + + } else { + if (odp_packet_extend_head(&pkt, hdr_len - offset, + NULL, NULL) < 0) + status.error.alg = 1; + } + + odp_packet_l3_offset_set(pkt, hdr_len); - return -1; + if (odp_packet_copy_from_mem(pkt, 0, + hdr_len, + ptr) < 0) + status.error.alg = 1; + + ipsec_sa = ipsec_out_single(pkt, sa, &pkt, opt, &status); + ODP_ASSERT(NULL != ipsec_sa); + + _odp_buffer_event_subtype_set(packet_to_buffer(pkt), + ODP_EVENT_PACKET_IPSEC); + result = ipsec_pkt_result(pkt); + memset(result, 0, sizeof(*result)); + result->sa = ipsec_sa->ipsec_sa_hdl; + result->status = status; + + if (!status.error.all) { + odp_pktout_queue_t pkqueue; + + if (odp_pktout_queue(inline_param[in_pkt].pktio, + &pkqueue, 1) < 0) { + status.error.alg = 1; + goto err; + } + + if (odp_pktout_send(pkqueue, &pkt, 1) < 0) { + status.error.alg = 1; + goto err; + } + } else { + odp_queue_t queue; + odp_buffer_t buf; +err: + buf = packet_to_buffer(pkt); + _odp_buffer_event_subtype_set(buf, + ODP_EVENT_PACKET_IPSEC); + result = ipsec_pkt_result(pkt); + memset(result, 0, sizeof(*result)); + result->sa = ipsec_sa->ipsec_sa_hdl; + result->status = status; + queue = ipsec_sa->queue; + + if (odp_queue_enq(queue, + odp_ipsec_packet_to_event(pkt))) { + odp_packet_free(pkt); + break; + } + } + in_pkt++; + sa_idx += sa_inc; + opt_idx += opt_inc; + + /* Last thing */ + _odp_ipsec_sa_unuse(ipsec_sa); + } + + return in_pkt; } int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t packet) { - (void)result; - (void)packet; + odp_ipsec_packet_result_t *res; - return -1; + ODP_ASSERT(result != NULL); + + res = ipsec_pkt_result(packet); + + /* FIXME: maybe postprocess here, setting alg error in case of crypto + * error instead of processing packet fully in ipsec_in/out_single */ + + *result = *res; + + return 0; } odp_packet_t odp_ipsec_packet_from_event(odp_event_t ev) { - (void)ev; - - return ODP_PACKET_INVALID; + return odp_packet_from_event(ev); } odp_event_t odp_ipsec_packet_to_event(odp_packet_t pkt) { - (void)pkt; - - return ODP_EVENT_INVALID; + return odp_packet_to_event(pkt); }