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.c23
1 files changed, 8 insertions, 15 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 0a0132a1c443..c2dc2e2b6c07 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1766,10 +1766,9 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1766 struct inet6_dev *idev; 1766 struct inet6_dev *idev;
1767 struct sk_buff *skb; 1767 struct sk_buff *skb;
1768 struct icmp6hdr *hdr; 1768 struct icmp6hdr *hdr;
1769 struct in6_addr *snd_addr; 1769 const struct in6_addr *snd_addr;
1770 struct in6_addr *addrp; 1770 struct in6_addr *addrp;
1771 struct in6_addr addr_buf; 1771 struct in6_addr addr_buf;
1772 struct in6_addr all_routers;
1773 int err, len, payload_len, full_len; 1772 int err, len, payload_len, full_len;
1774 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1773 u8 ra[8] = { IPPROTO_ICMPV6, 0,
1775 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1774 IPV6_TLV_ROUTERALERT, 2, 0, 0,
@@ -1780,11 +1779,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1780 IP6_INC_STATS(__in6_dev_get(dev), 1779 IP6_INC_STATS(__in6_dev_get(dev),
1781 IPSTATS_MIB_OUTREQUESTS); 1780 IPSTATS_MIB_OUTREQUESTS);
1782 rcu_read_unlock(); 1781 rcu_read_unlock();
1783 snd_addr = addr; 1782 if (type == ICMPV6_MGM_REDUCTION)
1784 if (type == ICMPV6_MGM_REDUCTION) { 1783 snd_addr = &in6addr_linklocal_allrouters;
1785 snd_addr = &all_routers; 1784 else
1786 ipv6_addr_all_routers(&all_routers); 1785 snd_addr = addr;
1787 }
1788 1786
1789 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); 1787 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
1790 payload_len = len + sizeof(ra); 1788 payload_len = len + sizeof(ra);
@@ -2309,24 +2307,19 @@ void ipv6_mc_init_dev(struct inet6_dev *idev)
2309void ipv6_mc_destroy_dev(struct inet6_dev *idev) 2307void ipv6_mc_destroy_dev(struct inet6_dev *idev)
2310{ 2308{
2311 struct ifmcaddr6 *i; 2309 struct ifmcaddr6 *i;
2312 struct in6_addr maddr;
2313 2310
2314 /* Deactivate timers */ 2311 /* Deactivate timers */
2315 ipv6_mc_down(idev); 2312 ipv6_mc_down(idev);
2316 2313
2317 /* Delete all-nodes address. */ 2314 /* Delete all-nodes address. */
2318 ipv6_addr_all_nodes(&maddr);
2319
2320 /* We cannot call ipv6_dev_mc_dec() directly, our caller in 2315 /* We cannot call ipv6_dev_mc_dec() directly, our caller in
2321 * addrconf.c has NULL'd out dev->ip6_ptr so in6_dev_get() will 2316 * addrconf.c has NULL'd out dev->ip6_ptr so in6_dev_get() will
2322 * fail. 2317 * fail.
2323 */ 2318 */
2324 __ipv6_dev_mc_dec(idev, &maddr); 2319 __ipv6_dev_mc_dec(idev, &in6addr_linklocal_allnodes);
2325 2320
2326 if (idev->cnf.forwarding) { 2321 if (idev->cnf.forwarding)
2327 ipv6_addr_all_routers(&maddr); 2322 __ipv6_dev_mc_dec(idev, &in6addr_linklocal_allrouters);
2328 __ipv6_dev_mc_dec(idev, &maddr);
2329 }
2330 2323
2331 write_lock_bh(&idev->lock); 2324 write_lock_bh(&idev->lock);
2332 while ((i = idev->mc_list) != NULL) { 2325 while ((i = idev->mc_list) != NULL) {