diff options
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 145 | 
1 files changed, 5 insertions, 140 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 949c62dba71..2a9b7dd0bb6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3968,140 +3968,6 @@ void dev_set_rx_mode(struct net_device *dev)  	netif_addr_unlock_bh(dev);  } -/* multicast addresses handling functions */ - -int __dev_addr_delete(struct dev_addr_list **list, int *count, -		      void *addr, int alen, int glbl) -{ -	struct dev_addr_list *da; - -	for (; (da = *list) != NULL; list = &da->next) { -		if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && -		    alen == da->da_addrlen) { -			if (glbl) { -				int old_glbl = da->da_gusers; -				da->da_gusers = 0; -				if (old_glbl == 0) -					break; -			} -			if (--da->da_users) -				return 0; - -			*list = da->next; -			kfree(da); -			(*count)--; -			return 0; -		} -	} -	return -ENOENT; -} - -int __dev_addr_add(struct dev_addr_list **list, int *count, -		   void *addr, int alen, int glbl) -{ -	struct dev_addr_list *da; - -	for (da = *list; da != NULL; da = da->next) { -		if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && -		    da->da_addrlen == alen) { -			if (glbl) { -				int old_glbl = da->da_gusers; -				da->da_gusers = 1; -				if (old_glbl) -					return 0; -			} -			da->da_users++; -			return 0; -		} -	} - -	da = kzalloc(sizeof(*da), GFP_ATOMIC); -	if (da == NULL) -		return -ENOMEM; -	memcpy(da->da_addr, addr, alen); -	da->da_addrlen = alen; -	da->da_users = 1; -	da->da_gusers = glbl ? 1 : 0; -	da->next = *list; -	*list = da; -	(*count)++; -	return 0; -} - - -int __dev_addr_sync(struct dev_addr_list **to, int *to_count, -		    struct dev_addr_list **from, int *from_count) -{ -	struct dev_addr_list *da, *next; -	int err = 0; - -	da = *from; -	while (da != NULL) { -		next = da->next; -		if (!da->da_synced) { -			err = __dev_addr_add(to, to_count, -					     da->da_addr, da->da_addrlen, 0); -			if (err < 0) -				break; -			da->da_synced = 1; -			da->da_users++; -		} else if (da->da_users == 1) { -			__dev_addr_delete(to, to_count, -					  da->da_addr, da->da_addrlen, 0); -			__dev_addr_delete(from, from_count, -					  da->da_addr, da->da_addrlen, 0); -		} -		da = next; -	} -	return err; -} -EXPORT_SYMBOL_GPL(__dev_addr_sync); - -void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, -		       struct dev_addr_list **from, int *from_count) -{ -	struct dev_addr_list *da, *next; - -	da = *from; -	while (da != NULL) { -		next = da->next; -		if (da->da_synced) { -			__dev_addr_delete(to, to_count, -					  da->da_addr, da->da_addrlen, 0); -			da->da_synced = 0; -			__dev_addr_delete(from, from_count, -					  da->da_addr, da->da_addrlen, 0); -		} -		da = next; -	} -} -EXPORT_SYMBOL_GPL(__dev_addr_unsync); - -static void __dev_addr_discard(struct dev_addr_list **list) -{ -	struct dev_addr_list *tmp; - -	while (*list != NULL) { -		tmp = *list; -		*list = tmp->next; -		if (tmp->da_users > tmp->da_gusers) -			printk("__dev_addr_discard: address leakage! " -			       "da_users=%d\n", tmp->da_users); -		kfree(tmp); -	} -} - -void dev_addr_discard(struct net_device *dev) -{ -	netif_addr_lock_bh(dev); - -	__dev_addr_discard(&dev->mc_list); -	netdev_mc_count(dev) = 0; - -	netif_addr_unlock_bh(dev); -} -EXPORT_SYMBOL(dev_addr_discard); -  /**   *	dev_get_flags - get flags reported to userspace   *	@dev: device @@ -4412,8 +4278,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)  			return -EINVAL;  		if (!netif_device_present(dev))  			return -ENODEV; -		return dev_mc_add(dev, ifr->ifr_hwaddr.sa_data, -				  dev->addr_len, 1); +		return dev_mc_add_global(dev, ifr->ifr_hwaddr.sa_data);  	case SIOCDELMULTI:  		if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) || @@ -4421,8 +4286,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)  			return -EINVAL;  		if (!netif_device_present(dev))  			return -ENODEV; -		return dev_mc_delete(dev, ifr->ifr_hwaddr.sa_data, -				     dev->addr_len, 1); +		return dev_mc_del_global(dev, ifr->ifr_hwaddr.sa_data);  	case SIOCSIFTXQLEN:  		if (ifr->ifr_qlen < 0) @@ -4730,7 +4594,7 @@ static void rollback_registered_many(struct list_head *head)  		 *	Flush the unicast and multicast chains  		 */  		dev_uc_flush(dev); -		dev_addr_discard(dev); +		dev_mc_flush(dev);  		if (dev->netdev_ops->ndo_uninit)  			dev->netdev_ops->ndo_uninit(dev); @@ -5310,6 +5174,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,  	if (dev_addr_init(dev))  		goto free_rx; +	dev_mc_init(dev);  	dev_uc_init(dev);  	dev_net_set(dev, &init_net); @@ -5545,7 +5410,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char  	 *	Flush the unicast and multicast chains  	 */  	dev_uc_flush(dev); -	dev_addr_discard(dev); +	dev_mc_flush(dev);  	netdev_unregister_kobject(dev);  |