OSDN Git Service

sctp: Add infrastructure for per net sysctls
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 7 Aug 2012 07:23:59 +0000 (07:23 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 15 Aug 2012 06:30:37 +0000 (23:30 -0700)
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" <ebiederm@xmission.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/netns/sctp.h
include/net/sctp/sctp.h
net/sctp/protocol.c
net/sctp/sysctl.c

index 06ccddf..9576b60 100644 (file)
@@ -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__ */
index 7dcd4df..c07421d 100644 (file)
@@ -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. */
index d58db31..0f2342b 100644 (file)
@@ -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 = {
index 2b2bfe9..bee36c4 100644 (file)
@@ -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.  */