diff options
author | Gao feng <gaofeng@cn.fujitsu.com> | 2012-09-13 16:58:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-09-19 15:37:01 -0400 |
commit | 828de4f6bf6e785f7b5497f8f7cfd4d4fbcfdb7e (patch) | |
tree | a6a9eba68dd775aaf900b4b30193cb07595b0694 /net/core | |
parent | 3fd91fb35847a8b3287f00970efc069de16df8b4 (diff) |
net: dev: fix incorrect getting net device's name
When moving a nic from net namespace A to net namespace B,
in dev_change_net_namesapce,we call __dev_get_by_name to
decide if the netns B has the device has the same name.
if the netns B already has the same named device,we call
dev_get_valid_name to try to get a valid name for this nic in
the netns B,but net_device->nd_net still point to netns A now.
this patch fix it.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 52cd1d7f004a..bb42eb161969 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -959,18 +959,30 @@ int dev_alloc_name(struct net_device *dev, const char *name) | |||
959 | } | 959 | } |
960 | EXPORT_SYMBOL(dev_alloc_name); | 960 | EXPORT_SYMBOL(dev_alloc_name); |
961 | 961 | ||
962 | static int dev_get_valid_name(struct net_device *dev, const char *name) | 962 | static int dev_alloc_name_ns(struct net *net, |
963 | struct net_device *dev, | ||
964 | const char *name) | ||
963 | { | 965 | { |
964 | struct net *net; | 966 | char buf[IFNAMSIZ]; |
967 | int ret; | ||
965 | 968 | ||
966 | BUG_ON(!dev_net(dev)); | 969 | ret = __dev_alloc_name(net, name, buf); |
967 | net = dev_net(dev); | 970 | if (ret >= 0) |
971 | strlcpy(dev->name, buf, IFNAMSIZ); | ||
972 | return ret; | ||
973 | } | ||
974 | |||
975 | static int dev_get_valid_name(struct net *net, | ||
976 | struct net_device *dev, | ||
977 | const char *name) | ||
978 | { | ||
979 | BUG_ON(!net); | ||
968 | 980 | ||
969 | if (!dev_valid_name(name)) | 981 | if (!dev_valid_name(name)) |
970 | return -EINVAL; | 982 | return -EINVAL; |
971 | 983 | ||
972 | if (strchr(name, '%')) | 984 | if (strchr(name, '%')) |
973 | return dev_alloc_name(dev, name); | 985 | return dev_alloc_name_ns(net, dev, name); |
974 | else if (__dev_get_by_name(net, name)) | 986 | else if (__dev_get_by_name(net, name)) |
975 | return -EEXIST; | 987 | return -EEXIST; |
976 | else if (dev->name != name) | 988 | else if (dev->name != name) |
@@ -1006,7 +1018,7 @@ int dev_change_name(struct net_device *dev, const char *newname) | |||
1006 | 1018 | ||
1007 | memcpy(oldname, dev->name, IFNAMSIZ); | 1019 | memcpy(oldname, dev->name, IFNAMSIZ); |
1008 | 1020 | ||
1009 | err = dev_get_valid_name(dev, newname); | 1021 | err = dev_get_valid_name(net, dev, newname); |
1010 | if (err < 0) | 1022 | if (err < 0) |
1011 | return err; | 1023 | return err; |
1012 | 1024 | ||
@@ -5589,7 +5601,7 @@ int register_netdevice(struct net_device *dev) | |||
5589 | 5601 | ||
5590 | dev->iflink = -1; | 5602 | dev->iflink = -1; |
5591 | 5603 | ||
5592 | ret = dev_get_valid_name(dev, dev->name); | 5604 | ret = dev_get_valid_name(net, dev, dev->name); |
5593 | if (ret < 0) | 5605 | if (ret < 0) |
5594 | goto out; | 5606 | goto out; |
5595 | 5607 | ||
@@ -6233,7 +6245,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | |||
6233 | /* We get here if we can't use the current device name */ | 6245 | /* We get here if we can't use the current device name */ |
6234 | if (!pat) | 6246 | if (!pat) |
6235 | goto out; | 6247 | goto out; |
6236 | if (dev_get_valid_name(dev, pat) < 0) | 6248 | if (dev_get_valid_name(net, dev, pat) < 0) |
6237 | goto out; | 6249 | goto out; |
6238 | } | 6250 | } |
6239 | 6251 | ||