diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 1147d1f57fed5a..b868c5383d9e04 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -429,6 +429,9 @@ struct mptcp_cb { #define OPTION_MPTCP (1 << 5) +/* Max number of fastclose retransmissions */ +#define MPTCP_FASTCLOSE_RETRIES 3 + #ifdef CONFIG_MPTCP /* Used for checking if the mptcp initialization has been successful */ diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index cd6ceb7bca5937..d34a39a941d77a 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -621,8 +621,10 @@ static void tcp_keepalive_timer (unsigned long data) if (!tp->retrans_stamp) tp->retrans_stamp = tcp_time_stamp ? : 1; - if (tcp_write_timeout(sk)) + if (icsk->icsk_retransmits >= MPTCP_FASTCLOSE_RETRIES) { + tcp_write_err(sk); goto out; + } tcp_send_ack(sk); icsk->icsk_retransmits++; diff --git a/net/mptcp/mptcp_output.c b/net/mptcp/mptcp_output.c index b8560e1affd770..3861c4afac012d 100644 --- a/net/mptcp/mptcp_output.c +++ b/net/mptcp/mptcp_output.c @@ -1314,6 +1314,10 @@ void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority) inet_csk_reset_keepalive_timer(sk, inet_csk(sk)->icsk_rto); meta_tp->send_mp_fclose = 1; + inet_csk(sk)->icsk_retransmits = 0; + + /* Prevent exp backoff reverting on ICMP dest unreachable */ + inet_csk(sk)->icsk_backoff = 0; MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_FASTCLOSETX); }