struct net_device *dev = (struct net_device *)if6->idev->dev;
        struct ipvl_dev *ipvlan = netdev_priv(dev);
 
-       /* FIXME IPv6 autoconf calls us from bh without RTNL */
-       if (in_softirq())
-               return NOTIFY_DONE;
-
        if (!netif_is_ipvlan(dev))
                return NOTIFY_DONE;
 
 
        struct net *net = dev_net(idev->dev);
        struct inet6_ifaddr *ifa = NULL;
        struct rt6_info *rt = NULL;
-       struct in6_validator_info i6vi;
        int err = 0;
        int addr_type = ipv6_addr_type(addr);
 
                goto out;
        }
 
-       i6vi.i6vi_addr = *addr;
-       i6vi.i6vi_dev = idev;
-       err = inet6addr_validator_notifier_call_chain(NETDEV_UP, &i6vi);
-       err = notifier_to_errno(err);
-       if (err < 0)
-               goto out;
+       /* validator notifier needs to be blocking;
+        * do not call in atomic context
+        */
+       if (can_block) {
+               struct in6_validator_info i6vi = {
+                       .i6vi_addr = *addr,
+                       .i6vi_dev = idev,
+               };
+
+               err = inet6addr_validator_notifier_call_chain(NETDEV_UP, &i6vi);
+               err = notifier_to_errno(err);
+               if (err < 0)
+                       goto out;
+       }
 
        ifa = kzalloc(sizeof(*ifa), gfp_flags);
        if (!ifa) {
 
 EXPORT_SYMBOL(__ipv6_addr_type);
 
 static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
-static ATOMIC_NOTIFIER_HEAD(inet6addr_validator_chain);
+static BLOCKING_NOTIFIER_HEAD(inet6addr_validator_chain);
 
 int register_inet6addr_notifier(struct notifier_block *nb)
 {
 
 int register_inet6addr_validator_notifier(struct notifier_block *nb)
 {
-       return atomic_notifier_chain_register(&inet6addr_validator_chain, nb);
+       return blocking_notifier_chain_register(&inet6addr_validator_chain, nb);
 }
 EXPORT_SYMBOL(register_inet6addr_validator_notifier);
 
 int unregister_inet6addr_validator_notifier(struct notifier_block *nb)
 {
-       return atomic_notifier_chain_unregister(&inet6addr_validator_chain, nb);
+       return blocking_notifier_chain_unregister(&inet6addr_validator_chain,
+                                                 nb);
 }
 EXPORT_SYMBOL(unregister_inet6addr_validator_notifier);
 
 int inet6addr_validator_notifier_call_chain(unsigned long val, void *v)
 {
-       return atomic_notifier_call_chain(&inet6addr_validator_chain, val, v);
+       return blocking_notifier_call_chain(&inet6addr_validator_chain, val, v);
 }
 EXPORT_SYMBOL(inet6addr_validator_notifier_call_chain);