@@ -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,
@@ -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;
@@ -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_ */
@@ -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,
@@ -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;
}
@@ -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)
{
@@ -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;
@@ -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;
@@ -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);
@@ -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 {
@@ -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,26 @@ 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 +243,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 +251,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 +299,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 +338,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 +357,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 +406,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 +422,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);
@@ -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;
}
@@ -14,59 +14,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;
}