[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: a18dfa9925b9ef6107ea3aa5814ca3c704d34a8a
WARNING: Author mismatch between patch and upstream commit: Backport author: Brett A C Sheffieldbacs@librecast.net Commit author: Willem de Bruijnwillemb@google.com
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.12.y | Present (different SHA1: c1502fc84d1c)
Note: The patch differs from the upstream commit: --- 1: a18dfa9925b9e ! 1: 5a27b7b998176 ipv6: save dontfrag in cork @@ ## Metadata ## -Author: Willem de Bruijn willemb@google.com +Author: Brett A C Sheffield (Librecast) bacs@librecast.net
## Commit message ## - ipv6: save dontfrag in cork + Revert "ipv6: save dontfrag in cork"
- When spanning datagram construction over multiple send calls using - MSG_MORE, per datagram settings are configured on the first send. + This reverts commit 8ebf2709fe4dcd0a1b7b95bf61e529ddcd3cdf51 which is + commit a18dfa9925b9ef6107ea3aa5814ca3c704d34a8a upstream.
- That is when ip(6)_setup_cork stores these settings for subsequent use - in __ip(6)_append_data and others. + A regression was introduced when backporting this to the stable kernels + without applying previous commits in this series.
- The only flag that escaped this was dontfrag. As a result, a datagram - could be constructed with df=0 on the first sendmsg, but df=1 on a - next. Which is what cmsg_ip.sh does in an upcoming MSG_MORE test in - the "diff" scenario. + When sending IPv6 UDP packets larger than MTU, EMSGSIZE was returned + instead of fragmenting the packets as expected.
- Changing datagram conditions in the middle of constructing an skb - makes this already complex code path even more convoluted. It is here - unintentional. Bring this flag in line with expected sockopt/cmsg - behavior. + As there is no compelling reason for this commit to be present in the + stable kernels it should be reverted.
- And stop passing ipc6 to __ip6_append_data, to avoid such issues - in the future. This is already the case for __ip_append_data. - - inet6_cork had a 6 byte hole, so the 1B flag has no impact. - - Signed-off-by: Willem de Bruijn willemb@google.com - Reviewed-by: Eric Dumazet edumazet@google.com - Link: https://patch.msgid.link/20250307033620.411611-3-willemdebruijn.kernel@gmail... - Signed-off-by: Jakub Kicinski kuba@kernel.org + Signed-off-by: Brett A C Sheffield bacs@librecast.net
## include/linux/ipv6.h ## @@ include/linux/ipv6.h: struct inet6_cork { struct ipv6_txoptions *opt; u8 hop_limit; u8 tclass; -+ u8 dontfrag:1; +- u8 dontfrag:1; };
/* struct ipv6_pinfo - ipv6 private area */ @@ net/ipv6/ip6_output.c: static int ip6_setup_cork(struct sock *sk, struct inet_co } v6_cork->hop_limit = ipc6->hlimit; v6_cork->tclass = ipc6->tclass; -+ v6_cork->dontfrag = ipc6->dontfrag; +- v6_cork->dontfrag = ipc6->dontfrag; if (rt->dst.flags & DST_XFRM_TUNNEL) - mtu = READ_ONCE(np->pmtudisc) >= IPV6_PMTUDISC_PROBE ? + mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst); @@ net/ipv6/ip6_output.c: static int __ip6_append_data(struct sock *sk, 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, struct ipcm6_cookie *ipc6) -+ unsigned int flags) +- unsigned int flags) ++ unsigned int flags, struct ipcm6_cookie *ipc6) { struct sk_buff *skb, *skb_prev = NULL; struct inet_cork *cork = &cork_full->base; @@ net/ipv6/ip6_output.c: static int __ip6_append_data(struct sock *sk, if (headersize + transhdrlen > mtu) goto emsgsize;
-- if (cork->length + length > mtu - headersize && ipc6->dontfrag && -+ if (cork->length + length > mtu - headersize && v6_cork->dontfrag && +- 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)) { @@ net/ipv6/ip6_output.c: 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, ipc6); -+ from, length, transhdrlen, flags); +- from, length, transhdrlen, flags); ++ from, length, transhdrlen, flags, ipc6); } EXPORT_SYMBOL_GPL(ip6_append_data);
@@ net/ipv6/ip6_output.c: struct sk_buff *ip6_make_skb(struct sock *sk, err = __ip6_append_data(sk, &queue, cork, &v6_cork, ¤t->task_frag, getfrag, from, length + exthdrlen, transhdrlen + exthdrlen, -- flags, ipc6); -+ flags); +- flags); ++ flags, ipc6); if (err) { __ip6_flush_pending_frames(sk, &queue, cork, &v6_cork); return ERR_PTR(err); ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-6.6.y | Success | Success |