From ebb7e95d9351f77a8ec1fca20eb645051401b7b2 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 7 Aug 2012 07:23:59 +0000 Subject: [PATCH] sctp: Add infrastructure for per net sysctls Start with an empty sctp_net_table that will be populated as the various tunable sysctls are made per net. Signed-off-by: "Eric W. Biederman" Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- include/net/netns/sctp.h | 6 +++++- include/net/sctp/sctp.h | 4 ++++ net/sctp/protocol.c | 7 +++++++ net/sctp/sysctl.c | 21 +++++++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/include/net/netns/sctp.h b/include/net/netns/sctp.h index 06ccddf9566c..9576b60cbd25 100644 --- a/include/net/netns/sctp.h +++ b/include/net/netns/sctp.h @@ -4,6 +4,7 @@ struct sock; struct proc_dir_entry; struct sctp_mib; +struct ctl_table_header; struct netns_sctp { DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics); @@ -11,7 +12,9 @@ struct netns_sctp { #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_net_sctp; #endif - +#ifdef CONFIG_SYSCTL + struct ctl_table_header *sysctl_header; +#endif /* This is the global socket data structure used for responding to * the Out-of-the-blue (OOTB) packets. A control sock will be created * for this socket at the initialization time. @@ -32,6 +35,7 @@ struct netns_sctp { /* Lock that protects the local_addr_list writers */ spinlock_t local_addr_lock; + }; #endif /* __NETNS_SCTP_H__ */ diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 7dcd4dfd7c3f..c07421d1772f 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -375,9 +375,13 @@ static inline void sctp_dbg_objcnt_exit(struct net *) { return; } #if defined CONFIG_SYSCTL void sctp_sysctl_register(void); void sctp_sysctl_unregister(void); +int sctp_sysctl_net_register(struct net *net); +void sctp_sysctl_net_unregister(struct net *net); #else static inline void sctp_sysctl_register(void) { return; } static inline void sctp_sysctl_unregister(void) { return; } +static inline int sctp_sysctl_net_register(struct net *net) { return 0; } +static inline void sctp_sysctl_net_unregister(struct net *net) { return; } #endif /* Size of Supported Address Parameter for 'x' address types. */ diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index d58db315db85..0f2342be61f3 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1169,6 +1169,10 @@ static int sctp_net_init(struct net *net) { int status; + status = sctp_sysctl_net_register(net); + if (status) + goto err_sysctl_register; + /* Allocate and initialise sctp mibs. */ status = init_sctp_mibs(net); if (status) @@ -1208,6 +1212,8 @@ err_ctl_sock_init: err_init_proc: cleanup_sctp_mibs(net); err_init_mibs: + sctp_sysctl_net_unregister(net); +err_sysctl_register: return status; } @@ -1224,6 +1230,7 @@ static void sctp_net_exit(struct net *net) sctp_proc_exit(net); cleanup_sctp_mibs(net); + sctp_sysctl_net_unregister(net); } static struct pernet_operations sctp_net_ops = { diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 2b2bfe933ff1..bee36c408dde 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -284,6 +284,27 @@ static ctl_table sctp_table[] = { { /* sentinel */ } }; +static ctl_table sctp_net_table[] = { + { /* sentinel */ } +}; + +int sctp_sysctl_net_register(struct net *net) +{ + struct ctl_table *table; + + table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); + if (!table) + return -ENOMEM; + + net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); + return 0; +} + +void sctp_sysctl_net_unregister(struct net *net) +{ + unregister_net_sysctl_table(net->sctp.sysctl_header); +} + static struct ctl_table_header * sctp_sysctl_header; /* Sysctl registration. */