Commit daad151263cf334d57fcc0270e2483d4b4639650

Authored by YOSHIFUJI Hideaki / 吉藤英明
Committed by David S. Miller
1 parent e7219858ac

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>

Showing 3 changed files with 28 additions and 46 deletions Side-by-side Diff

include/net/addrconf.h
... ... @@ -150,7 +150,31 @@
150 150 extern bool ipv6_chk_mcast_addr(struct net_device *dev,
151 151 const struct in6_addr *group,
152 152 const struct in6_addr *src_addr);
153   -extern bool ipv6_is_mld(struct sk_buff *skb, int nexthdr);
  153 +
  154 +/*
  155 + * identify MLD packets for MLD filter exceptions
  156 + */
  157 +static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset)
  158 +{
  159 + struct icmp6hdr *hdr;
  160 +
  161 + if (nexthdr != IPPROTO_ICMPV6 ||
  162 + !pskb_network_may_pull(skb, offset + sizeof(struct icmp6hdr)))
  163 + return false;
  164 +
  165 + hdr = (struct icmp6hdr *)(skb_network_header(skb) + offset);
  166 +
  167 + switch (hdr->icmp6_type) {
  168 + case ICMPV6_MGM_QUERY:
  169 + case ICMPV6_MGM_REPORT:
  170 + case ICMPV6_MGM_REDUCTION:
  171 + case ICMPV6_MLD2_REPORT:
  172 + return true;
  173 + default:
  174 + break;
  175 + }
  176 + return false;
  177 +}
154 178  
155 179 extern void addrconf_prefix_rcv(struct net_device *dev,
156 180 u8 *opt, int len, bool sllao);
net/ipv6/ip6_input.c
... ... @@ -212,7 +212,7 @@
212 212 if (ipv6_addr_is_multicast(&hdr->daddr) &&
213 213 !ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
214 214 &hdr->saddr) &&
215   - !ipv6_is_mld(skb, nexthdr))
  215 + !ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
216 216 goto discard;
217 217 }
218 218 if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
... ... @@ -283,7 +283,6 @@
283 283 if (unlikely(opt->ra)) {
284 284 /* Check if this is a mld message */
285 285 u8 *ptr = skb_network_header(skb) + opt->ra;
286   - struct icmp6hdr *icmp6;
287 286 u8 nexthdr = hdr->nexthdr;
288 287 __be16 frag_off;
289 288 int offset;
290 289  
... ... @@ -303,24 +302,10 @@
303 302 if (offset < 0)
304 303 goto out;
305 304  
306   - if (nexthdr != IPPROTO_ICMPV6)
  305 + if (!ipv6_is_mld(skb, nexthdr, offset))
307 306 goto out;
308 307  
309   - if (!pskb_may_pull(skb, (skb_network_header(skb) +
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;
  308 + deliver = true;
324 309 }
325 310 /* unknown RA - process it normally */
326 311 }
... ... @@ -935,33 +935,6 @@
935 935 }
936 936  
937 937 /*
938   - * identify MLD packets for MLD filter exceptions
939   - */
940   -bool 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 938 * check if the interface/address pair is valid
966 939 */
967 940 bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,