This patch enables support for NAT-T traversal in IPSEC ESP protocol offload mode for IPv6
Signed-off-by: Hemant Agrawal <hemant.agra...@nxp.com> --- drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c | 68 +++++++++++++-------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c index b34183d594..3814f954ce 100644 --- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c +++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c @@ -50,6 +50,7 @@ #define FSL_SUBSYSTEM_SEC 1 #define FSL_MC_DPSECI_DEVID 3 +#define DPAA2_DEFAULT_NAT_T_PORT 4500 #define NO_PREFETCH 0 #define DRIVER_DUMP_MODE "drv_dump_mode" @@ -3164,6 +3165,7 @@ dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev, uint8_t hdr[48] = {}; struct rte_ipv4_hdr *ip4_hdr; struct rte_ipv6_hdr *ip6_hdr; + struct rte_udp_hdr *uh = NULL; struct ipsec_encap_pdb encap_pdb; flc->dhr = SEC_FLC_DHR_OUTBOUND; @@ -3235,29 +3237,10 @@ dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev, memcpy(&ip4_hdr->dst_addr, &ipsec_xform->tunnel.ipv4.dst_ip, sizeof(struct in_addr)); if (ipsec_xform->options.udp_encap) { - uint16_t sport, dport; - struct rte_udp_hdr *uh = - (struct rte_udp_hdr *) (hdr + - sizeof(struct rte_ipv4_hdr)); - - sport = ipsec_xform->udp.sport ? - ipsec_xform->udp.sport : 4500; - dport = ipsec_xform->udp.dport ? - ipsec_xform->udp.dport : 4500; - uh->src_port = rte_cpu_to_be_16(sport); - uh->dst_port = rte_cpu_to_be_16(dport); - uh->dgram_len = 0; - uh->dgram_cksum = 0; - ip4_hdr->next_proto_id = IPPROTO_UDP; - ip4_hdr->total_length = - rte_cpu_to_be_16( + ip4_hdr->total_length = rte_cpu_to_be_16( sizeof(struct rte_ipv4_hdr) + sizeof(struct rte_udp_hdr)); - encap_pdb.ip_hdr_len += - sizeof(struct rte_udp_hdr); - encap_pdb.options |= - PDBOPTS_ESP_NAT | PDBOPTS_ESP_NUC; } else { ip4_hdr->total_length = rte_cpu_to_be_16( @@ -3284,14 +3267,39 @@ dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev, ip6_hdr->payload_len = 0; ip6_hdr->hop_limits = ipsec_xform->tunnel.ipv6.hlimit ? ipsec_xform->tunnel.ipv6.hlimit : 0x40; - 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); + if (ipsec_xform->options.udp_encap) + ip6_hdr->proto = IPPROTO_UDP; + else + ip6_hdr->proto = (ipsec_xform->proto == + RTE_SECURITY_IPSEC_SA_PROTO_ESP) ? + IPPROTO_ESP : IPPROTO_AH; + } + if (ipsec_xform->options.udp_encap) { + uint16_t sport, dport; + + if (ipsec_xform->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) + uh = (struct rte_udp_hdr *) (hdr + + sizeof(struct rte_ipv4_hdr)); + else + uh = (struct rte_udp_hdr *) (hdr + + sizeof(struct rte_ipv6_hdr)); + + sport = ipsec_xform->udp.sport ? + ipsec_xform->udp.sport : DPAA2_DEFAULT_NAT_T_PORT; + dport = ipsec_xform->udp.dport ? + ipsec_xform->udp.dport : DPAA2_DEFAULT_NAT_T_PORT; + uh->src_port = rte_cpu_to_be_16(sport); + uh->dst_port = rte_cpu_to_be_16(dport); + uh->dgram_len = 0; + uh->dgram_cksum = 0; + + encap_pdb.ip_hdr_len += sizeof(struct rte_udp_hdr); + encap_pdb.options |= PDBOPTS_ESP_NAT | PDBOPTS_ESP_NUC; } bufsize = cnstr_shdsc_ipsec_new_encap(priv->flc_desc[0].desc, @@ -3320,13 +3328,23 @@ dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev, if (ipsec_xform->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) { - decap_pdb.options = sizeof(struct ip) << 16; + if (ipsec_xform->options.udp_encap) + decap_pdb.options = + (sizeof(struct ip) + sizeof(struct rte_udp_hdr)) << 16; + else + decap_pdb.options = sizeof(struct ip) << 16; if (ipsec_xform->options.copy_df) decap_pdb.options |= PDBHMO_ESP_DFV; if (ipsec_xform->options.dec_ttl) decap_pdb.options |= PDBHMO_ESP_DECAP_DTTL; } else { - decap_pdb.options = sizeof(struct rte_ipv6_hdr) << 16; + if (ipsec_xform->options.udp_encap) { + decap_pdb.options = + (sizeof(struct rte_ipv6_hdr) + + sizeof(struct rte_udp_hdr)) << 16; + } else { + decap_pdb.options = sizeof(struct rte_ipv6_hdr) << 16; + } } if (ipsec_xform->options.esn) { decap_pdb.options |= PDBOPTS_ESP_ESN; -- 2.25.1