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

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsoleni...@linaro.org>
---
/** Email created from pull request 243 (lumag:ipsec-packet-impl-3)
 ** https://github.com/Linaro/odp/pull/243
 ** Patch: https://github.com/Linaro/odp/pull/243.patch
 ** Base sha: e3108af2f0b58c2ceca422b418439bba5de04b11
 ** Merge commit sha: 1ac4107a19a46e35c46e3a96416279c6ef0a33d1
 **/
 .../include/odp_classification_datamodel.h         |  2 --
 .../linux-generic/include/odp_ipsec_internal.h     |  7 ++++
 platform/linux-generic/odp_ipsec.c                 | 37 ++++++++++++++++++++--
 platform/linux-generic/odp_ipsec_sad.c             | 16 +++++++++-
 4 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/platform/linux-generic/include/odp_classification_datamodel.h 
b/platform/linux-generic/include/odp_classification_datamodel.h
index a40541986..25c488497 100644
--- a/platform/linux-generic/include/odp_classification_datamodel.h
+++ b/platform/linux-generic/include/odp_classification_datamodel.h
@@ -22,8 +22,6 @@ extern "C" {
 #include <odp/api/spinlock.h>
 #include <odp/api/classification.h>
 #include <odp_pool_internal.h>
-#include <odp_packet_internal.h>
-#include <odp_packet_io_internal.h>
 #include <odp_queue_if.h>
 #include <protocols/ip.h>
 
diff --git a/platform/linux-generic/include/odp_ipsec_internal.h 
b/platform/linux-generic/include/odp_ipsec_internal.h
index 0a7f96256..81ecec08e 100644
--- a/platform/linux-generic/include/odp_ipsec_internal.h
+++ b/platform/linux-generic/include/odp_ipsec_internal.h
@@ -23,6 +23,7 @@ extern "C" {
 #include <odp/api/byteorder.h>
 #include <odp/api/ipsec.h>
 #include <odp/api/ticketlock.h>
+#include <odp_classification_datamodel.h>
 
 /** @ingroup odp_ipsec
  *  @{
@@ -141,6 +142,7 @@ struct ipsec_sa_s {
                        odp_ipsec_lookup_mode_t lookup_mode;
                        odp_u32be_t     lookup_dst_ip;
                        odp_atomic_u64_t antireplay;
+                       cos_t           *cos;
                } in;
 
                struct {
@@ -229,6 +231,11 @@ int _odp_ipsec_sa_replay_update(ipsec_sa_t *ipsec_sa, 
uint32_t seq,
 int _odp_ipsec_try_inline(odp_packet_t pkt);
 
 /**
+ * Returns ODP IPsec configuration
+ */
+const odp_ipsec_config_t *_odp_ipsec_config_get(void);
+
+/**
  * @}
  */
 
diff --git a/platform/linux-generic/odp_ipsec.c 
b/platform/linux-generic/odp_ipsec.c
index 5bb8330cb..74a1c5766 100644
--- a/platform/linux-generic/odp_ipsec.c
+++ b/platform/linux-generic/odp_ipsec.c
@@ -13,6 +13,7 @@
 #include <odp_debug_internal.h>
 #include <odp_packet_internal.h>
 #include <odp_ipsec_internal.h>
+#include <odp_classification_internal.h>
 
 #include <protocols/eth.h>
 #include <protocols/ip.h>
@@ -30,6 +31,7 @@ int odp_ipsec_capability(odp_ipsec_capability_t *capa)
        int rc;
        odp_crypto_capability_t crypto_capa;
        odp_queue_capability_t queue_capa;
+       odp_cls_capability_t cls_capa;
 
        memset(capa, 0, sizeof(odp_ipsec_capability_t));
 
@@ -39,6 +41,7 @@ int odp_ipsec_capability(odp_ipsec_capability_t *capa)
        capa->op_mode_inline_out = ODP_SUPPORT_PREFERRED;
 
        capa->proto_ah = ODP_SUPPORT_YES;
+       capa->pipeline_cls = ODP_SUPPORT_YES;
 
        capa->max_num_sa = ODP_CONFIG_IPSEC_SAS;
 
@@ -57,6 +60,12 @@ int odp_ipsec_capability(odp_ipsec_capability_t *capa)
 
        capa->max_queues = queue_capa.max_queues;
 
+       rc = odp_cls_capability(&cls_capa);
+       if (rc < 0)
+               return rc;
+
+       capa->max_cls_cos = cls_capa.max_cos;
+
        return 0;
 }
 
@@ -95,6 +104,11 @@ int odp_ipsec_config(const odp_ipsec_config_t *config)
        return 0;
 }
 
+const odp_ipsec_config_t *_odp_ipsec_config_get(void)
+{
+       return &ipsec_config;
+}
+
 static odp_ipsec_packet_result_t *ipsec_pkt_result(odp_packet_t packet)
 {
        ODP_ASSERT(ODP_EVENT_PACKET_IPSEC ==
@@ -1060,7 +1074,16 @@ int odp_ipsec_in_enq(const odp_packet_t pkt_in[], int 
num_in,
                result->status = status;
                if (NULL != ipsec_sa) {
                        result->sa = ipsec_sa->ipsec_sa_hdl;
-                       queue = ipsec_sa->queue;
+                       if (ipsec_sa->in.cos && !status.error.all) {
+                               odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+                               const uint8_t *base = odp_packet_data(pkt);
+
+                               queue = cls_pkt_get_queue(pkt_hdr,
+                                                         ipsec_sa->in.cos,
+                                                         base);
+                       } else {
+                               queue = ipsec_sa->queue;
+                       }
                } else {
                        result->sa = ODP_IPSEC_SA_INVALID;
                        queue = ipsec_config.inbound.default_queue;
@@ -1143,6 +1166,7 @@ int _odp_ipsec_try_inline(odp_packet_t pkt)
        ipsec_sa_t *ipsec_sa;
        odp_ipsec_packet_result_t *result;
        odp_packet_hdr_t *pkt_hdr;
+       odp_queue_t queue;
 
        memset(&status, 0, sizeof(status));
 
@@ -1160,10 +1184,19 @@ int _odp_ipsec_try_inline(odp_packet_t pkt)
        memset(result, 0, sizeof(*result));
        result->status = status;
        result->sa = ipsec_sa->ipsec_sa_hdl;
+       result->flag.inline_mode = 1;
 
        pkt_hdr = odp_packet_hdr(pkt);
        pkt_hdr->p.input_flags.dst_queue = 1;
-       pkt_hdr->dst_queue = queue_fn->from_ext(ipsec_sa->queue);
+       if (ipsec_sa->in.cos && !status.error.all) {
+               odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+               const uint8_t *base = odp_packet_data(pkt);
+
+               queue = cls_pkt_get_queue(pkt_hdr, ipsec_sa->in.cos, base);
+       } else {
+               queue = ipsec_sa->queue;
+       }
+       pkt_hdr->dst_queue = queue_fn->from_ext(queue);
 
        /* Last thing */
        _odp_ipsec_sa_unuse(ipsec_sa);
diff --git a/platform/linux-generic/odp_ipsec_sad.c 
b/platform/linux-generic/odp_ipsec_sad.c
index e010cfaa3..6a17a9172 100644
--- a/platform/linux-generic/odp_ipsec_sad.c
+++ b/platform/linux-generic/odp_ipsec_sad.c
@@ -13,6 +13,7 @@
 
 #include <odp_debug_internal.h>
 #include <odp_ipsec_internal.h>
+#include <odp_classification_internal.h>
 
 #include <string.h>
 
@@ -216,9 +217,22 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const 
odp_ipsec_sa_param_t *param)
                               sizeof(ipsec_sa->in.lookup_dst_ip));
 
                if (param->inbound.antireplay_ws > IPSEC_ANTIREPLAY_WS)
-                       return ODP_IPSEC_SA_INVALID;
+                       goto error;
                ipsec_sa->antireplay = (param->inbound.antireplay_ws != 0);
                odp_atomic_init_u64(&ipsec_sa->in.antireplay, 0);
+
+               if (ODP_IPSEC_PIPELINE_CLS == param->inbound.pipeline) {
+                       if (ODP_IPSEC_OP_MODE_SYNC ==
+                           _odp_ipsec_config_get()->inbound_mode)
+                               goto error;
+
+                       ipsec_sa->in.cos =
+                               _odp_cos_get_entry(param->inbound.dest_cos);
+                       if (NULL == ipsec_sa->in.cos)
+                               goto error;
+               } else {
+                       ipsec_sa->in.cos = NULL;
+               }
        } else {
                odp_atomic_store_u32(&ipsec_sa->out.seq, 1);
        }

Reply via email to