aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2007-09-20 14:28:05 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:52:08 -0400
commit0dde7b5404a3d52dcd9ce66d46197f6c3ca97dda (patch)
treee2f6baf2552d5b844763d09d7430010183be80d6 /net
parent1a09404a2338163f181d170c7abdc2242b6c6f03 (diff)
[TCP]: Maintain highest_sack accurately to the highest skb
In general, it should not be necessary to call tcp_fragment for already SACKed skbs, but it's better to be safe than sorry. And indeed, it can be called from sacktag when a DSACK arrives or some ACK (with SACK) reordering occurs (sacktag could be made to avoid the call in the latter case though I'm not sure if it's worth of the trouble and added complexity to cover such marginal case). The collapse case has return for SACKED_ACKED case earlier, so just WARN_ON if internal inconsistency is detected for some reason. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_output.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index d65d17bb2a09..9df5b2a4da6e 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -692,6 +692,9 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
692 TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq; 692 TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq;
693 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq; 693 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
694 694
695 if (tp->sacked_out && (TCP_SKB_CB(skb)->seq == tp->highest_sack))
696 tp->highest_sack = TCP_SKB_CB(buff)->seq;
697
695 /* PSH and FIN should only be set in the second packet. */ 698 /* PSH and FIN should only be set in the second packet. */
696 flags = TCP_SKB_CB(skb)->flags; 699 flags = TCP_SKB_CB(skb)->flags;
697 TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH); 700 TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);
@@ -1723,6 +1726,10 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
1723 /* Update sequence range on original skb. */ 1726 /* Update sequence range on original skb. */
1724 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq; 1727 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq;
1725 1728
1729 if (WARN_ON(tp->sacked_out &&
1730 (TCP_SKB_CB(next_skb)->seq == tp->highest_sack)))
1731 return;
1732
1726 /* Merge over control information. */ 1733 /* Merge over control information. */
1727 flags |= TCP_SKB_CB(next_skb)->flags; /* This moves PSH/FIN etc. over */ 1734 flags |= TCP_SKB_CB(next_skb)->flags; /* This moves PSH/FIN etc. over */
1728 TCP_SKB_CB(skb)->flags = flags; 1735 TCP_SKB_CB(skb)->flags = flags;