[NETFILTER]: Restore netfilter assumptions in IPv6 multicast
Netfilter assumes that skb->data == skb->nh.ipv6h Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
18b8afc771
commit
e98231858b
|
@ -1301,15 +1301,6 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
skb_reserve(skb, LL_RESERVED_SPACE(dev));
|
skb_reserve(skb, LL_RESERVED_SPACE(dev));
|
||||||
if (dev->hard_header) {
|
|
||||||
unsigned char ha[MAX_ADDR_LEN];
|
|
||||||
|
|
||||||
ndisc_mc_map(&mld2_all_mcr, ha, dev, 1);
|
|
||||||
if (dev->hard_header(skb, dev, ETH_P_IPV6,ha,NULL,size) < 0) {
|
|
||||||
kfree_skb(skb);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipv6_get_lladdr(dev, &addr_buf)) {
|
if (ipv6_get_lladdr(dev, &addr_buf)) {
|
||||||
/* <draft-ietf-magma-mld-source-05.txt>:
|
/* <draft-ietf-magma-mld-source-05.txt>:
|
||||||
|
@ -1333,6 +1324,30 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int mld_dev_queue_xmit2(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct net_device *dev = skb->dev;
|
||||||
|
|
||||||
|
if (dev->hard_header) {
|
||||||
|
unsigned char ha[MAX_ADDR_LEN];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
ndisc_mc_map(&skb->nh.ipv6h->daddr, ha, dev, 1);
|
||||||
|
err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len);
|
||||||
|
if (err < 0) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dev_queue_xmit(skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int mld_dev_queue_xmit(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dev,
|
||||||
|
mld_dev_queue_xmit2);
|
||||||
|
}
|
||||||
|
|
||||||
static void mld_sendpack(struct sk_buff *skb)
|
static void mld_sendpack(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ipv6hdr *pip6 = skb->nh.ipv6h;
|
struct ipv6hdr *pip6 = skb->nh.ipv6h;
|
||||||
|
@ -1350,7 +1365,7 @@ static void mld_sendpack(struct sk_buff *skb)
|
||||||
pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
|
pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
|
||||||
IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
|
IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
|
||||||
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
|
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
|
||||||
dev_queue_xmit);
|
mld_dev_queue_xmit);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS);
|
ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS);
|
||||||
IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS);
|
IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS);
|
||||||
|
@ -1656,12 +1671,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_reserve(skb, LL_RESERVED_SPACE(dev));
|
skb_reserve(skb, LL_RESERVED_SPACE(dev));
|
||||||
if (dev->hard_header) {
|
|
||||||
unsigned char ha[MAX_ADDR_LEN];
|
|
||||||
ndisc_mc_map(snd_addr, ha, dev, 1);
|
|
||||||
if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipv6_get_lladdr(dev, &addr_buf)) {
|
if (ipv6_get_lladdr(dev, &addr_buf)) {
|
||||||
/* <draft-ietf-magma-mld-source-05.txt>:
|
/* <draft-ietf-magma-mld-source-05.txt>:
|
||||||
|
@ -1689,7 +1698,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
|
||||||
idev = in6_dev_get(skb->dev);
|
idev = in6_dev_get(skb->dev);
|
||||||
|
|
||||||
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
|
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
|
||||||
dev_queue_xmit);
|
mld_dev_queue_xmit);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if (type == ICMPV6_MGM_REDUCTION)
|
if (type == ICMPV6_MGM_REDUCTION)
|
||||||
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS);
|
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS);
|
||||||
|
@ -1703,10 +1712,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
|
||||||
if (likely(idev != NULL))
|
if (likely(idev != NULL))
|
||||||
in6_dev_put(idev);
|
in6_dev_put(idev);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
out:
|
|
||||||
IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
|
|
||||||
kfree_skb(skb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
|
static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
|
||||||
|
|
Loading…
Reference in New Issue