From f62c33bc4a83b16de10a5113afebd625f9e27441 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 21 Jun 2025 19:17:46 +0200 Subject: [PATCH] kernel: Fix IPv6 UDP fragmentation regression Fixes a IPv6 UDP fragmentation regression introduced in v6.6.93. Fixes: https://github.com/openwrt/openwrt/issues/19198 Link: https://github.com/openwrt/openwrt/pull/19199 Signed-off-by: Hauke Mehrtens --- ...50-Revert-ipv6-save-dontfrag-in-cork.patch | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 target/linux/generic/pending-6.6/650-Revert-ipv6-save-dontfrag-in-cork.patch diff --git a/target/linux/generic/pending-6.6/650-Revert-ipv6-save-dontfrag-in-cork.patch b/target/linux/generic/pending-6.6/650-Revert-ipv6-save-dontfrag-in-cork.patch new file mode 100644 index 00000000000..18ef72ef583 --- /dev/null +++ b/target/linux/generic/pending-6.6/650-Revert-ipv6-save-dontfrag-in-cork.patch @@ -0,0 +1,72 @@ +From 988e05f0c036c9c64f211b8b91a4a33c34db216a Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Sat, 21 Jun 2025 19:08:30 +0200 +Subject: [PATCH] Revert "ipv6: save dontfrag in cork" + +This reverts commit 8ebf2709fe4dcd0a1b7b95bf61e529ddcd3cdf51. + +This change breaks IPv6 UDP packet fragmentation. +See discussion: https://lore.kernel.org/stable/aFGl-mb--GOMY8ZQ@karahi.gladserv.com/ + +Signed-off-by: Hauke Mehrtens +--- + include/linux/ipv6.h | 1 - + net/ipv6/ip6_output.c | 9 ++++----- + 2 files changed, 4 insertions(+), 6 deletions(-) + +--- a/include/linux/ipv6.h ++++ b/include/linux/ipv6.h +@@ -199,7 +199,6 @@ struct inet6_cork { + struct ipv6_txoptions *opt; + u8 hop_limit; + u8 tclass; +- u8 dontfrag:1; + }; + + /* struct ipv6_pinfo - ipv6 private area */ +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1452,7 +1452,6 @@ static int ip6_setup_cork(struct sock *s + } + v6_cork->hop_limit = ipc6->hlimit; + v6_cork->tclass = ipc6->tclass; +- v6_cork->dontfrag = ipc6->dontfrag; + if (rt->dst.flags & DST_XFRM_TUNNEL) + mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? + READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst); +@@ -1486,7 +1485,7 @@ static int __ip6_append_data(struct sock + int getfrag(void *from, char *to, int offset, + int len, int odd, struct sk_buff *skb), + void *from, size_t length, int transhdrlen, +- unsigned int flags) ++ unsigned int flags, struct ipcm6_cookie *ipc6) + { + struct sk_buff *skb, *skb_prev = NULL; + struct inet_cork *cork = &cork_full->base; +@@ -1542,7 +1541,7 @@ static int __ip6_append_data(struct sock + if (headersize + transhdrlen > mtu) + goto emsgsize; + +- if (cork->length + length > mtu - headersize && v6_cork->dontfrag && ++ if (cork->length + length > mtu - headersize && ipc6->dontfrag && + (sk->sk_protocol == IPPROTO_UDP || + sk->sk_protocol == IPPROTO_ICMPV6 || + sk->sk_protocol == IPPROTO_RAW)) { +@@ -1914,7 +1913,7 @@ int ip6_append_data(struct sock *sk, + + return __ip6_append_data(sk, &sk->sk_write_queue, &inet->cork, + &np->cork, sk_page_frag(sk), getfrag, +- from, length, transhdrlen, flags); ++ from, length, transhdrlen, flags, ipc6); + } + EXPORT_SYMBOL_GPL(ip6_append_data); + +@@ -2119,7 +2118,7 @@ struct sk_buff *ip6_make_skb(struct sock + err = __ip6_append_data(sk, &queue, cork, &v6_cork, + ¤t->task_frag, getfrag, from, + length + exthdrlen, transhdrlen + exthdrlen, +- flags); ++ flags, ipc6); + if (err) { + __ip6_flush_pending_frames(sk, &queue, cork, &v6_cork); + return ERR_PTR(err); -- 2.47.2