summaryrefslogtreecommitdiff
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2023-10-25 18:04:31 -0700
committerJakub Kicinski <kuba@kernel.org>2023-10-25 18:04:31 -0700
commitd8c4ef76d7ccd478f8c9a3b7de1ba0b25fdffbee (patch)
tree9283e779aab9e7621bb9ae824dcadb28f699096e /net/ipv4/tcp_output.c
parent8846f9a04b10b7f61214425409838d764df7080d (diff)
parent03d6c848bfb406e9ef6d9846d759e97beaeea113 (diff)
Merge branch 'ipv6-avoid-atomic-fragment-on-gso-output'
Yan Zhai says: ==================== ipv6: avoid atomic fragment on GSO output When the ipv6 stack output a GSO packet, if its gso_size is larger than dst MTU, then all segments would be fragmented. However, it is possible for a GSO packet to have a trailing segment with smaller actual size than both gso_size as well as the MTU, which leads to an "atomic fragment". Atomic fragments are considered harmful in RFC-8021. An Existing report from APNIC also shows that atomic fragments are more likely to be dropped even it is equivalent to a no-op [1]. The series contains following changes: * drop feature RTAX_FEATURE_ALLFRAG, which has been broken. This helps simplifying other changes in this set. * refactor __ip6_finish_output code to separate GSO and non-GSO packet processing, mirroring IPv4 side logic. * avoid generating atomic fragment on GSO packets. Link: https://www.potaroo.net/presentations/2022-03-01-ipv6-frag.pdf [1] V4: https://lore.kernel.org/netdev/cover.1698114636.git.yan@cloudflare.com/ V3: https://lore.kernel.org/netdev/cover.1697779681.git.yan@cloudflare.com/ V2: https://lore.kernel.org/netdev/ZS1%2Fqtr0dZJ35VII@debian.debian/ ==================== Link: https://lore.kernel.org/r/cover.1698156966.git.yan@cloudflare.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c20
1 files changed, 1 insertions, 19 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 2866ccbccde07..ca4d7594efd48 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1698,14 +1698,6 @@ static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)
*/
mss_now = pmtu - icsk->icsk_af_ops->net_header_len - sizeof(struct tcphdr);
- /* IPv6 adds a frag_hdr in case RTAX_FEATURE_ALLFRAG is set */
- if (icsk->icsk_af_ops->net_frag_header_len) {
- const struct dst_entry *dst = __sk_dst_get(sk);
-
- if (dst && dst_allfrag(dst))
- mss_now -= icsk->icsk_af_ops->net_frag_header_len;
- }
-
/* Clamp it (mss_clamp does not include tcp options) */
if (mss_now > tp->rx_opt.mss_clamp)
mss_now = tp->rx_opt.mss_clamp;
@@ -1733,21 +1725,11 @@ int tcp_mss_to_mtu(struct sock *sk, int mss)
{
const struct tcp_sock *tp = tcp_sk(sk);
const struct inet_connection_sock *icsk = inet_csk(sk);
- int mtu;
- mtu = mss +
+ return mss +
tp->tcp_header_len +
icsk->icsk_ext_hdr_len +
icsk->icsk_af_ops->net_header_len;
-
- /* IPv6 adds a frag_hdr in case RTAX_FEATURE_ALLFRAG is set */
- if (icsk->icsk_af_ops->net_frag_header_len) {
- const struct dst_entry *dst = __sk_dst_get(sk);
-
- if (dst && dst_allfrag(dst))
- mtu += icsk->icsk_af_ops->net_frag_header_len;
- }
- return mtu;
}
EXPORT_SYMBOL(tcp_mss_to_mtu);