From patchwork Tue May 30 16:00:18 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: 100718 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp289428qge; Tue, 30 May 2017 09:07:57 -0700 (PDT) X-Received: by 10.36.192.197 with SMTP id u188mr2835189itf.39.1496160476956; Tue, 30 May 2017 09:07:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1496160476; cv=none; d=google.com; s=arc-20160816; b=Nz9stWxXCdP4WIBcu6Wp2mRNedvhvN+cWbc6Rp+SxbpcJwmaWbhamgiDYLlAC4QqJN C+rr5j7+CpWKTvCMM5YveANR/sLdduYL5X1QQbDhgQB/Z1TiIqmuwIunu4fFleZ7Ev2Q SlEGu58vRmA4Zi8iZ1uPqjk4XDfrTtu78sAfUC6e2kITiF6TKTec+I6e3MBADTxVppgf pU+ELbBVXCx3QVRv1eKcaH0QpyP7Uh3McridM015WlJEyzf0IceOSEO8L1ohztV4qAad s+QVOubVSAkpLFHKnv8kE5U76lwl2k6ElBOFqNcDY35b9S2Bqg6hTPBtEZ1U/VaqB2R6 DZAQ== 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=SFF0NQx1EzQ0sJvu0dEVa/JL/v3rq46SWQxTUGpWFBM=; b=Xgl9lCEny1aKL8D6uzFJU3Kh3yrg+AkrxNe7eWJ6Wf2X9rmkVioj1mKZ/xoRGq85TJ v27M+C/dktjRL2OJQOBwmnZYJHTyKtjoogfiH5Iyj+GHD92a78f3OizSkDQbpe/7bdMe rFokNv9lDuxMhp/rzEUbnHchWoCPgzWYQblukHwGRE1RBxkjm+5lwsLKEOxGgTw8mRTh c1CRT3hbou3NWPk0OLFaijsAsHH7RhkpqpBFMpI4f3oOLl6rhmGKiJDIRFG8LNCZqdgL CPYtKAv9XXk1xp8sUBY/2G198+KVVeexGCLvd1P8WSefFdcadkhce9pTLb0RezixDBFh zIOw== 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 135si24396084itf.60.2017.05.30.09.07.56; Tue, 30 May 2017 09:07:56 -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 723E06065A; Tue, 30 May 2017 16:07:56 +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=-0.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, URIBL_BLOCKED, URIBL_SBL, URIBL_SBL_A 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 8243960BF0; Tue, 30 May 2017 16:01:37 +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 A600C60BE6; Tue, 30 May 2017 16:01:28 +0000 (UTC) Received: from forward3m.cmail.yandex.net (forward3m.cmail.yandex.net [5.255.216.21]) by lists.linaro.org (Postfix) with ESMTPS id 3399B60BEA for ; Tue, 30 May 2017 16:00:36 +0000 (UTC) Received: from smtp3h.mail.yandex.net (smtp3h.mail.yandex.net [IPv6:2a02:6b8:0:f05::117]) by forward3m.cmail.yandex.net (Yandex) with ESMTP id A40592103F for ; Tue, 30 May 2017 19:00:34 +0300 (MSK) Received: from smtp3h.mail.yandex.net (localhost.localdomain [127.0.0.1]) by smtp3h.mail.yandex.net (Yandex) with ESMTP id 747F3440E00 for ; Tue, 30 May 2017 19:00:33 +0300 (MSK) Received: by smtp3h.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id GGvgnOIc9C-0WGKMY3c; Tue, 30 May 2017 19:00:32 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) X-Yandex-Suid-Status: 1 0 From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 30 May 2017 19:00:18 +0300 Message-Id: <1496160020-31721-3-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1496160020-31721-1-git-send-email-odpbot@yandex.ru> References: <1496160020-31721-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 28 Subject: [lng-odp] [PATCH API-NEXT v7 2/4] 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 28 (lumag:ipsec) ** https://github.com/Linaro/odp/pull/28 ** Patch: https://github.com/Linaro/odp/pull/28.patch ** Base sha: 552817483e9d4b6a84d49960920f1de50029f111 ** Merge commit sha: 0b87818fa5d85599e1381f06c907f7daa2a4986b **/ platform/linux-generic/Makefile.am | 2 + .../include/odp/api/plat/event_types.h | 3 +- platform/linux-generic/include/odp_internal.h | 4 + .../linux-generic/include/odp_ipsec_internal.h | 150 +++++++++++ platform/linux-generic/odp_event.c | 7 + platform/linux-generic/odp_init.c | 13 + platform/linux-generic/odp_ipsec.c | 19 +- platform/linux-generic/odp_ipsec_events.c | 274 +++++++++++++++++++++ 8 files changed, 461 insertions(+), 11 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 79f0e70c..0cd81498 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -155,6 +155,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_name_table_internal.h \ ${srcdir}/include/odp_packet_internal.h \ ${srcdir}/include/odp_packet_io_internal.h \ @@ -206,6 +207,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/api/plat/event_types.h b/platform/linux-generic/include/odp/api/plat/event_types.h index 0f517834..cb3a1f89 100644 --- a/platform/linux-generic/include/odp/api/plat/event_types.h +++ b/platform/linux-generic/include/odp/api/plat/event_types.h @@ -39,7 +39,8 @@ typedef enum odp_event_type_t { ODP_EVENT_PACKET = 2, ODP_EVENT_TIMEOUT = 3, ODP_EVENT_CRYPTO_COMPL = 4, - ODP_EVENT_IPSEC_RESULT = 5 + ODP_EVENT_IPSEC_RESULT = 5, + ODP_EVENT_IPSEC_STATUS = 6 } odp_event_type_t; /** diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index 90e2a629..149f8611 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -70,6 +70,7 @@ enum init_stage { CLASSIFICATION_INIT, TRAFFIC_MNGR_INIT, NAME_TABLE_INIT, + IPSEC_EVENTS_INIT, MODULES_INIT, ALL_INIT /* All init stages completed */ }; @@ -129,6 +130,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 00000000..9f644a81 --- /dev/null +++ b/platform/linux-generic/include/odp_ipsec_internal.h @@ -0,0 +1,150 @@ +/* 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_result_t); + +#define ODP_IPSEC_RESULT_INVALID \ + _odp_cast_scalar(ipsec_result_t, 0xffffffff) + +typedef ODP_HANDLE_T(ipsec_status_t); + +#define ODP_IPSEC_STATUS_INVALID \ + _odp_cast_scalar(ipsec_status_t, 0xffffffff) + +typedef struct ipsec_ctx_s ipsec_ctx_t; + +/** + * @internal Free IPsec context + * + * Frees the IPsec context into the pool it was allocated from. + * + * @param ctx IPsec context + */ +void _odp_ipsec_ctx_free(ipsec_ctx_t *ctx); + +/** + * @internal Process context filling operation result information + * + * Processes IPsec operation context related to completed operation, extracting + * operation result information. This function may update context provided via + * pointer to opaque context pointer. + * + * @param ctx IPsec context pointer. + * @param[out] result Pointer to operation result for output. May be + * NULL, if application is interested only on the + * number of packets. + * + * @return Number of packets remaining in the event. + * @retval <0 On failure + */ +int _odp_ipsec_ctx_result(ipsec_ctx_t *ctx, odp_ipsec_op_result_t *result); + +/** + * @internal Get ipsec_result handle from event + * + * Converts an ODP_EVENT_IPSEC_RESULT type event to an IPsec result event. + * + * @param ev Event handle + * + * @return IPsec result handle + * + * @see odp_event_type() + */ +ipsec_result_t _odp_ipsec_result_from_event(odp_event_t ev); + +/** + * @internal Free IPsec result event + * + * Frees the ipsec_result into the ipsec_result pool it was allocated from. + * + * @param res IPsec result handle + */ +void _odp_ipsec_result_free(ipsec_result_t res); + +/** + * @internal Send ODP_IPSEC_RESULT event + * + * Sends the ipsec_result event using provided information + * + * @param queue destination queue + * @param ctx IPsec context for the operation + * + * @retval 0 on success + * @retval <0 on failure + */ +int _odp_ipsec_result_send(odp_queue_t queue, ipsec_ctx_t *ctx); + +/** + * @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 ret status value + * @param sa SA respective to the operation + * + * @retval 0 on success + * @retval <0 on failure + */ +int _odp_ipsec_status_send(odp_queue_t queue, + odp_ipsec_status_id_t id, + int ret, + odp_ipsec_sa_t sa); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/odp_event.c b/platform/linux-generic/odp_event.c index d71f4464..fd0a5ff9 100644 --- a/platform/linux-generic/odp_event.c +++ b/platform/linux-generic/odp_event.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,12 @@ 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_RESULT: + _odp_ipsec_result_free(_odp_ipsec_result_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 685e02fa..1ff6880f 100644 --- a/platform/linux-generic/odp_init.c +++ b/platform/linux-generic/odp_init.c @@ -266,6 +266,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; @@ -296,6 +302,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 10918dfb..7d6b4103 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) @@ -73,6 +75,11 @@ int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa) return -1; } +void _odp_ipsec_ctx_free(ipsec_ctx_t *ctx) +{ + (void)ctx; +} + int odp_ipsec_in(const odp_ipsec_op_param_t *input, odp_ipsec_op_result_t *output) { @@ -114,18 +121,10 @@ int odp_ipsec_out_inline(const odp_ipsec_op_param_t *op_param, return -1; } -int odp_ipsec_result(odp_ipsec_op_result_t *result, odp_event_t event) +int _odp_ipsec_ctx_result(ipsec_ctx_t *ctx, odp_ipsec_op_result_t *result) { + (void)ctx; (void)result; - (void)event; - - return -1; -} - -int odp_ipsec_status(odp_ipsec_status_t *status, odp_event_t event) -{ - (void)status; - (void)event; return -1; } diff --git a/platform/linux-generic/odp_ipsec_events.c b/platform/linux-generic/odp_ipsec_events.c new file mode 100644 index 00000000..a73df8c2 --- /dev/null +++ b/platform/linux-generic/odp_ipsec_events.c @@ -0,0 +1,274 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include + +typedef struct { + /* common buffer header */ + odp_buffer_hdr_t buf_hdr; + + ipsec_ctx_t *ctx; +} ipsec_result_hdr_t; + +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_result_pool = ODP_POOL_INVALID; +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_result_hdr_t); + param.buf.align = 0; + param.buf.num = IPSEC_EVENTS_POOL_BUF_COUNT; + param.type = ODP_POOL_BUFFER; + + ipsec_result_pool = odp_pool_create("ipsec_result_pool", ¶m); + if (ODP_POOL_INVALID == ipsec_result_pool) { + ODP_ERR("Error: result pool create failed.\n"); + goto err_result; + } + + 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: + (void)odp_pool_destroy(ipsec_result_pool); +err_result: + 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; + } + + ret = odp_pool_destroy(ipsec_result_pool); + if (ret < 0) { + ODP_ERR("result pool destroy failed"); + rc = -1; + } + + return rc; +} + +ipsec_result_t _odp_ipsec_result_from_event(odp_event_t ev) +{ + ODP_ASSERT(ODP_EVENT_INVALID != ev); + ODP_ASSERT(ODP_EVENT_IPSEC_RESULT == odp_event_type(ev)); + + return (ipsec_result_t)ev; +} + +static +odp_event_t ipsec_result_to_event(ipsec_result_t res) +{ + ODP_ASSERT(ODP_IPSEC_RESULT_INVALID != res); + + return (odp_event_t)res; +} + +static +ipsec_result_hdr_t *ipsec_result_hdr_from_buf(odp_buffer_t buf) +{ + return (ipsec_result_hdr_t *)(void *)buf_hdl_to_hdr(buf); +} + +static +ipsec_result_hdr_t *ipsec_result_hdr(ipsec_result_t res) +{ + odp_buffer_t buf = odp_buffer_from_event(ipsec_result_to_event(res)); + + return ipsec_result_hdr_from_buf(buf); +} + +static +ipsec_result_t _odp_ipsec_result_alloc(void) +{ + odp_buffer_t buf = odp_buffer_alloc(ipsec_result_pool); + + if (odp_unlikely(buf == ODP_BUFFER_INVALID)) + return ODP_IPSEC_RESULT_INVALID; + + _odp_buffer_event_type_set(buf, ODP_EVENT_IPSEC_RESULT); + + return _odp_ipsec_result_from_event(odp_buffer_to_event(buf)); +} + +void _odp_ipsec_result_free(ipsec_result_t res) +{ + odp_event_t ev = ipsec_result_to_event(res); + ipsec_result_hdr_t *res_hdr = ipsec_result_hdr(res); + + _odp_ipsec_ctx_free(res_hdr->ctx); + + odp_buffer_free(odp_buffer_from_event(ev)); +} + +int _odp_ipsec_result_send(odp_queue_t queue, ipsec_ctx_t *ctx) +{ + ipsec_result_t ipsec_ev; + ipsec_result_hdr_t *res_hdr; + + ipsec_ev = _odp_ipsec_result_alloc(); + if (odp_unlikely(ODP_IPSEC_RESULT_INVALID == ipsec_ev)) { + _odp_ipsec_ctx_free(ctx); + return -1; + } + + res_hdr = ipsec_result_hdr(ipsec_ev); + res_hdr->ctx = ctx; + + if (odp_queue_enq(queue, ipsec_result_to_event(ipsec_ev))) { + _odp_ipsec_result_free(ipsec_ev); + _odp_ipsec_ctx_free(ctx); + return -1; + } + + return 0; +} + +int odp_ipsec_result(odp_ipsec_op_result_t *result, odp_event_t event) +{ + ipsec_result_t ipsec_ev; + ipsec_result_hdr_t *res_hdr; + + ODP_ASSERT(ODP_EVENT_INVALID != event); + + ipsec_ev = _odp_ipsec_result_from_event(event); + ODP_ASSERT(ODP_IPSEC_RESULT_INVALID != ipsec_ev); + + res_hdr = ipsec_result_hdr(ipsec_ev); + + return _odp_ipsec_ctx_result(res_hdr->ctx, result); +} + +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, + int ret, + odp_ipsec_sa_t sa) +{ + 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.ret = ret; + status_hdr->status.sa = sa; + + 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; +}