From: Tobias Brunner Date: Tue, 22 Apr 2025 09:19:34 +0000 (+0200) Subject: kernel-netlink: Suppress NAT mapping updates for per-CPU SAs X-Git-Tag: 6.0.2dr1~5^2~2 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=d83fbe82e44e224b744e6b4c752638269e93e89e;p=thirdparty%2Fstrongswan.git kernel-netlink: Suppress NAT mapping updates for per-CPU SAs 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. --- diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c index cf3d2e1ae2..01d8736462 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -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))