ipv6: Make ipv6_is_mld() inline and use it from ip6_mc_input().
authorYOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>
Sun, 13 Jan 2013 05:02:18 +0000 (05:02 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 14 Jan 2013 01:17:14 +0000 (20:17 -0500)
Move generalized version of ipv6_is_mld() to header,
and use it from ip6_mc_input().

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/addrconf.h
net/ipv6/ip6_input.c
net/ipv6/mcast.c

index df4ef94..7cd14c0 100644 (file)
@@ -150,7 +150,31 @@ extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
 extern bool ipv6_chk_mcast_addr(struct net_device *dev,
                                const struct in6_addr *group,
                                const struct in6_addr *src_addr);
-extern bool ipv6_is_mld(struct sk_buff *skb, int nexthdr);
+
+/*
+ * identify MLD packets for MLD filter exceptions
+ */
+static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset)
+{
+       struct icmp6hdr *hdr;
+
+       if (nexthdr != IPPROTO_ICMPV6 ||
+           !pskb_network_may_pull(skb, offset + sizeof(struct icmp6hdr)))
+               return false;
+
+       hdr = (struct icmp6hdr *)(skb_network_header(skb) + offset);
+
+       switch (hdr->icmp6_type) {
+       case ICMPV6_MGM_QUERY:
+       case ICMPV6_MGM_REPORT:
+       case ICMPV6_MGM_REDUCTION:
+       case ICMPV6_MLD2_REPORT:
+               return true;
+       default:
+               break;
+       }
+       return false;
+}
 
 extern void addrconf_prefix_rcv(struct net_device *dev,
                                u8 *opt, int len, bool sllao);
index a52d864..2ccd35e 100644 (file)
@@ -212,7 +212,7 @@ resubmit:
                        if (ipv6_addr_is_multicast(&hdr->daddr) &&
                            !ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
                            &hdr->saddr) &&
-                           !ipv6_is_mld(skb, nexthdr))
+                           !ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
                                goto discard;
                }
                if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
@@ -283,7 +283,6 @@ int ip6_mc_input(struct sk_buff *skb)
                if (unlikely(opt->ra)) {
                        /* Check if this is a mld message */
                        u8 *ptr = skb_network_header(skb) + opt->ra;
-                       struct icmp6hdr *icmp6;
                        u8 nexthdr = hdr->nexthdr;
                        __be16 frag_off;
                        int offset;
@@ -303,24 +302,10 @@ int ip6_mc_input(struct sk_buff *skb)
                                if (offset < 0)
                                        goto out;
 
-                               if (nexthdr != IPPROTO_ICMPV6)
+                               if (!ipv6_is_mld(skb, nexthdr, offset))
                                        goto out;
 
-                               if (!pskb_may_pull(skb, (skb_network_header(skb) +
-                                                  offset + 1 - skb->data)))
-                                       goto out;
-
-                               icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset);
-
-                               switch (icmp6->icmp6_type) {
-                               case ICMPV6_MGM_QUERY:
-                               case ICMPV6_MGM_REPORT:
-                               case ICMPV6_MGM_REDUCTION:
-                               case ICMPV6_MLD2_REPORT:
-                                       deliver = true;
-                                       break;
-                               }
-                               goto out;
+                               deliver = true;
                        }
                        /* unknown RA - process it normally */
                }
index 28dfa5f..8237ee1 100644 (file)
@@ -934,33 +934,6 @@ int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
        return err;
 }
 
-/*
- * identify MLD packets for MLD filter exceptions
- */
-bool ipv6_is_mld(struct sk_buff *skb, int nexthdr)
-{
-       struct icmp6hdr *pic;
-
-       if (nexthdr != IPPROTO_ICMPV6)
-               return false;
-
-       if (!pskb_may_pull(skb, sizeof(struct icmp6hdr)))
-               return false;
-
-       pic = icmp6_hdr(skb);
-
-       switch (pic->icmp6_type) {
-       case ICMPV6_MGM_QUERY:
-       case ICMPV6_MGM_REPORT:
-       case ICMPV6_MGM_REDUCTION:
-       case ICMPV6_MLD2_REPORT:
-               return true;
-       default:
-               break;
-       }
-       return false;
-}
-
 /*
  *     check if the interface/address pair is valid
  */