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)
 
 /**
        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'
 
 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);
 
        case NDISC_NEIGHBOUR_SOLICITATION:
        case NDISC_NEIGHBOUR_ADVERTISEMENT:
        case NDISC_REDIRECT:
-               ndisc_rcv(skb);
+               reason = ndisc_rcv(skb);
                break;
 
        case ICMPV6_MGM_QUERY:
 
        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);
 
        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) {
                break;
        }
 
-       return 0;
+       return reason;
 }
 
 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)