From: Dmitry Eremin-Solenikov <dmitry.ereminsoleni...@linaro.org>

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsoleni...@linaro.org>
---
/** Email created from pull request 256 (lumag:ipsec_sa_disable_v2)
 ** https://github.com/Linaro/odp/pull/256
 ** Patch: https://github.com/Linaro/odp/pull/256.patch
 ** Base sha: 825f75ed8644ef57c5648961e7982daf13cd9375
 ** Merge commit sha: ba520d0a3f4c46777c7aedca029e9979a89c69e7
 **/
 .../linux-generic/include/odp_ipsec_internal.h     | 20 +++++++-
 platform/linux-generic/odp_ipsec.c                 | 18 ++++----
 platform/linux-generic/odp_ipsec_events.c          | 54 +++++++++++++++++++++-
 platform/linux-generic/odp_ipsec_sad.c             | 16 ++-----
 4 files changed, 84 insertions(+), 24 deletions(-)

diff --git a/platform/linux-generic/include/odp_ipsec_internal.h 
b/platform/linux-generic/include/odp_ipsec_internal.h
index 1340ca7bd..09a7ac126 100644
--- a/platform/linux-generic/include/odp_ipsec_internal.h
+++ b/platform/linux-generic/include/odp_ipsec_internal.h
@@ -74,9 +74,20 @@ void _odp_ipsec_status_free(ipsec_status_t status);
 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);
 
+/**
+ * @internal Send SA_DISABLED event
+ *
+ * Sends the packet notifying application that SA finished all processing and
+ * is now disabled.
+ *
+ * @param queue         destination queue
+ * @param sa            SA respective to the operation
+ */
+int _odp_ipsec_sa_disabled_send(odp_queue_t queue,
+                               odp_ipsec_sa_t sa);
+
 #define IPSEC_MAX_IV_LEN       32   /**< Maximum IV length in bytes */
 
 #define IPSEC_MAX_SALT_LEN     4    /**< Maximum salt length in bytes */
@@ -191,6 +202,13 @@ int _odp_ipsec_sa_update_stats(ipsec_sa_t *ipsec_sa, 
uint32_t len,
 int _odp_ipsec_try_inline(odp_packet_t pkt);
 
 /**
+ * Return IPsec result instance connected to the IPsec packet
+ *
+ * @param packet packet of ODP_EVENT_PACKET_IPSEC subtype
+ */
+odp_ipsec_packet_result_t *_odp_ipsec_pkt_result(odp_packet_t packet);
+
+/**
  * @}
  */
 
diff --git a/platform/linux-generic/odp_ipsec.c 
b/platform/linux-generic/odp_ipsec.c
index e57736c2a..e9bf88c17 100644
--- a/platform/linux-generic/odp_ipsec.c
+++ b/platform/linux-generic/odp_ipsec.c
@@ -93,7 +93,7 @@ int odp_ipsec_config(const odp_ipsec_config_t *config)
        return 0;
 }
 
-static odp_ipsec_packet_result_t *ipsec_pkt_result(odp_packet_t packet)
+odp_ipsec_packet_result_t *_odp_ipsec_pkt_result(odp_packet_t packet)
 {
        ODP_ASSERT(ODP_EVENT_PACKET_IPSEC ==
                   odp_event_subtype(odp_packet_to_event(packet)));
@@ -902,7 +902,7 @@ int odp_ipsec_in(const odp_packet_t pkt_in[], int num_in,
 
                _odp_buffer_event_subtype_set(packet_to_buffer(pkt),
                                              ODP_EVENT_PACKET_IPSEC);
-               result = ipsec_pkt_result(pkt);
+               result = _odp_ipsec_pkt_result(pkt);
                memset(result, 0, sizeof(*result));
                result->status = status;
                if (NULL != ipsec_sa)
@@ -966,7 +966,7 @@ int odp_ipsec_out(const odp_packet_t pkt_in[], int num_in,
 
                _odp_buffer_event_subtype_set(packet_to_buffer(pkt),
                                              ODP_EVENT_PACKET_IPSEC);
-               result = ipsec_pkt_result(pkt);
+               result = _odp_ipsec_pkt_result(pkt);
                memset(result, 0, sizeof(*result));
                result->status = status;
                result->sa = ipsec_sa->ipsec_sa_hdl;
@@ -1014,7 +1014,7 @@ int odp_ipsec_in_enq(const odp_packet_t pkt_in[], int 
num_in,
 
                _odp_buffer_event_subtype_set(packet_to_buffer(pkt),
                                              ODP_EVENT_PACKET_IPSEC);
-               result = ipsec_pkt_result(pkt);
+               result = _odp_ipsec_pkt_result(pkt);
                memset(result, 0, sizeof(*result));
                result->status = status;
                if (NULL != ipsec_sa) {
@@ -1075,7 +1075,7 @@ int odp_ipsec_out_enq(const odp_packet_t pkt_in[], int 
num_in,
 
                _odp_buffer_event_subtype_set(packet_to_buffer(pkt),
                                              ODP_EVENT_PACKET_IPSEC);
-               result = ipsec_pkt_result(pkt);
+               result = _odp_ipsec_pkt_result(pkt);
                memset(result, 0, sizeof(*result));
                result->status = status;
                result->sa = ipsec_sa->ipsec_sa_hdl;
@@ -1115,7 +1115,7 @@ int _odp_ipsec_try_inline(odp_packet_t pkt)
 
        _odp_buffer_event_subtype_set(packet_to_buffer(pkt),
                                      ODP_EVENT_PACKET_IPSEC);
-       result = ipsec_pkt_result(pkt);
+       result = _odp_ipsec_pkt_result(pkt);
        memset(result, 0, sizeof(*result));
        result->status = status;
        result->sa = ipsec_sa->ipsec_sa_hdl;
@@ -1192,7 +1192,7 @@ int odp_ipsec_out_inline(const odp_packet_t pkt_in[], int 
num_in,
 
                _odp_buffer_event_subtype_set(packet_to_buffer(pkt),
                                              ODP_EVENT_PACKET_IPSEC);
-               result = ipsec_pkt_result(pkt);
+               result = _odp_ipsec_pkt_result(pkt);
                memset(result, 0, sizeof(*result));
                result->sa = ipsec_sa->ipsec_sa_hdl;
                result->status = status;
@@ -1217,7 +1217,7 @@ int odp_ipsec_out_inline(const odp_packet_t pkt_in[], int 
num_in,
                        buf = packet_to_buffer(pkt);
                        _odp_buffer_event_subtype_set(buf,
                                                      ODP_EVENT_PACKET_IPSEC);
-                       result = ipsec_pkt_result(pkt);
+                       result = _odp_ipsec_pkt_result(pkt);
                        memset(result, 0, sizeof(*result));
                        result->sa = ipsec_sa->ipsec_sa_hdl;
                        result->status = status;
@@ -1246,7 +1246,7 @@ int odp_ipsec_result(odp_ipsec_packet_result_t *result, 
odp_packet_t packet)
 
        ODP_ASSERT(result != NULL);
 
-       res = ipsec_pkt_result(packet);
+       res = _odp_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 */
diff --git a/platform/linux-generic/odp_ipsec_events.c 
b/platform/linux-generic/odp_ipsec_events.c
index 3a7ebd6e8..3a3a9f5f5 100644
--- a/platform/linux-generic/odp_ipsec_events.c
+++ b/platform/linux-generic/odp_ipsec_events.c
@@ -6,6 +6,8 @@
 
 #include "config.h"
 
+#include <string.h>
+
 #include <odp/api/ipsec.h>
 #include <odp/api/shared_memory.h>
 
@@ -13,6 +15,8 @@
 #include <odp_buffer_inlines.h>
 #include <odp_debug_internal.h>
 #include <odp_ipsec_internal.h>
+#include <odp/api/packet.h>
+#include <odp/api/plat/packet_inlines.h>
 #include <odp_pool_internal.h>
 
 typedef struct {
@@ -23,6 +27,7 @@ typedef struct {
 } ipsec_status_hdr_t;
 
 static odp_pool_t ipsec_status_pool = ODP_POOL_INVALID;
+static odp_pool_t ipsec_sa_disabled_pool = ODP_POOL_INVALID;
 
 #define IPSEC_EVENTS_POOL_BUF_COUNT 1024
 
@@ -43,8 +48,24 @@ int _odp_ipsec_events_init_global(void)
                goto err_status;
        }
 
+       odp_pool_param_init(&param);
+
+       param.pkt.seg_len = 16;
+       param.pkt.len     = 16;
+       param.pkt.num     = ODP_CONFIG_IPSEC_SAS;
+       param.type        = ODP_POOL_PACKET;
+
+       ipsec_sa_disabled_pool = odp_pool_create("ipsec_sa_disabled_pool",
+                                                &param);
+       if (ODP_POOL_INVALID == ipsec_sa_disabled_pool) {
+               ODP_ERR("Error: sa_disabled pool create failed.\n");
+               goto err_sa_disabled;
+       }
+
        return 0;
 
+err_sa_disabled:
+       odp_pool_destroy(ipsec_status_pool);
 err_status:
        return -1;
 }
@@ -54,6 +75,12 @@ int _odp_ipsec_events_term_global(void)
        int ret = 0;
        int rc = 0;
 
+       ret = odp_pool_destroy(ipsec_sa_disabled_pool);
+       if (ret < 0) {
+               ODP_ERR("sa_disabled pool destroy failed");
+               rc = -1;
+       }
+
        ret = odp_pool_destroy(ipsec_status_pool);
        if (ret < 0) {
                ODP_ERR("status pool destroy failed");
@@ -112,7 +139,6 @@ void _odp_ipsec_status_free(ipsec_status_t status)
 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();
@@ -125,7 +151,6 @@ int _odp_ipsec_status_send(odp_queue_t queue,
 
        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))) {
@@ -154,3 +179,28 @@ int odp_ipsec_status(odp_ipsec_status_t *status, 
odp_event_t event)
 
        return 0;
 }
+
+int _odp_ipsec_sa_disabled_send(odp_queue_t queue,
+                               odp_ipsec_sa_t sa)
+{
+       odp_packet_t packet;
+       odp_ipsec_packet_result_t *result;
+
+       ODP_ASSERT(ODP_POOL_INVALID != ipsec_sa_disabled_pool);
+       packet = odp_packet_alloc(ipsec_sa_disabled_pool, 0);
+       ODP_ASSERT(ODP_PACKET_INVALID != packet);
+
+       _odp_buffer_event_subtype_set(packet_to_buffer(packet),
+                                     ODP_EVENT_PACKET_IPSEC);
+       result = _odp_ipsec_pkt_result(packet);
+       memset(result, 0, sizeof(*result));
+       result->status.error.sa_disabled = 1;
+       result->sa = sa;
+
+       if (odp_queue_enq(queue, odp_ipsec_packet_to_event(packet))) {
+               odp_packet_free(packet);
+               return -1;
+       }
+
+       return 0;
+}
diff --git a/platform/linux-generic/odp_ipsec_sad.c 
b/platform/linux-generic/odp_ipsec_sad.c
index f0b5b9e4a..a1eff8849 100644
--- a/platform/linux-generic/odp_ipsec_sad.c
+++ b/platform/linux-generic/odp_ipsec_sad.c
@@ -171,7 +171,6 @@ 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);
 
@@ -179,9 +178,7 @@ void _odp_ipsec_sa_unuse(ipsec_sa_t *ipsec_sa)
        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);
+               _odp_ipsec_sa_disabled_send(queue, sa);
 }
 
 void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param)
@@ -370,17 +367,12 @@ int odp_ipsec_sa_disable(odp_ipsec_sa_t sa)
        }
 
        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 there was no active state when we disabled SA, send the
+                * event. Otherwise it will be sent by _odp_ipsec_sa_unuse().
                 */
                if (0 == state)
-                       _odp_ipsec_status_send(ipsec_sa->queue,
-                                              ODP_IPSEC_STATUS_SA_DISABLE,
-                                              ipsec_sa->ipsec_sa_hdl,
-                                              0, warn);
+                       _odp_ipsec_sa_disabled_send(ipsec_sa->queue, sa);
 
                return 0;
        }

Reply via email to