From 2b9669d63400ac6038c697960a3df37d680b6648 Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Fri, 10 May 2024 20:24:58 +0800 Subject: tcp: rstreason: fully support in tcp_rcv_synsent_state_process() In this function, only updating the map can finish the job for socket reset reason because the corresponding drop reasons are ready. Signed-off-by: Jason Xing Link: https://lore.kernel.org/r/20240510122502.27850-2-kerneljasonxing@gmail.com Signed-off-by: Jakub Kicinski --- include/net/rstreason.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/net/rstreason.h b/include/net/rstreason.h index df3b6ac0c9b3..f87814a60205 100644 --- a/include/net/rstreason.h +++ b/include/net/rstreason.h @@ -8,6 +8,8 @@ #define DEFINE_RST_REASON(FN, FNe) \ FN(NOT_SPECIFIED) \ FN(NO_SOCKET) \ + FN(TCP_INVALID_ACK_SEQUENCE) \ + FN(TCP_RFC7323_PAWS) \ FN(MPTCP_RST_EUNSPEC) \ FN(MPTCP_RST_EMPTCP) \ FN(MPTCP_RST_ERESOURCE) \ @@ -37,6 +39,17 @@ 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, /* Copy from include/uapi/linux/mptcp.h. * These reset fields will not be changed since they adhere to @@ -113,6 +126,10 @@ 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; default: /* If we don't have our own corresponding reason */ return SK_RST_REASON_NOT_SPECIFIED; -- cgit From 459a2b37a41c8ef83caee4762fc50751470c28e4 Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Fri, 10 May 2024 20:24:59 +0800 Subject: tcp: rstreason: fully support in tcp_ack() Based on the existing skb drop reason, updating the rstreason map can help us finish the rstreason job in this function. Signed-off-by: Jason Xing Link: https://lore.kernel.org/r/20240510122502.27850-3-kerneljasonxing@gmail.com Signed-off-by: Jakub Kicinski --- include/net/rstreason.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/net/rstreason.h b/include/net/rstreason.h index f87814a60205..69404c14f45d 100644 --- a/include/net/rstreason.h +++ b/include/net/rstreason.h @@ -10,6 +10,8 @@ FN(NO_SOCKET) \ FN(TCP_INVALID_ACK_SEQUENCE) \ FN(TCP_RFC7323_PAWS) \ + FN(TCP_TOO_OLD_ACK) \ + FN(TCP_ACK_UNSENT_DATA) \ FN(MPTCP_RST_EUNSPEC) \ FN(MPTCP_RST_EMPTCP) \ FN(MPTCP_RST_ERESOURCE) \ @@ -50,6 +52,13 @@ enum sk_rst_reason { * 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, /* Copy from include/uapi/linux/mptcp.h. * These reset fields will not be changed since they adhere to @@ -130,6 +139,10 @@ sk_rst_convert_drop_reason(enum skb_drop_reason reason) 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; default: /* If we don't have our own corresponding reason */ return SK_RST_REASON_NOT_SPECIFIED; -- cgit From f6d5e2cc291fdf6f804c2754e345b41055d1aac4 Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Fri, 10 May 2024 20:25:00 +0800 Subject: tcp: rstreason: fully support in tcp_rcv_state_process() Like the previous patch does in this series, finish the conversion map is enough to let rstreason mechanism work in this function. Signed-off-by: Jason Xing Link: https://lore.kernel.org/r/20240510122502.27850-4-kerneljasonxing@gmail.com Signed-off-by: Jakub Kicinski --- include/net/rstreason.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/net/rstreason.h b/include/net/rstreason.h index 69404c14f45d..fc1b99702771 100644 --- a/include/net/rstreason.h +++ b/include/net/rstreason.h @@ -12,6 +12,9 @@ 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(MPTCP_RST_EUNSPEC) \ FN(MPTCP_RST_EMPTCP) \ FN(MPTCP_RST_ERESOURCE) \ @@ -59,6 +62,15 @@ enum sk_rst_reason { * 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, /* Copy from include/uapi/linux/mptcp.h. * These reset fields will not be changed since they adhere to @@ -143,6 +155,12 @@ sk_rst_convert_drop_reason(enum skb_drop_reason reason) 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; -- cgit From 22a32557758a7100e46dfa8f383a401125e60b16 Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Fri, 10 May 2024 20:25:01 +0800 Subject: tcp: rstreason: handle timewait cases in the receive path There are two possible cases where TCP layer can send an RST. Since they happen in the same place, I think using one independent reason is enough to identify this special situation. Signed-off-by: Jason Xing Link: https://lore.kernel.org/r/20240510122502.27850-5-kerneljasonxing@gmail.com Signed-off-by: Jakub Kicinski --- include/net/rstreason.h | 5 +++++ net/ipv4/tcp_ipv4.c | 2 +- net/ipv6/tcp_ipv6.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/net/rstreason.h b/include/net/rstreason.h index fc1b99702771..7ae5bb55559b 100644 --- a/include/net/rstreason.h +++ b/include/net/rstreason.h @@ -15,6 +15,7 @@ FN(TCP_FLAGS) \ FN(TCP_OLD_ACK) \ FN(TCP_ABORT_ON_DATA) \ + FN(TCP_TIMEWAIT_SOCKET) \ FN(MPTCP_RST_EUNSPEC) \ FN(MPTCP_RST_EMPTCP) \ FN(MPTCP_RST_ERESOURCE) \ @@ -72,6 +73,10 @@ enum sk_rst_reason { */ 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, + /* Copy from include/uapi/linux/mptcp.h. * These reset fields will not be changed since they adhere to * RFC 8684. So do not touch them. I'm going to list each definition diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 108a438dc247..30ef0c8f5e92 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2427,7 +2427,7 @@ do_time_wait: 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:; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 7f6693e794bd..4c3605485b68 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1999,7 +1999,7 @@ do_time_wait: 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: -- cgit From 11f46ea9814d2f0a3c7a5bc749d7619e47251f75 Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Fri, 10 May 2024 20:25:02 +0800 Subject: tcp: rstreason: fully support in tcp_check_req() We're going to send an RST due to invalid syn packet which is already checked whether 1) it is in sequence, 2) it is a retransmitted skb. As RFC 793 says, if the state of socket is not CLOSED/LISTEN/SYN-SENT, then we should send an RST when receiving bad syn packet: "fourth, check the SYN bit,...If the SYN is in the window it is an error, send a reset" Signed-off-by: Jason Xing Link: https://lore.kernel.org/r/20240510122502.27850-6-kerneljasonxing@gmail.com Signed-off-by: Jakub Kicinski --- include/net/rstreason.h | 8 ++++++++ net/ipv4/tcp_minisocks.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/net/rstreason.h b/include/net/rstreason.h index 7ae5bb55559b..2575c85d7f7a 100644 --- a/include/net/rstreason.h +++ b/include/net/rstreason.h @@ -16,6 +16,7 @@ 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) \ @@ -76,6 +77,13 @@ enum sk_rst_reason { /* 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 diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 7d543569a180..b93619b2384b 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -879,7 +879,7 @@ embryonic_reset: * 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); -- cgit