diff options
| -rw-r--r-- | net/hsr/hsr_device.c | 21 | ||||
| -rw-r--r-- | net/hsr/hsr_device.h | 2 | ||||
| -rw-r--r-- | net/hsr/hsr_main.c | 9 | ||||
| -rw-r--r-- | net/hsr/hsr_netlink.c | 17 | 
4 files changed, 25 insertions, 24 deletions
| diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index cd99f548e440..478852ef98ef 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -339,7 +339,7 @@ static void hsr_announce(struct timer_list *t)  	rcu_read_unlock();  } -static void hsr_del_ports(struct hsr_priv *hsr) +void hsr_del_ports(struct hsr_priv *hsr)  {  	struct hsr_port *port; @@ -356,31 +356,12 @@ static void hsr_del_ports(struct hsr_priv *hsr)  		hsr_del_port(port);  } -/* This has to be called after all the readers are gone. - * Otherwise we would have to check the return value of - * hsr_port_get_hsr(). - */ -static void hsr_dev_destroy(struct net_device *hsr_dev) -{ -	struct hsr_priv *hsr = netdev_priv(hsr_dev); - -	hsr_debugfs_term(hsr); -	hsr_del_ports(hsr); - -	del_timer_sync(&hsr->prune_timer); -	del_timer_sync(&hsr->announce_timer); - -	hsr_del_self_node(hsr); -	hsr_del_nodes(&hsr->node_db); -} -  static const struct net_device_ops hsr_device_ops = {  	.ndo_change_mtu = hsr_dev_change_mtu,  	.ndo_open = hsr_dev_open,  	.ndo_stop = hsr_dev_close,  	.ndo_start_xmit = hsr_dev_xmit,  	.ndo_fix_features = hsr_fix_features, -	.ndo_uninit = hsr_dev_destroy,  };  static struct device_type hsr_type = { diff --git a/net/hsr/hsr_device.h b/net/hsr/hsr_device.h index a099d7de7e79..b8f9262ed101 100644 --- a/net/hsr/hsr_device.h +++ b/net/hsr/hsr_device.h @@ -11,6 +11,7 @@  #include <linux/netdevice.h>  #include "hsr_main.h" +void hsr_del_ports(struct hsr_priv *hsr);  void hsr_dev_setup(struct net_device *dev);  int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],  		     unsigned char multicast_spec, u8 protocol_version, @@ -18,5 +19,4 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],  void hsr_check_carrier_and_operstate(struct hsr_priv *hsr);  bool is_hsr_master(struct net_device *dev);  int hsr_get_max_mtu(struct hsr_priv *hsr); -  #endif /* __HSR_DEVICE_H */ diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c index e2564de67603..144da15f0a81 100644 --- a/net/hsr/hsr_main.c +++ b/net/hsr/hsr_main.c @@ -6,6 +6,7 @@   */  #include <linux/netdevice.h> +#include <net/rtnetlink.h>  #include <linux/rculist.h>  #include <linux/timer.h>  #include <linux/etherdevice.h> @@ -100,8 +101,10 @@ static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,  			master = hsr_port_get_hsr(port->hsr, HSR_PT_MASTER);  			hsr_del_port(port);  			if (hsr_slave_empty(master->hsr)) { -				unregister_netdevice_queue(master->dev, -							   &list_kill); +				const struct rtnl_link_ops *ops; + +				ops = master->dev->rtnl_link_ops; +				ops->dellink(master->dev, &list_kill);  				unregister_netdevice_many(&list_kill);  			}  		} @@ -144,9 +147,9 @@ static int __init hsr_init(void)  static void __exit hsr_exit(void)  { -	unregister_netdevice_notifier(&hsr_nb);  	hsr_netlink_exit();  	hsr_debugfs_remove_root(); +	unregister_netdevice_notifier(&hsr_nb);  }  module_init(hsr_init); diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c index 1decb25f6764..6e14b7d22639 100644 --- a/net/hsr/hsr_netlink.c +++ b/net/hsr/hsr_netlink.c @@ -83,6 +83,22 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev,  	return hsr_dev_finalize(dev, link, multicast_spec, hsr_version, extack);  } +static void hsr_dellink(struct net_device *dev, struct list_head *head) +{ +	struct hsr_priv *hsr = netdev_priv(dev); + +	del_timer_sync(&hsr->prune_timer); +	del_timer_sync(&hsr->announce_timer); + +	hsr_debugfs_term(hsr); +	hsr_del_ports(hsr); + +	hsr_del_self_node(hsr); +	hsr_del_nodes(&hsr->node_db); + +	unregister_netdevice_queue(dev, head); +} +  static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev)  {  	struct hsr_priv *hsr = netdev_priv(dev); @@ -118,6 +134,7 @@ static struct rtnl_link_ops hsr_link_ops __read_mostly = {  	.priv_size	= sizeof(struct hsr_priv),  	.setup		= hsr_dev_setup,  	.newlink	= hsr_newlink, +	.dellink	= hsr_dellink,  	.fill_info	= hsr_fill_info,  }; | 
