linux/net/ipv4
Neal Cardwell 5b35e1e6e9 tcp: fix tcp_trim_head() to adjust segment count with skb MSS
This commit fixes tcp_trim_head() to recalculate the number of
segments in the skb with the skb's existing MSS, so trimming the head
causes the skb segment count to be monotonically non-increasing - it
should stay the same or go down, but not increase.

Previously tcp_trim_head() used the current MSS of the connection. But
if there was a decrease in MSS between original transmission and ACK
(e.g. due to PMTUD), this could cause tcp_trim_head() to
counter-intuitively increase the segment count when trimming bytes off
the head of an skb. This violated assumptions in tcp_tso_acked() that
tcp_trim_head() only decreases the packet count, so that packets_acked
in tcp_tso_acked() could underflow, leading tcp_clean_rtx_queue() to
pass u32 pkts_acked values as large as 0xffffffff to
ca_ops->pkts_acked().

As an aside, if tcp_trim_head() had really wanted the skb to reflect
the current MSS, it should have called tcp_set_skb_tso_segs()
unconditionally, since a decrease in MSS would mean that a
single-packet skb should now be sliced into multiple segments.

Signed-off-by: Neal Cardwell <ncardwell@google.com>
Acked-by: Nandita Dukkipati <nanditad@google.com>
Acked-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-01-30 12:42:58 -05:00
..
netfilter Merge branch 'for-linus' of git://selinuxproject.org/~jmorris/linux-security 2012-01-14 18:36:33 -08:00
af_inet.c per-netns ipv4 sysctl_tcp_mem 2011-12-12 19:04:11 -05:00
ah4.c
arp.c ipv6: Use universal hash for NDISC. 2011-12-28 15:06:58 -05:00
cipso_ipv4.c
datagram.c
devinet.c net: reintroduce missing rcu_assign_pointer() calls 2012-01-12 12:26:56 -08:00
esp4.c
fib_frontend.c
fib_lookup.h
fib_rules.c net: ipv4: export fib_lookup and fib_table_lookup 2011-12-04 22:43:33 +01:00
fib_semantics.c
fib_trie.c net: reintroduce missing rcu_assign_pointer() calls 2012-01-12 12:26:56 -08:00
gre.c
icmp.c
igmp.c net: reintroduce missing rcu_assign_pointer() calls 2012-01-12 12:26:56 -08:00
inet_connection_sock.c tcp: bind() optimize port allocation 2012-01-25 21:50:43 -05:00
inet_diag.c inet_diag: Rename inet_diag_req_compat into inet_diag_req 2012-01-11 12:56:06 -08:00
inet_fragment.c
inet_hashtables.c
inet_lro.c
inet_timewait_sock.c
inetpeer.c inetpeer: initialize ->redirect_genid in inet_getpeer() 2012-01-17 15:52:12 -05:00
ip_forward.c
ip_fragment.c treewide: Fix typos in various parts of the kernel, and fix some comments. 2011-12-02 14:57:31 +01:00
ip_gre.c ipv6: Fix ip_gre lockless xmits. 2012-01-26 16:34:08 -05:00
ip_input.c
ip_options.c
ip_output.c net: Rename dst_get_neighbour{, _raw} to dst_get_neighbour_noref{, _raw}. 2011-12-05 15:20:19 -05:00
ip_sockglue.c net: use IS_ENABLED(CONFIG_IPV6) 2011-12-11 18:25:16 -05:00
ipcomp.c
ipconfig.c net: fix some sparse errors 2012-01-17 10:31:12 -05:00
ipip.c net: reintroduce missing rcu_assign_pointer() calls 2012-01-12 12:26:56 -08:00
ipmr.c net: reintroduce missing rcu_assign_pointer() calls 2012-01-12 12:26:56 -08:00
Kconfig Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-01-09 14:46:52 -08:00
Makefile tcp memory pressure controls 2011-12-12 19:04:10 -05:00
netfilter.c
ping.c net: fix some sparse errors 2012-01-17 10:31:12 -05:00
proc.c tcp: detect loss above high_seq in recovery 2012-01-22 15:08:44 -05:00
protocol.c
raw.c
route.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2011-12-23 17:13:56 -05:00
syncookies.c tcp: Replace constants with #define macros 2011-12-21 01:03:23 -05:00
sysctl_net_ipv4.c net/tcp: Fix tcp memory limits initialization when !CONFIG_SYSCTL 2012-01-30 12:41:06 -05:00
tcp_bic.c tcp: fix undo after RTO for BIC 2012-01-20 14:17:26 -05:00
tcp_cong.c
tcp_cubic.c tcp: fix undo after RTO for CUBIC 2012-01-20 14:17:26 -05:00
tcp_diag.c inet_diag: Rename inet_diag_req into inet_diag_req_v2 2012-01-11 12:56:06 -08:00
tcp_highspeed.c
tcp_htcp.c
tcp_hybla.c
tcp_illinois.c
tcp_input.c tcp: detect loss above high_seq in recovery 2012-01-22 15:08:44 -05:00
tcp_ipv4.c tcp: md5: using remote adress for md5 lookup in rst packet 2012-01-22 15:08:45 -05:00
tcp_lp.c
tcp_memcontrol.c net: decrement memcg jump label when limit, not usage, is changed 2012-01-12 12:27:59 -08:00
tcp_minisocks.c net: use IS_ENABLED(CONFIG_IPV6) 2011-12-11 18:25:16 -05:00
tcp_output.c tcp: fix tcp_trim_head() to adjust segment count with skb MSS 2012-01-30 12:42:58 -05:00
tcp_probe.c
tcp_scalable.c
tcp_timer.c net: fix assignment of 0/1 to bool variables. 2011-12-19 22:27:29 -05:00
tcp_vegas.c
tcp_vegas.h
tcp_veno.c
tcp_westwood.c
tcp_yeah.c
tcp.c net/tcp: Fix tcp memory limits initialization when !CONFIG_SYSCTL 2012-01-30 12:41:06 -05:00
tunnel4.c net: use IS_ENABLED(CONFIG_IPV6) 2011-12-11 18:25:16 -05:00
udp_diag.c net: kill duplicate included header 2012-01-17 10:31:12 -05:00
udp_impl.h
udp.c udp: Export code sk lookup routines 2011-12-09 14:14:08 -05:00
udplite.c
xfrm4_input.c
xfrm4_mode_beet.c
xfrm4_mode_transport.c
xfrm4_mode_tunnel.c
xfrm4_output.c
xfrm4_policy.c
xfrm4_state.c
xfrm4_tunnel.c net: use IS_ENABLED(CONFIG_IPV6) 2011-12-11 18:25:16 -05:00