[v4,07/10] ipsec: add support for NAT-T
Checks
Commit Message
Add support for the IPsec NAT-Traversal use case for Tunnel mode
packets.
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
Signed-off-by: Abhijit Sinha <abhijit.sinha@intel.com>
Signed-off-by: Daniel Martin Buckley <daniel.m.buckley@intel.com>
---
lib/ipsec/iph.h | 13 +++++++++++++
lib/ipsec/rte_ipsec_sa.h | 8 +++++++-
lib/ipsec/sa.c | 13 ++++++++++++-
lib/ipsec/sa.h | 4 ++++
4 files changed, 36 insertions(+), 2 deletions(-)
Comments
> -----Original Message-----
> From: Nicolau, Radu <radu.nicolau@intel.com>
> Sent: Friday, September 3, 2021 12:26 PM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Iremonger,
> Bernard <bernard.iremonger@intel.com>; Medvedkin, Vladimir
> <vladimir.medvedkin@intel.com>
> Cc: dev@dpdk.org; mdr@ashroe.eu; Richardson, Bruce
> <bruce.richardson@intel.com>; Zhang, Roy Fan <roy.fan.zhang@intel.com>;
> hemant.agrawal@nxp.com; gakhil@marvell.com; anoobj@marvell.com;
> Doherty, Declan <declan.doherty@intel.com>; Sinha, Abhijit
> <abhijit.sinha@intel.com>; Buckley, Daniel M <daniel.m.buckley@intel.com>;
> marchana@marvell.com; ktejasree@marvell.com; matan@nvidia.com;
> Nicolau, Radu <radu.nicolau@intel.com>
> Subject: [PATCH v4 07/10] ipsec: add support for NAT-T
>
> Add support for the IPsec NAT-Traversal use case for Tunnel mode
> packets.
>
> Signed-off-by: Declan Doherty <declan.doherty@intel.com>
> Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
> Signed-off-by: Abhijit Sinha <abhijit.sinha@intel.com>
> Signed-off-by: Daniel Martin Buckley <daniel.m.buckley@intel.com>
> ---
Acked-by: Fan Zhang <roy.fan.zhang@intel.com>
> Add support for the IPsec NAT-Traversal use case for Tunnel mode
> packets.
>
> Signed-off-by: Declan Doherty <declan.doherty@intel.com>
> Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
> Signed-off-by: Abhijit Sinha <abhijit.sinha@intel.com>
> Signed-off-by: Daniel Martin Buckley <daniel.m.buckley@intel.com>
> ---
> lib/ipsec/iph.h | 13 +++++++++++++
> lib/ipsec/rte_ipsec_sa.h | 8 +++++++-
> lib/ipsec/sa.c | 13 ++++++++++++-
> lib/ipsec/sa.h | 4 ++++
> 4 files changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/lib/ipsec/iph.h b/lib/ipsec/iph.h
> index 2d223199ac..093f86d34a 100644
> --- a/lib/ipsec/iph.h
> +++ b/lib/ipsec/iph.h
> @@ -251,6 +251,7 @@ update_tun_outb_l3hdr(const struct rte_ipsec_sa
> *sa, void *outh,
> {
> struct rte_ipv4_hdr *v4h;
> struct rte_ipv6_hdr *v6h;
> + struct rte_udp_hdr *udph;
> uint8_t is_outh_ipv4;
>
> if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV4) {
> @@ -258,11 +259,23 @@ update_tun_outb_l3hdr(const struct rte_ipsec_sa
> *sa, void *outh,
> v4h = outh;
> v4h->packet_id = pid;
> v4h->total_length = rte_cpu_to_be_16(plen - l2len);
> +
> + if (sa->type & RTE_IPSEC_SATP_NATT_ENABLE) {
> + udph = (struct rte_udp_hdr *)(v4h + 1);
> + udph->dgram_len = rte_cpu_to_be_16(plen - l2len -
> + (sizeof(*v4h) + sizeof(*udph)));
> + }
> } else {
> is_outh_ipv4 = 0;
> v6h = outh;
> v6h->payload_len = rte_cpu_to_be_16(plen - l2len -
> sizeof(*v6h));
> +
> + if (sa->type & RTE_IPSEC_SATP_NATT_ENABLE) {
> + udph = (struct rte_udp_hdr *)(v6h + 1);
> + udph->dgram_len = rte_cpu_to_be_16(plen - l2len -
> + (sizeof(*v6h) + sizeof(*udph)));
> + }
> }
>
> if (sa->type & TUN_HDR_MSK)
> diff --git a/lib/ipsec/rte_ipsec_sa.h b/lib/ipsec/rte_ipsec_sa.h
> index cf51ad8338..40d1e70d45 100644
> --- a/lib/ipsec/rte_ipsec_sa.h
> +++ b/lib/ipsec/rte_ipsec_sa.h
> @@ -76,6 +76,7 @@ struct rte_ipsec_sa_prm {
> * - inbound/outbound
> * - mode (TRANSPORT/TUNNEL)
> * - for TUNNEL outer IP version (IPv4/IPv6)
> + * - NAT-T UDP encapsulated (TUNNEL mode only)
> * - are SA SQN operations 'atomic'
> * - ESN enabled/disabled
> * ...
> @@ -86,7 +87,8 @@ enum {
> RTE_SATP_LOG2_PROTO,
> RTE_SATP_LOG2_DIR,
> RTE_SATP_LOG2_MODE,
> - RTE_SATP_LOG2_SQN = RTE_SATP_LOG2_MODE + 2,
> + RTE_SATP_LOG2_NATT = RTE_SATP_LOG2_MODE + 2,
> + RTE_SATP_LOG2_SQN,
> RTE_SATP_LOG2_ESN,
> RTE_SATP_LOG2_ECN,
> RTE_SATP_LOG2_DSCP
> @@ -109,6 +111,10 @@ enum {
> #define RTE_IPSEC_SATP_MODE_TUNLV4 (1ULL <<
> RTE_SATP_LOG2_MODE)
> #define RTE_IPSEC_SATP_MODE_TUNLV6 (2ULL <<
> RTE_SATP_LOG2_MODE)
>
> +#define RTE_IPSEC_SATP_NATT_MASK (1ULL <<
> RTE_SATP_LOG2_NATT)
> +#define RTE_IPSEC_SATP_NATT_DISABLE (0ULL <<
> RTE_SATP_LOG2_NATT)
> +#define RTE_IPSEC_SATP_NATT_ENABLE (1ULL <<
> RTE_SATP_LOG2_NATT)
> +
> #define RTE_IPSEC_SATP_SQN_MASK (1ULL <<
> RTE_SATP_LOG2_SQN)
> #define RTE_IPSEC_SATP_SQN_RAW (0ULL <<
> RTE_SATP_LOG2_SQN)
> #define RTE_IPSEC_SATP_SQN_ATOM (1ULL <<
> RTE_SATP_LOG2_SQN)
> diff --git a/lib/ipsec/sa.c b/lib/ipsec/sa.c
> index 2ecbbce0a4..8e369e4618 100644
> --- a/lib/ipsec/sa.c
> +++ b/lib/ipsec/sa.c
> @@ -217,6 +217,10 @@ fill_sa_type(const struct rte_ipsec_sa_prm *prm,
> uint64_t *type)
> } else
> return -EINVAL;
>
> + /* check for UDP encapsulation flag */
> + if (prm->ipsec_xform.options.udp_encap == 1)
> + tp |= RTE_IPSEC_SATP_NATT_ENABLE;
> +
> /* check for ESN flag */
> if (prm->ipsec_xform.options.esn == 0)
> tp |= RTE_IPSEC_SATP_ESN_DISABLE;
> @@ -372,7 +376,8 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct
> rte_ipsec_sa_prm *prm,
> const struct crypto_xform *cxf)
> {
> static const uint64_t msk = RTE_IPSEC_SATP_DIR_MASK |
> - RTE_IPSEC_SATP_MODE_MASK;
> + RTE_IPSEC_SATP_MODE_MASK |
> + RTE_IPSEC_SATP_NATT_MASK;
>
> if (prm->ipsec_xform.options.ecn)
> sa->tos_mask |= RTE_IPV4_HDR_ECN_MASK;
> @@ -475,10 +480,16 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct
> rte_ipsec_sa_prm *prm,
> case (RTE_IPSEC_SATP_DIR_IB | RTE_IPSEC_SATP_MODE_TRANS):
> esp_inb_init(sa);
> break;
> + case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV4 |
> + RTE_IPSEC_SATP_NATT_ENABLE):
> + case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV6 |
> + RTE_IPSEC_SATP_NATT_ENABLE):
> case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV4):
> case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV6):
> esp_outb_tun_init(sa, prm);
> break;
> + case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TRANS |
> + RTE_IPSEC_SATP_NATT_ENABLE):
> case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TRANS):
> esp_outb_init(sa, 0);
> break;
> diff --git a/lib/ipsec/sa.h b/lib/ipsec/sa.h
> index 5e237f3525..3f38921eb3 100644
> --- a/lib/ipsec/sa.h
> +++ b/lib/ipsec/sa.h
> @@ -101,6 +101,10 @@ struct rte_ipsec_sa {
> uint64_t msk;
> uint64_t val;
> } tx_offload;
> + struct {
> + uint16_t sport;
> + uint16_t dport;
> + } natt;
These ports are not getting used in this patch,
As indicated in the previous patch, do we really need these?
As for NAT-T, 4500 is the default port.
On 9/5/2021 4:00 PM, Akhil Goyal wrote:
>> Add support for the IPsec NAT-Traversal use case for Tunnel mode
>> packets.
>>
>> Signed-off-by: Declan Doherty <declan.doherty@intel.com>
>> Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
>> Signed-off-by: Abhijit Sinha <abhijit.sinha@intel.com>
>> Signed-off-by: Daniel Martin Buckley <daniel.m.buckley@intel.com>
>> ---
>>
>> These ports are not getting used in this patch,
>> As indicated in the previous patch, do we really need these?
>> As for NAT-T, 4500 is the default port.
Yes, you are right, they aren't used, I will update the patch. About the
need to have them, I replied in the prev patch, from what I see the RFC
doesn't require specific ports for UDP encapsulation.
@@ -251,6 +251,7 @@ update_tun_outb_l3hdr(const struct rte_ipsec_sa *sa, void *outh,
{
struct rte_ipv4_hdr *v4h;
struct rte_ipv6_hdr *v6h;
+ struct rte_udp_hdr *udph;
uint8_t is_outh_ipv4;
if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV4) {
@@ -258,11 +259,23 @@ update_tun_outb_l3hdr(const struct rte_ipsec_sa *sa, void *outh,
v4h = outh;
v4h->packet_id = pid;
v4h->total_length = rte_cpu_to_be_16(plen - l2len);
+
+ if (sa->type & RTE_IPSEC_SATP_NATT_ENABLE) {
+ udph = (struct rte_udp_hdr *)(v4h + 1);
+ udph->dgram_len = rte_cpu_to_be_16(plen - l2len -
+ (sizeof(*v4h) + sizeof(*udph)));
+ }
} else {
is_outh_ipv4 = 0;
v6h = outh;
v6h->payload_len = rte_cpu_to_be_16(plen - l2len -
sizeof(*v6h));
+
+ if (sa->type & RTE_IPSEC_SATP_NATT_ENABLE) {
+ udph = (struct rte_udp_hdr *)(v6h + 1);
+ udph->dgram_len = rte_cpu_to_be_16(plen - l2len -
+ (sizeof(*v6h) + sizeof(*udph)));
+ }
}
if (sa->type & TUN_HDR_MSK)
@@ -76,6 +76,7 @@ struct rte_ipsec_sa_prm {
* - inbound/outbound
* - mode (TRANSPORT/TUNNEL)
* - for TUNNEL outer IP version (IPv4/IPv6)
+ * - NAT-T UDP encapsulated (TUNNEL mode only)
* - are SA SQN operations 'atomic'
* - ESN enabled/disabled
* ...
@@ -86,7 +87,8 @@ enum {
RTE_SATP_LOG2_PROTO,
RTE_SATP_LOG2_DIR,
RTE_SATP_LOG2_MODE,
- RTE_SATP_LOG2_SQN = RTE_SATP_LOG2_MODE + 2,
+ RTE_SATP_LOG2_NATT = RTE_SATP_LOG2_MODE + 2,
+ RTE_SATP_LOG2_SQN,
RTE_SATP_LOG2_ESN,
RTE_SATP_LOG2_ECN,
RTE_SATP_LOG2_DSCP
@@ -109,6 +111,10 @@ enum {
#define RTE_IPSEC_SATP_MODE_TUNLV4 (1ULL << RTE_SATP_LOG2_MODE)
#define RTE_IPSEC_SATP_MODE_TUNLV6 (2ULL << RTE_SATP_LOG2_MODE)
+#define RTE_IPSEC_SATP_NATT_MASK (1ULL << RTE_SATP_LOG2_NATT)
+#define RTE_IPSEC_SATP_NATT_DISABLE (0ULL << RTE_SATP_LOG2_NATT)
+#define RTE_IPSEC_SATP_NATT_ENABLE (1ULL << RTE_SATP_LOG2_NATT)
+
#define RTE_IPSEC_SATP_SQN_MASK (1ULL << RTE_SATP_LOG2_SQN)
#define RTE_IPSEC_SATP_SQN_RAW (0ULL << RTE_SATP_LOG2_SQN)
#define RTE_IPSEC_SATP_SQN_ATOM (1ULL << RTE_SATP_LOG2_SQN)
@@ -217,6 +217,10 @@ fill_sa_type(const struct rte_ipsec_sa_prm *prm, uint64_t *type)
} else
return -EINVAL;
+ /* check for UDP encapsulation flag */
+ if (prm->ipsec_xform.options.udp_encap == 1)
+ tp |= RTE_IPSEC_SATP_NATT_ENABLE;
+
/* check for ESN flag */
if (prm->ipsec_xform.options.esn == 0)
tp |= RTE_IPSEC_SATP_ESN_DISABLE;
@@ -372,7 +376,8 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
const struct crypto_xform *cxf)
{
static const uint64_t msk = RTE_IPSEC_SATP_DIR_MASK |
- RTE_IPSEC_SATP_MODE_MASK;
+ RTE_IPSEC_SATP_MODE_MASK |
+ RTE_IPSEC_SATP_NATT_MASK;
if (prm->ipsec_xform.options.ecn)
sa->tos_mask |= RTE_IPV4_HDR_ECN_MASK;
@@ -475,10 +480,16 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
case (RTE_IPSEC_SATP_DIR_IB | RTE_IPSEC_SATP_MODE_TRANS):
esp_inb_init(sa);
break;
+ case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV4 |
+ RTE_IPSEC_SATP_NATT_ENABLE):
+ case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV6 |
+ RTE_IPSEC_SATP_NATT_ENABLE):
case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV4):
case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV6):
esp_outb_tun_init(sa, prm);
break;
+ case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TRANS |
+ RTE_IPSEC_SATP_NATT_ENABLE):
case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TRANS):
esp_outb_init(sa, 0);
break;
@@ -101,6 +101,10 @@ struct rte_ipsec_sa {
uint64_t msk;
uint64_t val;
} tx_offload;
+ struct {
+ uint16_t sport;
+ uint16_t dport;
+ } natt;
uint32_t salt;
uint8_t algo_type;
uint8_t proto; /* next proto */