aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/mcast.c47
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
1327static 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
1345static 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
1336static void mld_sendpack(struct sk_buff *skb) 1351static 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
1707out:
1708 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
1709 kfree_skb(skb);
1710} 1715}
1711 1716
1712static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, 1717static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,