]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/tcp_output.c
[TCP]: Maintain highest_sack accurately to the highest skb
[linux-2.6-omap-h63xx.git] / net / ipv4 / tcp_output.c
index d65d17bb2a099cd1b8a4ca61df37689d260d9b90..9df5b2a4da6e37d9bcd53d6fd490e26eee601975 100644 (file)
@@ -692,6 +692,9 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
        TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq;
        TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
 
+       if (tp->sacked_out && (TCP_SKB_CB(skb)->seq == tp->highest_sack))
+               tp->highest_sack = TCP_SKB_CB(buff)->seq;
+
        /* PSH and FIN should only be set in the second packet. */
        flags = TCP_SKB_CB(skb)->flags;
        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
                /* Update sequence range on original skb. */
                TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq;
 
+               if (WARN_ON(tp->sacked_out &&
+                   (TCP_SKB_CB(next_skb)->seq == tp->highest_sack)))
+                       return;
+
                /* Merge over control information. */
                flags |= TCP_SKB_CB(next_skb)->flags; /* This moves PSH/FIN etc. over */
                TCP_SKB_CB(skb)->flags = flags;