@@ -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>
@@ -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);
+
+/**
* @}
*/
@@ -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 ==
@@ -1055,7 +1069,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;
@@ -1138,6 +1161,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));
@@ -1155,10 +1179,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);
@@ -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);
}