ipv6: addrconf: Avoid calling netdevice notifiers with RCU read-side lock
[pandora-kernel.git] / net / ipv6 / addrconf.c
index 36806de..aef80d7 100644 (file)
@@ -429,11 +429,15 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
        ndev->tstamp = jiffies;
        addrconf_sysctl_register(ndev);
        /* protected by rtnl_lock */
-       RCU_INIT_POINTER(dev->ip6_ptr, ndev);
+       rcu_assign_pointer(dev->ip6_ptr, ndev);
 
        /* Join all-node multicast group */
        ipv6_dev_mc_inc(dev, &in6addr_linklocal_allnodes);
 
+       /* Join all-router multicast group if forwarding is set */
+       if (ndev->cnf.forwarding && dev && (dev->flags & IFF_MULTICAST))
+               ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
+
        return ndev;
 }
 
@@ -489,8 +493,7 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
        struct net_device *dev;
        struct inet6_dev *idev;
 
-       rcu_read_lock();
-       for_each_netdev_rcu(net, dev) {
+       for_each_netdev(net, dev) {
                idev = __in6_dev_get(dev);
                if (idev) {
                        int changed = (!idev->cnf.forwarding) ^ (!newf);
@@ -499,7 +502,6 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
                                dev_forward_change(idev);
                }
        }
-       rcu_read_unlock();
 }
 
 static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)