aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/mcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r--net/ipv6/mcast.c272
1 files changed, 173 insertions, 99 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index ab228d1ea114..54f91efdae58 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -59,6 +59,7 @@
59#include <net/ndisc.h> 59#include <net/ndisc.h>
60#include <net/addrconf.h> 60#include <net/addrconf.h>
61#include <net/ip6_route.h> 61#include <net/ip6_route.h>
62#include <net/inet_common.h>
62 63
63#include <net/ip6_checksum.h> 64#include <net/ip6_checksum.h>
64 65
@@ -126,10 +127,6 @@ static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
126/* Big mc list lock for all the sockets */ 127/* Big mc list lock for all the sockets */
127static DEFINE_RWLOCK(ipv6_sk_mc_lock); 128static DEFINE_RWLOCK(ipv6_sk_mc_lock);
128 129
129static struct socket *igmp6_socket;
130
131int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr);
132
133static void igmp6_join_group(struct ifmcaddr6 *ma); 130static void igmp6_join_group(struct ifmcaddr6 *ma);
134static void igmp6_leave_group(struct ifmcaddr6 *ma); 131static void igmp6_leave_group(struct ifmcaddr6 *ma);
135static void igmp6_timer_handler(unsigned long data); 132static void igmp6_timer_handler(unsigned long data);
@@ -178,11 +175,12 @@ int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
178 * socket join on multicast group 175 * socket join on multicast group
179 */ 176 */
180 177
181int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) 178int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
182{ 179{
183 struct net_device *dev = NULL; 180 struct net_device *dev = NULL;
184 struct ipv6_mc_socklist *mc_lst; 181 struct ipv6_mc_socklist *mc_lst;
185 struct ipv6_pinfo *np = inet6_sk(sk); 182 struct ipv6_pinfo *np = inet6_sk(sk);
183 struct net *net = sock_net(sk);
186 int err; 184 int err;
187 185
188 if (!ipv6_addr_is_multicast(addr)) 186 if (!ipv6_addr_is_multicast(addr))
@@ -208,14 +206,14 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr)
208 206
209 if (ifindex == 0) { 207 if (ifindex == 0) {
210 struct rt6_info *rt; 208 struct rt6_info *rt;
211 rt = rt6_lookup(addr, NULL, 0, 0); 209 rt = rt6_lookup(net, addr, NULL, 0, 0);
212 if (rt) { 210 if (rt) {
213 dev = rt->rt6i_dev; 211 dev = rt->rt6i_dev;
214 dev_hold(dev); 212 dev_hold(dev);
215 dst_release(&rt->u.dst); 213 dst_release(&rt->u.dst);
216 } 214 }
217 } else 215 } else
218 dev = dev_get_by_index(&init_net, ifindex); 216 dev = dev_get_by_index(net, ifindex);
219 217
220 if (dev == NULL) { 218 if (dev == NULL) {
221 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); 219 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
@@ -252,10 +250,11 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr)
252/* 250/*
253 * socket leave on multicast group 251 * socket leave on multicast group
254 */ 252 */
255int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr) 253int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
256{ 254{
257 struct ipv6_pinfo *np = inet6_sk(sk); 255 struct ipv6_pinfo *np = inet6_sk(sk);
258 struct ipv6_mc_socklist *mc_lst, **lnk; 256 struct ipv6_mc_socklist *mc_lst, **lnk;
257 struct net *net = sock_net(sk);
259 258
260 write_lock_bh(&ipv6_sk_mc_lock); 259 write_lock_bh(&ipv6_sk_mc_lock);
261 for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = &mc_lst->next) { 260 for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = &mc_lst->next) {
@@ -266,7 +265,8 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr)
266 *lnk = mc_lst->next; 265 *lnk = mc_lst->next;
267 write_unlock_bh(&ipv6_sk_mc_lock); 266 write_unlock_bh(&ipv6_sk_mc_lock);
268 267
269 if ((dev = dev_get_by_index(&init_net, mc_lst->ifindex)) != NULL) { 268 dev = dev_get_by_index(net, mc_lst->ifindex);
269 if (dev != NULL) {
270 struct inet6_dev *idev = in6_dev_get(dev); 270 struct inet6_dev *idev = in6_dev_get(dev);
271 271
272 (void) ip6_mc_leave_src(sk, mc_lst, idev); 272 (void) ip6_mc_leave_src(sk, mc_lst, idev);
@@ -286,7 +286,9 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr)
286 return -EADDRNOTAVAIL; 286 return -EADDRNOTAVAIL;
287} 287}
288 288
289static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex) 289static struct inet6_dev *ip6_mc_find_dev(struct net *net,
290 struct in6_addr *group,
291 int ifindex)
290{ 292{
291 struct net_device *dev = NULL; 293 struct net_device *dev = NULL;
292 struct inet6_dev *idev = NULL; 294 struct inet6_dev *idev = NULL;
@@ -294,14 +296,14 @@ static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex)
294 if (ifindex == 0) { 296 if (ifindex == 0) {
295 struct rt6_info *rt; 297 struct rt6_info *rt;
296 298
297 rt = rt6_lookup(group, NULL, 0, 0); 299 rt = rt6_lookup(net, group, NULL, 0, 0);
298 if (rt) { 300 if (rt) {
299 dev = rt->rt6i_dev; 301 dev = rt->rt6i_dev;
300 dev_hold(dev); 302 dev_hold(dev);
301 dst_release(&rt->u.dst); 303 dst_release(&rt->u.dst);
302 } 304 }
303 } else 305 } else
304 dev = dev_get_by_index(&init_net, ifindex); 306 dev = dev_get_by_index(net, ifindex);
305 307
306 if (!dev) 308 if (!dev)
307 return NULL; 309 return NULL;
@@ -324,6 +326,7 @@ void ipv6_sock_mc_close(struct sock *sk)
324{ 326{
325 struct ipv6_pinfo *np = inet6_sk(sk); 327 struct ipv6_pinfo *np = inet6_sk(sk);
326 struct ipv6_mc_socklist *mc_lst; 328 struct ipv6_mc_socklist *mc_lst;
329 struct net *net = sock_net(sk);
327 330
328 write_lock_bh(&ipv6_sk_mc_lock); 331 write_lock_bh(&ipv6_sk_mc_lock);
329 while ((mc_lst = np->ipv6_mc_list) != NULL) { 332 while ((mc_lst = np->ipv6_mc_list) != NULL) {
@@ -332,7 +335,7 @@ void ipv6_sock_mc_close(struct sock *sk)
332 np->ipv6_mc_list = mc_lst->next; 335 np->ipv6_mc_list = mc_lst->next;
333 write_unlock_bh(&ipv6_sk_mc_lock); 336 write_unlock_bh(&ipv6_sk_mc_lock);
334 337
335 dev = dev_get_by_index(&init_net, mc_lst->ifindex); 338 dev = dev_get_by_index(net, mc_lst->ifindex);
336 if (dev) { 339 if (dev) {
337 struct inet6_dev *idev = in6_dev_get(dev); 340 struct inet6_dev *idev = in6_dev_get(dev);
338 341
@@ -361,6 +364,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
361 struct inet6_dev *idev; 364 struct inet6_dev *idev;
362 struct ipv6_pinfo *inet6 = inet6_sk(sk); 365 struct ipv6_pinfo *inet6 = inet6_sk(sk);
363 struct ip6_sf_socklist *psl; 366 struct ip6_sf_socklist *psl;
367 struct net *net = sock_net(sk);
364 int i, j, rv; 368 int i, j, rv;
365 int leavegroup = 0; 369 int leavegroup = 0;
366 int pmclocked = 0; 370 int pmclocked = 0;
@@ -376,7 +380,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
376 if (!ipv6_addr_is_multicast(group)) 380 if (!ipv6_addr_is_multicast(group))
377 return -EINVAL; 381 return -EINVAL;
378 382
379 idev = ip6_mc_find_dev(group, pgsr->gsr_interface); 383 idev = ip6_mc_find_dev(net, group, pgsr->gsr_interface);
380 if (!idev) 384 if (!idev)
381 return -ENODEV; 385 return -ENODEV;
382 dev = idev->dev; 386 dev = idev->dev;
@@ -500,6 +504,7 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
500 struct inet6_dev *idev; 504 struct inet6_dev *idev;
501 struct ipv6_pinfo *inet6 = inet6_sk(sk); 505 struct ipv6_pinfo *inet6 = inet6_sk(sk);
502 struct ip6_sf_socklist *newpsl, *psl; 506 struct ip6_sf_socklist *newpsl, *psl;
507 struct net *net = sock_net(sk);
503 int leavegroup = 0; 508 int leavegroup = 0;
504 int i, err; 509 int i, err;
505 510
@@ -511,7 +516,7 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
511 gsf->gf_fmode != MCAST_EXCLUDE) 516 gsf->gf_fmode != MCAST_EXCLUDE)
512 return -EINVAL; 517 return -EINVAL;
513 518
514 idev = ip6_mc_find_dev(group, gsf->gf_interface); 519 idev = ip6_mc_find_dev(net, group, gsf->gf_interface);
515 520
516 if (!idev) 521 if (!idev)
517 return -ENODEV; 522 return -ENODEV;
@@ -592,13 +597,14 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
592 struct net_device *dev; 597 struct net_device *dev;
593 struct ipv6_pinfo *inet6 = inet6_sk(sk); 598 struct ipv6_pinfo *inet6 = inet6_sk(sk);
594 struct ip6_sf_socklist *psl; 599 struct ip6_sf_socklist *psl;
600 struct net *net = sock_net(sk);
595 601
596 group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr; 602 group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr;
597 603
598 if (!ipv6_addr_is_multicast(group)) 604 if (!ipv6_addr_is_multicast(group))
599 return -EINVAL; 605 return -EINVAL;
600 606
601 idev = ip6_mc_find_dev(group, gsf->gf_interface); 607 idev = ip6_mc_find_dev(net, group, gsf->gf_interface);
602 608
603 if (!idev) 609 if (!idev)
604 return -ENODEV; 610 return -ENODEV;
@@ -656,8 +662,8 @@ done:
656 return err; 662 return err;
657} 663}
658 664
659int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr, 665int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
660 struct in6_addr *src_addr) 666 const struct in6_addr *src_addr)
661{ 667{
662 struct ipv6_pinfo *np = inet6_sk(sk); 668 struct ipv6_pinfo *np = inet6_sk(sk);
663 struct ipv6_mc_socklist *mc; 669 struct ipv6_mc_socklist *mc;
@@ -863,7 +869,7 @@ static void mld_clear_delrec(struct inet6_dev *idev)
863/* 869/*
864 * device multicast group inc (add if not found) 870 * device multicast group inc (add if not found)
865 */ 871 */
866int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr) 872int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr)
867{ 873{
868 struct ifmcaddr6 *mc; 874 struct ifmcaddr6 *mc;
869 struct inet6_dev *idev; 875 struct inet6_dev *idev;
@@ -934,7 +940,7 @@ int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr)
934/* 940/*
935 * device multicast group del 941 * device multicast group del
936 */ 942 */
937int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr) 943int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr)
938{ 944{
939 struct ifmcaddr6 *ma, **map; 945 struct ifmcaddr6 *ma, **map;
940 946
@@ -959,7 +965,7 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr)
959 return -ENOENT; 965 return -ENOENT;
960} 966}
961 967
962int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr) 968int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
963{ 969{
964 struct inet6_dev *idev = in6_dev_get(dev); 970 struct inet6_dev *idev = in6_dev_get(dev);
965 int err; 971 int err;
@@ -1004,8 +1010,8 @@ int ipv6_is_mld(struct sk_buff *skb, int nexthdr)
1004/* 1010/*
1005 * check if the interface/address pair is valid 1011 * check if the interface/address pair is valid
1006 */ 1012 */
1007int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group, 1013int ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,
1008 struct in6_addr *src_addr) 1014 const struct in6_addr *src_addr)
1009{ 1015{
1010 struct inet6_dev *idev; 1016 struct inet6_dev *idev;
1011 struct ifmcaddr6 *mc; 1017 struct ifmcaddr6 *mc;
@@ -1393,10 +1399,12 @@ mld_scount(struct ifmcaddr6 *pmc, int type, int gdeleted, int sdeleted)
1393 1399
1394static struct sk_buff *mld_newpack(struct net_device *dev, int size) 1400static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1395{ 1401{
1396 struct sock *sk = igmp6_socket->sk; 1402 struct net *net = dev_net(dev);
1403 struct sock *sk = net->ipv6.igmp_sk;
1397 struct sk_buff *skb; 1404 struct sk_buff *skb;
1398 struct mld2_report *pmr; 1405 struct mld2_report *pmr;
1399 struct in6_addr addr_buf; 1406 struct in6_addr addr_buf;
1407 const struct in6_addr *saddr;
1400 int err; 1408 int err;
1401 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1409 u8 ra[8] = { IPPROTO_ICMPV6, 0,
1402 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1410 IPV6_TLV_ROUTERALERT, 2, 0, 0,
@@ -1415,10 +1423,11 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1415 * use unspecified address as the source address 1423 * use unspecified address as the source address
1416 * when a valid link-local address is not available. 1424 * when a valid link-local address is not available.
1417 */ 1425 */
1418 memset(&addr_buf, 0, sizeof(addr_buf)); 1426 saddr = &in6addr_any;
1419 } 1427 } else
1428 saddr = &addr_buf;
1420 1429
1421 ip6_nd_hdr(sk, skb, dev, &addr_buf, &mld2_all_mcr, NEXTHDR_HOP, 0); 1430 ip6_nd_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0);
1422 1431
1423 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); 1432 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
1424 1433
@@ -1433,25 +1442,6 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1433 return skb; 1442 return skb;
1434} 1443}
1435 1444
1436static inline int mld_dev_queue_xmit2(struct sk_buff *skb)
1437{
1438 struct net_device *dev = skb->dev;
1439 unsigned char ha[MAX_ADDR_LEN];
1440
1441 ndisc_mc_map(&ipv6_hdr(skb)->daddr, ha, dev, 1);
1442 if (dev_hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len) < 0) {
1443 kfree_skb(skb);
1444 return -EINVAL;
1445 }
1446 return dev_queue_xmit(skb);
1447}
1448
1449static inline int mld_dev_queue_xmit(struct sk_buff *skb)
1450{
1451 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
1452 mld_dev_queue_xmit2);
1453}
1454
1455static void mld_sendpack(struct sk_buff *skb) 1445static void mld_sendpack(struct sk_buff *skb)
1456{ 1446{
1457 struct ipv6hdr *pip6 = ipv6_hdr(skb); 1447 struct ipv6hdr *pip6 = ipv6_hdr(skb);
@@ -1459,7 +1449,9 @@ static void mld_sendpack(struct sk_buff *skb)
1459 (struct mld2_report *)skb_transport_header(skb); 1449 (struct mld2_report *)skb_transport_header(skb);
1460 int payload_len, mldlen; 1450 int payload_len, mldlen;
1461 struct inet6_dev *idev = in6_dev_get(skb->dev); 1451 struct inet6_dev *idev = in6_dev_get(skb->dev);
1452 struct net *net = dev_net(skb->dev);
1462 int err; 1453 int err;
1454 struct flowi fl;
1463 1455
1464 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); 1456 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
1465 payload_len = (skb->tail - skb->network_header) - sizeof(*pip6); 1457 payload_len = (skb->tail - skb->network_header) - sizeof(*pip6);
@@ -1469,8 +1461,25 @@ static void mld_sendpack(struct sk_buff *skb)
1469 pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, 1461 pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
1470 IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb), 1462 IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb),
1471 mldlen, 0)); 1463 mldlen, 0));
1464
1465 skb->dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
1466
1467 if (!skb->dst) {
1468 err = -ENOMEM;
1469 goto err_out;
1470 }
1471
1472 icmpv6_flow_init(net->ipv6.igmp_sk, &fl, ICMPV6_MLD2_REPORT,
1473 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
1474 skb->dev->ifindex);
1475
1476 err = xfrm_lookup(&skb->dst, &fl, NULL, 0);
1477 if (err)
1478 goto err_out;
1479
1472 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, 1480 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
1473 mld_dev_queue_xmit); 1481 dst_output);
1482out:
1474 if (!err) { 1483 if (!err) {
1475 ICMP6MSGOUT_INC_STATS_BH(idev, ICMPV6_MLD2_REPORT); 1484 ICMP6MSGOUT_INC_STATS_BH(idev, ICMPV6_MLD2_REPORT);
1476 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); 1485 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
@@ -1480,6 +1489,11 @@ static void mld_sendpack(struct sk_buff *skb)
1480 1489
1481 if (likely(idev != NULL)) 1490 if (likely(idev != NULL))
1482 in6_dev_put(idev); 1491 in6_dev_put(idev);
1492 return;
1493
1494err_out:
1495 kfree_skb(skb);
1496 goto out;
1483} 1497}
1484 1498
1485static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel) 1499static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel)
@@ -1749,28 +1763,28 @@ static void mld_send_cr(struct inet6_dev *idev)
1749 1763
1750static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) 1764static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1751{ 1765{
1752 struct sock *sk = igmp6_socket->sk; 1766 struct net *net = dev_net(dev);
1767 struct sock *sk = net->ipv6.igmp_sk;
1753 struct inet6_dev *idev; 1768 struct inet6_dev *idev;
1754 struct sk_buff *skb; 1769 struct sk_buff *skb;
1755 struct icmp6hdr *hdr; 1770 struct icmp6hdr *hdr;
1756 struct in6_addr *snd_addr; 1771 const struct in6_addr *snd_addr, *saddr;
1757 struct in6_addr *addrp; 1772 struct in6_addr *addrp;
1758 struct in6_addr addr_buf; 1773 struct in6_addr addr_buf;
1759 struct in6_addr all_routers;
1760 int err, len, payload_len, full_len; 1774 int err, len, payload_len, full_len;
1761 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1775 u8 ra[8] = { IPPROTO_ICMPV6, 0,
1762 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1776 IPV6_TLV_ROUTERALERT, 2, 0, 0,
1763 IPV6_TLV_PADN, 0 }; 1777 IPV6_TLV_PADN, 0 };
1778 struct flowi fl;
1764 1779
1765 rcu_read_lock(); 1780 rcu_read_lock();
1766 IP6_INC_STATS(__in6_dev_get(dev), 1781 IP6_INC_STATS(__in6_dev_get(dev),
1767 IPSTATS_MIB_OUTREQUESTS); 1782 IPSTATS_MIB_OUTREQUESTS);
1768 rcu_read_unlock(); 1783 rcu_read_unlock();
1769 snd_addr = addr; 1784 if (type == ICMPV6_MGM_REDUCTION)
1770 if (type == ICMPV6_MGM_REDUCTION) { 1785 snd_addr = &in6addr_linklocal_allrouters;
1771 snd_addr = &all_routers; 1786 else
1772 ipv6_addr_all_routers(&all_routers); 1787 snd_addr = addr;
1773 }
1774 1788
1775 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); 1789 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
1776 payload_len = len + sizeof(ra); 1790 payload_len = len + sizeof(ra);
@@ -1793,10 +1807,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1793 * use unspecified address as the source address 1807 * use unspecified address as the source address
1794 * when a valid link-local address is not available. 1808 * when a valid link-local address is not available.
1795 */ 1809 */
1796 memset(&addr_buf, 0, sizeof(addr_buf)); 1810 saddr = &in6addr_any;
1797 } 1811 } else
1812 saddr = &addr_buf;
1798 1813
1799 ip6_nd_hdr(sk, skb, dev, &addr_buf, snd_addr, NEXTHDR_HOP, payload_len); 1814 ip6_nd_hdr(sk, skb, dev, saddr, snd_addr, NEXTHDR_HOP, payload_len);
1800 1815
1801 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); 1816 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
1802 1817
@@ -1807,14 +1822,29 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1807 addrp = (struct in6_addr *) skb_put(skb, sizeof(struct in6_addr)); 1822 addrp = (struct in6_addr *) skb_put(skb, sizeof(struct in6_addr));
1808 ipv6_addr_copy(addrp, addr); 1823 ipv6_addr_copy(addrp, addr);
1809 1824
1810 hdr->icmp6_cksum = csum_ipv6_magic(&addr_buf, snd_addr, len, 1825 hdr->icmp6_cksum = csum_ipv6_magic(saddr, snd_addr, len,
1811 IPPROTO_ICMPV6, 1826 IPPROTO_ICMPV6,
1812 csum_partial((__u8 *) hdr, len, 0)); 1827 csum_partial((__u8 *) hdr, len, 0));
1813 1828
1814 idev = in6_dev_get(skb->dev); 1829 idev = in6_dev_get(skb->dev);
1815 1830
1831 skb->dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
1832 if (!skb->dst) {
1833 err = -ENOMEM;
1834 goto err_out;
1835 }
1836
1837 icmpv6_flow_init(sk, &fl, type,
1838 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
1839 skb->dev->ifindex);
1840
1841 err = xfrm_lookup(&skb->dst, &fl, NULL, 0);
1842 if (err)
1843 goto err_out;
1844
1816 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, 1845 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
1817 mld_dev_queue_xmit); 1846 dst_output);
1847out:
1818 if (!err) { 1848 if (!err) {
1819 ICMP6MSGOUT_INC_STATS(idev, type); 1849 ICMP6MSGOUT_INC_STATS(idev, type);
1820 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); 1850 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
@@ -1825,6 +1855,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1825 if (likely(idev != NULL)) 1855 if (likely(idev != NULL))
1826 in6_dev_put(idev); 1856 in6_dev_put(idev);
1827 return; 1857 return;
1858
1859err_out:
1860 kfree_skb(skb);
1861 goto out;
1828} 1862}
1829 1863
1830static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, 1864static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
@@ -2276,24 +2310,19 @@ void ipv6_mc_init_dev(struct inet6_dev *idev)
2276void ipv6_mc_destroy_dev(struct inet6_dev *idev) 2310void ipv6_mc_destroy_dev(struct inet6_dev *idev)
2277{ 2311{
2278 struct ifmcaddr6 *i; 2312 struct ifmcaddr6 *i;
2279 struct in6_addr maddr;
2280 2313
2281 /* Deactivate timers */ 2314 /* Deactivate timers */
2282 ipv6_mc_down(idev); 2315 ipv6_mc_down(idev);
2283 2316
2284 /* Delete all-nodes address. */ 2317 /* Delete all-nodes address. */
2285 ipv6_addr_all_nodes(&maddr);
2286
2287 /* We cannot call ipv6_dev_mc_dec() directly, our caller in 2318 /* We cannot call ipv6_dev_mc_dec() directly, our caller in
2288 * addrconf.c has NULL'd out dev->ip6_ptr so in6_dev_get() will 2319 * addrconf.c has NULL'd out dev->ip6_ptr so in6_dev_get() will
2289 * fail. 2320 * fail.
2290 */ 2321 */
2291 __ipv6_dev_mc_dec(idev, &maddr); 2322 __ipv6_dev_mc_dec(idev, &in6addr_linklocal_allnodes);
2292 2323
2293 if (idev->cnf.forwarding) { 2324 if (idev->cnf.forwarding)
2294 ipv6_addr_all_routers(&maddr); 2325 __ipv6_dev_mc_dec(idev, &in6addr_linklocal_allrouters);
2295 __ipv6_dev_mc_dec(idev, &maddr);
2296 }
2297 2326
2298 write_lock_bh(&idev->lock); 2327 write_lock_bh(&idev->lock);
2299 while ((i = idev->mc_list) != NULL) { 2328 while ((i = idev->mc_list) != NULL) {
@@ -2310,6 +2339,7 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev)
2310 2339
2311#ifdef CONFIG_PROC_FS 2340#ifdef CONFIG_PROC_FS
2312struct igmp6_mc_iter_state { 2341struct igmp6_mc_iter_state {
2342 struct seq_net_private p;
2313 struct net_device *dev; 2343 struct net_device *dev;
2314 struct inet6_dev *idev; 2344 struct inet6_dev *idev;
2315}; 2345};
@@ -2320,9 +2350,10 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
2320{ 2350{
2321 struct ifmcaddr6 *im = NULL; 2351 struct ifmcaddr6 *im = NULL;
2322 struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq); 2352 struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
2353 struct net *net = seq_file_net(seq);
2323 2354
2324 state->idev = NULL; 2355 state->idev = NULL;
2325 for_each_netdev(&init_net, state->dev) { 2356 for_each_netdev(net, state->dev) {
2326 struct inet6_dev *idev; 2357 struct inet6_dev *idev;
2327 idev = in6_dev_get(state->dev); 2358 idev = in6_dev_get(state->dev);
2328 if (!idev) 2359 if (!idev)
@@ -2424,8 +2455,8 @@ static const struct seq_operations igmp6_mc_seq_ops = {
2424 2455
2425static int igmp6_mc_seq_open(struct inode *inode, struct file *file) 2456static int igmp6_mc_seq_open(struct inode *inode, struct file *file)
2426{ 2457{
2427 return seq_open_private(file, &igmp6_mc_seq_ops, 2458 return seq_open_net(inode, file, &igmp6_mc_seq_ops,
2428 sizeof(struct igmp6_mc_iter_state)); 2459 sizeof(struct igmp6_mc_iter_state));
2429} 2460}
2430 2461
2431static const struct file_operations igmp6_mc_seq_fops = { 2462static const struct file_operations igmp6_mc_seq_fops = {
@@ -2433,10 +2464,11 @@ static const struct file_operations igmp6_mc_seq_fops = {
2433 .open = igmp6_mc_seq_open, 2464 .open = igmp6_mc_seq_open,
2434 .read = seq_read, 2465 .read = seq_read,
2435 .llseek = seq_lseek, 2466 .llseek = seq_lseek,
2436 .release = seq_release_private, 2467 .release = seq_release_net,
2437}; 2468};
2438 2469
2439struct igmp6_mcf_iter_state { 2470struct igmp6_mcf_iter_state {
2471 struct seq_net_private p;
2440 struct net_device *dev; 2472 struct net_device *dev;
2441 struct inet6_dev *idev; 2473 struct inet6_dev *idev;
2442 struct ifmcaddr6 *im; 2474 struct ifmcaddr6 *im;
@@ -2449,10 +2481,11 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq)
2449 struct ip6_sf_list *psf = NULL; 2481 struct ip6_sf_list *psf = NULL;
2450 struct ifmcaddr6 *im = NULL; 2482 struct ifmcaddr6 *im = NULL;
2451 struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq); 2483 struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
2484 struct net *net = seq_file_net(seq);
2452 2485
2453 state->idev = NULL; 2486 state->idev = NULL;
2454 state->im = NULL; 2487 state->im = NULL;
2455 for_each_netdev(&init_net, state->dev) { 2488 for_each_netdev(net, state->dev) {
2456 struct inet6_dev *idev; 2489 struct inet6_dev *idev;
2457 idev = in6_dev_get(state->dev); 2490 idev = in6_dev_get(state->dev);
2458 if (unlikely(idev == NULL)) 2491 if (unlikely(idev == NULL))
@@ -2584,8 +2617,8 @@ static const struct seq_operations igmp6_mcf_seq_ops = {
2584 2617
2585static int igmp6_mcf_seq_open(struct inode *inode, struct file *file) 2618static int igmp6_mcf_seq_open(struct inode *inode, struct file *file)
2586{ 2619{
2587 return seq_open_private(file, &igmp6_mcf_seq_ops, 2620 return seq_open_net(inode, file, &igmp6_mcf_seq_ops,
2588 sizeof(struct igmp6_mcf_iter_state)); 2621 sizeof(struct igmp6_mcf_iter_state));
2589} 2622}
2590 2623
2591static const struct file_operations igmp6_mcf_seq_fops = { 2624static const struct file_operations igmp6_mcf_seq_fops = {
@@ -2593,47 +2626,88 @@ static const struct file_operations igmp6_mcf_seq_fops = {
2593 .open = igmp6_mcf_seq_open, 2626 .open = igmp6_mcf_seq_open,
2594 .read = seq_read, 2627 .read = seq_read,
2595 .llseek = seq_lseek, 2628 .llseek = seq_lseek,
2596 .release = seq_release_private, 2629 .release = seq_release_net,
2597}; 2630};
2631
2632static int igmp6_proc_init(struct net *net)
2633{
2634 int err;
2635
2636 err = -ENOMEM;
2637 if (!proc_net_fops_create(net, "igmp6", S_IRUGO, &igmp6_mc_seq_fops))
2638 goto out;
2639 if (!proc_net_fops_create(net, "mcfilter6", S_IRUGO,
2640 &igmp6_mcf_seq_fops))
2641 goto out_proc_net_igmp6;
2642
2643 err = 0;
2644out:
2645 return err;
2646
2647out_proc_net_igmp6:
2648 proc_net_remove(net, "igmp6");
2649 goto out;
2650}
2651
2652static void igmp6_proc_exit(struct net *net)
2653{
2654 proc_net_remove(net, "mcfilter6");
2655 proc_net_remove(net, "igmp6");
2656}
2657#else
2658static int igmp6_proc_init(struct net *net)
2659{
2660 return 0;
2661}
2662static void igmp6_proc_exit(struct net *net)
2663{
2664 ;
2665}
2598#endif 2666#endif
2599 2667
2600int __init igmp6_init(struct net_proto_family *ops) 2668static int igmp6_net_init(struct net *net)
2601{ 2669{
2602 struct ipv6_pinfo *np;
2603 struct sock *sk;
2604 int err; 2670 int err;
2605 2671
2606 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &igmp6_socket); 2672 err = inet_ctl_sock_create(&net->ipv6.igmp_sk, PF_INET6,
2673 SOCK_RAW, IPPROTO_ICMPV6, net);
2607 if (err < 0) { 2674 if (err < 0) {
2608 printk(KERN_ERR 2675 printk(KERN_ERR
2609 "Failed to initialize the IGMP6 control socket (err %d).\n", 2676 "Failed to initialize the IGMP6 control socket (err %d).\n",
2610 err); 2677 err);
2611 igmp6_socket = NULL; /* For safety. */ 2678 goto out;
2612 return err;
2613 } 2679 }
2614 2680
2615 sk = igmp6_socket->sk; 2681 inet6_sk(net->ipv6.igmp_sk)->hop_limit = 1;
2616 sk->sk_allocation = GFP_ATOMIC;
2617 sk->sk_prot->unhash(sk);
2618 2682
2619 np = inet6_sk(sk); 2683 err = igmp6_proc_init(net);
2620 np->hop_limit = 1; 2684 if (err)
2685 goto out_sock_create;
2686out:
2687 return err;
2621 2688
2622#ifdef CONFIG_PROC_FS 2689out_sock_create:
2623 proc_net_fops_create(&init_net, "igmp6", S_IRUGO, &igmp6_mc_seq_fops); 2690 inet_ctl_sock_destroy(net->ipv6.igmp_sk);
2624 proc_net_fops_create(&init_net, "mcfilter6", S_IRUGO, &igmp6_mcf_seq_fops); 2691 goto out;
2625#endif 2692}
2626 2693
2627 return 0; 2694static void igmp6_net_exit(struct net *net)
2695{
2696 inet_ctl_sock_destroy(net->ipv6.igmp_sk);
2697 igmp6_proc_exit(net);
2628} 2698}
2629 2699
2630void igmp6_cleanup(void) 2700static struct pernet_operations igmp6_net_ops = {
2701 .init = igmp6_net_init,
2702 .exit = igmp6_net_exit,
2703};
2704
2705int __init igmp6_init(void)
2631{ 2706{
2632 sock_release(igmp6_socket); 2707 return register_pernet_subsys(&igmp6_net_ops);
2633 igmp6_socket = NULL; /* for safety */ 2708}
2634 2709
2635#ifdef CONFIG_PROC_FS 2710void igmp6_cleanup(void)
2636 proc_net_remove(&init_net, "mcfilter6"); 2711{
2637 proc_net_remove(&init_net, "igmp6"); 2712 unregister_pernet_subsys(&igmp6_net_ops);
2638#endif
2639} 2713}