diff options
| author | Jakub Kicinski <[email protected]> | 2023-10-26 01:04:31 +0000 |
|---|---|---|
| committer | Jakub Kicinski <[email protected]> | 2023-10-26 01:04:31 +0000 |
| commit | d8c4ef76d7ccd478f8c9a3b7de1ba0b25fdffbee (patch) | |
| tree | 9283e779aab9e7621bb9ae824dcadb28f699096e /net/ipv4/tcp_output.c | |
| parent | Merge branch 'mptcp-features-and-fixes-for-v6-7' (diff) | |
| parent | ipv6: avoid atomic fragment on GSO packets (diff) | |
| download | kernel-d8c4ef76d7ccd478f8c9a3b7de1ba0b25fdffbee.tar.gz kernel-d8c4ef76d7ccd478f8c9a3b7de1ba0b25fdffbee.zip | |
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/[email protected]/
V3: https://lore.kernel.org/netdev/[email protected]/
V2: https://lore.kernel.org/netdev/ZS1%[email protected]/
====================
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Diffstat (limited to 'net/ipv4/tcp_output.c')
| -rw-r--r-- | net/ipv4/tcp_output.c | 20 |
1 files changed, 1 insertions, 19 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 2866ccbccde0..ca4d7594efd4 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); |
