]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
kernel-netlink: Suppress NAT mapping updates for per-CPU SAs
authorTobias Brunner <tobias@strongswan.org>
Tue, 22 Apr 2025 09:19:34 +0000 (11:19 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 28 May 2025 14:35:27 +0000 (16:35 +0200)
As we set the remote port to 0, we'd get a mapping change message with
every packet. Setting the threshold avoids all kernel messages after the
first, which we suppress explicitly as well.

src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c

index cf3d2e1ae21b2473b37eae6f77f1a1aef70928c7..01d8736462a43c6f646f25bc22981dd664cfbdaa 100644 (file)
@@ -1161,13 +1161,23 @@ static void process_mapping(private_kernel_netlink_ipsec_t *this,
                dst = xfrm2host(mapping->id.family, &mapping->id.daddr, 0);
                if (dst)
                {
-                       new = xfrm2host(mapping->id.family, &mapping->new_saddr,
-                                                       mapping->new_sport);
-                       if (new)
+                       if (!mapping->old_sport)
                        {
-                               charon->kernel->mapping(charon->kernel, IPPROTO_ESP, spi, dst,
-                                                                               new);
-                               new->destroy(new);
+                               /* ignore mappings for per-CPU SAs with 0 source port */
+                               DBG1(DBG_KNL, "ignore NAT mapping change for per-resource "
+                                        "CHILD_SA %N/0x%08x/%H", protocol_id_names, PROTO_ESP,
+                                        htonl(spi), dst);
+                       }
+                       else
+                       {
+                               new = xfrm2host(mapping->id.family, &mapping->new_saddr,
+                                                               mapping->new_sport);
+                               if (new)
+                               {
+                                       charon->kernel->mapping(charon->kernel, IPPROTO_ESP, spi, dst,
+                                                                                       new);
+                                       new->destroy(new);
+                               }
                        }
                        dst->destroy(dst);
                }
@@ -2053,6 +2063,15 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
                 * No. The reason the kernel ignores NAT-OA is that it recomputes
                 * (or, rather, just ignores) the checksum. If packets pass the IPsec
                 * checks it marks them "checksum ok" so OA isn't needed. */
+
+               /* if the remote port is set to 0 for UDP-encapsulated per-CPU SAs, we
+                * increase the treshold for mapping changes as it gets otherwise
+                * triggered with every packet */
+               if (data->inbound && !id->src->get_port(id->src) &&
+                       !add_uint32(hdr, sizeof(request), XFRMA_MTIMER_THRESH, UINT32_MAX))
+               {
+                       goto failed;
+               }
        }
 
        if (!add_mark(hdr, sizeof(request), id->mark))