diff options
author | Octavian Purdila <opurdila@ixiacom.com> | 2009-11-17 21:36:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-18 08:03:35 -0500 |
commit | d90310243fd750240755e217c5faa13e24f41536 (patch) | |
tree | 05496a71a478bd5b273dd425c275f781e3bd1b58 /net/core | |
parent | 7adcdb4c1142dc446ab9d4c51ab09cc87e0749c9 (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.c | 69 |
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 | } |
934 | EXPORT_SYMBOL(dev_alloc_name); | 935 | EXPORT_SYMBOL(dev_alloc_name); |
935 | 936 | ||
937 | static 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 | ||
976 | rollback: | 984 | rollback: |
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 | ||
4884 | int register_netdevice(struct net_device *dev) | 4892 | int 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 | ||
5461 | int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat) | 5455 | int 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); |