Commit edefba66 authored by Jason Xing's avatar Jason Xing Committed by David S. Miller
Browse files

tcp: rstreason: introduce SK_RST_REASON_TCP_STATE for active reset



Introducing a new type TCP_STATE to handle some reset conditions
appearing in RFC 793 due to its socket state. Actually, we can look
into RFC 9293 which has no discrepancy about this part.

Signed-off-by: default avatarJason Xing <kernelxing@tencent.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8407994f
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
	FN(TCP_ABORT_ON_CLOSE)		\
	FN(TCP_ABORT_ON_LINGER)		\
	FN(TCP_ABORT_ON_MEMORY)		\
	FN(TCP_STATE)			\
	FN(MPTCP_RST_EUNSPEC)		\
	FN(MPTCP_RST_EMPTCP)		\
	FN(MPTCP_RST_ERESOURCE)		\
@@ -102,6 +103,11 @@ enum sk_rst_reason {
	 * corresponding to LINUX_MIB_TCPABORTONMEMORY
	 */
	SK_RST_REASON_TCP_ABORT_ON_MEMORY,
	/**
	 * @SK_RST_REASON_TCP_STATE: abort on tcp state
	 * Please see RFC 9293 for all possible reset conditions
	 */
	SK_RST_REASON_TCP_STATE,

	/* Copy from include/uapi/linux/mptcp.h.
	 * These reset fields will not be changed since they adhere to
+6 −4
Original line number Diff line number Diff line
@@ -3025,9 +3025,11 @@ int tcp_disconnect(struct sock *sk, int flags)
		inet_csk_listen_stop(sk);
	} else if (unlikely(tp->repair)) {
		WRITE_ONCE(sk->sk_err, ECONNABORTED);
	} else if (tcp_need_reset(old_state) ||
		   (tp->snd_nxt != tp->write_seq &&
		    (1 << old_state) & (TCPF_CLOSING | TCPF_LAST_ACK))) {
	} else if (tcp_need_reset(old_state)) {
		tcp_send_active_reset(sk, gfp_any(), SK_RST_REASON_TCP_STATE);
		WRITE_ONCE(sk->sk_err, ECONNRESET);
	} else if (tp->snd_nxt != tp->write_seq &&
		   (1 << old_state) & (TCPF_CLOSING | TCPF_LAST_ACK)) {
		/* The last check adjusts for discrepancy of Linux wrt. RFC
		 * states
		 */
@@ -4649,7 +4651,7 @@ int tcp_abort(struct sock *sk, int err)
	if (!sock_flag(sk, SOCK_DEAD)) {
		if (tcp_need_reset(sk->sk_state))
			tcp_send_active_reset(sk, GFP_ATOMIC,
					      SK_RST_REASON_NOT_SPECIFIED);
					      SK_RST_REASON_TCP_STATE);
		tcp_done_with_error(sk, err);
	}

+1 −1
Original line number Diff line number Diff line
@@ -779,7 +779,7 @@ static void tcp_keepalive_timer (struct timer_list *t)
				goto out;
			}
		}
		tcp_send_active_reset(sk, GFP_ATOMIC, SK_RST_REASON_NOT_SPECIFIED);
		tcp_send_active_reset(sk, GFP_ATOMIC, SK_RST_REASON_TCP_STATE);
		goto death;
	}