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 | |
| 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>
| -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); |
