@@ -179,6 +179,7 @@ Features supported
* IPv6
* ESP
* Tunnel mode
+* Transport mode(IPv4)
* ESN
* Anti-replay
* UDP Encapsulation
@@ -133,6 +133,8 @@ New Features
* Added support for DIGEST_ENCRYPTED mode in OCTEON TX2 crypto PMD.
* Updated the OCTEON TX2 crypto PMD lookaside protocol offload for IPsec with
UDP encapsulation support for NAT Traversal.
+ * Updated the OCTEON TX2 crypto PMD lookaside protocol offload for IPsec with
+ IPv4 transport mode support.
* **Updated testpmd.**
@@ -932,7 +932,7 @@ otx2_cpt_sec_post_process(struct rte_crypto_op *cop, uintptr_t *rsp)
struct rte_mbuf *m = sym_op->m_src;
struct rte_ipv6_hdr *ip6;
struct rte_ipv4_hdr *ip;
- uint16_t m_len;
+ uint16_t m_len = 0;
int mdata_len;
char *data;
@@ -942,11 +942,12 @@ otx2_cpt_sec_post_process(struct rte_crypto_op *cop, uintptr_t *rsp)
if (word0->s.opcode.major == OTX2_IPSEC_PO_PROCESS_IPSEC_INB) {
data = rte_pktmbuf_mtod(m, char *);
- if (rsp[4] == RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
+ if (rsp[4] == OTX2_IPSEC_PO_TRANSPORT ||
+ rsp[4] == OTX2_IPSEC_PO_TUNNEL_IPV4) {
ip = (struct rte_ipv4_hdr *)(data +
OTX2_IPSEC_PO_INB_RPTR_HDR);
m_len = rte_be_to_cpu_16(ip->total_length);
- } else {
+ } else if (rsp[4] == OTX2_IPSEC_PO_TUNNEL_IPV6) {
ip6 = (struct rte_ipv6_hdr *)(data +
OTX2_IPSEC_PO_INB_RPTR_HDR);
m_len = rte_be_to_cpu_16(ip6->payload_len) +
@@ -25,12 +25,15 @@ ipsec_lp_len_precalc(struct rte_security_ipsec_xform *ipsec,
{
struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
- if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
- lp->partial_len = sizeof(struct rte_ipv4_hdr);
- else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
- lp->partial_len = sizeof(struct rte_ipv6_hdr);
- else
- return -EINVAL;
+ lp->partial_len = 0;
+ if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
+ if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
+ lp->partial_len = sizeof(struct rte_ipv4_hdr);
+ else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
+ lp->partial_len = sizeof(struct rte_ipv6_hdr);
+ else
+ return -EINVAL;
+ }
if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) {
lp->partial_len += sizeof(struct rte_esp_hdr);
@@ -203,7 +206,7 @@ crypto_sec_ipsec_outb_session_create(struct rte_cryptodev *crypto_dev,
struct rte_security_session *sec_sess)
{
struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
- struct otx2_ipsec_po_ip_template *template;
+ struct otx2_ipsec_po_ip_template *template = NULL;
const uint8_t *cipher_key, *auth_key;
struct otx2_sec_session_ipsec_lp *lp;
struct otx2_ipsec_po_sa_ctl *ctl;
@@ -229,10 +232,10 @@ crypto_sec_ipsec_outb_session_create(struct rte_cryptodev *crypto_dev,
memset(sa, 0, sizeof(struct otx2_ipsec_po_out_sa));
/* Initialize lookaside ipsec private data */
+ lp->mode_type = OTX2_IPSEC_PO_TRANSPORT;
lp->ip_id = 0;
lp->seq_lo = 1;
lp->seq_hi = 0;
- lp->tunnel_type = ipsec->tunnel.type;
ret = ipsec_po_sa_ctl_set(ipsec, crypto_xform, ctl);
if (ret)
@@ -242,46 +245,47 @@ crypto_sec_ipsec_outb_session_create(struct rte_cryptodev *crypto_dev,
if (ret)
return ret;
- if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
- /* Start ip id from 1 */
- lp->ip_id = 1;
+ /* Start ip id from 1 */
+ lp->ip_id = 1;
+
+ if (ctl->enc_type == OTX2_IPSEC_PO_SA_ENC_AES_GCM) {
+ template = &sa->aes_gcm.template;
+ ctx_len = offsetof(struct otx2_ipsec_po_out_sa,
+ aes_gcm.template) + sizeof(
+ sa->aes_gcm.template.ip4);
+ ctx_len = RTE_ALIGN_CEIL(ctx_len, 8);
+ lp->ctx_len = ctx_len >> 3;
+ } else if (ctl->auth_type ==
+ OTX2_IPSEC_PO_SA_AUTH_SHA1) {
+ template = &sa->sha1.template;
+ ctx_len = offsetof(struct otx2_ipsec_po_out_sa,
+ sha1.template) + sizeof(
+ sa->sha1.template.ip4);
+ ctx_len = RTE_ALIGN_CEIL(ctx_len, 8);
+ lp->ctx_len = ctx_len >> 3;
+ } else if (ctl->auth_type ==
+ OTX2_IPSEC_PO_SA_AUTH_SHA2_256) {
+ template = &sa->sha2.template;
+ ctx_len = offsetof(struct otx2_ipsec_po_out_sa,
+ sha2.template) + sizeof(
+ sa->sha2.template.ip4);
+ ctx_len = RTE_ALIGN_CEIL(ctx_len, 8);
+ lp->ctx_len = ctx_len >> 3;
+ } else {
+ return -EINVAL;
+ }
+ ip = &template->ip4.ipv4_hdr;
+ if (ipsec->options.udp_encap) {
+ ip->next_proto_id = IPPROTO_UDP;
+ template->ip4.udp_src = rte_be_to_cpu_16(4500);
+ template->ip4.udp_dst = rte_be_to_cpu_16(4500);
+ } else {
+ ip->next_proto_id = IPPROTO_ESP;
+ }
+ if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
-
- if (ctl->enc_type == OTX2_IPSEC_PO_SA_ENC_AES_GCM) {
- template = &sa->aes_gcm.template;
- ctx_len = offsetof(struct otx2_ipsec_po_out_sa,
- aes_gcm.template) + sizeof(
- sa->aes_gcm.template.ip4);
- ctx_len = RTE_ALIGN_CEIL(ctx_len, 8);
- lp->ctx_len = ctx_len >> 3;
- } else if (ctl->auth_type ==
- OTX2_IPSEC_PO_SA_AUTH_SHA1) {
- template = &sa->sha1.template;
- ctx_len = offsetof(struct otx2_ipsec_po_out_sa,
- sha1.template) + sizeof(
- sa->sha1.template.ip4);
- ctx_len = RTE_ALIGN_CEIL(ctx_len, 8);
- lp->ctx_len = ctx_len >> 3;
- } else if (ctl->auth_type ==
- OTX2_IPSEC_PO_SA_AUTH_SHA2_256) {
- template = &sa->sha2.template;
- ctx_len = offsetof(struct otx2_ipsec_po_out_sa,
- sha2.template) + sizeof(
- sa->sha2.template.ip4);
- ctx_len = RTE_ALIGN_CEIL(ctx_len, 8);
- lp->ctx_len = ctx_len >> 3;
- } else {
- return -EINVAL;
- }
- ip = &template->ip4.ipv4_hdr;
- if (ipsec->options.udp_encap) {
- ip->next_proto_id = IPPROTO_UDP;
- template->ip4.udp_src = rte_be_to_cpu_16(4500);
- template->ip4.udp_dst = rte_be_to_cpu_16(4500);
- } else {
- ip->next_proto_id = IPPROTO_ESP;
- }
+ lp->mode_type = OTX2_IPSEC_PO_TUNNEL_IPV4;
ip->version_ihl = RTE_IPV4_VHL_DEF;
ip->time_to_live = ipsec->tunnel.ipv4.ttl;
ip->type_of_service |= (ipsec->tunnel.ipv4.dscp << 2);
@@ -294,6 +298,7 @@ crypto_sec_ipsec_outb_session_create(struct rte_cryptodev *crypto_dev,
} else if (ipsec->tunnel.type ==
RTE_SECURITY_IPSEC_TUNNEL_IPV6) {
+ lp->mode_type = OTX2_IPSEC_PO_TUNNEL_IPV6;
if (ctl->enc_type == OTX2_IPSEC_PO_SA_ENC_AES_GCM) {
template = &sa->aes_gcm.template;
ctx_len = offsetof(struct otx2_ipsec_po_out_sa,
@@ -343,11 +348,7 @@ crypto_sec_ipsec_outb_session_create(struct rte_cryptodev *crypto_dev,
sizeof(struct in6_addr));
memcpy(&ip6->dst_addr, &ipsec->tunnel.ipv6.dst_addr,
sizeof(struct in6_addr));
- } else {
- return -EINVAL;
}
- } else {
- return -EINVAL;
}
cipher_xform = crypto_xform;
@@ -428,13 +429,20 @@ crypto_sec_ipsec_inb_session_create(struct rte_cryptodev *crypto_dev,
if (ret)
return ret;
- lp->tunnel_type = ipsec->tunnel.type;
+ lp->mode_type = OTX2_IPSEC_PO_TRANSPORT;
+
auth_xform = crypto_xform;
cipher_xform = crypto_xform->next;
cipher_key_len = 0;
auth_key_len = 0;
+ if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
+ lp->mode_type = (ipsec->tunnel.type ==
+ RTE_SECURITY_IPSEC_TUNNEL_IPV4) ?
+ OTX2_IPSEC_PO_TUNNEL_IPV4 :
+ OTX2_IPSEC_PO_TUNNEL_IPV6;
+
if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM)
memcpy(sa->iv.gcm.nonce, &ipsec->salt, 4);
@@ -55,8 +55,8 @@ struct otx2_sec_session_ipsec_lp {
uint8_t iv_length;
/** Auth IV length in bytes */
uint8_t auth_iv_length;
- /** IPsec tunnel type */
- enum rte_security_ipsec_tunnel_type tunnel_type;
+ /** IPsec mode and tunnel type */
+ enum otx2_ipsec_po_mode_type mode_type;
};
int otx2_crypto_sec_ctx_create(struct rte_cryptodev *crypto_dev);
@@ -20,6 +20,12 @@
#define OTX2_IPSEC_PO_INB_RPTR_HDR 0x8
+enum otx2_ipsec_po_mode_type {
+ OTX2_IPSEC_PO_TRANSPORT = 1,
+ OTX2_IPSEC_PO_TUNNEL_IPV4,
+ OTX2_IPSEC_PO_TUNNEL_IPV6,
+};
+
enum otx2_ipsec_po_comp_e {
OTX2_IPSEC_PO_CC_SUCCESS = 0x00,
OTX2_IPSEC_PO_CC_AUTH_UNSUPPORTED = 0xB0,
@@ -26,7 +26,7 @@ otx2_ipsec_po_out_rlen_get(struct otx2_sec_session_ipsec_lp *sess,
static __rte_always_inline struct cpt_request_info *
alloc_request_struct(char *maddr, void *cop, int mdata_len,
- enum rte_security_ipsec_tunnel_type tunnel_type)
+ enum otx2_ipsec_po_mode_type mode_type)
{
struct cpt_request_info *req;
struct cpt_meta_info *meta;
@@ -48,7 +48,7 @@ alloc_request_struct(char *maddr, void *cop, int mdata_len,
op[1] = (uintptr_t)cop;
op[2] = (uintptr_t)req;
op[3] = mdata_len;
- op[4] = tunnel_type;
+ op[4] = mode_type;
return req;
}
@@ -89,7 +89,7 @@ process_outb_sa(struct rte_crypto_op *cop,
mdata += extend_tail; /* mdata follows encrypted data */
req = alloc_request_struct(mdata, (void *)cop, mdata_len,
- sess->tunnel_type);
+ sess->mode_type);
data = rte_pktmbuf_prepend(m_src, extend_head);
if (unlikely(data == NULL)) {
@@ -162,7 +162,7 @@ process_inb_sa(struct rte_crypto_op *cop,
}
req = alloc_request_struct(mdata, (void *)cop, mdata_len,
- sess->tunnel_type);
+ sess->mode_type);
/* Prepare CPT instruction */
word0.u64 = sess->ucmd_w0;