aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorOctavian Purdila <opurdila@ixiacom.com>2009-11-17 21:36:59 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-18 08:03:35 -0500
commitd90310243fd750240755e217c5faa13e24f41536 (patch)
tree05496a71a478bd5b273dd425c275f781e3bd1b58 /net/core
parent7adcdb4c1142dc446ab9d4c51ab09cc87e0749c9 (diff)
net: device name allocation cleanups
Signed-off-by: Octavian Purdila <opurdila@ixiacom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c69
1 files changed, 24 insertions, 45 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index c128af708ebf..9977288583b8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -893,7 +893,8 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf)
893 free_page((unsigned long) inuse); 893 free_page((unsigned long) inuse);
894 } 894 }
895 895
896 snprintf(buf, IFNAMSIZ, name, i); 896 if (buf != name)
897 snprintf(buf, IFNAMSIZ, name, i);
897 if (!__dev_get_by_name(net, buf)) 898 if (!__dev_get_by_name(net, buf))
898 return i; 899 return i;
899 900
@@ -933,6 +934,21 @@ int dev_alloc_name(struct net_device *dev, const char *name)
933} 934}
934EXPORT_SYMBOL(dev_alloc_name); 935EXPORT_SYMBOL(dev_alloc_name);
935 936
937static int dev_get_valid_name(struct net *net, const char *name, char *buf,
938 bool fmt)
939{
940 if (!dev_valid_name(name))
941 return -EINVAL;
942
943 if (fmt && strchr(name, '%'))
944 return __dev_alloc_name(net, name, buf);
945 else if (__dev_get_by_name(net, name))
946 return -EEXIST;
947 else if (buf != name)
948 strlcpy(buf, name, IFNAMSIZ);
949
950 return 0;
951}
936 952
937/** 953/**
938 * dev_change_name - change name of a device 954 * dev_change_name - change name of a device
@@ -956,22 +972,14 @@ int dev_change_name(struct net_device *dev, const char *newname)
956 if (dev->flags & IFF_UP) 972 if (dev->flags & IFF_UP)
957 return -EBUSY; 973 return -EBUSY;
958 974
959 if (!dev_valid_name(newname))
960 return -EINVAL;
961
962 if (strncmp(newname, dev->name, IFNAMSIZ) == 0) 975 if (strncmp(newname, dev->name, IFNAMSIZ) == 0)
963 return 0; 976 return 0;
964 977
965 memcpy(oldname, dev->name, IFNAMSIZ); 978 memcpy(oldname, dev->name, IFNAMSIZ);
966 979
967 if (strchr(newname, '%')) { 980 err = dev_get_valid_name(net, newname, dev->name, 1);
968 err = dev_alloc_name(dev, newname); 981 if (err < 0)
969 if (err < 0) 982 return err;
970 return err;
971 } else if (__dev_get_by_name(net, newname))
972 return -EEXIST;
973 else
974 strlcpy(dev->name, newname, IFNAMSIZ);
975 983
976rollback: 984rollback:
977 /* For now only devices in the initial network namespace 985 /* For now only devices in the initial network namespace
@@ -4883,8 +4891,6 @@ EXPORT_SYMBOL(netdev_fix_features);
4883 4891
4884int register_netdevice(struct net_device *dev) 4892int register_netdevice(struct net_device *dev)
4885{ 4893{
4886 struct hlist_head *head;
4887 struct hlist_node *p;
4888 int ret; 4894 int ret;
4889 struct net *net = dev_net(dev); 4895 struct net *net = dev_net(dev);
4890 4896
@@ -4913,26 +4919,14 @@ int register_netdevice(struct net_device *dev)
4913 } 4919 }
4914 } 4920 }
4915 4921
4916 if (!dev_valid_name(dev->name)) { 4922 ret = dev_get_valid_name(net, dev->name, dev->name, 0);
4917 ret = -EINVAL; 4923 if (ret)
4918 goto err_uninit; 4924 goto err_uninit;
4919 }
4920 4925
4921 dev->ifindex = dev_new_index(net); 4926 dev->ifindex = dev_new_index(net);
4922 if (dev->iflink == -1) 4927 if (dev->iflink == -1)
4923 dev->iflink = dev->ifindex; 4928 dev->iflink = dev->ifindex;
4924 4929
4925 /* Check for existence of name */
4926 head = dev_name_hash(net, dev->name);
4927 hlist_for_each(p, head) {
4928 struct net_device *d
4929 = hlist_entry(p, struct net_device, name_hlist);
4930 if (!strncmp(d->name, dev->name, IFNAMSIZ)) {
4931 ret = -EEXIST;
4932 goto err_uninit;
4933 }
4934 }
4935
4936 /* Fix illegal checksum combinations */ 4930 /* Fix illegal checksum combinations */
4937 if ((dev->features & NETIF_F_HW_CSUM) && 4931 if ((dev->features & NETIF_F_HW_CSUM) &&
4938 (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { 4932 (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
@@ -5460,8 +5454,6 @@ EXPORT_SYMBOL(unregister_netdev);
5460 5454
5461int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat) 5455int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat)
5462{ 5456{
5463 char buf[IFNAMSIZ];
5464 const char *destname;
5465 int err; 5457 int err;
5466 5458
5467 ASSERT_RTNL(); 5459 ASSERT_RTNL();
@@ -5494,20 +5486,11 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
5494 * we can use it in the destination network namespace. 5486 * we can use it in the destination network namespace.
5495 */ 5487 */
5496 err = -EEXIST; 5488 err = -EEXIST;
5497 destname = dev->name; 5489 if (__dev_get_by_name(net, dev->name)) {
5498 if (__dev_get_by_name(net, destname)) {
5499 /* We get here if we can't use the current device name */ 5490 /* We get here if we can't use the current device name */
5500 if (!pat) 5491 if (!pat)
5501 goto out; 5492 goto out;
5502 if (!dev_valid_name(pat)) 5493 if (dev_get_valid_name(net, pat, dev->name, 1))
5503 goto out;
5504 if (strchr(pat, '%')) {
5505 if (__dev_alloc_name(net, pat, buf) < 0)
5506 goto out;
5507 destname = buf;
5508 } else
5509 destname = pat;
5510 if (__dev_get_by_name(net, destname))
5511 goto out; 5494 goto out;
5512 } 5495 }
5513 5496
@@ -5544,10 +5527,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
5544 /* Actually switch the network namespace */ 5527 /* Actually switch the network namespace */
5545 dev_net_set(dev, net); 5528 dev_net_set(dev, net);
5546 5529
5547 /* Assign the new device name */
5548 if (destname != dev->name)
5549 strcpy(dev->name, destname);
5550
5551 /* If there is an ifindex conflict assign a new one */ 5530 /* If there is an ifindex conflict assign a new one */
5552 if (__dev_get_by_index(net, dev->ifindex)) { 5531 if (__dev_get_by_index(net, dev->ifindex)) {
5553 int iflink = (dev->iflink == dev->ifindex); 5532 int iflink = (dev->iflink == dev->ifindex);