diff options
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 56 | 
1 files changed, 25 insertions, 31 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index c25d453b2803..99e1d759f41e 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;  } @@ -1597,10 +1617,14 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)  		return NET_RX_DROP;  	}  	skb->skb_iif = 0; -	skb_set_dev(skb, dev); +	skb->dev = dev; +	skb_dst_drop(skb);  	skb->tstamp.tv64 = 0;  	skb->pkt_type = PACKET_HOST;  	skb->protocol = eth_type_trans(skb, dev); +	skb->mark = 0; +	secpath_reset(skb); +	nf_reset(skb);  	return netif_rx(skb);  }  EXPORT_SYMBOL_GPL(dev_forward_skb); @@ -1849,36 +1873,6 @@ void netif_device_attach(struct net_device *dev)  }  EXPORT_SYMBOL(netif_device_attach); -/** - * skb_dev_set -- assign a new device to a buffer - * @skb: buffer for the new device - * @dev: network device - * - * If an skb is owned by a device already, we have to reset - * all data private to the namespace a device belongs to - * before assigning it a new device. - */ -#ifdef CONFIG_NET_NS -void skb_set_dev(struct sk_buff *skb, struct net_device *dev) -{ -	skb_dst_drop(skb); -	if (skb->dev && !net_eq(dev_net(skb->dev), dev_net(dev))) { -		secpath_reset(skb); -		nf_reset(skb); -		skb_init_secmark(skb); -		skb->mark = 0; -		skb->priority = 0; -		skb->nf_trace = 0; -		skb->ipvs_property = 0; -#ifdef CONFIG_NET_SCHED -		skb->tc_index = 0; -#endif -	} -	skb->dev = dev; -} -EXPORT_SYMBOL(skb_set_dev); -#endif /* CONFIG_NET_NS */ -  static void skb_warn_bad_offload(const struct sk_buff *skb)  {  	static const netdev_features_t null_features = 0;  | 
