From 194ee66693088d40aa7774f6d2cb1523908430ed Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 30 Nov 2007 23:55:42 +1100 Subject: [PATCH] --- yaml --- r: 78232 b: refs/heads/master c: 95bdfccb2bf4ea21c0065772c6a2c75cbaf6ad0d h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/net/net_namespace.h | 9 +++++ trunk/net/sysctl_net.c | 57 +++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 79859eab81d2..600827c72ffb 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e51b6ba077791f2f8c876022b37419be7a2ceec3 +refs/heads/master: 95bdfccb2bf4ea21c0065772c6a2c75cbaf6ad0d diff --git a/trunk/include/net/net_namespace.h b/trunk/include/net/net_namespace.h index 4d0d6349aa7e..235214c4c231 100644 --- a/trunk/include/net/net_namespace.h +++ b/trunk/include/net/net_namespace.h @@ -25,6 +25,8 @@ struct net { struct proc_dir_entry *proc_net_stat; struct proc_dir_entry *proc_net_root; + struct list_head sysctl_table_headers; + struct net_device *loopback_dev; /* The loopback */ struct list_head dev_base_head; @@ -144,4 +146,11 @@ extern void unregister_pernet_subsys(struct pernet_operations *); extern int register_pernet_device(struct pernet_operations *); extern void unregister_pernet_device(struct pernet_operations *); +struct ctl_path; +struct ctl_table; +struct ctl_table_header; +extern struct ctl_table_header *register_net_sysctl_table(struct net *net, + const struct ctl_path *path, struct ctl_table *table); +extern void unregister_net_sysctl_table(struct ctl_table_header *header); + #endif /* __NET_NET_NAMESPACE_H */ diff --git a/trunk/net/sysctl_net.c b/trunk/net/sysctl_net.c index cd4eafbab1b8..c50c793aa7f0 100644 --- a/trunk/net/sysctl_net.c +++ b/trunk/net/sysctl_net.c @@ -14,6 +14,7 @@ #include #include +#include #include @@ -54,3 +55,59 @@ struct ctl_table net_table[] = { #endif { 0 }, }; + +static struct list_head * +net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces) +{ + return &namespaces->net_ns->sysctl_table_headers; +} + +static struct ctl_table_root net_sysctl_root = { + .lookup = net_ctl_header_lookup, +}; + +static int sysctl_net_init(struct net *net) +{ + INIT_LIST_HEAD(&net->sysctl_table_headers); + return 0; +} + +static void sysctl_net_exit(struct net *net) +{ + WARN_ON(!list_empty(&net->sysctl_table_headers)); + return; +} + +static struct pernet_operations sysctl_pernet_ops = { + .init = sysctl_net_init, + .exit = sysctl_net_exit, +}; + +static __init int sysctl_init(void) +{ + int ret; + ret = register_pernet_subsys(&sysctl_pernet_ops); + if (ret) + goto out; + register_sysctl_root(&net_sysctl_root); +out: + return ret; +} +subsys_initcall(sysctl_init); + +struct ctl_table_header *register_net_sysctl_table(struct net *net, + const struct ctl_path *path, struct ctl_table *table) +{ + struct nsproxy namespaces; + namespaces = *current->nsproxy; + namespaces.net_ns = net; + return __register_sysctl_paths(&net_sysctl_root, + &namespaces, path, table); +} +EXPORT_SYMBOL_GPL(register_net_sysctl_table); + +void unregister_net_sysctl_table(struct ctl_table_header *header) +{ + return unregister_sysctl_table(header); +} +EXPORT_SYMBOL_GPL(unregister_net_sysctl_table);