|
@@ -1002,7 +1002,8 @@ static void tcp_skb_mark_lost(struct tcp_sock *tp, struct sk_buff *skb)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb)
|
|
|
+static void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp,
|
|
|
+ struct sk_buff *skb)
|
|
|
{
|
|
|
tcp_verify_retransmit_hint(tp, skb);
|
|
|
|
|
@@ -2559,6 +2560,56 @@ static void tcp_mtup_probe_success(struct sock *sk, struct sk_buff *skb)
|
|
|
tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
|
|
|
}
|
|
|
|
|
|
+/* Do a simple retransmit without using the backoff mechanisms in
|
|
|
+ * tcp_timer. This is used for path mtu discovery.
|
|
|
+ * The socket is already locked here.
|
|
|
+ */
|
|
|
+void tcp_simple_retransmit(struct sock *sk)
|
|
|
+{
|
|
|
+ const struct inet_connection_sock *icsk = inet_csk(sk);
|
|
|
+ struct tcp_sock *tp = tcp_sk(sk);
|
|
|
+ struct sk_buff *skb;
|
|
|
+ unsigned int mss = tcp_current_mss(sk, 0);
|
|
|
+ u32 prior_lost = tp->lost_out;
|
|
|
+
|
|
|
+ tcp_for_write_queue(skb, sk) {
|
|
|
+ if (skb == tcp_send_head(sk))
|
|
|
+ break;
|
|
|
+ if (skb->len > mss &&
|
|
|
+ !(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) {
|
|
|
+ if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) {
|
|
|
+ TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
|
|
|
+ tp->retrans_out -= tcp_skb_pcount(skb);
|
|
|
+ }
|
|
|
+ tcp_skb_mark_lost_uncond_verify(tp, skb);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ tcp_clear_retrans_hints_partial(tp);
|
|
|
+
|
|
|
+ if (prior_lost == tp->lost_out)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (tcp_is_reno(tp))
|
|
|
+ tcp_limit_reno_sacked(tp);
|
|
|
+
|
|
|
+ tcp_verify_left_out(tp);
|
|
|
+
|
|
|
+ /* Don't muck with the congestion window here.
|
|
|
+ * Reason is that we do not increase amount of _data_
|
|
|
+ * in network, but units changed and effective
|
|
|
+ * cwnd/ssthresh really reduced now.
|
|
|
+ */
|
|
|
+ if (icsk->icsk_ca_state != TCP_CA_Loss) {
|
|
|
+ tp->high_seq = tp->snd_nxt;
|
|
|
+ tp->snd_ssthresh = tcp_current_ssthresh(sk);
|
|
|
+ tp->prior_ssthresh = 0;
|
|
|
+ tp->undo_marker = 0;
|
|
|
+ tcp_set_ca_state(sk, TCP_CA_Loss);
|
|
|
+ }
|
|
|
+ tcp_xmit_retransmit_queue(sk);
|
|
|
+}
|
|
|
+
|
|
|
/* Process an event, which can update packets-in-flight not trivially.
|
|
|
* Main goal of this function is to calculate new estimate for left_out,
|
|
|
* taking into account both packets sitting in receiver's buffer and
|