net: skb: use kfree_skb_reason() in tcp_v4_rcv()
authorMenglong Dong <imagedong@tencent.com>
Sun, 9 Jan 2022 06:36:27 +0000 (14:36 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Jul 2022 15:25:15 +0000 (17:25 +0200)
[ Upstream commit 85125597419aec3aa7b8f3b8713e415f997796f2 ]

Replace kfree_skb() with kfree_skb_reason() in tcp_v4_rcv(). Following
drop reasons are added:

SKB_DROP_REASON_NO_SOCKET
SKB_DROP_REASON_PKT_TOO_SMALL
SKB_DROP_REASON_TCP_CSUM
SKB_DROP_REASON_TCP_FILTER

After this patch, 'kfree_skb' event will print message like this:

$           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
$              | |         |   |||||     |         |
          <idle>-0       [000] ..s1.    36.113438: kfree_skb: skbaddr=(____ptrval____) protocol=2048 location=(____ptrval____) reason: NO_SOCKET

The reason of skb drop is printed too.

Signed-off-by: Menglong Dong <imagedong@tencent.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/linux/skbuff.h
include/trace/events/skb.h
net/ipv4/tcp_ipv4.c

index 029bc22..5305af6 100644 (file)
@@ -312,6 +312,10 @@ struct sk_buff;
  */
 enum skb_drop_reason {
        SKB_DROP_REASON_NOT_SPECIFIED,
+       SKB_DROP_REASON_NO_SOCKET,
+       SKB_DROP_REASON_PKT_TOO_SMALL,
+       SKB_DROP_REASON_TCP_CSUM,
+       SKB_DROP_REASON_TCP_FILTER,
        SKB_DROP_REASON_MAX,
 };
 
index 294c61b..faa7d06 100644 (file)
 
 #define TRACE_SKB_DROP_REASON                                  \
        EM(SKB_DROP_REASON_NOT_SPECIFIED, NOT_SPECIFIED)        \
+       EM(SKB_DROP_REASON_NO_SOCKET, NO_SOCKET)                \
+       EM(SKB_DROP_REASON_PKT_TOO_SMALL, PKT_TOO_SMALL)        \
+       EM(SKB_DROP_REASON_TCP_CSUM, TCP_CSUM)                  \
+       EM(SKB_DROP_REASON_TCP_FILTER, TCP_FILTER)              \
        EMe(SKB_DROP_REASON_MAX, MAX)
 
 #undef EM
index b9a9f28..d901858 100644 (file)
@@ -1976,8 +1976,10 @@ int tcp_v4_rcv(struct sk_buff *skb)
        const struct tcphdr *th;
        bool refcounted;
        struct sock *sk;
+       int drop_reason;
        int ret;
 
+       drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
        if (skb->pkt_type != PACKET_HOST)
                goto discard_it;
 
@@ -1989,8 +1991,10 @@ int tcp_v4_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;
 
@@ -2093,8 +2097,10 @@ process:
 
        nf_reset_ct(skb);
 
-       if (tcp_filter(sk, skb))
+       if (tcp_filter(sk, skb)) {
+               drop_reason = SKB_DROP_REASON_TCP_FILTER;
                goto discard_and_relse;
+       }
        th = (const struct tcphdr *)skb->data;
        iph = ip_hdr(skb);
        tcp_v4_fill_cb(skb, iph, th);
@@ -2131,6 +2137,7 @@ put_and_return:
        return ret;
 
 no_tcp_socket:
+       drop_reason = SKB_DROP_REASON_NO_SOCKET;
        if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
                goto discard_it;
 
@@ -2138,6 +2145,7 @@ no_tcp_socket:
 
        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:
@@ -2148,7 +2156,7 @@ bad_packet:
 
 discard_it:
        /* Discard frame. */
-       kfree_skb(skb);
+       kfree_skb_reason(skb, drop_reason);
        return 0;
 
 discard_and_relse: