void ipv6_mc_remap(struct inet6_dev *idev);
 void ipv6_mc_init_dev(struct inet6_dev *idev);
 void ipv6_mc_destroy_dev(struct inet6_dev *idev);
-int ipv6_mc_check_icmpv6(struct sk_buff *skb);
 int ipv6_mc_check_mld(struct sk_buff *skb);
 void addrconf_dad_failure(struct sk_buff *skb, struct inet6_ifaddr *ifp);
 
 
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
-static int br_ip6_multicast_mrd_rcv(struct net_bridge *br,
-                                   struct net_bridge_port *port,
-                                   struct sk_buff *skb)
+static void br_ip6_multicast_mrd_rcv(struct net_bridge *br,
+                                    struct net_bridge_port *port,
+                                    struct sk_buff *skb)
 {
-       int ret;
-
-       if (ipv6_hdr(skb)->nexthdr != IPPROTO_ICMPV6)
-               return -ENOMSG;
-
-       ret = ipv6_mc_check_icmpv6(skb);
-       if (ret < 0)
-               return ret;
-
        if (icmp6_hdr(skb)->icmp6_type != ICMPV6_MRDISC_ADV)
-               return -ENOMSG;
+               return;
 
        br_multicast_mark_router(br, port);
-
-       return 0;
 }
 
 static int br_multicast_ipv6_rcv(struct net_bridge *br,
 
        err = ipv6_mc_check_mld(skb);
 
-       if (err == -ENOMSG) {
+       if (err == -ENOMSG || err == -ENODATA) {
                if (!ipv6_addr_is_ll_all_nodes(&ipv6_hdr(skb)->daddr))
                        BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
-
-               if (ipv6_addr_is_all_snoopers(&ipv6_hdr(skb)->daddr)) {
-                       err = br_ip6_multicast_mrd_rcv(br, port, skb);
-
-                       if (err < 0 && err != -ENOMSG) {
-                               br_multicast_err_count(br, port, skb->protocol);
-                               return err;
-                       }
-               }
+               if (err == -ENODATA &&
+                   ipv6_addr_is_all_snoopers(&ipv6_hdr(skb)->daddr))
+                       br_ip6_multicast_mrd_rcv(br, port, skb);
 
                return 0;
        } else if (err < 0) {
 
        struct mld_msg *mld;
 
        if (!ipv6_mc_may_pull(skb, len))
-               return -EINVAL;
+               return -ENODATA;
 
        mld = (struct mld_msg *)skb_transport_header(skb);
 
        case ICMPV6_MGM_QUERY:
                return ipv6_mc_check_mld_query(skb);
        default:
-               return -ENOMSG;
+               return -ENODATA;
        }
 }
 
        return skb_checksum_validate(skb, IPPROTO_ICMPV6, ip6_compute_pseudo);
 }
 
-int ipv6_mc_check_icmpv6(struct sk_buff *skb)
+static int ipv6_mc_check_icmpv6(struct sk_buff *skb)
 {
        unsigned int len = skb_transport_offset(skb) + sizeof(struct icmp6hdr);
        unsigned int transport_len = ipv6_transport_len(skb);
 
        return 0;
 }
-EXPORT_SYMBOL(ipv6_mc_check_icmpv6);
 
 /**
  * ipv6_mc_check_mld - checks whether this is a sane MLD packet
  *
  * -EINVAL: A broken packet was detected, i.e. it violates some internet
  *  standard
- * -ENOMSG: IP header validation succeeded but it is not an MLD packet.
+ * -ENOMSG: IP header validation succeeded but it is not an ICMPv6 packet
+ *  with a hop-by-hop option.
+ * -ENODATA: IP+ICMPv6 header with hop-by-hop option validation succeeded
+ *  but it is not an MLD packet.
  * -ENOMEM: A memory allocation failure happened.
  *
  * Caller needs to set the skb network header and free any returned skb if it