]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
kernel-wfp: Install bypass policies also on FWPM_SUBLAYER_IPSEC_TUNNEL sublayer
authorTobias Brunner <tobias@strongswan.org>
Wed, 1 Mar 2023 16:08:37 +0000 (17:08 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 21 Mar 2023 15:30:09 +0000 (16:30 +0100)
This is apparently necessary to bypass tunnel mode SAs/policies.

References strongswan/strongswan#1552

src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c

index df533810c0d4a1f7a07e29cd2e327bcfdade72b4..a60dbe6637c043b1a6cb3bfc3fb38be03bd376a0 100644 (file)
@@ -2492,7 +2492,8 @@ METHOD(kernel_ipsec_t, flush_policies, status_t,
  * Add a bypass policy for a specific UDP port
  */
 static bool add_bypass(private_kernel_wfp_ipsec_t *this,
-                                          int family, uint16_t port, bool inbound, UINT64 *luid)
+                                          int family, uint16_t port, bool inbound, bool tunnel,
+                                          UINT64 *luid)
 {
        FWPM_FILTER_CONDITION0 *cond, *conds = NULL;
        int count = 0;
@@ -2525,6 +2526,11 @@ static bool add_bypass(private_kernel_wfp_ipsec_t *this,
                        return FALSE;
        }
 
+       if (tunnel)
+       {
+               filter.subLayerKey = FWPM_SUBLAYER_IPSEC_TUNNEL;
+       }
+
        cond = append_condition(&conds, &count);
        cond->fieldKey = FWPM_CONDITION_IP_PROTOCOL;
        cond->matchType = FWP_MATCH_EQUAL;
@@ -2558,8 +2564,8 @@ METHOD(kernel_ipsec_t, bypass_socket, bool,
                SOCKADDR_IN in;
                SOCKADDR_IN6 in6;
        } saddr;
-       int addrlen = sizeof(saddr);
-       UINT64 filter_out, filter_in = 0;
+       int addrlen = sizeof(saddr), i;
+       UINT64 filters[4] = { 0 };
        uint16_t port;
 
        if (getsockname(fd, &saddr.sa, &addrlen) == SOCKET_ERROR)
@@ -2578,19 +2584,26 @@ METHOD(kernel_ipsec_t, bypass_socket, bool,
                        return FALSE;
        }
 
-       if (!add_bypass(this, family, port, TRUE, &filter_in) ||
-               !add_bypass(this, family, port, FALSE, &filter_out))
+       if (!add_bypass(this, family, port, TRUE, FALSE,  &filters[0]) ||
+               !add_bypass(this, family, port, TRUE, TRUE,   &filters[1]) ||
+               !add_bypass(this, family, port, FALSE, FALSE, &filters[2]) ||
+               !add_bypass(this, family, port, FALSE, TRUE,  &filters[3]))
        {
-               if (filter_in)
+               for (i = 0; i < countof(filters); i++)
                {
-                       FwpmFilterDeleteById0(this->handle, filter_in);
+                       if (filters[i])
+                       {
+                               FwpmFilterDeleteById0(this->handle, filters[i]);
+                       }
                }
                return FALSE;
        }
 
        this->mutex->lock(this->mutex);
-       array_insert(this->bypass, ARRAY_TAIL, &filter_in);
-       array_insert(this->bypass, ARRAY_TAIL, &filter_out);
+       for (i = 0; i < countof(filters); i++)
+       {
+               array_insert(this->bypass, ARRAY_TAIL, &filters[i]);
+       }
        this->mutex->unlock(this->mutex);
 
        return TRUE;