From 5ab35d2e3ee16e566165e7745127334572d72018 Mon Sep 17 00:00:00 2001 From: Akhil Goyal Date: Thu, 5 Sep 2019 18:18:05 +0530 Subject: [PATCH] crypto/dpaa_sec: support IPv6 tunnel for protocol offload outer IP header is formed at the time of session initialization using the ipsec xform. This outer IP header will be appended by hardware for each packet. Signed-off-by: Akhil Goyal --- drivers/crypto/dpaa_sec/dpaa_sec.c | 73 ++++++++++++++++++++++-------- drivers/crypto/dpaa_sec/dpaa_sec.h | 7 ++- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c index 39c9271ffd..758f893205 100644 --- a/drivers/crypto/dpaa_sec/dpaa_sec.c +++ b/drivers/crypto/dpaa_sec/dpaa_sec.c @@ -2238,26 +2238,58 @@ dpaa_sec_set_ipsec_session(__rte_unused struct rte_cryptodev *dev, } if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { - memset(&session->encap_pdb, 0, sizeof(struct ipsec_encap_pdb) + + if (ipsec_xform->tunnel.type == + RTE_SECURITY_IPSEC_TUNNEL_IPV4) { + memset(&session->encap_pdb, 0, + sizeof(struct ipsec_encap_pdb) + sizeof(session->ip4_hdr)); - session->ip4_hdr.ip_v = IPVERSION; - session->ip4_hdr.ip_hl = 5; - session->ip4_hdr.ip_len = rte_cpu_to_be_16( + session->ip4_hdr.ip_v = IPVERSION; + session->ip4_hdr.ip_hl = 5; + session->ip4_hdr.ip_len = rte_cpu_to_be_16( sizeof(session->ip4_hdr)); - session->ip4_hdr.ip_tos = ipsec_xform->tunnel.ipv4.dscp; - session->ip4_hdr.ip_id = 0; - session->ip4_hdr.ip_off = 0; - session->ip4_hdr.ip_ttl = ipsec_xform->tunnel.ipv4.ttl; - session->ip4_hdr.ip_p = (ipsec_xform->proto == - RTE_SECURITY_IPSEC_SA_PROTO_ESP) ? IPPROTO_ESP - : IPPROTO_AH; - session->ip4_hdr.ip_sum = 0; - session->ip4_hdr.ip_src = ipsec_xform->tunnel.ipv4.src_ip; - session->ip4_hdr.ip_dst = ipsec_xform->tunnel.ipv4.dst_ip; - session->ip4_hdr.ip_sum = calc_chksum((uint16_t *) + session->ip4_hdr.ip_tos = ipsec_xform->tunnel.ipv4.dscp; + session->ip4_hdr.ip_id = 0; + session->ip4_hdr.ip_off = 0; + session->ip4_hdr.ip_ttl = ipsec_xform->tunnel.ipv4.ttl; + session->ip4_hdr.ip_p = (ipsec_xform->proto == + RTE_SECURITY_IPSEC_SA_PROTO_ESP) ? + IPPROTO_ESP : IPPROTO_AH; + session->ip4_hdr.ip_sum = 0; + session->ip4_hdr.ip_src = + ipsec_xform->tunnel.ipv4.src_ip; + session->ip4_hdr.ip_dst = + ipsec_xform->tunnel.ipv4.dst_ip; + session->ip4_hdr.ip_sum = calc_chksum((uint16_t *) (void *)&session->ip4_hdr, sizeof(struct ip)); - + session->encap_pdb.ip_hdr_len = sizeof(struct ip); + } else if (ipsec_xform->tunnel.type == + RTE_SECURITY_IPSEC_TUNNEL_IPV6) { + memset(&session->encap_pdb, 0, + sizeof(struct ipsec_encap_pdb) + + sizeof(session->ip6_hdr)); + session->ip6_hdr.vtc_flow = rte_cpu_to_be_32( + DPAA_IPv6_DEFAULT_VTC_FLOW | + ((ipsec_xform->tunnel.ipv6.dscp << + RTE_IPV6_HDR_TC_SHIFT) & + RTE_IPV6_HDR_TC_MASK) | + ((ipsec_xform->tunnel.ipv6.flabel << + RTE_IPV6_HDR_FL_SHIFT) & + RTE_IPV6_HDR_FL_MASK)); + /* Payload length will be updated by HW */ + session->ip6_hdr.payload_len = 0; + session->ip6_hdr.hop_limits = + ipsec_xform->tunnel.ipv6.hlimit; + session->ip6_hdr.proto = (ipsec_xform->proto == + RTE_SECURITY_IPSEC_SA_PROTO_ESP) ? + IPPROTO_ESP : IPPROTO_AH; + memcpy(&session->ip6_hdr.src_addr, + &ipsec_xform->tunnel.ipv6.src_addr, 16); + memcpy(&session->ip6_hdr.dst_addr, + &ipsec_xform->tunnel.ipv6.dst_addr, 16); + session->encap_pdb.ip_hdr_len = + sizeof(struct rte_ipv6_hdr); + } session->encap_pdb.options = (IPVERSION << PDBNH_ESP_ENCAP_SHIFT) | PDBOPTS_ESP_OIHI_PDB_INL | @@ -2266,15 +2298,16 @@ dpaa_sec_set_ipsec_session(__rte_unused struct rte_cryptodev *dev, PDBHMO_ESP_SNR; if (ipsec_xform->options.esn) session->encap_pdb.options |= PDBOPTS_ESP_ESN; - session->encap_pdb.spi = ipsec_xform->spi; - session->encap_pdb.ip_hdr_len = sizeof(struct ip); - session->dir = DIR_ENC; } else if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { memset(&session->decap_pdb, 0, sizeof(struct ipsec_decap_pdb)); - session->decap_pdb.options = sizeof(struct ip) << 16; + if (ipsec_xform->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) + session->decap_pdb.options = sizeof(struct ip) << 16; + else + session->decap_pdb.options = + sizeof(struct rte_ipv6_hdr) << 16; if (ipsec_xform->options.esn) session->decap_pdb.options |= PDBOPTS_ESP_ESN; session->dir = DIR_DEC; diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.h b/drivers/crypto/dpaa_sec/dpaa_sec.h index 75c0960a9d..08e7d66e53 100644 --- a/drivers/crypto/dpaa_sec/dpaa_sec.h +++ b/drivers/crypto/dpaa_sec/dpaa_sec.h @@ -19,6 +19,8 @@ #define AES_CTR_IV_LEN 16 #define AES_GCM_IV_LEN 12 +#define DPAA_IPv6_DEFAULT_VTC_FLOW 0x60000000 + /* Minimum job descriptor consists of a oneword job descriptor HEADER and * a pointer to the shared descriptor. */ @@ -139,7 +141,10 @@ typedef struct dpaa_sec_session_entry { uint32_t digest_length; struct ipsec_decap_pdb decap_pdb; struct ipsec_encap_pdb encap_pdb; - struct ip ip4_hdr; + union { + struct ip ip4_hdr; + struct rte_ipv6_hdr ip6_hdr; + }; }; struct sec_pdcp_ctxt pdcp; }; -- 2.20.1