forked from mirrors/linux
		
	net: device name allocation cleanups
Signed-off-by: Octavian Purdila <opurdila@ixiacom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									7adcdb4c11
								
							
						
					
					
						commit
						d90310243f
					
				
					 1 changed files with 24 additions and 45 deletions
				
			
		|  | @ -893,7 +893,8 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) | ||||||
| 		free_page((unsigned long) inuse); | 		free_page((unsigned long) inuse); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	snprintf(buf, IFNAMSIZ, name, i); | 	if (buf != name) | ||||||
|  | 		snprintf(buf, IFNAMSIZ, name, i); | ||||||
| 	if (!__dev_get_by_name(net, buf)) | 	if (!__dev_get_by_name(net, buf)) | ||||||
| 		return i; | 		return i; | ||||||
| 
 | 
 | ||||||
|  | @ -933,6 +934,21 @@ int dev_alloc_name(struct net_device *dev, const char *name) | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(dev_alloc_name); | EXPORT_SYMBOL(dev_alloc_name); | ||||||
| 
 | 
 | ||||||
|  | static int dev_get_valid_name(struct net *net, const char *name, char *buf, | ||||||
|  | 			      bool fmt) | ||||||
|  | { | ||||||
|  | 	if (!dev_valid_name(name)) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	if (fmt && strchr(name, '%')) | ||||||
|  | 		return __dev_alloc_name(net, name, buf); | ||||||
|  | 	else if (__dev_get_by_name(net, name)) | ||||||
|  | 		return -EEXIST; | ||||||
|  | 	else if (buf != name) | ||||||
|  | 		strlcpy(buf, name, IFNAMSIZ); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  *	dev_change_name - change name of a device |  *	dev_change_name - change name of a device | ||||||
|  | @ -956,22 +972,14 @@ int dev_change_name(struct net_device *dev, const char *newname) | ||||||
| 	if (dev->flags & IFF_UP) | 	if (dev->flags & IFF_UP) | ||||||
| 		return -EBUSY; | 		return -EBUSY; | ||||||
| 
 | 
 | ||||||
| 	if (!dev_valid_name(newname)) |  | ||||||
| 		return -EINVAL; |  | ||||||
| 
 |  | ||||||
| 	if (strncmp(newname, dev->name, IFNAMSIZ) == 0) | 	if (strncmp(newname, dev->name, IFNAMSIZ) == 0) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	memcpy(oldname, dev->name, IFNAMSIZ); | 	memcpy(oldname, dev->name, IFNAMSIZ); | ||||||
| 
 | 
 | ||||||
| 	if (strchr(newname, '%')) { | 	err = dev_get_valid_name(net, newname, dev->name, 1); | ||||||
| 		err = dev_alloc_name(dev, newname); | 	if (err < 0) | ||||||
| 		if (err < 0) | 		return err; | ||||||
| 			return err; |  | ||||||
| 	} else if (__dev_get_by_name(net, newname)) |  | ||||||
| 		return -EEXIST; |  | ||||||
| 	else |  | ||||||
| 		strlcpy(dev->name, newname, IFNAMSIZ); |  | ||||||
| 
 | 
 | ||||||
| rollback: | rollback: | ||||||
| 	/* For now only devices in the initial network namespace
 | 	/* For now only devices in the initial network namespace
 | ||||||
|  | @ -4883,8 +4891,6 @@ EXPORT_SYMBOL(netdev_fix_features); | ||||||
| 
 | 
 | ||||||
| int register_netdevice(struct net_device *dev) | int register_netdevice(struct net_device *dev) | ||||||
| { | { | ||||||
| 	struct hlist_head *head; |  | ||||||
| 	struct hlist_node *p; |  | ||||||
| 	int ret; | 	int ret; | ||||||
| 	struct net *net = dev_net(dev); | 	struct net *net = dev_net(dev); | ||||||
| 
 | 
 | ||||||
|  | @ -4913,26 +4919,14 @@ int register_netdevice(struct net_device *dev) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!dev_valid_name(dev->name)) { | 	ret = dev_get_valid_name(net, dev->name, dev->name, 0); | ||||||
| 		ret = -EINVAL; | 	if (ret) | ||||||
| 		goto err_uninit; | 		goto err_uninit; | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	dev->ifindex = dev_new_index(net); | 	dev->ifindex = dev_new_index(net); | ||||||
| 	if (dev->iflink == -1) | 	if (dev->iflink == -1) | ||||||
| 		dev->iflink = dev->ifindex; | 		dev->iflink = dev->ifindex; | ||||||
| 
 | 
 | ||||||
| 	/* Check for existence of name */ |  | ||||||
| 	head = dev_name_hash(net, dev->name); |  | ||||||
| 	hlist_for_each(p, head) { |  | ||||||
| 		struct net_device *d |  | ||||||
| 			= hlist_entry(p, struct net_device, name_hlist); |  | ||||||
| 		if (!strncmp(d->name, dev->name, IFNAMSIZ)) { |  | ||||||
| 			ret = -EEXIST; |  | ||||||
| 			goto err_uninit; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* Fix illegal checksum combinations */ | 	/* Fix illegal checksum combinations */ | ||||||
| 	if ((dev->features & NETIF_F_HW_CSUM) && | 	if ((dev->features & NETIF_F_HW_CSUM) && | ||||||
| 	    (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | 	    (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | ||||||
|  | @ -5460,8 +5454,6 @@ EXPORT_SYMBOL(unregister_netdev); | ||||||
| 
 | 
 | ||||||
| int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat) | int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat) | ||||||
| { | { | ||||||
| 	char buf[IFNAMSIZ]; |  | ||||||
| 	const char *destname; |  | ||||||
| 	int err; | 	int err; | ||||||
| 
 | 
 | ||||||
| 	ASSERT_RTNL(); | 	ASSERT_RTNL(); | ||||||
|  | @ -5494,20 +5486,11 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | ||||||
| 	 * we can use it in the destination network namespace. | 	 * we can use it in the destination network namespace. | ||||||
| 	 */ | 	 */ | ||||||
| 	err = -EEXIST; | 	err = -EEXIST; | ||||||
| 	destname = dev->name; | 	if (__dev_get_by_name(net, dev->name)) { | ||||||
| 	if (__dev_get_by_name(net, destname)) { |  | ||||||
| 		/* We get here if we can't use the current device name */ | 		/* We get here if we can't use the current device name */ | ||||||
| 		if (!pat) | 		if (!pat) | ||||||
| 			goto out; | 			goto out; | ||||||
| 		if (!dev_valid_name(pat)) | 		if (dev_get_valid_name(net, pat, dev->name, 1)) | ||||||
| 			goto out; |  | ||||||
| 		if (strchr(pat, '%')) { |  | ||||||
| 			if (__dev_alloc_name(net, pat, buf) < 0) |  | ||||||
| 				goto out; |  | ||||||
| 			destname = buf; |  | ||||||
| 		} else |  | ||||||
| 			destname = pat; |  | ||||||
| 		if (__dev_get_by_name(net, destname)) |  | ||||||
| 			goto out; | 			goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -5544,10 +5527,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | ||||||
| 	/* Actually switch the network namespace */ | 	/* Actually switch the network namespace */ | ||||||
| 	dev_net_set(dev, net); | 	dev_net_set(dev, net); | ||||||
| 
 | 
 | ||||||
| 	/* Assign the new device name */ |  | ||||||
| 	if (destname != dev->name) |  | ||||||
| 		strcpy(dev->name, destname); |  | ||||||
| 
 |  | ||||||
| 	/* If there is an ifindex conflict assign a new one */ | 	/* If there is an ifindex conflict assign a new one */ | ||||||
| 	if (__dev_get_by_index(net, dev->ifindex)) { | 	if (__dev_get_by_index(net, dev->ifindex)) { | ||||||
| 		int iflink = (dev->iflink == dev->ifindex); | 		int iflink = (dev->iflink == dev->ifindex); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Octavian Purdila
						Octavian Purdila