[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>
This commit is contained in:
parent
1a09404a23
commit
0dde7b5404
1 changed files with 7 additions and 0 deletions
|
@ -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;
|
||||
|
|
Reference in a new issue