diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 28 | 
1 files changed, 15 insertions, 13 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 5b92fbff431..0075514bf32 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4156,7 +4156,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev  	 * send the join/membership reports.  The curr_active_slave found  	 * will send all of this type of traffic.  	 */ -	if ((iph->protocol == htons(IPPROTO_IGMP)) && +	if ((iph->protocol == IPPROTO_IGMP) &&  	    (skb->protocol == htons(ETH_P_IP))) {  		read_lock(&bond->curr_slave_lock); @@ -4450,6 +4450,14 @@ static const struct net_device_ops bond_netdev_ops = {  	.ndo_vlan_rx_kill_vid	= bond_vlan_rx_kill_vid,  }; +static void bond_destructor(struct net_device *bond_dev) +{ +	struct bonding *bond = netdev_priv(bond_dev); +	if (bond->wq) +		destroy_workqueue(bond->wq); +	free_netdev(bond_dev); +} +  static void bond_setup(struct net_device *bond_dev)  {  	struct bonding *bond = netdev_priv(bond_dev); @@ -4470,7 +4478,7 @@ static void bond_setup(struct net_device *bond_dev)  	bond_dev->ethtool_ops = &bond_ethtool_ops;  	bond_set_mode_ops(bond, bond->params.mode); -	bond_dev->destructor = free_netdev; +	bond_dev->destructor = bond_destructor;  	/* Initialize the device options */  	bond_dev->tx_queue_len = 0; @@ -4542,9 +4550,6 @@ static void bond_uninit(struct net_device *bond_dev)  	bond_remove_proc_entry(bond); -	if (bond->wq) -		destroy_workqueue(bond->wq); -  	netif_addr_lock_bh(bond_dev);  	bond_mc_list_destroy(bond);  	netif_addr_unlock_bh(bond_dev); @@ -4956,8 +4961,8 @@ int bond_create(struct net *net, const char *name)  				bond_setup);  	if (!bond_dev) {  		pr_err("%s: eek! can't alloc netdev!\n", name); -		res = -ENOMEM; -		goto out; +		rtnl_unlock(); +		return -ENOMEM;  	}  	dev_net_set(bond_dev, net); @@ -4966,19 +4971,16 @@ int bond_create(struct net *net, const char *name)  	if (!name) {  		res = dev_alloc_name(bond_dev, "bond%d");  		if (res < 0) -			goto out_netdev; +			goto out;  	}  	res = register_netdevice(bond_dev); -	if (res < 0) -		goto out_netdev;  out:  	rtnl_unlock(); +	if (res < 0) +		bond_destructor(bond_dev);  	return res; -out_netdev: -	free_netdev(bond_dev); -	goto out;  }  static int __net_init bond_net_init(struct net *net)  |