[v3,2/3] crypto/dpaa2_sec: support IPv6 tunnel for protocol offload
Checks
Commit Message
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 <akhil.goyal@nxp.com>
---
drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c | 69 +++++++++++++++------
drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h | 2 +
2 files changed, 52 insertions(+), 19 deletions(-)
@@ -9,6 +9,7 @@
#include <net/if.h>
#include <unistd.h>
+#include <rte_ip.h>
#include <rte_mbuf.h>
#include <rte_cryptodev.h>
#include <rte_malloc.h>
@@ -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) |
@@ -2490,18 +2479,60 @@ dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev,
PDBHMO_ESP_ENCAP_DTTL |
PDBHMO_ESP_SNR;
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;
memset(&decap_pdb, 0, sizeof(struct ipsec_decap_pdb));
- decap_pdb.options = sizeof(struct ip) << 16;
+ 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,
@@ -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)