Skip to content

Commit

Permalink
ipv6: Make ipv6_is_mld() inline and use it from ip6_mc_input().
Browse files Browse the repository at this point in the history
Move generalized version of ipv6_is_mld() to header,
and use it from ip6_mc_input().

Signed-off-by: YOSHIFUJI Hideaki <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
yoshfuji authored and davem330 committed Jan 14, 2013
1 parent e721985 commit daad151
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 46 deletions.
26 changes: 25 additions & 1 deletion include/net/addrconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
21 changes: 3 additions & 18 deletions net/ipv6/ip6_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ static int ip6_input_finish(struct sk_buff *skb)
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) &&
Expand Down Expand Up @@ -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;
Expand All @@ -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 */
}
Expand Down
27 changes: 0 additions & 27 deletions net/ipv6/mcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down

0 comments on commit daad151

Please sign in to comment.