diff options
| -rw-r--r-- | net/ipv6/mcast.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index c0ca92e8230b..562fcd14fdea 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
| @@ -1301,15 +1301,6 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) | |||
| 1301 | return NULL; | 1301 | return NULL; |
| 1302 | 1302 | ||
| 1303 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1303 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
| 1304 | if (dev->hard_header) { | ||
| 1305 | unsigned char ha[MAX_ADDR_LEN]; | ||
| 1306 | |||
| 1307 | ndisc_mc_map(&mld2_all_mcr, ha, dev, 1); | ||
| 1308 | if (dev->hard_header(skb, dev, ETH_P_IPV6,ha,NULL,size) < 0) { | ||
| 1309 | kfree_skb(skb); | ||
| 1310 | return NULL; | ||
| 1311 | } | ||
| 1312 | } | ||
| 1313 | 1304 | ||
| 1314 | if (ipv6_get_lladdr(dev, &addr_buf)) { | 1305 | if (ipv6_get_lladdr(dev, &addr_buf)) { |
| 1315 | /* <draft-ietf-magma-mld-source-05.txt>: | 1306 | /* <draft-ietf-magma-mld-source-05.txt>: |
| @@ -1333,6 +1324,30 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) | |||
| 1333 | return skb; | 1324 | return skb; |
| 1334 | } | 1325 | } |
| 1335 | 1326 | ||
| 1327 | static inline int mld_dev_queue_xmit2(struct sk_buff *skb) | ||
| 1328 | { | ||
| 1329 | struct net_device *dev = skb->dev; | ||
| 1330 | |||
| 1331 | if (dev->hard_header) { | ||
| 1332 | unsigned char ha[MAX_ADDR_LEN]; | ||
| 1333 | int err; | ||
| 1334 | |||
| 1335 | ndisc_mc_map(&skb->nh.ipv6h->daddr, ha, dev, 1); | ||
| 1336 | err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len); | ||
| 1337 | if (err < 0) { | ||
| 1338 | kfree_skb(skb); | ||
| 1339 | return err; | ||
| 1340 | } | ||
| 1341 | } | ||
| 1342 | return dev_queue_xmit(skb); | ||
| 1343 | } | ||
| 1344 | |||
| 1345 | static inline int mld_dev_queue_xmit(struct sk_buff *skb) | ||
| 1346 | { | ||
| 1347 | return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dev, | ||
| 1348 | mld_dev_queue_xmit2); | ||
| 1349 | } | ||
| 1350 | |||
| 1336 | static void mld_sendpack(struct sk_buff *skb) | 1351 | static void mld_sendpack(struct sk_buff *skb) |
| 1337 | { | 1352 | { |
| 1338 | struct ipv6hdr *pip6 = skb->nh.ipv6h; | 1353 | struct ipv6hdr *pip6 = skb->nh.ipv6h; |
| @@ -1350,7 +1365,7 @@ static void mld_sendpack(struct sk_buff *skb) | |||
| 1350 | pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, | 1365 | pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, |
| 1351 | IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0)); | 1366 | IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0)); |
| 1352 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, | 1367 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, |
| 1353 | dev_queue_xmit); | 1368 | mld_dev_queue_xmit); |
| 1354 | if (!err) { | 1369 | if (!err) { |
| 1355 | ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS); | 1370 | ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS); |
| 1356 | IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); | 1371 | IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); |
| @@ -1656,12 +1671,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
| 1656 | } | 1671 | } |
| 1657 | 1672 | ||
| 1658 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1673 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
| 1659 | if (dev->hard_header) { | ||
| 1660 | unsigned char ha[MAX_ADDR_LEN]; | ||
| 1661 | ndisc_mc_map(snd_addr, ha, dev, 1); | ||
| 1662 | if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0) | ||
| 1663 | goto out; | ||
| 1664 | } | ||
| 1665 | 1674 | ||
| 1666 | if (ipv6_get_lladdr(dev, &addr_buf)) { | 1675 | if (ipv6_get_lladdr(dev, &addr_buf)) { |
| 1667 | /* <draft-ietf-magma-mld-source-05.txt>: | 1676 | /* <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) | |||
| 1689 | idev = in6_dev_get(skb->dev); | 1698 | idev = in6_dev_get(skb->dev); |
| 1690 | 1699 | ||
| 1691 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, | 1700 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, |
| 1692 | dev_queue_xmit); | 1701 | mld_dev_queue_xmit); |
| 1693 | if (!err) { | 1702 | if (!err) { |
| 1694 | if (type == ICMPV6_MGM_REDUCTION) | 1703 | if (type == ICMPV6_MGM_REDUCTION) |
| 1695 | ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS); | 1704 | 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) | |||
| 1703 | if (likely(idev != NULL)) | 1712 | if (likely(idev != NULL)) |
| 1704 | in6_dev_put(idev); | 1713 | in6_dev_put(idev); |
| 1705 | return; | 1714 | return; |
| 1706 | |||
| 1707 | out: | ||
| 1708 | IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | ||
| 1709 | kfree_skb(skb); | ||
| 1710 | } | 1715 | } |
| 1711 | 1716 | ||
| 1712 | static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, | 1717 | static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, |
