Home » Mailing lists » Devel » [PATCH 00/16] core network namespace support
Re: [PATCH 03/16] net: Basic network namespace infrastructure. [message #19984 is a reply to message #19969] |
Sun, 09 September 2007 00:33   |
paulmck
Messages: 13 Registered: August 2006
|
Junior Member |
|
|
On Sat, Sep 08, 2007 at 03:15:34PM -0600, Eric W. Biederman wrote:
>
> This is the basic infrastructure needed to support network
> namespaces. This infrastructure is:
> - Registration functions to support initializing per network
> namespace data when a network namespaces is created or destroyed.
>
> - struct net. The network namespace data structure.
> This structure will grow as variables are made per network
> namespace but this is the minimal starting point.
>
> - Functions to grab a reference to the network namespace.
> I provide both get/put functions that keep a network namespace
> from being freed. And hold/release functions serve as weak references
> and will warn if their count is not zero when the data structure
> is freed. Useful for dealing with more complicated data structures
> like the ipv4 route cache.
>
> - A list of all of the network namespaces so we can iterate over them.
>
> - A slab for the network namespace data structure allowing leaks
> to be spotted.
If I understand this correctly, the only way to get to a namespace is
via get_net_ns_by_pid(), which contains the rcu_read_lock() that matches
the rcu_barrier() below.
So, is the get_net() in sock_copy() in this patch adding a reference to
an element that is guaranteed to already have at least one reference?
If not, how are we preventing sock_copy() from running concurrently with
cleanup_net()? Ah, I see -- in sock_copy() we are getting a reference
to the new struct sock that no one else can get a reference to, so OK.
Ditto for the get_net() in sk_alloc().
But I still don't understand what is protecting the get_net() in
dev_seq_open(). Is there an existing reference? If so, how do we know
that it won't be removed just as we are trying to add our reference
(while at the same time cleanup_net() is running)? Ditto for the other
_open() operations in the same patch. And for netlink_seq_open().
Enlightenment?
Thanx, Paul
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
> ---
> include/net/net_namespace.h | 68 ++++++++++
> net/core/Makefile | 2 +-
> net/core/net_namespace.c | 292 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 361 insertions(+), 1 deletions(-)
> create mode 100644 include/net/net_namespace.h
> create mode 100644 net/core/net_namespace.c
>
> diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
> new file mode 100644
> index 0000000..6344b77
> --- /dev/null
> +++ b/include/net/net_namespace.h
> @@ -0,0 +1,68 @@
> +/*
> + * Operations on the network namespace
> + */
> +#ifndef __NET_NET_NAMESPACE_H
> +#define __NET_NET_NAMESPACE_H
> +
> +#include <asm/atomic.h>
> +#include <linux/workqueue.h>
> +#include <linux/list.h>
> +
> +struct net {
> + atomic_t count; /* To decided when the network
> + * namespace should be freed.
> + */
> + atomic_t use_count; /* To track references we
> + * destroy on demand
> + */
> + struct list_head list; /* list of network namespaces */
> + struct work_struct work; /* work struct for freeing */
> +};
> +
> +extern struct net init_net;
> +extern struct list_head net_namespace_list;
> +
> +extern void __put_net(struct net *net);
> +
> +static inline struct net *get_net(struct net *net)
> +{
> + atomic_inc(&net->count);
> + return net;
> +}
> +
> +static inline void put_net(struct net *net)
> +{
> + if (atomic_dec_and_test(&net->count))
> + __put_net(net);
> +}
> +
> +static inline struct net *hold_net(struct net *net)
> +{
> + atomic_inc(&net->use_count);
> + return net;
> +}
> +
> +static inline void release_net(struct net *net)
> +{
> + atomic_dec(&net->use_count);
> +}
> +
> +extern void net_lock(void);
> +extern void net_unlock(void);
> +
> +#define for_each_net(VAR) \
> + list_for_each_entry(VAR, &net_namespace_list, list)
> +
> +
> +struct pernet_operations {
> + struct list_head list;
> + int (*init)(struct net *net);
> + void (*exit)(struct net *net);
> +};
> +
> +extern int register_pernet_subsys(struct pernet_operations *);
> +extern void unregister_pernet_subsys(struct pernet_operations *);
> +extern int register_pernet_device(struct pernet_operations *);
> +extern void unregister_pernet_device(struct pernet_operations *);
> +
> +#endif /* __NET_NET_NAMESPACE_H */
> diff --git a/net/core/Makefile b/net/core/Makefile
> index 4751613..ea9b3f3 100644
> --- a/net/core/Makefile
> +++ b/net/core/Makefile
> @@ -3,7 +3,7 @@
> #
>
> obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
> - gen_stats.o gen_estimator.o
> + gen_stats.o gen_estimator.o net_namespace.o
>
> obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
>
> diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
> new file mode 100644
> index 0000000..f259a9b
> --- /dev/null
> +++ b/net/core/net_namespace.c
> @@ -0,0 +1,292 @@
> +#include <linux/workqueue.h>
> +#include <linux/rtnetlink.h>
> +#include <linux/cache.h>
> +#include <linux/slab.h>
> +#include <linux/list.h>
> +#include <linux/delay.h>
> +#include <net/net_namespace.h>
> +
> +/*
> + * Our network namespace constructor/destructor lists
> + */
> +
> +static LIST_HEAD(pernet_list);
> +static struct list_head *first_device = &pernet_list;
> +static DEFINE_MUTEX(net_mutex);
> +
> +static DEFINE_MUTEX(net_list_mutex);
> +LIST_HEAD(net_namespace_list);
> +
> +static struct kmem_cache *net_cachep;
> +
> +struct net init_net;
> +EXPORT_SYMBOL_GPL(init_net);
> +
> +void net_lock(void)
> +{
> + mutex_lock(&net_list_mutex);
> +}
> +
> +void net_unlock(void)
> +{
> + mutex_unlock(&net_list_mutex);
> +}
> +
> +static struct net *net_alloc(void)
> +{
> + return kmem_cache_alloc(net_cachep, GFP_KERNEL);
> +}
> +
> +static void net_free(struct net *net)
> +{
> + if (!net)
> + return;
> +
> + if (unlikely(atomic_read(&net->use_count) != 0)) {
> + printk(KERN_EMERG "network namespace not free! Usage: %d\n",
> + atomic_read(&net->use_count));
> + return;
> + }
> +
> + kmem_cache_free(net_cachep, net);
> +}
> +
> +static void cleanup_net(struct work_struct *work)
> +{
> + struct pernet_operations *ops;
> + struct list_head *ptr;
> + struct net *net;
> +
> + net = container_of(work, struct net, work);
> +
> + mutex_lock(&net_mutex);
> +
> + /* Don't let anyone else find us. */
> + net_lock();
> + list_del(&net->list);
> + net_unlock();
> +
> + /* Run all of the network namespace exit methods */
> + list_for_each_prev(ptr, &pernet_list) {
> + ops = list_entry(ptr, struct pernet_operations, list);
> + if (ops->exit)
> + ops->exit(net);
> + }
> +
> + mutex_unlock(&net_mutex);
> +
> + /* Ensure there are no outstanding rcu callbacks using this
> + * network namespace.
> + */
> + rcu_barrier();
> +
> + /* Finally it is safe to free my network namespace structure */
> + net_free(net);
> +}
> +
> +
> +void __put_net(struct net *net)
> +{
> + /* Cleanup the network namespace in process context */
> + INIT_WORK(&net->work, cleanup_net);
> + schedule_work(&net->work);
> +}
> +EXPORT_SYMBOL_GPL(__put_net);
> +
> +/*
> + * setup_net runs the initializers for the network namespace object.
> + */
> +static int setup_net(struct net *net)
> +{
> + /* Must be called with net_mutex held */
> + struct pernet_operations *ops;
> + struct list_head *ptr;
> + int error;
> +
> + memset(net, 0, sizeof(struct net));
> + atomic_set(&net->count, 1);
> + atomic_set(&net->use_count, 0);
> +
> + error = 0;
> + list_for_each(ptr, &pernet_list) {
> + ops = list_entry(ptr, struct pernet_operations, list);
> + if (ops->init) {
> + error = ops->init(net);
> + if (error < 0)
> + goto out_undo;
> + }
> + }
> +out:
> + return error;
> +out_undo:
> + /* Walk through the list backwards calling the exit functions
> + * for the pernet modules whose init functions did not fail.
> + */
> + for (ptr = ptr->prev; ptr != &pernet_list; ptr = ptr->prev) {
> + ops = list_entry(ptr, struct pernet_operations, list);
> + if (ops->exit)
> + ops->exit(net);
> + }
> + goto out;
> +}
> +
> +static int __init net_ns_init(void)
> +{
> + int err;
> +
> + printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net));
> + net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
> + SMP_CACHE_BYTES,
> + SLAB_PANIC, NULL);
> + mutex_lock(&net_mutex);
> + err = setup_net(&init_net);
> +
> + net_lock();
> + list_add_tail(&init_net.list, &net_namespace_list);
> + net_unlock();
> +
> + mutex_unlock(&net_mutex);
> + if (err)
> + panic("Could not setup the initial network namespace");
> +
> + return 0;
> +}
> +
> +pure_initcall(net_ns_init);
> +
> +static int register_pernet_operations(struct list_head *list,
> + struct pernet_operations *ops)
> +{
> + struct net *net, *undo_net;
> + int error;
> +
> + error = 0;
> + list_add_tail(&ops->list, list);
> + for_each_net(net) {
> + if (ops->init) {
> + error
...
|
|
|
 |
|
[PATCH 00/16] core network namespace support
By: ebiederm on Sat, 08 September 2007 21:07
|
 |
|
[PATCH 01/16] appletalk: In notifier handlers convert the void pointer to a netdevice
By: ebiederm on Sat, 08 September 2007 21:09
|
 |
|
[PATCH 02/16] net: Don't implement dev_ifname32 inline
By: ebiederm on Sat, 08 September 2007 21:13
|
 |
|
[PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Sat, 08 September 2007 21:15
|
 |
|
[PATCH 04/16] net: Add a network namespace parameter to tasks
By: ebiederm on Sat, 08 September 2007 21:17
|
 |
|
[PATCH 05/16] net: Add a network namespace tag to struct net_device
By: ebiederm on Sat, 08 September 2007 21:18
|
 |
|
[PATCH 07/16] net: Make /proc/net per network namespace
By: ebiederm on Sat, 08 September 2007 21:20
|
 |
|
[PATCH 08/16] net: Make socket creation namespace safe.
By: ebiederm on Sat, 08 September 2007 21:23
|
 |
|
[PATCH 09/16] net: Initialize the network namespace of network devices.
By: ebiederm on Sat, 08 September 2007 21:24
|
 |
|
[PATCH 10/16] net: Make packet reception network namespace safe
By: ebiederm on Sat, 08 September 2007 21:25
|
 |
|
[PATCH 11/16] net: Make device event notification network namespace safe
By: ebiederm on Sat, 08 September 2007 21:27
|
 |
|
[PATCH 12/16] net: Support multiple network namespaces with netlink
By: ebiederm on Sat, 08 September 2007 21:28
|
 |
|
[PATCH 13/16] net: Make the device list and device lookups per namespace.
By: ebiederm on Sat, 08 September 2007 21:35
|
 |
|
[PATCH 14/16] net: Factor out __dev_alloc_name from dev_alloc_name
By: ebiederm on Sat, 08 September 2007 21:36
|
 |
|
[PATCH 15/16] net: Implement network device movement between namespaces
By: ebiederm on Sat, 08 September 2007 21:38
|
 |
|
[PATCH 16/16] net: netlink support for moving devices between network namespaces.
By: ebiederm on Sat, 08 September 2007 21:43
|
 |
|
[PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
By: ebiederm on Sat, 08 September 2007 21:47
|
 |
|
Re: [PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
By: ebiederm on Mon, 10 September 2007 15:27
|
 |
|
Re: [PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
|
 |
|
Re: [PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
By: davem on Wed, 12 September 2007 11:59
|
 |
|
Re: [PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
By: davem on Wed, 12 September 2007 12:03
|
 |
|
Re: [PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
By: ebiederm on Wed, 12 September 2007 12:16
|
 |
|
Re: [PATCH 16/16] net: netlink support for moving devices between network namespaces.
By: ebiederm on Mon, 10 September 2007 19:30
|
 |
|
Re: [PATCH 16/16] net: netlink support for moving devices between network namespaces.
By: serue on Tue, 11 September 2007 00:54
|
 |
|
Re: [PATCH 16/16] net: netlink support for moving devices between network namespaces.
By: serue on Mon, 10 September 2007 19:07
|
 |
|
Re: [PATCH 16/16] net: netlink support for moving devices between network namespaces.
By: davem on Wed, 12 September 2007 11:57
|
 |
|
Re: [PATCH 15/16] net: Implement network device movement between namespaces
By: davem on Wed, 12 September 2007 11:54
|
 |
|
Re: [PATCH 14/16] net: Factor out __dev_alloc_name from dev_alloc_name
By: davem on Wed, 12 September 2007 11:49
|
 |
|
Re: [PATCH 13/16] net: Make the device list and device lookups per namespace.
By: davem on Wed, 12 September 2007 11:39
|
 |
|
Re: [PATCH 12/16] net: Support multiple network namespaces with netlink
By: ebiederm on Mon, 10 September 2007 15:24
|
 |
|
Re: [PATCH 12/16] net: Support multiple network namespaces with netlink
|
 |
|
Re: [PATCH 12/16] net: Support multiple network namespaces with netlink
By: davem on Wed, 12 September 2007 11:06
|
 |
|
Re: [PATCH 11/16] net: Make device event notification network namespace safe
By: davem on Wed, 12 September 2007 11:02
|
 |
|
Re: [PATCH 10/16] net: Make packet reception network namespace safe
By: davem on Wed, 12 September 2007 11:00
|
 |
|
Re: [PATCH 09/16] net: Initialize the network namespace of network devices.
By: davem on Wed, 12 September 2007 10:58
|
 |
|
Re: [PATCH 08/16] net: Make socket creation namespace safe.
By: davem on Wed, 12 September 2007 10:04
|
 |
|
Re: [PATCH 07/16] net: Make /proc/net per network namespace
By: davem on Wed, 12 September 2007 10:02
|
 |
|
Re: [PATCH 07/16] net: Make /proc/net per network namespace
|
 |
|
Re: [PATCH 07/16] net: Make /proc/net per network namespace
By: davem on Wed, 12 September 2007 12:19
|
 |
|
[PATCH 06/16] net: Add a network namespace parameter to struct sock
By: ebiederm on Sat, 08 September 2007 21:21
|
 |
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
By: davem on Wed, 12 September 2007 09:58
|
 |
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
By: den on Thu, 20 September 2007 12:55
|
 |
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
|
 |
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
By: den on Fri, 21 September 2007 05:04
|
 |
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
By: ebiederm on Fri, 21 September 2007 05:58
|
 |
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
|
 |
|
Re: [PATCH 05/16] net: Add a network namespace tag to struct net_device
By: davem on Wed, 12 September 2007 09:57
|
 |
|
Re: [PATCH 04/16] net: Add a network namespace parameter to tasks
By: davem on Wed, 12 September 2007 09:55
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: paulmck on Sun, 09 September 2007 00:33
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Sun, 09 September 2007 10:04
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: paulmck on Sun, 09 September 2007 16:45
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Mon, 10 September 2007 06:32
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Sun, 09 September 2007 10:18
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Mon, 10 September 2007 06:40
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Mon, 10 September 2007 15:53
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
|
 |
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: davem on Wed, 12 September 2007 09:52
|
 |
|
Re: [PATCH 02/16] net: Don't implement dev_ifname32 inline
By: davem on Wed, 12 September 2007 09:39
|
 |
|
Re: [PATCH 01/16] appletalk: In notifier handlers convert the void pointer to a netdevice
By: davem on Wed, 12 September 2007 09:27
|
Goto Forum:
Current Time: Sat Aug 23 17:00:51 GMT 2025
Total time taken to generate the page: 0.13423 seconds
|