Commit a6fb9862 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'tcp-support-rstreasons-in-the-passive-logic'

Jason Xing says:

====================
tcp: support rstreasons in the passive logic

In this series, I split all kinds of reasons into five part which,
I think, can be easily reviewed. I respectively implement corresponding
rstreasons in those functions. After this, we can trace the whole tcp
passive reset with clear reasons.
====================

Link: https://lore.kernel.org/r/20240510122502.27850-1-kerneljasonxing@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 0621be48 11f46ea9
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
@@ -8,6 +8,15 @@
#define DEFINE_RST_REASON(FN, FNe)	\
	FN(NOT_SPECIFIED)		\
	FN(NO_SOCKET)			\
	FN(TCP_INVALID_ACK_SEQUENCE)	\
	FN(TCP_RFC7323_PAWS)		\
	FN(TCP_TOO_OLD_ACK)		\
	FN(TCP_ACK_UNSENT_DATA)		\
	FN(TCP_FLAGS)			\
	FN(TCP_OLD_ACK)			\
	FN(TCP_ABORT_ON_DATA)		\
	FN(TCP_TIMEWAIT_SOCKET)		\
	FN(INVALID_SYN)			\
	FN(MPTCP_RST_EUNSPEC)		\
	FN(MPTCP_RST_EMPTCP)		\
	FN(MPTCP_RST_ERESOURCE)		\
@@ -37,6 +46,44 @@ enum sk_rst_reason {
	SK_RST_REASON_NOT_SPECIFIED,
	/** @SK_RST_REASON_NO_SOCKET: no valid socket that can be used */
	SK_RST_REASON_NO_SOCKET,
	/**
	 * @SK_RST_REASON_TCP_INVALID_ACK_SEQUENCE: Not acceptable ACK SEQ
	 * field because ack sequence is not in the window between snd_una
	 * and snd_nxt
	 */
	SK_RST_REASON_TCP_INVALID_ACK_SEQUENCE,
	/**
	 * @SK_RST_REASON_TCP_RFC7323_PAWS: PAWS check, corresponding to
	 * LINUX_MIB_PAWSESTABREJECTED, LINUX_MIB_PAWSACTIVEREJECTED
	 */
	SK_RST_REASON_TCP_RFC7323_PAWS,
	/** @SK_RST_REASON_TCP_TOO_OLD_ACK: TCP ACK is too old */
	SK_RST_REASON_TCP_TOO_OLD_ACK,
	/**
	 * @SK_RST_REASON_TCP_ACK_UNSENT_DATA: TCP ACK for data we haven't
	 * sent yet
	 */
	SK_RST_REASON_TCP_ACK_UNSENT_DATA,
	/** @SK_RST_REASON_TCP_FLAGS: TCP flags invalid */
	SK_RST_REASON_TCP_FLAGS,
	/** @SK_RST_REASON_TCP_OLD_ACK: TCP ACK is old, but in window */
	SK_RST_REASON_TCP_OLD_ACK,
	/**
	 * @SK_RST_REASON_TCP_ABORT_ON_DATA: abort on data
	 * corresponding to LINUX_MIB_TCPABORTONDATA
	 */
	SK_RST_REASON_TCP_ABORT_ON_DATA,

	/* Here start with the independent reasons */
	/** @SK_RST_REASON_TCP_TIMEWAIT_SOCKET: happen on the timewait socket */
	SK_RST_REASON_TCP_TIMEWAIT_SOCKET,
	/**
	 * @SK_RST_REASON_INVALID_SYN: receive bad syn packet
	 * RFC 793 says if the state is not CLOSED/LISTEN/SYN-SENT then
	 * "fourth, check the SYN bit,...If the SYN is in the window it is
	 * an error, send a reset"
	 */
	SK_RST_REASON_INVALID_SYN,

	/* Copy from include/uapi/linux/mptcp.h.
	 * These reset fields will not be changed since they adhere to
@@ -113,6 +160,20 @@ sk_rst_convert_drop_reason(enum skb_drop_reason reason)
		return SK_RST_REASON_NOT_SPECIFIED;
	case SKB_DROP_REASON_NO_SOCKET:
		return SK_RST_REASON_NO_SOCKET;
	case SKB_DROP_REASON_TCP_INVALID_ACK_SEQUENCE:
		return SK_RST_REASON_TCP_INVALID_ACK_SEQUENCE;
	case SKB_DROP_REASON_TCP_RFC7323_PAWS:
		return SK_RST_REASON_TCP_RFC7323_PAWS;
	case SKB_DROP_REASON_TCP_TOO_OLD_ACK:
		return SK_RST_REASON_TCP_TOO_OLD_ACK;
	case SKB_DROP_REASON_TCP_ACK_UNSENT_DATA:
		return SK_RST_REASON_TCP_ACK_UNSENT_DATA;
	case SKB_DROP_REASON_TCP_FLAGS:
		return SK_RST_REASON_TCP_FLAGS;
	case SKB_DROP_REASON_TCP_OLD_ACK:
		return SK_RST_REASON_TCP_OLD_ACK;
	case SKB_DROP_REASON_TCP_ABORT_ON_DATA:
		return SK_RST_REASON_TCP_ABORT_ON_DATA;
	default:
		/* If we don't have our own corresponding reason */
		return SK_RST_REASON_NOT_SPECIFIED;
+1 −1
Original line number Diff line number Diff line
@@ -2427,7 +2427,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
		tcp_v4_timewait_ack(sk, skb);
		break;
	case TCP_TW_RST:
		tcp_v4_send_reset(sk, skb, sk_rst_convert_drop_reason(drop_reason));
		tcp_v4_send_reset(sk, skb, SK_RST_REASON_TCP_TIMEWAIT_SOCKET);
		inet_twsk_deschedule_put(inet_twsk(sk));
		goto discard_it;
	case TCP_TW_SUCCESS:;
+1 −1
Original line number Diff line number Diff line
@@ -879,7 +879,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
		 * avoid becoming vulnerable to outside attack aiming at
		 * resetting legit local connections.
		 */
		req->rsk_ops->send_reset(sk, skb, SK_RST_REASON_NOT_SPECIFIED);
		req->rsk_ops->send_reset(sk, skb, SK_RST_REASON_INVALID_SYN);
	} else if (fastopen) { /* received a valid RST pkt */
		reqsk_fastopen_remove(sk, req, true);
		tcp_reset(sk, skb);
+1 −1
Original line number Diff line number Diff line
@@ -1999,7 +1999,7 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
		tcp_v6_timewait_ack(sk, skb);
		break;
	case TCP_TW_RST:
		tcp_v6_send_reset(sk, skb, sk_rst_convert_drop_reason(drop_reason));
		tcp_v6_send_reset(sk, skb, SK_RST_REASON_TCP_TIMEWAIT_SOCKET);
		inet_twsk_deschedule_put(inet_twsk(sk));
		goto discard_it;
	case TCP_TW_SUCCESS: