diff options
Diffstat (limited to 'net/ipv6')
-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, |