[PATCH AUTOSEL 6.18-5.10] xfrm: allow migration from UDP encapsulated to non-encapsulated ESP

From: Sasha Levin

Date: Mon Aug 31 2026 - 12:15:24 EST


From: Antony Antony <antony.antony@xxxxxxxxxxx>

[ Upstream commit b8addb8884f2dc1b13cf3e4fa0265ecd0bc58b69 ]

The current code prevents migrating an SA from UDP encapsulation to
plain ESP. This is needed when moving from a NATed path to a non-NATed
one, for example when switching from IPv4+NAT to IPv6.

Only copy the existing encapsulation during migration if the encap
attribute is explicitly provided.

Note: PF_KEY's SADB_X_MIGRATE always passes encap=NULL and never
supported encapsulation in migration. PF_KEY is deprecated and was
in feature freeze when UDP encapsulation was added to xfrm.

Tested-by: Yan Yan <evitayan@xxxxxxxxxx>
Reviewed-by: Sabrina Dubroca <sd@xxxxxxxxxxxxxxx>
Signed-off-by: Antony Antony <antony.antony@xxxxxxxxxxx>
Signed-off-by: Steffen Klassert <steffen.klassert@xxxxxxxxxxx>
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---

LLM Generated explanations, may be completely bogus:

The branch check finished. Commit `b8addb8884f2d` is in mainline and
several `-next` trees (via the `ipsec-next-2026-06-12` merge), but not
in `stable/linux-6.18.y` — which matches the earlier analysis.

**Summary:** Backport to 6.18.y is warranted. The buggy encap-
inheritance code is still present, the adapted patch applies cleanly on
top of the already-backported `b64120d`, and this completes the MOBIKE
NAT→non-NAT migration fix that partial stable work started.

**YES**

net/xfrm/xfrm_state.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index b9049c2297bd5..0a629fce0a00f 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2017,14 +2017,8 @@ static struct xfrm_state *xfrm_state_clone_and_setup(struct xfrm_state *orig,
}
x->props.calgo = orig->props.calgo;

- if (encap || orig->encap) {
- if (encap)
- x->encap = kmemdup(encap, sizeof(*x->encap),
- GFP_KERNEL);
- else
- x->encap = kmemdup(orig->encap, sizeof(*x->encap),
- GFP_KERNEL);
-
+ if (encap) {
+ x->encap = kmemdup(encap, sizeof(*x->encap), GFP_KERNEL);
if (!x->encap)
goto error;
x->mapping_maxage = orig->mapping_maxage;
--
2.53.0