diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index af9361eba64a6933a88f61520918310b24b9c55a..e80eb1788f80bb4b1e3b65b5d2a19e55b9231380 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2507,6 +2507,7 @@ static void tcp_rtx_queue_purge(struct sock *sk) { struct rb_node *p = rb_first(&sk->tcp_rtx_queue); + tcp_sk(sk)->highest_sack = NULL; while (p) { struct sk_buff *skb = rb_to_skb(p); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 6225c87f0b44240ade7d565105c1c524ae0401d2..dd7b751f83c3b5b7cfdcb6ebfbdbc2783c99c0dd 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3152,6 +3152,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, u32 prior_fack, tp->retransmit_skb_hint = NULL; if (unlikely(skb == tp->lost_skb_hint)) tp->lost_skb_hint = NULL; + tcp_highest_sack_replace(sk, skb, next); tcp_rtx_queue_unlink_and_free(skb, sk); } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 1cc20edf476238c5d7af5cc44611360a98d946ed..cc4ba42052c21b206850594db6751810d8fc72b4 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3165,6 +3165,7 @@ int tcp_send_synack(struct sock *sk) if (!nskb) return -ENOMEM; INIT_LIST_HEAD(&nskb->tcp_tsorted_anchor); + tcp_highest_sack_replace(sk, skb, nskb); tcp_rtx_queue_unlink_and_free(skb, sk); __skb_header_release(nskb); tcp_rbtree_insert(&sk->tcp_rtx_queue, nskb);