examples/ipsec-secgw: support UDP encap for inline crypto
authorRadu Nicolau <radu.nicolau@intel.com>
Mon, 1 Nov 2021 12:58:11 +0000 (12:58 +0000)
committerAkhil Goyal <gakhil@marvell.com>
Thu, 4 Nov 2021 18:46:27 +0000 (19:46 +0100)
Enable UDP encapsulation for both transport and tunnel modes for the
inline crypto offload path.

Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
Acked-by: Akhil Goyal <gakhil@marvell.com>
doc/guides/sample_app_ug/ipsec_secgw.rst
examples/ipsec-secgw/ipsec.c
examples/ipsec-secgw/ipsec.h
examples/ipsec-secgw/sa.c

index 0a198d8..08566b4 100644 (file)
@@ -717,7 +717,8 @@ where each options means:
  ``<udp-encap>``
 
  * Option to enable IPsec UDP encapsulation for NAT Traversal.
-   Only *lookaside-protocol-offload* mode is supported at the moment.
+   Only *lookaside-protocol-offload* and *inline-crypto-offload* modes are
+   supported at the moment.
 
  * Optional: Yes, it is disabled by default
 
index b6b7bdd..90d9e61 100644 (file)
@@ -221,6 +221,12 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa,
                }
        }
 
+       if (sa->udp_encap) {
+               sess_conf.ipsec.options.udp_encap = 1;
+               sess_conf.ipsec.udp.sport = htons(sa->udp.sport);
+               sess_conf.ipsec.udp.dport = htons(sa->udp.dport);
+       }
+
        RTE_LOG_DP(DEBUG, IPSEC, "Create session for SA spi %u on port %u\n",
                sa->spi, sa->portid);
 
@@ -289,12 +295,31 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa,
                        sa->ipv4_spec.hdr.src_addr = sa->src.ip.ip4;
                }
 
-               sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_ESP;
-               sa->pattern[2].spec = &sa->esp_spec;
-               sa->pattern[2].mask = &rte_flow_item_esp_mask;
                sa->esp_spec.hdr.spi = rte_cpu_to_be_32(sa->spi);
 
-               sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
+               if (sa->udp_encap) {
+
+                       sa->udp_spec.hdr.dst_port =
+                                       rte_cpu_to_be_16(sa->udp.dport);
+                       sa->udp_spec.hdr.src_port =
+                                       rte_cpu_to_be_16(sa->udp.sport);
+
+                       sa->pattern[2].mask = &rte_flow_item_udp_mask;
+                       sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP;
+                       sa->pattern[2].spec = &sa->udp_spec;
+
+                       sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_ESP;
+                       sa->pattern[3].spec = &sa->esp_spec;
+                       sa->pattern[3].mask = &rte_flow_item_esp_mask;
+
+                       sa->pattern[4].type = RTE_FLOW_ITEM_TYPE_END;
+               } else {
+                       sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_ESP;
+                       sa->pattern[2].spec = &sa->esp_spec;
+                       sa->pattern[2].mask = &rte_flow_item_esp_mask;
+
+                       sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
+               }
 
                sa->action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY;
                sa->action[0].conf = ips->security.ses;
index 2c36408..d19f851 100644 (file)
@@ -125,6 +125,10 @@ struct ipsec_sa {
 #define IP6_TRANSPORT (1 << 4)
        struct ip_addr src;
        struct ip_addr dst;
+       struct {
+               uint16_t sport;
+               uint16_t dport;
+       } udp;
        uint8_t cipher_key[MAX_KEY_SIZE];
        uint16_t cipher_key_len;
        uint8_t auth_key[MAX_KEY_SIZE];
@@ -141,7 +145,7 @@ struct ipsec_sa {
        uint8_t fdir_qid;
        uint8_t fdir_flag;
 
-#define MAX_RTE_FLOW_PATTERN (4)
+#define MAX_RTE_FLOW_PATTERN (5)
 #define MAX_RTE_FLOW_ACTIONS (3)
        struct rte_flow_item pattern[MAX_RTE_FLOW_PATTERN];
        struct rte_flow_action action[MAX_RTE_FLOW_ACTIONS];
@@ -150,6 +154,7 @@ struct ipsec_sa {
                struct rte_flow_item_ipv4 ipv4_spec;
                struct rte_flow_item_ipv6 ipv6_spec;
        };
+       struct rte_flow_item_udp udp_spec;
        struct rte_flow_item_esp esp_spec;
        struct rte_flow *flow;
        struct rte_security_session_conf sess_conf;
index 97f265c..e2c5120 100644 (file)
@@ -17,6 +17,7 @@
 #include <rte_byteorder.h>
 #include <rte_errno.h>
 #include <rte_ip.h>
+#include <rte_udp.h>
 #include <rte_random.h>
 #include <rte_ethdev.h>
 #include <rte_malloc.h>
@@ -781,6 +782,11 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
                                app_sa_prm.udp_encap = 1;
                                udp_encap_p = 1;
                                break;
+                       case RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO:
+                               rule->udp_encap = 1;
+                               rule->udp.sport = 0;
+                               rule->udp.dport = 4500;
+                               break;
                        default:
                                APP_CHECK(0, status,
                                        "UDP encapsulation not supported for "
@@ -868,6 +874,8 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
        }
 
        printf("mode:");
+       if (sa->udp_encap)
+               printf("UDP encapsulated ");
 
        switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
        case IP4_TUNNEL:
@@ -1327,6 +1335,7 @@ fill_ipsec_sa_prm(struct rte_ipsec_sa_prm *prm, const struct ipsec_sa *ss,
        prm->ipsec_xform.mode = (IS_TRANSPORT(ss->flags)) ?
                RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT :
                RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
+       prm->ipsec_xform.options.udp_encap = ss->udp_encap;
        prm->ipsec_xform.options.ecn = 1;
        prm->ipsec_xform.options.copy_dscp = 1;