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>
This commit is contained in:
parent
e7219858ac
commit
daad151263
@ -150,7 +150,31 @@ extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
|
|||||||
extern bool ipv6_chk_mcast_addr(struct net_device *dev,
|
extern bool ipv6_chk_mcast_addr(struct net_device *dev,
|
||||||
const struct in6_addr *group,
|
const struct in6_addr *group,
|
||||||
const struct in6_addr *src_addr);
|
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,
|
extern void addrconf_prefix_rcv(struct net_device *dev,
|
||||||
u8 *opt, int len, bool sllao);
|
u8 *opt, int len, bool sllao);
|
||||||
|
@ -212,7 +212,7 @@ static int ip6_input_finish(struct sk_buff *skb)
|
|||||||
if (ipv6_addr_is_multicast(&hdr->daddr) &&
|
if (ipv6_addr_is_multicast(&hdr->daddr) &&
|
||||||
!ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
|
!ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
|
||||||
&hdr->saddr) &&
|
&hdr->saddr) &&
|
||||||
!ipv6_is_mld(skb, nexthdr))
|
!ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
|
if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
|
||||||
@ -283,7 +283,6 @@ int ip6_mc_input(struct sk_buff *skb)
|
|||||||
if (unlikely(opt->ra)) {
|
if (unlikely(opt->ra)) {
|
||||||
/* Check if this is a mld message */
|
/* Check if this is a mld message */
|
||||||
u8 *ptr = skb_network_header(skb) + opt->ra;
|
u8 *ptr = skb_network_header(skb) + opt->ra;
|
||||||
struct icmp6hdr *icmp6;
|
|
||||||
u8 nexthdr = hdr->nexthdr;
|
u8 nexthdr = hdr->nexthdr;
|
||||||
__be16 frag_off;
|
__be16 frag_off;
|
||||||
int offset;
|
int offset;
|
||||||
@ -303,24 +302,10 @@ int ip6_mc_input(struct sk_buff *skb)
|
|||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (nexthdr != IPPROTO_ICMPV6)
|
if (!ipv6_is_mld(skb, nexthdr, offset))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!pskb_may_pull(skb, (skb_network_header(skb) +
|
deliver = true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
/* unknown RA - process it normally */
|
/* unknown RA - process it normally */
|
||||||
}
|
}
|
||||||
|
@ -934,33 +934,6 @@ int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
|
|||||||
return err;
|
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
|
* check if the interface/address pair is valid
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user