From: Menglong Dong <imaged...@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*

Reviewed-by: Mengen Sun <mengen...@tencent.com>
Reviewed-by: Hao Peng <flyingp...@tencent.com>
Signed-off-by: Menglong Dong <imaged...@tencent.com>
Reviewed-by: Eric Dumazet <eduma...@google.com>
Reviewed-by: David Ahern <dsah...@kernel.org>
Signed-off-by: David S. Miller <da...@davemloft.net>
Acked-by: Nikolay Borisov <nbori...@suse.com>
Signed-off-by: Nikolay Borisov <nikolay.bori...@virtuozzo.com>
---
 include/linux/skbuff.h     | 13 +++++++++++++
 include/trace/events/skb.h |  4 ++++
 net/ipv4/tcp_ipv4.c        | 13 +++++++++----
 net/ipv6/tcp_ipv6.c        | 10 +++++++---
 4 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f81a4bc09585..307dbbea8e45 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -344,6 +344,19 @@ 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
+                                        */
+
 
 
 
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index 2d11e23e402e..2742080fa181 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 0267b0cc1da0..7931903edbd8 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1397,7 +1397,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
        /*
@@ -1430,11 +1431,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;
        }
@@ -1447,6 +1450,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),
@@ -1957,13 +1961,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;
@@ -2011,7 +2015,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;
@@ -2081,7 +2086,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 19e7b2a400ae..6c8dcfcbcf89 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -768,7 +768,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;
@@ -791,11 +792,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;
        }
@@ -806,6 +809,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",
@@ -1674,7 +1678,7 @@ 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;
@@ -1741,7 +1745,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

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to