From 53982ba2805d4dea724c923836d0ea8a4e16232d Mon Sep 17 00:00:00 2001 From: Akhil Goyal Date: Thu, 5 Sep 2019 18:18:06 +0530 Subject: [PATCH] crypto/dpaa2_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/dpaa2_sec/dpaa2_sec_dpseci.c | 68 +++++++++++++++------ drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h | 2 + 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c index 420e865893..f162eeed29 100644 --- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c +++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -2465,23 +2466,11 @@ dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev, session->ctxt_type = DPAA2_SEC_IPSEC; if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { + uint8_t *hdr = NULL; struct ip ip4_hdr; + struct rte_ipv6_hdr ip6_hdr; flc->dhr = SEC_FLC_DHR_OUTBOUND; - ip4_hdr.ip_v = IPVERSION; - ip4_hdr.ip_hl = 5; - ip4_hdr.ip_len = rte_cpu_to_be_16(sizeof(ip4_hdr)); - ip4_hdr.ip_tos = ipsec_xform->tunnel.ipv4.dscp; - ip4_hdr.ip_id = 0; - ip4_hdr.ip_off = 0; - ip4_hdr.ip_ttl = ipsec_xform->tunnel.ipv4.ttl; - ip4_hdr.ip_p = IPPROTO_ESP; - ip4_hdr.ip_sum = 0; - ip4_hdr.ip_src = ipsec_xform->tunnel.ipv4.src_ip; - ip4_hdr.ip_dst = ipsec_xform->tunnel.ipv4.dst_ip; - ip4_hdr.ip_sum = calc_chksum((uint16_t *)(void *)&ip4_hdr, - sizeof(struct ip)); - /* For Sec Proto only one descriptor is required. */ memset(&encap_pdb, 0, sizeof(struct ipsec_encap_pdb)); encap_pdb.options = (IPVERSION << PDBNH_ESP_ENCAP_SHIFT) | @@ -2492,13 +2481,52 @@ dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev, if (ipsec_xform->options.esn) encap_pdb.options |= PDBOPTS_ESP_ESN; encap_pdb.spi = ipsec_xform->spi; - encap_pdb.ip_hdr_len = sizeof(struct ip); - session->dir = DIR_ENC; + if (ipsec_xform->tunnel.type == + RTE_SECURITY_IPSEC_TUNNEL_IPV4) { + encap_pdb.ip_hdr_len = sizeof(struct ip); + ip4_hdr.ip_v = IPVERSION; + ip4_hdr.ip_hl = 5; + ip4_hdr.ip_len = rte_cpu_to_be_16(sizeof(ip4_hdr)); + ip4_hdr.ip_tos = ipsec_xform->tunnel.ipv4.dscp; + ip4_hdr.ip_id = 0; + ip4_hdr.ip_off = 0; + ip4_hdr.ip_ttl = ipsec_xform->tunnel.ipv4.ttl; + ip4_hdr.ip_p = IPPROTO_ESP; + ip4_hdr.ip_sum = 0; + ip4_hdr.ip_src = ipsec_xform->tunnel.ipv4.src_ip; + ip4_hdr.ip_dst = ipsec_xform->tunnel.ipv4.dst_ip; + ip4_hdr.ip_sum = calc_chksum((uint16_t *)(void *) + &ip4_hdr, sizeof(struct ip)); + hdr = (uint8_t *)&ip4_hdr; + } else if (ipsec_xform->tunnel.type == + RTE_SECURITY_IPSEC_TUNNEL_IPV6) { + ip6_hdr.vtc_flow = rte_cpu_to_be_32( + DPAA2_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 */ + ip6_hdr.payload_len = 0; + ip6_hdr.hop_limits = + ipsec_xform->tunnel.ipv6.hlimit; + ip6_hdr.proto = (ipsec_xform->proto == + RTE_SECURITY_IPSEC_SA_PROTO_ESP) ? + IPPROTO_ESP : IPPROTO_AH; + memcpy(&ip6_hdr.src_addr, + &ipsec_xform->tunnel.ipv6.src_addr, 16); + memcpy(&ip6_hdr.dst_addr, + &ipsec_xform->tunnel.ipv6.dst_addr, 16); + encap_pdb.ip_hdr_len = sizeof(struct rte_ipv6_hdr); + hdr = (uint8_t *)&ip6_hdr; + } + bufsize = cnstr_shdsc_ipsec_new_encap(priv->flc_desc[0].desc, 1, 0, SHR_SERIAL, &encap_pdb, - (uint8_t *)&ip4_hdr, - &cipherdata, &authdata); + hdr, &cipherdata, &authdata); } else if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { flc->dhr = SEC_FLC_DHR_INBOUND; @@ -2506,6 +2534,10 @@ dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev, decap_pdb.options = sizeof(struct ip) << 16; if (ipsec_xform->options.esn) decap_pdb.options |= PDBOPTS_ESP_ESN; + decap_pdb.options = (ipsec_xform->tunnel.type == + RTE_SECURITY_IPSEC_TUNNEL_IPV4) ? + sizeof(struct ip) << 16 : + sizeof(struct rte_ipv6_hdr) << 16; session->dir = DIR_DEC; bufsize = cnstr_shdsc_ipsec_new_decap(priv->flc_desc[0].desc, 1, 0, SHR_SERIAL, diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h b/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h index 51751103d2..a05deaebd0 100644 --- a/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h +++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h @@ -41,6 +41,8 @@ enum shr_desc_type { #define DIR_ENC 1 #define DIR_DEC 0 +#define DPAA2_IPv6_DEFAULT_VTC_FLOW 0x60000000 + #define DPAA2_SET_FLC_EWS(flc) (flc->word1_bits23_16 |= 0x1) #define DPAA2_SET_FLC_RSC(flc) (flc->word1_bits31_24 |= 0x1) #define DPAA2_SET_FLC_REUSE_BS(flc) (flc->mode_bits |= 0x8000) -- 2.20.1