#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include "ipsec.h"
#include "esp.h"
static inline int
create_session(
struct ipsec_ctx *ipsec_ctx
__rte_unused,
struct ipsec_sa *sa)
{
unsigned long cdev_id_qp = 0;
int32_t ret;
struct cdev_key key = { 0 };
key.cipher_algo = (uint8_t)sa->cipher_algo;
key.auth_algo = (uint8_t)sa->auth_algo;
(void **)&cdev_id_qp);
if (ret < 0) {
RTE_LOG(ERR, IPSEC,
"No cryptodev: core %u, cipher_algo %u, "
"auth_algo %u\n", key.lcore_id, key.cipher_algo,
key.auth_algo);
return -1;
}
RTE_LOG_DP(DEBUG, IPSEC,
"Create session for SA spi %u on cryptodev "
"%u qp %u\n", sa->spi,
ipsec_ctx->tbl[cdev_id_qp].id,
ipsec_ctx->tbl[cdev_id_qp].qp);
ipsec_ctx->tbl[cdev_id_qp].id, sa->xforms);
ipsec_ctx->tbl[cdev_id_qp].qp,
sa->crypto_session);
if (ret < 0) {
"Session cannot be attached to qp %u ",
ipsec_ctx->tbl[cdev_id_qp].qp);
return -1;
}
}
sa->cdev_id_qp = cdev_id_qp;
return 0;
}
static inline void
{
int32_t ret, i;
cqp->buf[cqp->len++] = cop;
if (cqp->len == MAX_PKT_BURST) {
cqp->buf, cqp->len);
if (ret < cqp->len) {
" enqueued %u crypto ops out of %u\n",
cqp->id, cqp->qp,
ret, cqp->len);
for (i = ret; i < cqp->len; i++)
}
cqp->in_flight += ret;
cqp->len = 0;
}
}
static inline void
ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
struct rte_mbuf *pkts[],
struct ipsec_sa *sas[],
uint16_t nb_pkts)
{
int32_t ret = 0, i;
struct ipsec_mbuf_metadata *priv;
struct ipsec_sa *sa;
for (i = 0; i < nb_pkts; i++) {
continue;
}
priv = get_priv(pkts[i]);
sa = sas[i];
priv->sa = sa;
priv->cop.sym = &priv->sym_cop;
if ((
unlikely(sa->crypto_session == NULL)) &&
create_session(ipsec_ctx, sa)) {
continue;
}
sa->crypto_session);
ret = xform_func(pkts[i], sa, &priv->cop);
continue;
}
RTE_ASSERT(sa->cdev_id_qp < ipsec_ctx->nb_qps);
enqueue_cop(&ipsec_ctx->tbl[sa->cdev_id_qp], &priv->cop);
}
}
static inline int
ipsec_dequeue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
struct rte_mbuf *pkts[], uint16_t max_pkts)
{
int32_t nb_pkts = 0, ret = 0, i, j, nb_cops;
struct ipsec_mbuf_metadata *priv;
struct ipsec_sa *sa;
for (i = 0; i < ipsec_ctx->nb_qps && nb_pkts < max_pkts; i++) {
struct cdev_qp *cqp;
cqp = &ipsec_ctx->tbl[ipsec_ctx->last_qp++];
if (ipsec_ctx->last_qp == ipsec_ctx->nb_qps)
ipsec_ctx->last_qp %= ipsec_ctx->nb_qps;
if (cqp->in_flight == 0)
continue;
cops, max_pkts - nb_pkts);
cqp->in_flight -= nb_cops;
for (j = 0; j < nb_cops; j++) {
priv = get_priv(pkt);
sa = priv->sa;
RTE_ASSERT(sa != NULL);
ret = xform_func(pkt, sa, cops[j]);
else
pkts[nb_pkts++] = pkt;
}
}
return nb_pkts;
}
uint16_t
ipsec_inbound(
struct ipsec_ctx *ctx,
struct rte_mbuf *pkts[],
uint16_t nb_pkts, uint16_t len)
{
struct ipsec_sa *sas[nb_pkts];
inbound_sa_lookup(ctx->sa_ctx, pkts, sas, nb_pkts);
ipsec_enqueue(esp_inbound, ctx, pkts, sas, nb_pkts);
return ipsec_dequeue(esp_inbound_post, ctx, pkts, len);
}
uint16_t
ipsec_outbound(
struct ipsec_ctx *ctx,
struct rte_mbuf *pkts[],
uint32_t sa_idx[], uint16_t nb_pkts, uint16_t len)
{
struct ipsec_sa *sas[nb_pkts];
outbound_sa_lookup(ctx->sa_ctx, sa_idx, sas, nb_pkts);
ipsec_enqueue(esp_outbound, ctx, pkts, sas, nb_pkts);
return ipsec_dequeue(esp_outbound_post, ctx, pkts, len);
}