+clib_error_t *create_sym_session (struct rte_cryptodev_sym_session **session,
+ u32 sa_idx, crypto_resource_t * res,
+ crypto_worker_main_t * cwm, u8 is_outbound);
+
+static_always_inline u32
+crypto_op_len (void)
+{
+ const u32 align = 16;
+ u32 op_size =
+ sizeof (struct rte_crypto_op) + sizeof (struct rte_crypto_sym_op);
+
+ return ((op_size + align - 1) & ~(align - 1)) + sizeof (dpdk_op_priv_t);
+}
+
+static_always_inline u32
+crypto_op_get_priv_offset (void)
+{
+ const u32 align = 16;
+ u32 offset;
+
+ offset = sizeof (struct rte_crypto_op) + sizeof (struct rte_crypto_sym_op);
+ offset = (offset + align - 1) & ~(align - 1);
+
+ return offset;
+}
+
+static_always_inline dpdk_op_priv_t *
+crypto_op_get_priv (struct rte_crypto_op * op)
+{
+ return (dpdk_op_priv_t *) (((u8 *) op) + crypto_op_get_priv_offset ());
+}
+
+/* XXX this requires 64 bit builds so hash_xxx macros use u64 key */
+typedef union
+{
+ u64 val;
+ struct
+ {
+ u32 drv_id;
+ u32 sa_idx;
+ };
+} crypto_session_key_t;
+
+static_always_inline clib_error_t *
+crypto_get_session (struct rte_cryptodev_sym_session **session,
+ u32 sa_idx,
+ crypto_resource_t * res,
+ crypto_worker_main_t * cwm, u8 is_outbound)
+{
+ crypto_session_key_t key = { 0 };
+
+ key.drv_id = res->drv_id;
+ key.sa_idx = sa_idx;
+
+ uword *val = hash_get (cwm->session_by_drv_id_and_sa_index, key.val);
+
+ if (PREDICT_FALSE (!val))
+ return create_sym_session (session, sa_idx, res, cwm, is_outbound);
+
+ session[0] = (struct rte_cryptodev_sym_session *) val[0];
+
+ return NULL;
+}
+
+static_always_inline u16
+get_resource (crypto_worker_main_t * cwm, ipsec_sa_t * sa)
+{
+ u16 cipher_res = cwm->cipher_resource_idx[sa->crypto_alg];
+ u16 auth_res = cwm->auth_resource_idx[sa->integ_alg];
+ u8 is_aead;
+
+ /* Not allowed to setup SA with no-aead-cipher/NULL or NULL/NULL */
+
+ is_aead = ((sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128) |
+ (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_192) |
+ (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_256));
+
+ if (sa->crypto_alg == IPSEC_CRYPTO_ALG_NONE)
+ return auth_res;
+
+ if (cipher_res == auth_res)
+ return cipher_res;
+
+ if (is_aead)
+ return cipher_res;
+
+ return (u16) ~ 0;
+}
+
+static_always_inline i32
+crypto_alloc_ops (u8 numa, struct rte_crypto_op ** ops, u32 n)