diff options
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 20 | 
1 files changed, 20 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index c25d453b2803..9bb8f87c4cda 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1409,14 +1409,34 @@ EXPORT_SYMBOL(register_netdevice_notifier);   *	register_netdevice_notifier(). The notifier is unlinked into the   *	kernel structures and may then be reused. A negative errno code   *	is returned on a failure. + * + * 	After unregistering unregister and down device events are synthesized + *	for all devices on the device list to the removed notifier to remove + *	the need for special case cleanup code.   */  int unregister_netdevice_notifier(struct notifier_block *nb)  { +	struct net_device *dev; +	struct net *net;  	int err;  	rtnl_lock();  	err = raw_notifier_chain_unregister(&netdev_chain, nb); +	if (err) +		goto unlock; + +	for_each_net(net) { +		for_each_netdev(net, dev) { +			if (dev->flags & IFF_UP) { +				nb->notifier_call(nb, NETDEV_GOING_DOWN, dev); +				nb->notifier_call(nb, NETDEV_DOWN, dev); +			} +			nb->notifier_call(nb, NETDEV_UNREGISTER, dev); +			nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev); +		} +	} +unlock:  	rtnl_unlock();  	return err;  }  | 
