Provide options to enforce NAT-T UDP encapsulation. Options are
encapsulation=true for libreswan and forceencaps=true for strongswan.
This may be required in environments where firewalls drop ESP
traffic but where NAT-T detection fails because packets are not
subject to NAT.

Signed-off-by: Andreas Karis <[email protected]>
Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2041681
Signed-off-by: Numan Siddique <[email protected]>
(cherry picked from commit d6dd8e49551141159f040406202f8550c18a1846)

Conflicts:
        NEWS
---
 Documentation/tutorials/ovn-ipsec.rst | 24 ++++++++++++++++++++++++
 NEWS                                  |  7 ++++---
 controller/encaps.c                   | 15 +++++++++++++++
 tests/ovn-ipsec.at                    |  3 +++
 4 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/Documentation/tutorials/ovn-ipsec.rst 
b/Documentation/tutorials/ovn-ipsec.rst
index 305dd566d..aea7aa309 100644
--- a/Documentation/tutorials/ovn-ipsec.rst
+++ b/Documentation/tutorials/ovn-ipsec.rst
@@ -93,6 +93,29 @@ database to false::
        # systemctl enable firewalld
        # firewall-cmd --permanent --add-service ipsec
 
+Enforcing IPsec NAT-T UDP encapsulation
+---------------------------------------
+
+In specific situations, it may be required to enforce NAT-T (RFC3948) UDP
+encapsulation unconditionally and to bypass the normal NAT detection mechanism.
+For example, this may be required in environments where firewalls drop ESP
+traffic, but where NAT-T detection (RFC3947) fails because packets otherwise
+are not subject to NAT.
+In such scenarios, UDP encapsulation can be enforced with the following.
+
+For libreswan backends::
+
+    $ ovn-nbctl set nb_global . options:ipsec_encapsulation=true
+
+For strongswan backends::
+
+    $ ovn-nbctl set nb_global . options:ipsec_forceencaps=true
+
+.. note::
+
+   Support for this feature is only availably when OVN is used together with
+   OVS releases that accept IPsec custom tunnel options.
+
 Troubleshooting
 ---------------
 
@@ -119,6 +142,7 @@ For example::
    Remote name:    host_2
    CA cert:        /path/to/cacert.pem
    PSK:            None
+   Custom Options: {'encapsulation': 'yes'} <---- Whether NAT-T is enforced
    Ofport:         2          <--- Whether ovs-vswitchd has assigned Ofport
                                    number to this Tunnel Port
    CFM state:      Disabled     <--- Whether CFM declared this tunnel healthy
diff --git a/NEWS b/NEWS
index 32e342a18..3744362e3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,3 @@
-OVN v22.06.1 - xx xxx xxxx
---------------------------
-
 OVN v22.06.0 - 03 Jun 2022
 --------------------------
   - Support IGMP and MLD snooping on transit logical switches that connect
@@ -29,6 +26,10 @@ OVN v22.06.0 - 03 Jun 2022
   - Support list of chassis for Logical_Switch_Port:options:requested-chassis.
   - Support Logical_Switch_Port:options:activation-strategy for live migration
     scenarios.
+  - Added nb_global IPsec options ipsec_encapsulation=true (libreswan)
+    and ipsec_forceencaps=true (strongswan) to unconditionally enforce
+    NAT-T UDP encapsulation. Requires OVS support for IPsec custom tunnel
+    options (which will be available in OVS 2.18).
 
 OVN v22.03.0 - 11 Mar 2022
 --------------------------
diff --git a/controller/encaps.c b/controller/encaps.c
index ed01b1368..476da05af 100644
--- a/controller/encaps.c
+++ b/controller/encaps.c
@@ -199,6 +199,21 @@ tunnel_add(struct tunnel_ctx *tc, const struct 
sbrec_sb_global *sbg,
     if (sbg->ipsec) {
         set_local_ip = true;
         smap_add(&options, "remote_name", new_chassis_id);
+
+        /* Force NAT-T traversal via configuration */
+        /* Two ipsec backends are supported: libreswan and strongswan */
+        /* libreswan param: encapsulation; strongswan param: forceencaps */
+        bool encapsulation;
+        bool forceencaps;
+        encapsulation = smap_get_bool(&sbg->options, "ipsec_encapsulation",
+                                      false);
+        forceencaps = smap_get_bool(&sbg->options, "ipsec_forceencaps", false);
+        if (encapsulation) {
+            smap_add(&options, "ipsec_encapsulation", "yes");
+        }
+        if (forceencaps) {
+            smap_add(&options, "ipsec_forceencaps", "yes");
+        }
     }
 
     if (set_local_ip) {
diff --git a/tests/ovn-ipsec.at b/tests/ovn-ipsec.at
index 4c600a9f2..10ef97878 100644
--- a/tests/ovn-ipsec.at
+++ b/tests/ovn-ipsec.at
@@ -44,15 +44,18 @@ ovs-vsctl \
 
 # Enable IPsec
 ovn-nbctl set nb_global . ipsec=true
+ovn-nbctl set nb_global . options:ipsec_encapsulation=true
 
 check ovn-nbctl --wait=hv sync
 
 AT_CHECK([as hv2 ovs-vsctl get Interface ovn-hv1-0 options:remote_ip | tr -d 
'"\n'], [0], [192.168.0.1])
 AT_CHECK([as hv2 ovs-vsctl get Interface ovn-hv1-0 options:local_ip | tr -d 
'"\n'], [0], [192.168.0.2])
 AT_CHECK([as hv2 ovs-vsctl get Interface ovn-hv1-0 options:remote_name | tr -d 
'\n'], [0], [hv1])
+AT_CHECK([as hv2 ovs-vsctl get Interface ovn-hv1-0 options:ipsec_encapsulation 
| tr -d '\n'], [0], [yes])
 AT_CHECK([as hv1 ovs-vsctl get Interface ovn-hv2-0 options:remote_ip | tr -d 
'"\n'], [0], [192.168.0.2])
 AT_CHECK([as hv1 ovs-vsctl get Interface ovn-hv2-0 options:local_ip | tr -d 
'"\n'], [0], [192.168.0.1])
 AT_CHECK([as hv1 ovs-vsctl get Interface ovn-hv2-0 options:remote_name | tr -d 
'\n'], [0], [hv2])
+AT_CHECK([as hv1 ovs-vsctl get Interface ovn-hv2-0 options:ipsec_encapsulation 
| tr -d '\n'], [0], [yes])
 
 AT_CLEANUP
 
-- 
2.35.3

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to