tcp_sacktag_skip() directly return the input skb only if TCP_SKB_CB(skb)->seq>skip_to_seq, this is not right, and the logic should be TCP_SKB_CB(skb)->seq>=skip_to_seq, for example if start_seq is equal to tcp_highest_sack_seq() , the start_seq is equal to seq of skb which is from tcp_highest_sack(). and on the other side ,when tcp_highest_sack_seq() < start_seq in tcp_sacktag_write_queue(), the skb is from tcp_highest_sack() will be ignored in tcp_sacktag_skip(), so clean the logic also. Fixes: 75c119afe14f ("tcp: implement rb-tree based retransmit queue") Signed-off-by: Xin Guo --- net/ipv4/tcp_input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 79e3bfb0108f..bbefb866c649 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1809,7 +1809,7 @@ static struct sk_buff *tcp_sacktag_bsearch(struct sock *sk, u32 seq) static struct sk_buff *tcp_sacktag_skip(struct sk_buff *skb, struct sock *sk, u32 skip_to_seq) { - if (skb && after(TCP_SKB_CB(skb)->seq, skip_to_seq)) + if (skb && !before(TCP_SKB_CB(skb)->seq, skip_to_seq)) return skb; return tcp_sacktag_bsearch(sk, skip_to_seq); @@ -1997,7 +1997,7 @@ tcp_sacktag_write_queue(struct sock *sk, const struct sk_buff *ack_skb, continue; } - if (!before(start_seq, tcp_highest_sack_seq(tp))) { + if (tcp_highest_sack_seq(tp) == start_seq) { skb = tcp_highest_sack(sk); if (!skb) break; -- 2.43.0