Commit 0dde7b54 authored by Ilpo Järvinen's avatar Ilpo Järvinen Committed by David S. Miller

[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: default avatarIlpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a09404a
...@@ -692,6 +692,9 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss ...@@ -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(buff)->end_seq = TCP_SKB_CB(skb)->end_seq;
TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->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. */ /* PSH and FIN should only be set in the second packet. */
flags = TCP_SKB_CB(skb)->flags; flags = TCP_SKB_CB(skb)->flags;
TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH); 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,6 +1726,10 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
/* Update sequence range on original skb. */ /* Update sequence range on original skb. */
TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq; 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. */ /* Merge over control information. */
flags |= TCP_SKB_CB(next_skb)->flags; /* This moves PSH/FIN etc. over */ flags |= TCP_SKB_CB(next_skb)->flags; /* This moves PSH/FIN etc. over */
TCP_SKB_CB(skb)->flags = flags; TCP_SKB_CB(skb)->flags = flags;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment