All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive
@ 2022-02-18  8:31 menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 1/9] net: tcp: introduce tcp_drop_reason() menglong8.dong
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: menglong8.dong @ 2022-02-18  8:31 UTC (permalink / raw)
  To: dsahern, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

From: Menglong Dong <imagedong@tencent.com>

In the commit c504e5c2f964 ("net: skb: introduce kfree_skb_reason()"),
we added the support of reporting the reasons of skb drops to kfree_skb
tracepoint. And in this series patches, reasons for skb drops are added
to TCP layer (both TCPv4 and TCPv6 are considered).
Following functions are processed:

tcp_v4_rcv()
tcp_v6_rcv()
tcp_v4_inbound_md5_hash()
tcp_v6_inbound_md5_hash()
tcp_add_backlog()
tcp_v4_do_rcv()
tcp_v6_do_rcv()
tcp_rcv_established()
tcp_data_queue()
tcp_data_queue_ofo()

The functions we handled are mostly for packet ingress, as skb drops
hardly happens in the egress path of TCP layer. However, it's a little
complex for TCP state processing, as I find that it's hard to report skb
drop reasons to where it is freed. For example, when skb is dropped in
tcp_rcv_state_process(), the reason can be caused by the call of
tcp_v4_conn_request(), and it's hard to return a drop reason from
tcp_v4_conn_request(). So such cases are skipped  for this moment.

Following new drop reasons are introduced (what they mean can be see
in the document for them):

/* SKB_DROP_REASON_TCP_MD5* corresponding to LINUX_MIB_TCPMD5* */
SKB_DROP_REASON_TCP_MD5NOTFOUND
SKB_DROP_REASON_TCP_MD5UNEXPECTED
SKB_DROP_REASON_TCP_MD5FAILURE
SKB_DROP_REASON_SOCKET_BACKLOG
SKB_DROP_REASON_TCP_FLAGS
SKB_DROP_REASON_TCP_ZEROWINDOW
SKB_DROP_REASON_TCP_OLD_DATA
SKB_DROP_REASON_TCP_OVERWINDOW
/* corresponding to LINUX_MIB_TCPOFOMERGE */
SKB_DROP_REASON_TCP_OFOMERGE

Here is a example to get TCP packet drop reasons from ftrace:

$ echo 1 > /sys/kernel/debug/tracing/events/skb/kfree_skb/enable
$ cat /sys/kernel/debug/tracing/trace
$ <idle>-0       [036] ..s1.   647.428165: kfree_skb: skbaddr=000000004d037db6 protocol=2048 location=0000000074cd1243 reason: NO_SOCKET
$ <idle>-0       [020] ..s2.   639.676674: kfree_skb: skbaddr=00000000bcbfa42d protocol=2048 location=00000000bfe89d35 reason: PROTO_MEM

From the reason 'PROTO_MEM' we can know that the skb is dropped because
the memory configured in net.ipv4.tcp_mem is up to the limition.

Changes since v1:
- enrich the document for this series patches in the cover letter,
  as Eric suggested
- fix compile warning report by Jakub in the 6th patch
- let NO_SOCKET trump the XFRM failure in the 2th and 3th patches

Menglong Dong (9):
  net: tcp: introduce tcp_drop_reason()
  net: tcp: add skb drop reasons to tcp_v4_rcv()
  net: tcp: use kfree_skb_reason() for tcp_v6_rcv()
  net: tcp: add skb drop reasons to tcp_v{4,6}_inbound_md5_hash()
  net: tcp: add skb drop reasons to tcp_add_backlog()
  net: tcp: use kfree_skb_reason() for tcp_v{4,6}_do_rcv()
  net: tcp: use tcp_drop_reason() for tcp_rcv_established()
  net: tcp: use tcp_drop_reason() for tcp_data_queue()
  net: tcp: use tcp_drop_reason() for tcp_data_queue_ofo()

 include/linux/skbuff.h     | 34 ++++++++++++++++++++++++++++++
 include/net/tcp.h          |  3 ++-
 include/trace/events/skb.h | 10 +++++++++
 net/ipv4/tcp_input.c       | 42 +++++++++++++++++++++++++++++---------
 net/ipv4/tcp_ipv4.c        | 32 +++++++++++++++++++++--------
 net/ipv6/tcp_ipv6.c        | 39 +++++++++++++++++++++++++++--------
 6 files changed, 132 insertions(+), 28 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 1/9] net: tcp: introduce tcp_drop_reason()
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
@ 2022-02-18  8:31 ` menglong8.dong
  2022-02-19  4:40   ` Jakub Kicinski
  2022-02-18  8:31 ` [PATCH net-next v2 2/9] net: tcp: add skb drop reasons to tcp_v4_rcv() menglong8.dong
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 13+ messages in thread
From: menglong8.dong @ 2022-02-18  8:31 UTC (permalink / raw)
  To: dsahern, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

From: Menglong Dong <imagedong@tencent.com>

For TCP protocol, tcp_drop() is used to free the skb when it needs
to be dropped. To make use of kfree_skb_reason() and pass the drop
reason to it, introduce the function tcp_drop_reason(). Meanwhile,
make tcp_drop() an inline call to tcp_drop_reason().

Signed-off-by: Menglong Dong <imagedong@tencent.com>
---
 net/ipv4/tcp_input.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index af94a6d22a9d..0a2740add404 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4684,10 +4684,16 @@ static bool tcp_ooo_try_coalesce(struct sock *sk,
 	return res;
 }
 
-static void tcp_drop(struct sock *sk, struct sk_buff *skb)
+static void tcp_drop_reason(struct sock *sk, struct sk_buff *skb,
+			    enum skb_drop_reason reason)
 {
 	sk_drops_add(sk, skb);
-	__kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
+}
+
+static inline void tcp_drop(struct sock *sk, struct sk_buff *skb)
+{
+	tcp_drop_reason(sk, skb, SKB_DROP_REASON_NOT_SPECIFIED);
 }
 
 /* This one checks to see if we can put data from the
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 2/9] net: tcp: add skb drop reasons to tcp_v4_rcv()
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 1/9] net: tcp: introduce tcp_drop_reason() menglong8.dong
@ 2022-02-18  8:31 ` menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 3/9] net: tcp: use kfree_skb_reason() for tcp_v6_rcv() menglong8.dong
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-02-18  8:31 UTC (permalink / raw)
  To: dsahern, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

From: Menglong Dong <imagedong@tencent.com>

Use kfree_skb_reason() for some path in tcp_v4_rcv() that missed before,
including:

SKB_DROP_REASON_SOCKET_FILTER
SKB_DROP_REASON_XFRM_POLICY

Signed-off-by: Menglong Dong <imagedong@tencent.com>
---
v2:
- let NO_SOCKET trump the XFRM failure
---
 net/ipv4/tcp_ipv4.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 6873f46fc8ba..a3beab01e9a7 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2057,6 +2057,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
 			iph = ip_hdr(skb);
 			tcp_v4_fill_cb(skb, iph, th);
 			nsk = tcp_check_req(sk, skb, req, false, &req_stolen);
+		} else {
+			drop_reason = SKB_DROP_REASON_SOCKET_FILTER;
 		}
 		if (!nsk) {
 			reqsk_put(req);
@@ -2092,8 +2094,10 @@ int tcp_v4_rcv(struct sk_buff *skb)
 		}
 	}
 
-	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
+	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
+		drop_reason = SKB_DROP_REASON_XFRM_POLICY;
 		goto discard_and_relse;
+	}
 
 	if (tcp_v4_inbound_md5_hash(sk, skb, dif, sdif))
 		goto discard_and_relse;
@@ -2166,6 +2170,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
 
 do_time_wait:
 	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+		drop_reason = SKB_DROP_REASON_XFRM_POLICY;
 		inet_twsk_put(inet_twsk(sk));
 		goto discard_it;
 	}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 3/9] net: tcp: use kfree_skb_reason() for tcp_v6_rcv()
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 1/9] net: tcp: introduce tcp_drop_reason() menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 2/9] net: tcp: add skb drop reasons to tcp_v4_rcv() menglong8.dong
@ 2022-02-18  8:31 ` menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 4/9] net: tcp: add skb drop reasons to tcp_v{4,6}_inbound_md5_hash() menglong8.dong
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-02-18  8:31 UTC (permalink / raw)
  To: dsahern, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

From: Menglong Dong <imagedong@tencent.com>

Replace kfree_skb() used in tcp_v6_rcv() with kfree_skb_reason().

Signed-off-by: Menglong Dong <imagedong@tencent.com>
---
v2:
- let NO_SOCKET trump the XFRM failure
---
 net/ipv6/tcp_ipv6.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 0c648bf07f39..0aa17073df1a 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1627,6 +1627,7 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr,
 
 INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 {
+	enum skb_drop_reason drop_reason;
 	int sdif = inet6_sdif(skb);
 	int dif = inet6_iif(skb);
 	const struct tcphdr *th;
@@ -1636,6 +1637,7 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 	int ret;
 	struct net *net = dev_net(skb->dev);
 
+	drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
 	if (skb->pkt_type != PACKET_HOST)
 		goto discard_it;
 
@@ -1649,8 +1651,10 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 
 	th = (const struct tcphdr *)skb->data;
 
-	if (unlikely(th->doff < sizeof(struct tcphdr)/4))
+	if (unlikely(th->doff < sizeof(struct tcphdr) / 4)) {
+		drop_reason = SKB_DROP_REASON_PKT_TOO_SMALL;
 		goto bad_packet;
+	}
 	if (!pskb_may_pull(skb, th->doff*4))
 		goto discard_it;
 
@@ -1706,6 +1710,8 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 			hdr = ipv6_hdr(skb);
 			tcp_v6_fill_cb(skb, hdr, th);
 			nsk = tcp_check_req(sk, skb, req, false, &req_stolen);
+		} else {
+			drop_reason = SKB_DROP_REASON_SOCKET_FILTER;
 		}
 		if (!nsk) {
 			reqsk_put(req);
@@ -1741,14 +1747,18 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 		}
 	}
 
-	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
+	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) {
+		drop_reason = SKB_DROP_REASON_XFRM_POLICY;
 		goto discard_and_relse;
+	}
 
 	if (tcp_v6_inbound_md5_hash(sk, skb, dif, sdif))
 		goto discard_and_relse;
 
-	if (tcp_filter(sk, skb))
+	if (tcp_filter(sk, skb)) {
+		drop_reason = SKB_DROP_REASON_SOCKET_FILTER;
 		goto discard_and_relse;
+	}
 	th = (const struct tcphdr *)skb->data;
 	hdr = ipv6_hdr(skb);
 	tcp_v6_fill_cb(skb, hdr, th);
@@ -1779,6 +1789,7 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 	return ret ? -1 : 0;
 
 no_tcp_socket:
+	drop_reason = SKB_DROP_REASON_NO_SOCKET;
 	if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
 		goto discard_it;
 
@@ -1786,6 +1797,7 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 
 	if (tcp_checksum_complete(skb)) {
 csum_error:
+		drop_reason = SKB_DROP_REASON_TCP_CSUM;
 		trace_tcp_bad_csum(skb);
 		__TCP_INC_STATS(net, TCP_MIB_CSUMERRORS);
 bad_packet:
@@ -1795,7 +1807,7 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 	}
 
 discard_it:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, drop_reason);
 	return 0;
 
 discard_and_relse:
@@ -1806,6 +1818,7 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 
 do_time_wait:
 	if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+		drop_reason = SKB_DROP_REASON_XFRM_POLICY;
 		inet_twsk_put(inet_twsk(sk));
 		goto discard_it;
 	}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 4/9] net: tcp: add skb drop reasons to tcp_v{4,6}_inbound_md5_hash()
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
                   ` (2 preceding siblings ...)
  2022-02-18  8:31 ` [PATCH net-next v2 3/9] net: tcp: use kfree_skb_reason() for tcp_v6_rcv() menglong8.dong
@ 2022-02-18  8:31 ` menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 5/9] net: tcp: add skb drop reasons to tcp_add_backlog() menglong8.dong
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-02-18  8:31 UTC (permalink / raw)
  To: dsahern, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

From: Menglong Dong <imagedong@tencent.com>

Pass the address of drop reason to tcp_v4_inbound_md5_hash() and
tcp_v6_inbound_md5_hash() to store the reasons for skb drops when this
function fails. Therefore, the drop reason can be passed to
kfree_skb_reason() when the skb needs to be freed.

Following drop reasons are added:

SKB_DROP_REASON_TCP_MD5NOTFOUND
SKB_DROP_REASON_TCP_MD5UNEXPECTED
SKB_DROP_REASON_TCP_MD5FAILURE

SKB_DROP_REASON_TCP_MD5* above correspond to LINUX_MIB_TCPMD5*

Signed-off-by: Menglong Dong <imagedong@tencent.com>
---
 include/linux/skbuff.h     | 12 ++++++++++++
 include/trace/events/skb.h |  4 ++++
 net/ipv4/tcp_ipv4.c        | 13 +++++++++----
 net/ipv6/tcp_ipv6.c        | 11 ++++++++---
 4 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index a5adbf6b51e8..46678eb587ff 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -346,6 +346,18 @@ enum skb_drop_reason {
 					 * udp packet drop out of
 					 * udp_memory_allocated.
 					 */
+	SKB_DROP_REASON_TCP_MD5NOTFOUND,	/* no MD5 hash and one
+						 * expected, corresponding
+						 * to LINUX_MIB_TCPMD5NOTFOUND
+						 */
+	SKB_DROP_REASON_TCP_MD5UNEXPECTED,	/* MD5 hash and we're not
+						 * expecting one, corresponding
+						 * to LINUX_MIB_TCPMD5UNEXPECTED
+						 */
+	SKB_DROP_REASON_TCP_MD5FAILURE,	/* MD5 hash and its wrong,
+					 * corresponding to
+					 * LINUX_MIB_TCPMD5FAILURE
+					 */
 	SKB_DROP_REASON_MAX,
 };
 
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index cfcfd26399f7..46c06b0be850 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -27,6 +27,10 @@
 	EM(SKB_DROP_REASON_IP_NOPROTO, IP_NOPROTO)		\
 	EM(SKB_DROP_REASON_SOCKET_RCVBUFF, SOCKET_RCVBUFF)	\
 	EM(SKB_DROP_REASON_PROTO_MEM, PROTO_MEM)		\
+	EM(SKB_DROP_REASON_TCP_MD5NOTFOUND, TCP_MD5NOTFOUND)	\
+	EM(SKB_DROP_REASON_TCP_MD5UNEXPECTED,			\
+	   TCP_MD5UNEXPECTED)					\
+	EM(SKB_DROP_REASON_TCP_MD5FAILURE, TCP_MD5FAILURE)	\
 	EMe(SKB_DROP_REASON_MAX, MAX)
 
 #undef EM
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index a3beab01e9a7..d3c417119057 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1412,7 +1412,8 @@ EXPORT_SYMBOL(tcp_v4_md5_hash_skb);
 /* Called with rcu_read_lock() */
 static bool tcp_v4_inbound_md5_hash(const struct sock *sk,
 				    const struct sk_buff *skb,
-				    int dif, int sdif)
+				    int dif, int sdif,
+				    enum skb_drop_reason *reason)
 {
 #ifdef CONFIG_TCP_MD5SIG
 	/*
@@ -1445,11 +1446,13 @@ static bool tcp_v4_inbound_md5_hash(const struct sock *sk,
 		return false;
 
 	if (hash_expected && !hash_location) {
+		*reason = SKB_DROP_REASON_TCP_MD5NOTFOUND;
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND);
 		return true;
 	}
 
 	if (!hash_expected && hash_location) {
+		*reason = SKB_DROP_REASON_TCP_MD5UNEXPECTED;
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED);
 		return true;
 	}
@@ -1462,6 +1465,7 @@ static bool tcp_v4_inbound_md5_hash(const struct sock *sk,
 				      NULL, skb);
 
 	if (genhash || memcmp(hash_location, newhash, 16) != 0) {
+		*reason = SKB_DROP_REASON_TCP_MD5FAILURE;
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5FAILURE);
 		net_info_ratelimited("MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s L3 index %d\n",
 				     &iph->saddr, ntohs(th->source),
@@ -1971,13 +1975,13 @@ static void tcp_v4_fill_cb(struct sk_buff *skb, const struct iphdr *iph,
 int tcp_v4_rcv(struct sk_buff *skb)
 {
 	struct net *net = dev_net(skb->dev);
+	enum skb_drop_reason drop_reason;
 	int sdif = inet_sdif(skb);
 	int dif = inet_iif(skb);
 	const struct iphdr *iph;
 	const struct tcphdr *th;
 	bool refcounted;
 	struct sock *sk;
-	int drop_reason;
 	int ret;
 
 	drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
@@ -2025,7 +2029,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
 		struct sock *nsk;
 
 		sk = req->rsk_listener;
-		if (unlikely(tcp_v4_inbound_md5_hash(sk, skb, dif, sdif))) {
+		if (unlikely(tcp_v4_inbound_md5_hash(sk, skb, dif, sdif,
+						     &drop_reason))) {
 			sk_drops_add(sk, skb);
 			reqsk_put(req);
 			goto discard_it;
@@ -2099,7 +2104,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
 		goto discard_and_relse;
 	}
 
-	if (tcp_v4_inbound_md5_hash(sk, skb, dif, sdif))
+	if (tcp_v4_inbound_md5_hash(sk, skb, dif, sdif, &drop_reason))
 		goto discard_and_relse;
 
 	nf_reset_ct(skb);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 0aa17073df1a..1262b790b146 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -775,7 +775,8 @@ static int tcp_v6_md5_hash_skb(char *md5_hash,
 
 static bool tcp_v6_inbound_md5_hash(const struct sock *sk,
 				    const struct sk_buff *skb,
-				    int dif, int sdif)
+				    int dif, int sdif,
+				    enum skb_drop_reason *reason)
 {
 #ifdef CONFIG_TCP_MD5SIG
 	const __u8 *hash_location = NULL;
@@ -798,11 +799,13 @@ static bool tcp_v6_inbound_md5_hash(const struct sock *sk,
 		return false;
 
 	if (hash_expected && !hash_location) {
+		*reason = SKB_DROP_REASON_TCP_MD5NOTFOUND;
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND);
 		return true;
 	}
 
 	if (!hash_expected && hash_location) {
+		*reason = SKB_DROP_REASON_TCP_MD5UNEXPECTED;
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED);
 		return true;
 	}
@@ -813,6 +816,7 @@ static bool tcp_v6_inbound_md5_hash(const struct sock *sk,
 				      NULL, skb);
 
 	if (genhash || memcmp(hash_location, newhash, 16) != 0) {
+		*reason = SKB_DROP_REASON_TCP_MD5FAILURE;
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5FAILURE);
 		net_info_ratelimited("MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u L3 index %d\n",
 				     genhash ? "failed" : "mismatch",
@@ -1681,7 +1685,8 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 		struct sock *nsk;
 
 		sk = req->rsk_listener;
-		if (tcp_v6_inbound_md5_hash(sk, skb, dif, sdif)) {
+		if (tcp_v6_inbound_md5_hash(sk, skb, dif, sdif,
+					    &drop_reason)) {
 			sk_drops_add(sk, skb);
 			reqsk_put(req);
 			goto discard_it;
@@ -1752,7 +1757,7 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 		goto discard_and_relse;
 	}
 
-	if (tcp_v6_inbound_md5_hash(sk, skb, dif, sdif))
+	if (tcp_v6_inbound_md5_hash(sk, skb, dif, sdif, &drop_reason))
 		goto discard_and_relse;
 
 	if (tcp_filter(sk, skb)) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 5/9] net: tcp: add skb drop reasons to tcp_add_backlog()
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
                   ` (3 preceding siblings ...)
  2022-02-18  8:31 ` [PATCH net-next v2 4/9] net: tcp: add skb drop reasons to tcp_v{4,6}_inbound_md5_hash() menglong8.dong
@ 2022-02-18  8:31 ` menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 6/9] net: tcp: use kfree_skb_reason() for tcp_v{4,6}_do_rcv() menglong8.dong
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-02-18  8:31 UTC (permalink / raw)
  To: dsahern, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

From: Menglong Dong <imagedong@tencent.com>

Pass the address of drop_reason to tcp_add_backlog() to store the
reasons for skb drops when fails. Following drop reasons are
introduced:

SKB_DROP_REASON_SOCKET_BACKLOG

Signed-off-by: Menglong Dong <imagedong@tencent.com>
---
 include/linux/skbuff.h     | 4 ++++
 include/net/tcp.h          | 3 ++-
 include/trace/events/skb.h | 1 +
 net/ipv4/tcp_ipv4.c        | 7 +++++--
 net/ipv6/tcp_ipv6.c        | 2 +-
 5 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 46678eb587ff..f7f33c79945b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -358,6 +358,10 @@ enum skb_drop_reason {
 					 * corresponding to
 					 * LINUX_MIB_TCPMD5FAILURE
 					 */
+	SKB_DROP_REASON_SOCKET_BACKLOG,	/* failed to add skb to socket
+					 * backlog (see
+					 * LINUX_MIB_TCPBACKLOGDROP)
+					 */
 	SKB_DROP_REASON_MAX,
 };
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
index eff2487d972d..04f4650e0ff0 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1367,7 +1367,8 @@ static inline bool tcp_checksum_complete(struct sk_buff *skb)
 		__skb_checksum_complete(skb);
 }
 
-bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb);
+bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
+		     enum skb_drop_reason *reason);
 
 #ifdef CONFIG_INET
 void __sk_defer_free_flush(struct sock *sk);
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index 46c06b0be850..bfccd77e9071 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -31,6 +31,7 @@
 	EM(SKB_DROP_REASON_TCP_MD5UNEXPECTED,			\
 	   TCP_MD5UNEXPECTED)					\
 	EM(SKB_DROP_REASON_TCP_MD5FAILURE, TCP_MD5FAILURE)	\
+	EM(SKB_DROP_REASON_SOCKET_BACKLOG, SOCKET_BACKLOG)	\
 	EMe(SKB_DROP_REASON_MAX, MAX)
 
 #undef EM
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index d3c417119057..cbca8637ba2f 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1811,7 +1811,8 @@ int tcp_v4_early_demux(struct sk_buff *skb)
 	return 0;
 }
 
-bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
+bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
+		     enum skb_drop_reason *reason)
 {
 	u32 limit, tail_gso_size, tail_gso_segs;
 	struct skb_shared_info *shinfo;
@@ -1837,6 +1838,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
 	if (unlikely(tcp_checksum_complete(skb))) {
 		bh_unlock_sock(sk);
 		trace_tcp_bad_csum(skb);
+		*reason = SKB_DROP_REASON_TCP_CSUM;
 		__TCP_INC_STATS(sock_net(sk), TCP_MIB_CSUMERRORS);
 		__TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS);
 		return true;
@@ -1925,6 +1927,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
 
 	if (unlikely(sk_add_backlog(sk, skb, limit))) {
 		bh_unlock_sock(sk);
+		*reason = SKB_DROP_REASON_SOCKET_BACKLOG;
 		__NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPBACKLOGDROP);
 		return true;
 	}
@@ -2133,7 +2136,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
 	if (!sock_owned_by_user(sk)) {
 		ret = tcp_v4_do_rcv(sk, skb);
 	} else {
-		if (tcp_add_backlog(sk, skb))
+		if (tcp_add_backlog(sk, skb, &drop_reason))
 			goto discard_and_relse;
 	}
 	bh_unlock_sock(sk);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 1262b790b146..abf0ad547858 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1784,7 +1784,7 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 	if (!sock_owned_by_user(sk)) {
 		ret = tcp_v6_do_rcv(sk, skb);
 	} else {
-		if (tcp_add_backlog(sk, skb))
+		if (tcp_add_backlog(sk, skb, &drop_reason))
 			goto discard_and_relse;
 	}
 	bh_unlock_sock(sk);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 6/9] net: tcp: use kfree_skb_reason() for tcp_v{4,6}_do_rcv()
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
                   ` (4 preceding siblings ...)
  2022-02-18  8:31 ` [PATCH net-next v2 5/9] net: tcp: add skb drop reasons to tcp_add_backlog() menglong8.dong
@ 2022-02-18  8:31 ` menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 7/9] net: tcp: use tcp_drop_reason() for tcp_rcv_established() menglong8.dong
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-02-18  8:31 UTC (permalink / raw)
  To: dsahern, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

From: Menglong Dong <imagedong@tencent.com>

Replace kfree_skb() used in tcp_v4_do_rcv() and tcp_v6_do_rcv() with
kfree_skb_reason().

Signed-off-by: Menglong Dong <imagedong@tencent.com>
---
v2:
- init 'reason' properly in tcp_v6_do_rcv()
---
 net/ipv4/tcp_ipv4.c | 5 ++++-
 net/ipv6/tcp_ipv6.c | 5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index cbca8637ba2f..d42824aedc36 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1708,6 +1708,7 @@ INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *,
  */
 int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 {
+	enum skb_drop_reason reason;
 	struct sock *rsk;
 
 	if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
@@ -1730,6 +1731,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 		return 0;
 	}
 
+	reason = SKB_DROP_REASON_NOT_SPECIFIED;
 	if (tcp_checksum_complete(skb))
 		goto csum_err;
 
@@ -1757,7 +1759,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 reset:
 	tcp_v4_send_reset(rsk, skb);
 discard:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	/* Be careful here. If this function gets more complicated and
 	 * gcc suffers from register pressure on the x86, sk (in %ebx)
 	 * might be destroyed here. This current version compiles correctly,
@@ -1766,6 +1768,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 	return 0;
 
 csum_err:
+	reason = SKB_DROP_REASON_TCP_CSUM;
 	trace_tcp_bad_csum(skb);
 	TCP_INC_STATS(sock_net(sk), TCP_MIB_CSUMERRORS);
 	TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index abf0ad547858..91cee8010285 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1476,6 +1476,7 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 {
 	struct ipv6_pinfo *np = tcp_inet6_sk(sk);
 	struct sk_buff *opt_skb = NULL;
+	enum skb_drop_reason reason;
 	struct tcp_sock *tp;
 
 	/* Imagine: socket is IPv6. IPv4 packet arrives,
@@ -1510,6 +1511,7 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 	if (np->rxopt.all)
 		opt_skb = skb_clone(skb, sk_gfp_mask(sk, GFP_ATOMIC));
 
+	reason = SKB_DROP_REASON_NOT_SPECIFIED;
 	if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
 		struct dst_entry *dst;
 
@@ -1563,9 +1565,10 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 discard:
 	if (opt_skb)
 		__kfree_skb(opt_skb);
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	return 0;
 csum_err:
+	reason = SKB_DROP_REASON_TCP_CSUM;
 	trace_tcp_bad_csum(skb);
 	TCP_INC_STATS(sock_net(sk), TCP_MIB_CSUMERRORS);
 	TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 7/9] net: tcp: use tcp_drop_reason() for tcp_rcv_established()
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
                   ` (5 preceding siblings ...)
  2022-02-18  8:31 ` [PATCH net-next v2 6/9] net: tcp: use kfree_skb_reason() for tcp_v{4,6}_do_rcv() menglong8.dong
@ 2022-02-18  8:31 ` menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 8/9] net: tcp: use tcp_drop_reason() for tcp_data_queue() menglong8.dong
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-02-18  8:31 UTC (permalink / raw)
  To: dsahern, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

From: Menglong Dong <imagedong@tencent.com>

Replace tcp_drop() used in tcp_rcv_established() with tcp_drop_reason().
Following drop reasons are added:

SKB_DROP_REASON_TCP_FLAGS

Signed-off-by: Menglong Dong <imagedong@tencent.com>
---
 include/linux/skbuff.h     | 1 +
 include/trace/events/skb.h | 1 +
 net/ipv4/tcp_input.c       | 9 +++++++--
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f7f33c79945b..671db9f49efe 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -362,6 +362,7 @@ enum skb_drop_reason {
 					 * backlog (see
 					 * LINUX_MIB_TCPBACKLOGDROP)
 					 */
+	SKB_DROP_REASON_TCP_FLAGS,	/* TCP flags invalid */
 	SKB_DROP_REASON_MAX,
 };
 
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index bfccd77e9071..d332e7313a61 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -32,6 +32,7 @@
 	   TCP_MD5UNEXPECTED)					\
 	EM(SKB_DROP_REASON_TCP_MD5FAILURE, TCP_MD5FAILURE)	\
 	EM(SKB_DROP_REASON_SOCKET_BACKLOG, SOCKET_BACKLOG)	\
+	EM(SKB_DROP_REASON_TCP_FLAGS, TCP_FLAGS)		\
 	EMe(SKB_DROP_REASON_MAX, MAX)
 
 #undef EM
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0a2740add404..16ee1127e25d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5787,6 +5787,7 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
  */
 void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
 {
+	enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
 	const struct tcphdr *th = (const struct tcphdr *)skb->data;
 	struct tcp_sock *tp = tcp_sk(sk);
 	unsigned int len = skb->len;
@@ -5875,6 +5876,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
 				tp->rcv_rtt_last_tsecr = tp->rx_opt.rcv_tsecr;
 				return;
 			} else { /* Header too small */
+				reason = SKB_DROP_REASON_PKT_TOO_SMALL;
 				TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS);
 				goto discard;
 			}
@@ -5930,8 +5932,10 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
 	if (len < (th->doff << 2) || tcp_checksum_complete(skb))
 		goto csum_error;
 
-	if (!th->ack && !th->rst && !th->syn)
+	if (!th->ack && !th->rst && !th->syn) {
+		reason = SKB_DROP_REASON_TCP_FLAGS;
 		goto discard;
+	}
 
 	/*
 	 *	Standard slow path.
@@ -5957,12 +5961,13 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
 	return;
 
 csum_error:
+	reason = SKB_DROP_REASON_TCP_CSUM;
 	trace_tcp_bad_csum(skb);
 	TCP_INC_STATS(sock_net(sk), TCP_MIB_CSUMERRORS);
 	TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS);
 
 discard:
-	tcp_drop(sk, skb);
+	tcp_drop_reason(sk, skb, reason);
 }
 EXPORT_SYMBOL(tcp_rcv_established);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 8/9] net: tcp: use tcp_drop_reason() for tcp_data_queue()
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
                   ` (6 preceding siblings ...)
  2022-02-18  8:31 ` [PATCH net-next v2 7/9] net: tcp: use tcp_drop_reason() for tcp_rcv_established() menglong8.dong
@ 2022-02-18  8:31 ` menglong8.dong
  2022-02-18  8:31 ` [PATCH net-next v2 9/9] net: tcp: use tcp_drop_reason() for tcp_data_queue_ofo() menglong8.dong
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-02-18  8:31 UTC (permalink / raw)
  To: dsahern, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

From: Menglong Dong <imagedong@tencent.com>

Replace tcp_drop() used in tcp_data_queue() with tcp_drop_reason().
Following drop reasons are introduced:

SKB_DROP_REASON_TCP_ZEROWINDOW
SKB_DROP_REASON_TCP_OLD_DATA
SKB_DROP_REASON_TCP_OVERWINDOW

SKB_DROP_REASON_TCP_OLD_DATA is used for the case that end_seq of skb
less than the left edges of receive window. (Maybe there is a better
name?)

Signed-off-by: Menglong Dong <imagedong@tencent.com>
---
 include/linux/skbuff.h     | 13 +++++++++++++
 include/trace/events/skb.h |  3 +++
 net/ipv4/tcp_input.c       | 13 +++++++++++--
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 671db9f49efe..554ef2c848ee 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -363,6 +363,19 @@ enum skb_drop_reason {
 					 * LINUX_MIB_TCPBACKLOGDROP)
 					 */
 	SKB_DROP_REASON_TCP_FLAGS,	/* TCP flags invalid */
+	SKB_DROP_REASON_TCP_ZEROWINDOW,	/* TCP receive window size is zero,
+					 * see LINUX_MIB_TCPZEROWINDOWDROP
+					 */
+	SKB_DROP_REASON_TCP_OLD_DATA,	/* the TCP data reveived is already
+					 * received before (spurious retrans
+					 * may happened), see
+					 * LINUX_MIB_DELAYEDACKLOST
+					 */
+	SKB_DROP_REASON_TCP_OVERWINDOW,	/* the TCP data is out of window,
+					 * the seq of the first byte exceed
+					 * the right edges of receive
+					 * window
+					 */
 	SKB_DROP_REASON_MAX,
 };
 
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index d332e7313a61..cc1c8f7eaf72 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -33,6 +33,9 @@
 	EM(SKB_DROP_REASON_TCP_MD5FAILURE, TCP_MD5FAILURE)	\
 	EM(SKB_DROP_REASON_SOCKET_BACKLOG, SOCKET_BACKLOG)	\
 	EM(SKB_DROP_REASON_TCP_FLAGS, TCP_FLAGS)		\
+	EM(SKB_DROP_REASON_TCP_ZEROWINDOW, TCP_ZEROWINDOW)	\
+	EM(SKB_DROP_REASON_TCP_OLD_DATA, TCP_OLD_DATA)		\
+	EM(SKB_DROP_REASON_TCP_OVERWINDOW, TCP_OVERWINDOW)	\
 	EMe(SKB_DROP_REASON_MAX, MAX)
 
 #undef EM
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 16ee1127e25d..0a4ca818d580 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4988,6 +4988,7 @@ void tcp_data_ready(struct sock *sk)
 static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
+	enum skb_drop_reason reason;
 	bool fragstolen;
 	int eaten;
 
@@ -5006,6 +5007,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 	skb_dst_drop(skb);
 	__skb_pull(skb, tcp_hdr(skb)->doff * 4);
 
+	reason = SKB_DROP_REASON_NOT_SPECIFIED;
 	tp->rx_opt.dsack = 0;
 
 	/*  Queue data for delivery to the user.
@@ -5014,6 +5016,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 	 */
 	if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {
 		if (tcp_receive_window(tp) == 0) {
+			reason = SKB_DROP_REASON_TCP_ZEROWINDOW;
 			NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPZEROWINDOWDROP);
 			goto out_of_window;
 		}
@@ -5023,6 +5026,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 		if (skb_queue_len(&sk->sk_receive_queue) == 0)
 			sk_forced_mem_schedule(sk, skb->truesize);
 		else if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) {
+			reason = SKB_DROP_REASON_PROTO_MEM;
 			NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPRCVQDROP);
 			sk->sk_data_ready(sk);
 			goto drop;
@@ -5059,6 +5063,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 	if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) {
 		tcp_rcv_spurious_retrans(sk, skb);
 		/* A retransmit, 2nd most common case.  Force an immediate ack. */
+		reason = SKB_DROP_REASON_TCP_OLD_DATA;
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOST);
 		tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
 
@@ -5066,13 +5071,16 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 		tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS);
 		inet_csk_schedule_ack(sk);
 drop:
-		tcp_drop(sk, skb);
+		tcp_drop_reason(sk, skb, reason);
 		return;
 	}
 
 	/* Out of window. F.e. zero window probe. */
-	if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt + tcp_receive_window(tp)))
+	if (!before(TCP_SKB_CB(skb)->seq,
+		    tp->rcv_nxt + tcp_receive_window(tp))) {
+		reason = SKB_DROP_REASON_TCP_OVERWINDOW;
 		goto out_of_window;
+	}
 
 	if (before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
 		/* Partial packet, seq < rcv_next < end_seq */
@@ -5082,6 +5090,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 		 * remembering D-SACK for its head made in previous line.
 		 */
 		if (!tcp_receive_window(tp)) {
+			reason = SKB_DROP_REASON_TCP_ZEROWINDOW;
 			NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPZEROWINDOWDROP);
 			goto out_of_window;
 		}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 9/9] net: tcp: use tcp_drop_reason() for tcp_data_queue_ofo()
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
                   ` (7 preceding siblings ...)
  2022-02-18  8:31 ` [PATCH net-next v2 8/9] net: tcp: use tcp_drop_reason() for tcp_data_queue() menglong8.dong
@ 2022-02-18  8:31 ` menglong8.dong
  2022-02-18 18:51 ` [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive Eric Dumazet
  2022-02-18 21:23 ` David Ahern
  10 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-02-18  8:31 UTC (permalink / raw)
  To: dsahern, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

From: Menglong Dong <imagedong@tencent.com>

Replace tcp_drop() used in tcp_data_queue_ofo with tcp_drop_reason().
Following drop reasons are introduced:

SKB_DROP_REASON_TCP_OFOMERGE

Signed-off-by: Menglong Dong <imagedong@tencent.com>
---
 include/linux/skbuff.h     |  4 ++++
 include/trace/events/skb.h |  1 +
 net/ipv4/tcp_input.c       | 10 ++++++----
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 554ef2c848ee..a3e90efe6586 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -376,6 +376,10 @@ enum skb_drop_reason {
 					 * the right edges of receive
 					 * window
 					 */
+	SKB_DROP_REASON_TCP_OFOMERGE,	/* the data of skb is already in
+					 * the ofo queue, corresponding to
+					 * LINUX_MIB_TCPOFOMERGE
+					 */
 	SKB_DROP_REASON_MAX,
 };
 
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index cc1c8f7eaf72..2ab7193313aa 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -36,6 +36,7 @@
 	EM(SKB_DROP_REASON_TCP_ZEROWINDOW, TCP_ZEROWINDOW)	\
 	EM(SKB_DROP_REASON_TCP_OLD_DATA, TCP_OLD_DATA)		\
 	EM(SKB_DROP_REASON_TCP_OVERWINDOW, TCP_OVERWINDOW)	\
+	EM(SKB_DROP_REASON_TCP_OFOMERGE, TCP_OFOMERGE)		\
 	EMe(SKB_DROP_REASON_MAX, MAX)
 
 #undef EM
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0a4ca818d580..1fc422af11f8 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4779,7 +4779,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
 	if (unlikely(tcp_try_rmem_schedule(sk, skb, skb->truesize))) {
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPOFODROP);
 		sk->sk_data_ready(sk);
-		tcp_drop(sk, skb);
+		tcp_drop_reason(sk, skb, SKB_DROP_REASON_PROTO_MEM);
 		return;
 	}
 
@@ -4842,7 +4842,8 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
 				/* All the bits are present. Drop. */
 				NET_INC_STATS(sock_net(sk),
 					      LINUX_MIB_TCPOFOMERGE);
-				tcp_drop(sk, skb);
+				tcp_drop_reason(sk, skb,
+						SKB_DROP_REASON_TCP_OFOMERGE);
 				skb = NULL;
 				tcp_dsack_set(sk, seq, end_seq);
 				goto add_sack;
@@ -4861,7 +4862,8 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
 						 TCP_SKB_CB(skb1)->end_seq);
 				NET_INC_STATS(sock_net(sk),
 					      LINUX_MIB_TCPOFOMERGE);
-				tcp_drop(sk, skb1);
+				tcp_drop_reason(sk, skb1,
+						SKB_DROP_REASON_TCP_OFOMERGE);
 				goto merge_right;
 			}
 		} else if (tcp_ooo_try_coalesce(sk, skb1,
@@ -4889,7 +4891,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
 		tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
 				 TCP_SKB_CB(skb1)->end_seq);
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPOFOMERGE);
-		tcp_drop(sk, skb1);
+		tcp_drop_reason(sk, skb1, SKB_DROP_REASON_TCP_OFOMERGE);
 	}
 	/* If there is no skb after us, we are the last_skb ! */
 	if (!skb1)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
                   ` (8 preceding siblings ...)
  2022-02-18  8:31 ` [PATCH net-next v2 9/9] net: tcp: use tcp_drop_reason() for tcp_data_queue_ofo() menglong8.dong
@ 2022-02-18 18:51 ` Eric Dumazet
  2022-02-18 21:23 ` David Ahern
  10 siblings, 0 replies; 13+ messages in thread
From: Eric Dumazet @ 2022-02-18 18:51 UTC (permalink / raw)
  To: Menglong Dong
  Cc: David Ahern, Jakub Kicinski, David Miller, Steven Rostedt,
	Ingo Molnar, Hideaki YOSHIFUJI, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
	Menglong Dong, Talal Ahmad, Kees Cook, Ilias Apalodimas,
	Alexander Lobakin, Kumar Kartikeya Dwivedi, Antoine Tenart,
	Sebastian Andrzej Siewior, Paolo Abeni, Yunsheng Lin,
	Arnd Bergmann, Yajun Deng, Roopa Prabhu, Willem de Bruijn,
	Vasily Averin, Cong Wang, Luiz Augusto von Dentz, LKML, netdev,
	bpf, flyingpeng

On Fri, Feb 18, 2022 at 12:32 AM <menglong8.dong@gmail.com> wrote:
>
> From: Menglong Dong <imagedong@tencent.com>
>
> In the commit c504e5c2f964 ("net: skb: introduce kfree_skb_reason()"),
> we added the support of reporting the reasons of skb drops to kfree_skb
> tracepoint. And in this series patches, reasons for skb drops are added
> to TCP layer (both TCPv4 and TCPv6 are considered).
> Following functions are processed:
>

>
> /* SKB_DROP_REASON_TCP_MD5* corresponding to LINUX_MIB_TCPMD5* */
> SKB_DROP_REASON_TCP_MD5NOTFOUND
> SKB_DROP_REASON_TCP_MD5UNEXPECTED
> SKB_DROP_REASON_TCP_MD5FAILURE
> SKB_DROP_REASON_SOCKET_BACKLOG
> SKB_DROP_REASON_TCP_FLAGS
> SKB_DROP_REASON_TCP_ZEROWINDOW
> SKB_DROP_REASON_TCP_OLD_DATA
> SKB_DROP_REASON_TCP_OVERWINDOW
> /* corresponding to LINUX_MIB_TCPOFOMERGE */
> SKB_DROP_REASON_TCP_OFOMERGE
>

For the whole series:

Reviewed-by: Eric Dumazet <edumazet@google.com>

Thanks !

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive
  2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
                   ` (9 preceding siblings ...)
  2022-02-18 18:51 ` [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive Eric Dumazet
@ 2022-02-18 21:23 ` David Ahern
  10 siblings, 0 replies; 13+ messages in thread
From: David Ahern @ 2022-02-18 21:23 UTC (permalink / raw)
  To: menglong8.dong, kuba
  Cc: edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel, hawk,
	john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, linux-kernel, netdev, bpf, flyingpeng

On 2/18/22 1:31 AM, menglong8.dong@gmail.com wrote:
> From: Menglong Dong <imagedong@tencent.com>
> 
> In the commit c504e5c2f964 ("net: skb: introduce kfree_skb_reason()"),
> we added the support of reporting the reasons of skb drops to kfree_skb
> tracepoint. And in this series patches, reasons for skb drops are added
> to TCP layer (both TCPv4 and TCPv6 are considered).
> Following functions are processed:
> 
> tcp_v4_rcv()
> tcp_v6_rcv()
> tcp_v4_inbound_md5_hash()
> tcp_v6_inbound_md5_hash()
> tcp_add_backlog()
> tcp_v4_do_rcv()
> tcp_v6_do_rcv()
> tcp_rcv_established()
> tcp_data_queue()
> tcp_data_queue_ofo()
> 
> The functions we handled are mostly for packet ingress, as skb drops
> hardly happens in the egress path of TCP layer. However, it's a little
> complex for TCP state processing, as I find that it's hard to report skb
> drop reasons to where it is freed. For example, when skb is dropped in
> tcp_rcv_state_process(), the reason can be caused by the call of
> tcp_v4_conn_request(), and it's hard to return a drop reason from
> tcp_v4_conn_request(). So such cases are skipped  for this moment.
> 
> Following new drop reasons are introduced (what they mean can be see
> in the document for them):
> 
> /* SKB_DROP_REASON_TCP_MD5* corresponding to LINUX_MIB_TCPMD5* */
> SKB_DROP_REASON_TCP_MD5NOTFOUND
> SKB_DROP_REASON_TCP_MD5UNEXPECTED
> SKB_DROP_REASON_TCP_MD5FAILURE
> SKB_DROP_REASON_SOCKET_BACKLOG
> SKB_DROP_REASON_TCP_FLAGS
> SKB_DROP_REASON_TCP_ZEROWINDOW
> SKB_DROP_REASON_TCP_OLD_DATA
> SKB_DROP_REASON_TCP_OVERWINDOW
> /* corresponding to LINUX_MIB_TCPOFOMERGE */
> SKB_DROP_REASON_TCP_OFOMERGE
> 
> Here is a example to get TCP packet drop reasons from ftrace:
> 
> $ echo 1 > /sys/kernel/debug/tracing/events/skb/kfree_skb/enable
> $ cat /sys/kernel/debug/tracing/trace
> $ <idle>-0       [036] ..s1.   647.428165: kfree_skb: skbaddr=000000004d037db6 protocol=2048 location=0000000074cd1243 reason: NO_SOCKET
> $ <idle>-0       [020] ..s2.   639.676674: kfree_skb: skbaddr=00000000bcbfa42d protocol=2048 location=00000000bfe89d35 reason: PROTO_MEM
> 
> From the reason 'PROTO_MEM' we can know that the skb is dropped because
> the memory configured in net.ipv4.tcp_mem is up to the limition.
> 
> Changes since v1:
> - enrich the document for this series patches in the cover letter,
>   as Eric suggested
> - fix compile warning report by Jakub in the 6th patch
> - let NO_SOCKET trump the XFRM failure in the 2th and 3th patches
> 
> Menglong Dong (9):
>   net: tcp: introduce tcp_drop_reason()
>   net: tcp: add skb drop reasons to tcp_v4_rcv()
>   net: tcp: use kfree_skb_reason() for tcp_v6_rcv()
>   net: tcp: add skb drop reasons to tcp_v{4,6}_inbound_md5_hash()
>   net: tcp: add skb drop reasons to tcp_add_backlog()
>   net: tcp: use kfree_skb_reason() for tcp_v{4,6}_do_rcv()
>   net: tcp: use tcp_drop_reason() for tcp_rcv_established()
>   net: tcp: use tcp_drop_reason() for tcp_data_queue()
>   net: tcp: use tcp_drop_reason() for tcp_data_queue_ofo()
> 
>  include/linux/skbuff.h     | 34 ++++++++++++++++++++++++++++++
>  include/net/tcp.h          |  3 ++-
>  include/trace/events/skb.h | 10 +++++++++
>  net/ipv4/tcp_input.c       | 42 +++++++++++++++++++++++++++++---------
>  net/ipv4/tcp_ipv4.c        | 32 +++++++++++++++++++++--------
>  net/ipv6/tcp_ipv6.c        | 39 +++++++++++++++++++++++++++--------
>  6 files changed, 132 insertions(+), 28 deletions(-)
> 

LGTM. for the set:

Reviewed-by: David Ahern <dsahern@kernel.org>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 1/9] net: tcp: introduce tcp_drop_reason()
  2022-02-18  8:31 ` [PATCH net-next v2 1/9] net: tcp: introduce tcp_drop_reason() menglong8.dong
@ 2022-02-19  4:40   ` Jakub Kicinski
  0 siblings, 0 replies; 13+ messages in thread
From: Jakub Kicinski @ 2022-02-19  4:40 UTC (permalink / raw)
  To: menglong8.dong
  Cc: dsahern, edumazet, davem, rostedt, mingo, yoshfuji, ast, daniel,
	hawk, john.fastabend, imagedong, talalahmad, keescook,
	ilias.apalodimas, alobakin, memxor, atenart, bigeasy, pabeni,
	linyunsheng, arnd, yajun.deng, roopa, willemb, vvs, cong.wang,
	luiz.von.dentz, netdev, bpf, flyingpeng

On Fri, 18 Feb 2022 16:31:25 +0800 menglong8.dong@gmail.com wrote:
> +static inline void tcp_drop(struct sock *sk, struct sk_buff *skb)

The patches are marked as changes requested in patchwork.

I presume Dave also thinks this static inline is best avoided.

Is this function really not getting inlined? Otherwise please 
repost with the inline keyword removed.

> +{
> +	tcp_drop_reason(sk, skb, SKB_DROP_REASON_NOT_SPECIFIED);
>  }

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2022-02-19  4:40 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-18  8:31 [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive menglong8.dong
2022-02-18  8:31 ` [PATCH net-next v2 1/9] net: tcp: introduce tcp_drop_reason() menglong8.dong
2022-02-19  4:40   ` Jakub Kicinski
2022-02-18  8:31 ` [PATCH net-next v2 2/9] net: tcp: add skb drop reasons to tcp_v4_rcv() menglong8.dong
2022-02-18  8:31 ` [PATCH net-next v2 3/9] net: tcp: use kfree_skb_reason() for tcp_v6_rcv() menglong8.dong
2022-02-18  8:31 ` [PATCH net-next v2 4/9] net: tcp: add skb drop reasons to tcp_v{4,6}_inbound_md5_hash() menglong8.dong
2022-02-18  8:31 ` [PATCH net-next v2 5/9] net: tcp: add skb drop reasons to tcp_add_backlog() menglong8.dong
2022-02-18  8:31 ` [PATCH net-next v2 6/9] net: tcp: use kfree_skb_reason() for tcp_v{4,6}_do_rcv() menglong8.dong
2022-02-18  8:31 ` [PATCH net-next v2 7/9] net: tcp: use tcp_drop_reason() for tcp_rcv_established() menglong8.dong
2022-02-18  8:31 ` [PATCH net-next v2 8/9] net: tcp: use tcp_drop_reason() for tcp_data_queue() menglong8.dong
2022-02-18  8:31 ` [PATCH net-next v2 9/9] net: tcp: use tcp_drop_reason() for tcp_data_queue_ofo() menglong8.dong
2022-02-18 18:51 ` [PATCH net-next v2 0/9] net: add skb drop reasons to TCP packet receive Eric Dumazet
2022-02-18 21:23 ` David Ahern

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.