summaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c18
-rw-r--r--net/core/net-sysfs.c4
-rw-r--r--net/core/net_namespace.c32
-rw-r--r--net/core/sock.c4
4 files changed, 42 insertions, 16 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index d0cbc93fcf3..515473ee52c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -203,7 +203,7 @@ static struct list_head offload_base __read_mostly;
DEFINE_RWLOCK(dev_base_lock);
EXPORT_SYMBOL(dev_base_lock);
-DEFINE_SEQLOCK(devnet_rename_seq);
+seqcount_t devnet_rename_seq;
static inline void dev_base_seq_inc(struct net *net)
{
@@ -1093,10 +1093,10 @@ int dev_change_name(struct net_device *dev, const char *newname)
if (dev->flags & IFF_UP)
return -EBUSY;
- write_seqlock(&devnet_rename_seq);
+ write_seqcount_begin(&devnet_rename_seq);
if (strncmp(newname, dev->name, IFNAMSIZ) == 0) {
- write_sequnlock(&devnet_rename_seq);
+ write_seqcount_end(&devnet_rename_seq);
return 0;
}
@@ -1104,7 +1104,7 @@ int dev_change_name(struct net_device *dev, const char *newname)
err = dev_get_valid_name(net, dev, newname);
if (err < 0) {
- write_sequnlock(&devnet_rename_seq);
+ write_seqcount_end(&devnet_rename_seq);
return err;
}
@@ -1112,11 +1112,11 @@ rollback:
ret = device_rename(&dev->dev, dev->name);
if (ret) {
memcpy(dev->name, oldname, IFNAMSIZ);
- write_sequnlock(&devnet_rename_seq);
+ write_seqcount_end(&devnet_rename_seq);
return ret;
}
- write_sequnlock(&devnet_rename_seq);
+ write_seqcount_end(&devnet_rename_seq);
write_lock_bh(&dev_base_lock);
hlist_del_rcu(&dev->name_hlist);
@@ -1135,7 +1135,7 @@ rollback:
/* err >= 0 after dev_alloc_name() or stores the first errno */
if (err >= 0) {
err = ret;
- write_seqlock(&devnet_rename_seq);
+ write_seqcount_begin(&devnet_rename_seq);
memcpy(dev->name, oldname, IFNAMSIZ);
goto rollback;
} else {
@@ -4180,7 +4180,7 @@ static int dev_ifname(struct net *net, struct ifreq __user *arg)
return -EFAULT;
retry:
- seq = read_seqbegin(&devnet_rename_seq);
+ seq = read_seqcount_begin(&devnet_rename_seq);
rcu_read_lock();
dev = dev_get_by_index_rcu(net, ifr.ifr_ifindex);
if (!dev) {
@@ -4190,7 +4190,7 @@ retry:
strcpy(ifr.ifr_name, dev->name);
rcu_read_unlock();
- if (read_seqretry(&devnet_rename_seq, seq))
+ if (read_seqcount_retry(&devnet_rename_seq, seq))
goto retry;
if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 334efd5d67a..28c5f5aa7ca 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1334,7 +1334,6 @@ struct kobj_ns_type_operations net_ns_type_operations = {
};
EXPORT_SYMBOL_GPL(net_ns_type_operations);
-#ifdef CONFIG_HOTPLUG
static int netdev_uevent(struct device *d, struct kobj_uevent_env *env)
{
struct net_device *dev = to_net_dev(d);
@@ -1353,7 +1352,6 @@ static int netdev_uevent(struct device *d, struct kobj_uevent_env *env)
exit:
return retval;
}
-#endif
/*
* netdev_release -- destroy and free a dead device.
@@ -1382,9 +1380,7 @@ static struct class net_class = {
#ifdef CONFIG_SYSFS
.dev_attrs = net_class_attributes,
#endif /* CONFIG_SYSFS */
-#ifdef CONFIG_HOTPLUG
.dev_uevent = netdev_uevent,
-#endif
.ns_type = &net_ns_type_operations,
.namespace = net_namespace,
};
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 6456439cbbd..8acce01b6da 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -381,6 +381,21 @@ struct net *get_net_ns_by_pid(pid_t pid)
}
EXPORT_SYMBOL_GPL(get_net_ns_by_pid);
+static __net_init int net_ns_net_init(struct net *net)
+{
+ return proc_alloc_inum(&net->proc_inum);
+}
+
+static __net_exit void net_ns_net_exit(struct net *net)
+{
+ proc_free_inum(net->proc_inum);
+}
+
+static struct pernet_operations __net_initdata net_ns_ops = {
+ .init = net_ns_net_init,
+ .exit = net_ns_net_exit,
+};
+
static int __init net_ns_init(void)
{
struct net_generic *ng;
@@ -412,6 +427,8 @@ static int __init net_ns_init(void)
mutex_unlock(&net_mutex);
+ register_pernet_subsys(&net_ns_ops);
+
return 0;
}
@@ -630,16 +647,29 @@ static void netns_put(void *ns)
static int netns_install(struct nsproxy *nsproxy, void *ns)
{
+ struct net *net = ns;
+
+ if (!ns_capable(net->user_ns, CAP_SYS_ADMIN) ||
+ !nsown_capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
put_net(nsproxy->net_ns);
- nsproxy->net_ns = get_net(ns);
+ nsproxy->net_ns = get_net(net);
return 0;
}
+static unsigned int netns_inum(void *ns)
+{
+ struct net *net = ns;
+ return net->proc_inum;
+}
+
const struct proc_ns_operations netns_operations = {
.name = "net",
.type = CLONE_NEWNET,
.get = netns_get,
.put = netns_put,
.install = netns_install,
+ .inum = netns_inum,
};
#endif
diff --git a/net/core/sock.c b/net/core/sock.c
index a692ef49c9b..bc131d41968 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -583,7 +583,7 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval,
goto out;
retry:
- seq = read_seqbegin(&devnet_rename_seq);
+ seq = read_seqcount_begin(&devnet_rename_seq);
rcu_read_lock();
dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if);
ret = -ENODEV;
@@ -594,7 +594,7 @@ retry:
strcpy(devname, dev->name);
rcu_read_unlock();
- if (read_seqretry(&devnet_rename_seq, seq))
+ if (read_seqcount_retry(&devnet_rename_seq, seq))
goto retry;
len = strlen(devname) + 1;