aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>2013-01-13 00:02:18 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-13 20:17:14 -0500
commitdaad151263cf334d57fcc0270e2483d4b4639650 (patch)
treeca0ba6274d94c1ce31a51a296a7032bb43a1cc08 /net/ipv6
parente7219858ac1f98213a4714d0e24e7a003e1bf6a2 (diff)
ipv6: Make ipv6_is_mld() inline and use it from ip6_mc_input().
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>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_input.c21
-rw-r--r--net/ipv6/mcast.c27
2 files changed, 3 insertions, 45 deletions
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index a52d864d562b..2ccd35ec3628 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -212,7 +212,7 @@ resubmit:
212 if (ipv6_addr_is_multicast(&hdr->daddr) && 212 if (ipv6_addr_is_multicast(&hdr->daddr) &&
213 !ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, 213 !ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
214 &hdr->saddr) && 214 &hdr->saddr) &&
215 !ipv6_is_mld(skb, nexthdr)) 215 !ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
216 goto discard; 216 goto discard;
217 } 217 }
218 if (!(ipprot->flags & INET6_PROTO_NOPOLICY) && 218 if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
@@ -283,7 +283,6 @@ int ip6_mc_input(struct sk_buff *skb)
283 if (unlikely(opt->ra)) { 283 if (unlikely(opt->ra)) {
284 /* Check if this is a mld message */ 284 /* Check if this is a mld message */
285 u8 *ptr = skb_network_header(skb) + opt->ra; 285 u8 *ptr = skb_network_header(skb) + opt->ra;
286 struct icmp6hdr *icmp6;
287 u8 nexthdr = hdr->nexthdr; 286 u8 nexthdr = hdr->nexthdr;
288 __be16 frag_off; 287 __be16 frag_off;
289 int offset; 288 int offset;
@@ -303,24 +302,10 @@ int ip6_mc_input(struct sk_buff *skb)
303 if (offset < 0) 302 if (offset < 0)
304 goto out; 303 goto out;
305 304
306 if (nexthdr != IPPROTO_ICMPV6) 305 if (!ipv6_is_mld(skb, nexthdr, offset))
307 goto out; 306 goto out;
308 307
309 if (!pskb_may_pull(skb, (skb_network_header(skb) + 308 deliver = true;
310 offset + 1 - skb->data)))
311 goto out;
312
313 icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset);
314
315 switch (icmp6->icmp6_type) {
316 case ICMPV6_MGM_QUERY:
317 case ICMPV6_MGM_REPORT:
318 case ICMPV6_MGM_REDUCTION:
319 case ICMPV6_MLD2_REPORT:
320 deliver = true;
321 break;
322 }
323 goto out;
324 } 309 }
325 /* unknown RA - process it normally */ 310 /* unknown RA - process it normally */
326 } 311 }
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 28dfa5f3801f..8237ee15eafd 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -935,33 +935,6 @@ int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
935} 935}
936 936
937/* 937/*
938 * identify MLD packets for MLD filter exceptions
939 */
940bool ipv6_is_mld(struct sk_buff *skb, int nexthdr)
941{
942 struct icmp6hdr *pic;
943
944 if (nexthdr != IPPROTO_ICMPV6)
945 return false;
946
947 if (!pskb_may_pull(skb, sizeof(struct icmp6hdr)))
948 return false;
949
950 pic = icmp6_hdr(skb);
951
952 switch (pic->icmp6_type) {
953 case ICMPV6_MGM_QUERY:
954 case ICMPV6_MGM_REPORT:
955 case ICMPV6_MGM_REDUCTION:
956 case ICMPV6_MLD2_REPORT:
957 return true;
958 default:
959 break;
960 }
961 return false;
962}
963
964/*
965 * check if the interface/address pair is valid 938 * check if the interface/address pair is valid
966 */ 939 */
967bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group, 940bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,