OSDN Git Service

ipv6: icmp6: add drop reason support to ndisc_rcv()
authorEric Dumazet <edumazet@google.com>
Fri, 10 Feb 2023 18:47:08 +0000 (18:47 +0000)
committerJakub Kicinski <kuba@kernel.org>
Tue, 14 Feb 2023 03:55:32 +0000 (19:55 -0800)
Creates three new drop reasons:

SKB_DROP_REASON_IPV6_NDISC_FRAG: invalid frag (suppress_frag_ndisc).

SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT: invalid hop limit.

SKB_DROP_REASON_IPV6_NDISC_BAD_CODE: invalid NDISC icmp6 code.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/dropreason.h
include/net/ndisc.h
net/ipv6/icmp.c
net/ipv6/ndisc.c

index 6c41e53..ef3f65d 100644 (file)
@@ -73,6 +73,9 @@
        FN(FRAG_TOO_FAR)                \
        FN(TCP_MINTTL)                  \
        FN(IPV6_BAD_EXTHDR)             \
+       FN(IPV6_NDISC_FRAG)             \
+       FN(IPV6_NDISC_HOP_LIMIT)        \
+       FN(IPV6_NDISC_BAD_CODE)         \
        FNe(MAX)
 
 /**
@@ -321,6 +324,12 @@ enum skb_drop_reason {
        SKB_DROP_REASON_TCP_MINTTL,
        /** @SKB_DROP_REASON_IPV6_BAD_EXTHDR: Bad IPv6 extension header. */
        SKB_DROP_REASON_IPV6_BAD_EXTHDR,
+       /** @SKB_DROP_REASON_IPV6_NDISC_FRAG: invalid frag (suppress_frag_ndisc). */
+       SKB_DROP_REASON_IPV6_NDISC_FRAG,
+       /** @SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT: invalid hop limit. */
+       SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT,
+       /** @SKB_DROP_REASON_IPV6_NDISC_BAD_CODE: invalid NDISC icmp6 code. */
+       SKB_DROP_REASON_IPV6_NDISC_BAD_CODE,
        /**
         * @SKB_DROP_REASON_MAX: the maximum of drop reason, which shouldn't be
         * used as a real 'reason'
index da7eec8..07e5168 100644 (file)
@@ -445,7 +445,7 @@ int ndisc_late_init(void);
 void ndisc_late_cleanup(void);
 void ndisc_cleanup(void);
 
-int ndisc_rcv(struct sk_buff *skb);
+enum skb_drop_reason ndisc_rcv(struct sk_buff *skb);
 
 struct sk_buff *ndisc_ns_create(struct net_device *dev, const struct in6_addr *solicit,
                                const struct in6_addr *saddr, u64 nonce);
index 40bb5de..f32bc98 100644 (file)
@@ -969,7 +969,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
        case NDISC_NEIGHBOUR_SOLICITATION:
        case NDISC_NEIGHBOUR_ADVERTISEMENT:
        case NDISC_REDIRECT:
-               ndisc_rcv(skb);
+               reason = ndisc_rcv(skb);
                break;
 
        case ICMPV6_MGM_QUERY:
index 3a55349..9548b5a 100644 (file)
@@ -1804,15 +1804,16 @@ static bool ndisc_suppress_frag_ndisc(struct sk_buff *skb)
        return false;
 }
 
-int ndisc_rcv(struct sk_buff *skb)
+enum skb_drop_reason ndisc_rcv(struct sk_buff *skb)
 {
        struct nd_msg *msg;
+       SKB_DR(reason);
 
        if (ndisc_suppress_frag_ndisc(skb))
-               return 0;
+               return SKB_DROP_REASON_IPV6_NDISC_FRAG;
 
        if (skb_linearize(skb))
-               return 0;
+               return SKB_DROP_REASON_NOMEM;
 
        msg = (struct nd_msg *)skb_transport_header(skb);
 
@@ -1821,13 +1822,13 @@ int ndisc_rcv(struct sk_buff *skb)
        if (ipv6_hdr(skb)->hop_limit != 255) {
                ND_PRINTK(2, warn, "NDISC: invalid hop-limit: %d\n",
                          ipv6_hdr(skb)->hop_limit);
-               return 0;
+               return SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT;
        }
 
        if (msg->icmph.icmp6_code != 0) {
                ND_PRINTK(2, warn, "NDISC: invalid ICMPv6 code: %d\n",
                          msg->icmph.icmp6_code);
-               return 0;
+               return SKB_DROP_REASON_IPV6_NDISC_BAD_CODE;
        }
 
        switch (msg->icmph.icmp6_type) {
@@ -1853,7 +1854,7 @@ int ndisc_rcv(struct sk_buff *skb)
                break;
        }
 
-       return 0;
+       return reason;
 }
 
 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)