net/cnxk: use full context IPsec structures

Use the Full context SA structures and command in IPsec fast path.
For inline outbound, populate CPT instruction as per full context.
Added new macros and functions with respect to full context.

Populate WQE ptr in CPT instruction with proper offset from mbuf.
Also add option to override outbound inline SA IV for debug
Update mbuf length based on IP version in Rx post process purposes
via environment variable.

User can set env variable as:
export ETH_SEC_IV_OVR="0x0, 0x0,..."

Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
This commit is contained in:
Vidya Sagar Velumuri 2022-09-12 18:44:08 +05:30 committed by Jerin Jacob
parent 0070027288
commit 4440eb88dd
13 changed files with 254 additions and 102 deletions

View File

@ -1242,7 +1242,9 @@ cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec,
ctx_len += sizeof(template->ip4);
ip4->version_ihl = RTE_IPV4_VHL_DEF;
ip4->time_to_live = ipsec->tunnel.ipv4.ttl;
ip4->time_to_live = ipsec->tunnel.ipv4.ttl ?
ipsec->tunnel.ipv4.ttl :
0x40;
ip4->type_of_service |= (ipsec->tunnel.ipv4.dscp << 2);
if (ipsec->tunnel.ipv4.df)
frag_off |= RTE_IPV4_HDR_DF_FLAG;
@ -1275,7 +1277,9 @@ cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec,
((ipsec->tunnel.ipv6.flabel
<< RTE_IPV6_HDR_FL_SHIFT) &
RTE_IPV6_HDR_FL_MASK));
ip6->hop_limits = ipsec->tunnel.ipv6.hlimit;
ip6->hop_limits = ipsec->tunnel.ipv6.hlimit ?
ipsec->tunnel.ipv6.hlimit :
0x40;
memcpy(&ip6->src_addr, &ipsec->tunnel.ipv6.src_addr,
sizeof(struct in6_addr));
memcpy(&ip6->dst_addr, &ipsec->tunnel.ipv6.dst_addr,

View File

@ -277,7 +277,7 @@ roc_cpt_inline_ipsec_inb_cfg_read(struct roc_cpt *roc_cpt,
int
roc_cpt_inline_ipsec_inb_cfg(struct roc_cpt *roc_cpt, uint16_t param1,
uint16_t param2)
uint16_t param2, uint16_t opcode)
{
struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
struct cpt_rx_inline_lf_cfg_msg *req;
@ -292,6 +292,7 @@ roc_cpt_inline_ipsec_inb_cfg(struct roc_cpt *roc_cpt, uint16_t param1,
req->sso_pf_func = idev_sso_pffunc_get();
req->param1 = param1;
req->param2 = param2;
req->opcode = opcode;
return mbox_process(mbox);
}
@ -998,7 +999,7 @@ roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr,
}
int
roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, uint64_t sa, uint8_t opcode,
roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, uint64_t sa, bool inb,
uint16_t ctx_len, uint8_t egrp)
{
union cpt_res_s res, *hw_res;
@ -1014,7 +1015,9 @@ roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, uint64_t sa, uint8_t opcode,
hw_res->cn9k.compcode = CPT_COMP_NOT_DONE;
inst.w4.s.opcode_major = opcode;
inst.w4.s.opcode_major = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_OUTBOUND;
if (inb)
inst.w4.s.opcode_major = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_INBOUND;
inst.w4.s.opcode_minor = ctx_len >> 3;
inst.w4.s.param1 = 0;
inst.w4.s.param2 = 0;

View File

@ -161,7 +161,8 @@ int __roc_api roc_cpt_inline_ipsec_cfg(struct dev *dev, uint8_t slot,
int __roc_api roc_cpt_inline_ipsec_inb_cfg_read(
struct roc_cpt *roc_cpt, struct nix_inline_ipsec_cfg *inb_cfg);
int __roc_api roc_cpt_inline_ipsec_inb_cfg(struct roc_cpt *roc_cpt,
uint16_t param1, uint16_t param2);
uint16_t param1, uint16_t param2,
uint16_t opcode);
int __roc_api roc_cpt_afs_print(struct roc_cpt *roc_cpt);
int __roc_api roc_cpt_lfs_print(struct roc_cpt *roc_cpt);
void __roc_api roc_cpt_iq_disable(struct roc_cpt_lf *lf);
@ -173,7 +174,6 @@ void __roc_api roc_cpt_parse_hdr_dump(const struct cpt_parse_hdr_s *cpth);
int __roc_api roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr,
void *sa_cptr, uint16_t sa_len);
int __roc_api roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, uint64_t sa,
uint8_t opcode, uint16_t ctx_len,
uint8_t egrp);
int __roc_api roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, uint64_t sa, bool inb,
uint16_t ctx_len, uint8_t egrp);
#endif /* _ROC_CPT_H_ */

View File

@ -13,6 +13,12 @@
#define ROC_IE_ON_MAJOR_OP_PROCESS_OUTBOUND_IPSEC 0x23
#define ROC_IE_ON_MAJOR_OP_PROCESS_INBOUND_IPSEC 0x24
#define ROC_IE_ON_INB_MAX_CTX_LEN 34UL
#define ROC_IE_ON_INB_IKEV2_SINGLE_SA_SUPPORT (1 << 12)
#define ROC_IE_ON_OUTB_MAX_CTX_LEN 31UL
#define ROC_IE_ON_OUTB_IKEV2_SINGLE_SA_SUPPORT (1 << 9)
#define ROC_IE_ON_OUTB_PER_PKT_IV (1 << 11)
/* Ucode completion codes */
enum roc_ie_on_ucc_ipsec {
ROC_IE_ON_UCC_SUCCESS = 0,

View File

@ -8,11 +8,11 @@
uint32_t soft_exp_consumer_cnt;
roc_nix_inl_meta_pool_cb_t meta_pool_cb;
PLT_STATIC_ASSERT(ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ ==
1UL << ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ_LOG2);
PLT_STATIC_ASSERT(ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ == 512);
PLT_STATIC_ASSERT(ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ ==
1UL << ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ_LOG2);
PLT_STATIC_ASSERT(ROC_NIX_INL_ON_IPSEC_INB_SA_SZ ==
1UL << ROC_NIX_INL_ON_IPSEC_INB_SA_SZ_LOG2);
PLT_STATIC_ASSERT(ROC_NIX_INL_ON_IPSEC_INB_SA_SZ == 1024);
PLT_STATIC_ASSERT(ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ ==
1UL << ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ_LOG2);
PLT_STATIC_ASSERT(ROC_NIX_INL_OT_IPSEC_INB_SA_SZ ==
1UL << ROC_NIX_INL_OT_IPSEC_INB_SA_SZ_LOG2);
PLT_STATIC_ASSERT(ROC_NIX_INL_OT_IPSEC_INB_SA_SZ == 1024);
@ -184,7 +184,7 @@ nix_inl_inb_sa_tbl_setup(struct roc_nix *roc_nix)
/* CN9K SA size is different */
if (roc_model_is_cn9k())
inb_sa_sz = ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ;
inb_sa_sz = ROC_NIX_INL_ON_IPSEC_INB_SA_SZ;
else
inb_sa_sz = ROC_NIX_INL_OT_IPSEC_INB_SA_SZ;
@ -422,7 +422,9 @@ roc_nix_inl_inb_init(struct roc_nix *roc_nix)
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct idev_cfg *idev = idev_get_cfg();
struct roc_cpt *roc_cpt;
uint16_t opcode;
uint16_t param1;
uint16_t param2;
int rc;
if (idev == NULL)
@ -439,17 +441,23 @@ roc_nix_inl_inb_init(struct roc_nix *roc_nix)
}
if (roc_model_is_cn9k()) {
param1 = ROC_ONF_IPSEC_INB_MAX_L2_SZ;
param1 = (ROC_ONF_IPSEC_INB_MAX_L2_SZ >> 3) & 0xf;
param2 = ROC_IE_ON_INB_IKEV2_SINGLE_SA_SUPPORT;
opcode =
((ROC_IE_ON_INB_MAX_CTX_LEN << 8) |
(ROC_IE_ON_MAJOR_OP_PROCESS_INBOUND_IPSEC | (1 << 6)));
} else {
union roc_ot_ipsec_inb_param1 u;
u.u16 = 0;
u.s.esp_trailer_disable = 1;
param1 = u.u16;
param2 = 0;
opcode = (ROC_IE_OT_MAJOR_OP_PROCESS_INBOUND_IPSEC | (1 << 6));
}
/* Do onetime Inbound Inline config in CPTPF */
rc = roc_cpt_inline_ipsec_inb_cfg(roc_cpt, param1, 0);
rc = roc_cpt_inline_ipsec_inb_cfg(roc_cpt, param1, param2, opcode);
if (rc && rc != -EEXIST) {
plt_err("Failed to setup inbound lf, rc=%d", rc);
return rc;
@ -605,7 +613,7 @@ roc_nix_inl_outb_init(struct roc_nix *roc_nix)
/* CN9K SA size is different */
if (roc_model_is_cn9k())
sa_sz = ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ;
sa_sz = ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ;
else
sa_sz = ROC_NIX_INL_OT_IPSEC_OUTB_SA_SZ;
/* Alloc contiguous memory of outbound SA */
@ -1212,7 +1220,12 @@ roc_nix_inl_ctx_write(struct roc_nix *roc_nix, void *sa_dptr, void *sa_cptr,
/* Nothing much to do on cn9k */
if (roc_model_is_cn9k()) {
plt_atomic_thread_fence(__ATOMIC_ACQ_REL);
nix = roc_nix_to_nix_priv(roc_nix);
outb_lf = nix->cpt_lf_base;
rc = roc_on_cpt_ctx_write(outb_lf, (uint64_t)sa_dptr, inb,
sa_len, ROC_CPT_DFLT_ENG_GRP_SE_IE);
if (rc)
return rc;
return 0;
}

View File

@ -22,6 +22,24 @@
(ROC_NIX_INL_ONF_IPSEC_OUTB_HW_SZ + ROC_NIX_INL_ONF_IPSEC_OUTB_SW_RSVD)
#define ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ_LOG2 8
/* ON INB HW area */
#define ROC_NIX_INL_ON_IPSEC_INB_HW_SZ \
PLT_ALIGN(sizeof(struct roc_ie_on_inb_sa), ROC_ALIGN)
/* ON INB SW reserved area */
#define ROC_NIX_INL_ON_IPSEC_INB_SW_RSVD 640
#define ROC_NIX_INL_ON_IPSEC_INB_SA_SZ \
(ROC_NIX_INL_ON_IPSEC_INB_HW_SZ + ROC_NIX_INL_ON_IPSEC_INB_SW_RSVD)
#define ROC_NIX_INL_ON_IPSEC_INB_SA_SZ_LOG2 10
/* ONF OUTB HW area */
#define ROC_NIX_INL_ON_IPSEC_OUTB_HW_SZ \
PLT_ALIGN(sizeof(struct roc_ie_on_outb_sa), ROC_ALIGN)
/* ONF OUTB SW reserved area */
#define ROC_NIX_INL_ON_IPSEC_OUTB_SW_RSVD 256
#define ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ \
(ROC_NIX_INL_ON_IPSEC_OUTB_HW_SZ + ROC_NIX_INL_ON_IPSEC_OUTB_SW_RSVD)
#define ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ_LOG2 9
/* OT INB HW area */
#define ROC_NIX_INL_OT_IPSEC_INB_HW_SZ \
PLT_ALIGN(sizeof(struct roc_ot_ipsec_inb_sa), ROC_ALIGN)
@ -61,6 +79,34 @@
#define ROC_NIX_INL_REAS_ZOMBIE_LIMIT 0xFFF
#define ROC_NIX_INL_REAS_ZOMBIE_THRESHOLD 10
static inline struct roc_ie_on_inb_sa *
roc_nix_inl_on_ipsec_inb_sa(uintptr_t base, uint64_t idx)
{
uint64_t off = idx << ROC_NIX_INL_ON_IPSEC_INB_SA_SZ_LOG2;
return PLT_PTR_ADD(base, off);
}
static inline struct roc_ie_on_outb_sa *
roc_nix_inl_on_ipsec_outb_sa(uintptr_t base, uint64_t idx)
{
uint64_t off = idx << ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ_LOG2;
return PLT_PTR_ADD(base, off);
}
static inline void *
roc_nix_inl_on_ipsec_inb_sa_sw_rsvd(void *sa)
{
return PLT_PTR_ADD(sa, ROC_NIX_INL_ON_IPSEC_INB_HW_SZ);
}
static inline void *
roc_nix_inl_on_ipsec_outb_sa_sw_rsvd(void *sa)
{
return PLT_PTR_ADD(sa, ROC_NIX_INL_ON_IPSEC_OUTB_HW_SZ);
}
static inline struct roc_onf_ipsec_inb_sa *
roc_nix_inl_onf_ipsec_inb_sa(uintptr_t base, uint64_t idx)
{

View File

@ -394,7 +394,7 @@ nix_inl_nix_setup(struct nix_inl_dev *inl_dev)
/* CN9K SA is different */
if (roc_model_is_cn9k())
inb_sa_sz = ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ;
inb_sa_sz = ROC_NIX_INL_ON_IPSEC_INB_SA_SZ;
else
inb_sa_sz = ROC_NIX_INL_OT_IPSEC_INB_SA_SZ;

View File

@ -29,7 +29,6 @@ cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp,
union cpt_inst_w4 w4;
union cpt_inst_w7 w7;
size_t ctx_len;
uint8_t opcode;
uint8_t egrp;
int ret;
@ -80,10 +79,9 @@ cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp,
return ret;
ctx_len = ret;
opcode = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_OUTBOUND;
egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
ret = roc_on_cpt_ctx_write(&qp->lf, rte_mempool_virt2iova(&sa->out_sa),
opcode, ctx_len, egrp);
false, ctx_len, egrp);
if (ret)
return ret;
@ -133,7 +131,6 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp,
union cpt_inst_w4 w4;
union cpt_inst_w7 w7;
size_t ctx_len = 0;
uint8_t opcode;
uint8_t egrp;
int ret = 0;
@ -172,10 +169,9 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp,
sa->esn_en = 1;
ctx_len = ret;
opcode = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_INBOUND;
egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
ret = roc_on_cpt_ctx_write(&qp->lf, rte_mempool_virt2iova(&sa->in_sa),
opcode, ctx_len, egrp);
true, ctx_len, egrp);
if (ret)
return ret;

View File

@ -617,12 +617,14 @@ cn9k_sso_hws_xmit_sec_one(const struct cn9k_eth_txq *txq, uint64_t base,
struct nix_send_hdr_s *send_hdr;
uint64_t sa_base = txq->sa_base;
uint32_t pkt_len, dlen_adj, rlen;
struct roc_ie_on_outb_hdr *hdr;
uint64x2_t cmd01, cmd23;
uint64_t lmt_status, sa;
union nix_send_sg_s *sg;
uint32_t esn_lo, esn_hi;
uintptr_t dptr, nixtx;
uint64_t ucode_cmd[4];
uint64_t esn, *iv;
uint64_t esn;
uint8_t l2_len;
mdata.u64 = *rte_security_dynfield(m);
@ -661,14 +663,19 @@ cn9k_sso_hws_xmit_sec_one(const struct cn9k_eth_txq *txq, uint64_t base,
/* Load opcode and cptr already prepared at pkt metadata set */
pkt_len -= l2_len;
pkt_len += sizeof(struct roc_onf_ipsec_outb_hdr) +
ROC_ONF_IPSEC_OUTB_MAX_L2_INFO_SZ;
pkt_len += (sizeof(struct roc_ie_on_outb_hdr) - ROC_IE_ON_MAX_IV_LEN) +
ROC_ONF_IPSEC_OUTB_MAX_L2_INFO_SZ;
sa_base &= ~(ROC_NIX_INL_SA_BASE_ALIGN - 1);
sa = (uintptr_t)roc_nix_inl_onf_ipsec_outb_sa(sa_base, mdata.sa_idx);
sa = (uintptr_t)roc_nix_inl_on_ipsec_outb_sa(sa_base, mdata.sa_idx);
ucode_cmd[3] = (ROC_CPT_DFLT_ENG_GRP_SE_IE << 61 | sa);
ucode_cmd[0] = (ROC_IE_ONF_MAJOR_OP_PROCESS_OUTBOUND_IPSEC << 48 |
0x40UL << 48 | pkt_len);
ucode_cmd[0] = (((ROC_IE_ON_OUTB_MAX_CTX_LEN << 8) |
ROC_IE_ON_MAJOR_OP_PROCESS_OUTBOUND_IPSEC)
<< 48 |
(ROC_IE_ON_OUTB_IKEV2_SINGLE_SA_SUPPORT |
(ROC_ONF_IPSEC_OUTB_MAX_L2_INFO_SZ >>
3)) << 32 |
pkt_len);
/* CPT Word 0 and Word 1 */
cmd01 = vdupq_n_u64((nixtx + 16) | (cn9k_nix_tx_ext_subs(flags) + 1));
@ -678,35 +685,40 @@ cn9k_sso_hws_xmit_sec_one(const struct cn9k_eth_txq *txq, uint64_t base,
/* CPT word 2 and 3 */
cmd23 = vdupq_n_u64(0);
cmd23 = vsetq_lane_u64((((uint64_t)RTE_EVENT_TYPE_CPU << 28) |
CNXK_ETHDEV_SEC_OUTB_EV_SUB << 20), cmd23, 0);
cmd23 = vsetq_lane_u64((uintptr_t)m | 1, cmd23, 1);
CNXK_ETHDEV_SEC_OUTB_EV_SUB << 20),
cmd23, 0);
cmd23 = vsetq_lane_u64(((uintptr_t)m + sizeof(struct rte_mbuf)) | 1,
cmd23, 1);
dptr += l2_len - ROC_ONF_IPSEC_OUTB_MAX_L2_INFO_SZ -
sizeof(struct roc_onf_ipsec_outb_hdr);
(sizeof(struct roc_ie_on_outb_hdr) - ROC_IE_ON_MAX_IV_LEN);
ucode_cmd[1] = dptr;
ucode_cmd[2] = dptr;
/* Update IV to zero and l2 sz */
*(uint16_t *)(dptr + sizeof(struct roc_onf_ipsec_outb_hdr)) =
/* Update l2 sz */
*(uint16_t *)(dptr + (sizeof(struct roc_ie_on_outb_hdr) -
ROC_IE_ON_MAX_IV_LEN)) =
rte_cpu_to_be_16(ROC_ONF_IPSEC_OUTB_MAX_L2_INFO_SZ);
iv = (uint64_t *)(dptr + 8);
iv[0] = 0;
iv[1] = 0;
/* Head wait if needed */
if (base)
roc_sso_hws_head_wait(base);
/* ESN */
outb_priv = roc_nix_inl_onf_ipsec_outb_sa_sw_rsvd((void *)sa);
outb_priv = roc_nix_inl_on_ipsec_outb_sa_sw_rsvd((void *)sa);
esn = outb_priv->esn;
outb_priv->esn = esn + 1;
ucode_cmd[0] |= (esn >> 32) << 16;
esn = rte_cpu_to_be_32(esn & (BIT_ULL(32) - 1));
esn_lo = rte_cpu_to_be_32(esn & (BIT_ULL(32) - 1));
esn_hi = rte_cpu_to_be_32(esn >> 32);
/* Update ESN and IPID and IV */
*(uint64_t *)dptr = esn << 32 | esn;
/* Update ESN, IPID and IV */
hdr = (struct roc_ie_on_outb_hdr *)dptr;
hdr->ip_id = esn_lo;
hdr->seq = esn_lo;
hdr->esn = esn_hi;
hdr->df_tos = 0;
rte_io_wmb();
cn9k_sso_txq_fc_wait(txq);

View File

@ -79,6 +79,9 @@ struct cn9k_outb_priv_data {
/* Back pointer to eth sec session */
struct cnxk_eth_sec_sess *eth_sec;
/* IV in DBG mode */
uint8_t iv_dbg[ROC_IE_ON_MAX_IV_LEN];
};
struct cn9k_sec_sess_priv {

View File

@ -134,6 +134,37 @@ ar_window_init(struct cn9k_inb_priv_data *inb_priv)
return 0;
}
static void
outb_dbg_iv_update(struct roc_ie_on_common_sa *common_sa, const char *__iv_str)
{
uint8_t *iv_dbg = common_sa->iv.aes_iv;
char *iv_str = strdup(__iv_str);
char *iv_b = NULL;
char *save;
int i, iv_len = ROC_IE_ON_MAX_IV_LEN;
if (!iv_str)
return;
if (common_sa->ctl.enc_type == ROC_IE_OT_SA_ENC_AES_GCM ||
common_sa->ctl.enc_type == ROC_IE_OT_SA_ENC_AES_CTR ||
common_sa->ctl.enc_type == ROC_IE_OT_SA_ENC_AES_CCM ||
common_sa->ctl.auth_type == ROC_IE_OT_SA_AUTH_AES_GMAC) {
iv_dbg = common_sa->iv.gcm.iv;
iv_len = 8;
}
memset(iv_dbg, 0, iv_len);
for (i = 0; i < iv_len; i++) {
iv_b = strtok_r(i ? NULL : iv_str, ",", &save);
if (!iv_b)
break;
iv_dbg[i] = strtoul(iv_b, NULL, 0);
}
free(iv_str);
}
static int
cn9k_eth_sec_session_create(void *device,
struct rte_security_session_conf *conf,
@ -150,6 +181,7 @@ cn9k_eth_sec_session_create(void *device,
rte_spinlock_t *lock;
char tbuf[128] = {0};
bool inbound;
int ctx_len;
int rc = 0;
if (conf->action_type != RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL)
@ -183,21 +215,25 @@ cn9k_eth_sec_session_create(void *device,
memset(eth_sec, 0, sizeof(struct cnxk_eth_sec_sess));
sess_priv.u64 = 0;
if (!dev->outb.lf_base) {
plt_err("Could not allocate security session private data");
return -ENOMEM;
}
if (inbound) {
struct cn9k_inb_priv_data *inb_priv;
struct roc_onf_ipsec_inb_sa *inb_sa;
struct roc_ie_on_inb_sa *inb_sa;
uint32_t spi_mask;
PLT_STATIC_ASSERT(sizeof(struct cn9k_inb_priv_data) <
ROC_NIX_INL_ONF_IPSEC_INB_SW_RSVD);
ROC_NIX_INL_ON_IPSEC_INB_SW_RSVD);
spi_mask = roc_nix_inl_inb_spi_range(nix, false, NULL, NULL);
/* Get Inbound SA from NIX_RX_IPSEC_SA_BASE. Assume no inline
* device always for CN9K.
*/
inb_sa = (struct roc_onf_ipsec_inb_sa *)
roc_nix_inl_inb_sa_get(nix, false, ipsec->spi);
inb_sa = (struct roc_ie_on_inb_sa *)roc_nix_inl_inb_sa_get(nix, false, ipsec->spi);
if (!inb_sa) {
snprintf(tbuf, sizeof(tbuf),
"Failed to create ingress sa");
@ -206,7 +242,7 @@ cn9k_eth_sec_session_create(void *device,
}
/* Check if SA is already in use */
if (inb_sa->ctl.valid) {
if (inb_sa->common_sa.ctl.valid) {
snprintf(tbuf, sizeof(tbuf),
"Inbound SA with SPI %u already in use",
ipsec->spi);
@ -214,17 +250,26 @@ cn9k_eth_sec_session_create(void *device,
goto mempool_put;
}
memset(inb_sa, 0, sizeof(struct roc_onf_ipsec_inb_sa));
memset(inb_sa, 0, sizeof(struct roc_ie_on_inb_sa));
/* Fill inbound sa params */
rc = cnxk_onf_ipsec_inb_sa_fill(inb_sa, ipsec, crypto);
if (rc) {
rc = cnxk_on_ipsec_inb_sa_create(ipsec, crypto, inb_sa);
if (rc < 0) {
snprintf(tbuf, sizeof(tbuf),
"Failed to init inbound sa, rc=%d", rc);
goto mempool_put;
}
inb_priv = roc_nix_inl_onf_ipsec_inb_sa_sw_rsvd(inb_sa);
ctx_len = rc;
rc = roc_nix_inl_ctx_write(&dev->nix, inb_sa, inb_sa, inbound,
ctx_len);
if (rc) {
snprintf(tbuf, sizeof(tbuf),
"Failed to create inbound sa, rc=%d", rc);
goto mempool_put;
}
inb_priv = roc_nix_inl_on_ipsec_inb_sa_sw_rsvd(inb_sa);
/* Back pointer to get eth_sec */
inb_priv->eth_sec = eth_sec;
@ -253,27 +298,38 @@ cn9k_eth_sec_session_create(void *device,
dev->inb.nb_sess++;
} else {
struct cn9k_outb_priv_data *outb_priv;
struct roc_onf_ipsec_outb_sa *outb_sa;
uintptr_t sa_base = dev->outb.sa_base;
struct cnxk_ipsec_outb_rlens *rlens;
struct roc_ie_on_outb_sa *outb_sa;
const char *iv_str;
uint32_t sa_idx;
PLT_STATIC_ASSERT(sizeof(struct cn9k_outb_priv_data) <
ROC_NIX_INL_ONF_IPSEC_OUTB_SW_RSVD);
ROC_NIX_INL_ON_IPSEC_OUTB_SW_RSVD);
/* Alloc an sa index */
rc = cnxk_eth_outb_sa_idx_get(dev, &sa_idx, 0);
if (rc)
goto mempool_put;
outb_sa = roc_nix_inl_onf_ipsec_outb_sa(sa_base, sa_idx);
outb_priv = roc_nix_inl_onf_ipsec_outb_sa_sw_rsvd(outb_sa);
outb_sa = roc_nix_inl_on_ipsec_outb_sa(sa_base, sa_idx);
outb_priv = roc_nix_inl_on_ipsec_outb_sa_sw_rsvd(outb_sa);
rlens = &outb_priv->rlens;
memset(outb_sa, 0, sizeof(struct roc_onf_ipsec_outb_sa));
memset(outb_sa, 0, sizeof(struct roc_ie_on_outb_sa));
/* Fill outbound sa params */
rc = cnxk_onf_ipsec_outb_sa_fill(outb_sa, ipsec, crypto);
rc = cnxk_on_ipsec_outb_sa_create(ipsec, crypto, outb_sa);
if (rc < 0) {
snprintf(tbuf, sizeof(tbuf),
"Failed to init outbound sa, rc=%d", rc);
rc |= cnxk_eth_outb_sa_idx_put(dev, sa_idx);
goto mempool_put;
}
ctx_len = rc;
rc = roc_nix_inl_ctx_write(&dev->nix, outb_sa, outb_sa, inbound,
ctx_len);
if (rc) {
snprintf(tbuf, sizeof(tbuf),
"Failed to init outbound sa, rc=%d", rc);
@ -281,6 +337,18 @@ cn9k_eth_sec_session_create(void *device,
goto mempool_put;
}
/* Always enable explicit IV.
* Copy the IV from application only when iv_gen_disable flag is
* set
*/
outb_sa->common_sa.ctl.explicit_iv_en = 1;
if (conf->ipsec.options.iv_gen_disable == 1) {
iv_str = getenv("ETH_SEC_IV_OVR");
if (iv_str)
outb_dbg_iv_update(&outb_sa->common_sa, iv_str);
}
/* Save userdata */
outb_priv->userdata = conf->userdata;
outb_priv->sa_idx = sa_idx;
@ -288,8 +356,8 @@ cn9k_eth_sec_session_create(void *device,
/* Start sequence number with 1 */
outb_priv->seq = 1;
memcpy(&outb_priv->nonce, outb_sa->nonce, 4);
if (outb_sa->ctl.enc_type == ROC_IE_ON_SA_ENC_AES_GCM)
memcpy(&outb_priv->nonce, outb_sa->common_sa.iv.gcm.nonce, 4);
if (outb_sa->common_sa.ctl.enc_type == ROC_IE_ON_SA_ENC_AES_GCM)
outb_priv->copy_salt = 1;
/* Save rlen info */
@ -337,9 +405,9 @@ cn9k_eth_sec_session_destroy(void *device, struct rte_security_session *sess)
{
struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)device;
struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
struct roc_onf_ipsec_outb_sa *outb_sa;
struct roc_onf_ipsec_inb_sa *inb_sa;
struct cnxk_eth_sec_sess *eth_sec;
struct roc_ie_on_outb_sa *outb_sa;
struct roc_ie_on_inb_sa *inb_sa;
struct rte_mempool *mp;
rte_spinlock_t *lock;
@ -353,14 +421,14 @@ cn9k_eth_sec_session_destroy(void *device, struct rte_security_session *sess)
if (eth_sec->inb) {
inb_sa = eth_sec->sa;
/* Disable SA */
inb_sa->ctl.valid = 0;
inb_sa->common_sa.ctl.valid = 0;
TAILQ_REMOVE(&dev->inb.list, eth_sec, entry);
dev->inb.nb_sess--;
} else {
outb_sa = eth_sec->sa;
/* Disable SA */
outb_sa->ctl.valid = 0;
outb_sa->common_sa.ctl.valid = 0;
/* Release Outbound SA index */
cnxk_eth_outb_sa_idx_put(dev, eth_sec->sa_idx);

View File

@ -171,7 +171,7 @@ nix_cqe_xtract_mseg(const union nix_rx_parse_u *rx, struct rte_mbuf *mbuf,
}
static inline int
ipsec_antireplay_check(struct roc_onf_ipsec_inb_sa *sa,
ipsec_antireplay_check(struct roc_ie_on_inb_sa *sa,
struct cn9k_inb_priv_data *priv, uintptr_t data,
uint32_t win_sz)
{
@ -183,7 +183,7 @@ ipsec_antireplay_check(struct roc_onf_ipsec_inb_sa *sa,
uint8_t esn;
int rc;
esn = sa->ctl.esn_en;
esn = sa->common_sa.ctl.esn_en;
seql = rte_be_to_cpu_32(*((uint32_t *)(data + IPSEC_SQ_LO_IDX)));
if (!esn) {
@ -200,11 +200,12 @@ ipsec_antireplay_check(struct roc_onf_ipsec_inb_sa *sa,
rte_spinlock_lock(&ar->lock);
rc = cnxk_on_anti_replay_check(seq, ar, win_sz);
if (esn && !rc) {
seq_in_sa = ((uint64_t)rte_be_to_cpu_32(sa->esn_hi) << 32) |
rte_be_to_cpu_32(sa->esn_low);
seq_in_sa = ((uint64_t)rte_be_to_cpu_32(sa->common_sa.seq_t.th)
<< 32) |
rte_be_to_cpu_32(sa->common_sa.seq_t.tl);
if (seq > seq_in_sa) {
sa->esn_low = rte_cpu_to_be_32(seql);
sa->esn_hi = rte_cpu_to_be_32(seqh);
sa->common_sa.seq_t.tl = rte_cpu_to_be_32(seql);
sa->common_sa.seq_t.th = rte_cpu_to_be_32(seqh);
}
}
rte_spinlock_unlock(&ar->lock);
@ -266,9 +267,10 @@ nix_rx_sec_mbuf_update(const struct nix_cqe_hdr_s *cq, struct rte_mbuf *m,
const union nix_rx_parse_u *rx =
(const union nix_rx_parse_u *)((const uint64_t *)cq + 1);
struct cn9k_inb_priv_data *sa_priv;
struct roc_onf_ipsec_inb_sa *sa;
struct roc_ie_on_inb_sa *sa;
uint8_t lcptr = rx->lcptr;
struct rte_ipv4_hdr *ipv4;
struct rte_ipv4_hdr *ip;
struct rte_ipv6_hdr *ip6;
uint16_t data_off, res;
uint32_t spi, win_sz;
uint32_t spi_mask;
@ -279,6 +281,7 @@ nix_rx_sec_mbuf_update(const struct nix_cqe_hdr_s *cq, struct rte_mbuf *m,
res = *(uint64_t *)(res_sg0 + 8);
data_off = *rearm_val & (BIT_ULL(16) - 1);
data = (uintptr_t)m->buf_addr;
data += data_off;
rte_prefetch0((void *)data);
@ -294,10 +297,10 @@ nix_rx_sec_mbuf_update(const struct nix_cqe_hdr_s *cq, struct rte_mbuf *m,
sa_w = sa_base & (ROC_NIX_INL_SA_BASE_ALIGN - 1);
sa_base &= ~(ROC_NIX_INL_SA_BASE_ALIGN - 1);
spi_mask = (1ULL << sa_w) - 1;
sa = roc_nix_inl_onf_ipsec_inb_sa(sa_base, spi & spi_mask);
sa = roc_nix_inl_on_ipsec_inb_sa(sa_base, spi & spi_mask);
/* Update dynamic field with userdata */
sa_priv = roc_nix_inl_onf_ipsec_inb_sa_sw_rsvd(sa);
sa_priv = roc_nix_inl_on_ipsec_inb_sa_sw_rsvd(sa);
dw = *(__uint128_t *)sa_priv;
*rte_security_dynfield(m) = (uint64_t)dw;
@ -309,16 +312,26 @@ nix_rx_sec_mbuf_update(const struct nix_cqe_hdr_s *cq, struct rte_mbuf *m,
}
/* Get total length from IPv4 header. We can assume only IPv4 */
ipv4 = (struct rte_ipv4_hdr *)(data + ROC_ONF_IPSEC_INB_SPI_SEQ_SZ +
ROC_ONF_IPSEC_INB_MAX_L2_SZ);
ip = (struct rte_ipv4_hdr *)(data + ROC_ONF_IPSEC_INB_SPI_SEQ_SZ +
ROC_ONF_IPSEC_INB_MAX_L2_SZ);
if (((ip->version_ihl & 0xf0) >> RTE_IPV4_IHL_MULTIPLIER) ==
IPVERSION) {
*len = rte_be_to_cpu_16(ip->total_length) + lcptr;
} else {
PLT_ASSERT(((ip->version_ihl & 0xf0) >>
RTE_IPV4_IHL_MULTIPLIER) == 6);
ip6 = (struct rte_ipv6_hdr *)ip;
*len = rte_be_to_cpu_16(ip6->payload_len) +
sizeof(struct rte_ipv6_hdr) + lcptr;
}
/* Update data offset */
data_off += (ROC_ONF_IPSEC_INB_SPI_SEQ_SZ +
ROC_ONF_IPSEC_INB_MAX_L2_SZ);
data_off +=
(ROC_ONF_IPSEC_INB_SPI_SEQ_SZ + ROC_ONF_IPSEC_INB_MAX_L2_SZ);
*rearm_val = *rearm_val & ~(BIT_ULL(16) - 1);
*rearm_val |= data_off;
*len = rte_be_to_cpu_16(ipv4->total_length) + lcptr;
return RTE_MBUF_F_RX_SEC_OFFLOAD;
}

View File

@ -16,59 +16,47 @@
static int
copy_outb_sa_9k(struct rte_tel_data *d, uint32_t i, void *sa)
{
struct roc_onf_ipsec_outb_sa *out_sa;
union {
struct roc_ie_onf_sa_ctl ctl;
struct roc_ie_on_sa_ctl ctl;
uint64_t u64;
} w0;
struct roc_ie_on_outb_sa *out_sa;
char strw0[W0_MAXLEN];
char str[STR_MAXLEN];
out_sa = (struct roc_onf_ipsec_outb_sa *)sa;
w0.ctl = out_sa->ctl;
out_sa = (struct roc_ie_on_outb_sa *)sa;
w0.ctl = out_sa->common_sa.ctl;
snprintf(str, sizeof(str), "outsa_w0_%u", i);
snprintf(strw0, sizeof(strw0), "%" PRIu64, w0.u64);
rte_tel_data_add_dict_string(d, str, strw0);
snprintf(str, sizeof(str), "outsa_src_%u", i);
rte_tel_data_add_dict_u64(d, str, out_sa->udp_src);
snprintf(str, sizeof(str), "outsa_dst_%u", i);
rte_tel_data_add_dict_u64(d, str, out_sa->udp_dst);
snprintf(str, sizeof(str), "outsa_isrc_%u", i);
rte_tel_data_add_dict_u64(d, str, out_sa->ip_src);
snprintf(str, sizeof(str), "outsa_idst_%u", i);
rte_tel_data_add_dict_u64(d, str, out_sa->ip_dst);
return 0;
}
static int
copy_inb_sa_9k(struct rte_tel_data *d, uint32_t i, void *sa)
{
struct roc_onf_ipsec_inb_sa *in_sa;
union {
struct roc_ie_onf_sa_ctl ctl;
struct roc_ie_on_sa_ctl ctl;
uint64_t u64;
} w0;
struct roc_ie_on_inb_sa *in_sa;
char strw0[W0_MAXLEN];
char str[STR_MAXLEN];
in_sa = (struct roc_onf_ipsec_inb_sa *)sa;
w0.ctl = in_sa->ctl;
in_sa = (struct roc_ie_on_inb_sa *)sa;
w0.ctl = in_sa->common_sa.ctl;
snprintf(str, sizeof(str), "insa_w0_%u", i);
snprintf(strw0, sizeof(strw0), "%" PRIu64, w0.u64);
rte_tel_data_add_dict_string(d, str, strw0);
snprintf(str, sizeof(str), "insa_esnh_%u", i);
rte_tel_data_add_dict_u64(d, str, in_sa->esn_hi);
rte_tel_data_add_dict_u64(d, str, in_sa->common_sa.seq_t.th);
snprintf(str, sizeof(str), "insa_esnl_%u", i);
rte_tel_data_add_dict_u64(d, str, in_sa->esn_low);
rte_tel_data_add_dict_u64(d, str, in_sa->common_sa.seq_t.tl);
return 0;
}