diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 7bb5cb6..333c72b 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -1058,7 +1058,7 @@ struct ctl_path { void register_sysctl_root(struct ctl_table_root *root); struct ctl_table_header *__register_sysctl_paths( struct ctl_table_root *root, struct nsproxy *namespaces, - const struct ctl_path *path, struct ctl_table *table); + const struct ctl_path *path, struct ctl_table *table, void *pathdata); struct ctl_table_header *register_sysctl_table(struct ctl_table * table); struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path, struct ctl_table *table); diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index b3b4a34..4c80c30 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -274,6 +274,8 @@ 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); +struct ctl_table_header *register_net_sysctl_table_pathdata(struct net *net, + const struct ctl_path *path, struct ctl_table *table, void *pathdata); extern struct ctl_table_header *register_net_sysctl_rotable( const struct ctl_path *path, struct ctl_table *table); extern void unregister_net_sysctl_table(struct ctl_table_header *header); diff --git a/kernel/sysctl.c b/kernel/sysctl.c index bc86bb3..279a0c8 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1773,6 +1773,8 @@ static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q) * @namespaces: Data to compute which lists of sysctl entries are visible * @path: The path to the directory the sysctl table is in. * @table: the top-level table structure + * @pathdata: user provided pointer to data that will be stored in + * every ctl_table node of the path allocated for @path * * Register a sysctl table hierarchy. @table should be a filled in ctl_table * array. A completely 0 filled entry terminates the table. @@ -1823,7 +1825,7 @@ static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q) struct ctl_table_header *__register_sysctl_paths( struct ctl_table_root *root, struct nsproxy *namespaces, - const struct ctl_path *path, struct ctl_table *table) + const struct ctl_path *path, struct ctl_table *table, void *pathdata) { struct ctl_table_header *header; struct ctl_table *new, **prevp; @@ -1855,6 +1857,7 @@ struct ctl_table_header *__register_sysctl_paths( /* Copy the procname */ new->procname = path->procname; new->mode = 0555; + new->extra2 = pathdata; *prevp = new; prevp = &new->child; @@ -1910,7 +1913,7 @@ struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path, struct ctl_table *table) { return __register_sysctl_paths(&sysctl_table_root, current->nsproxy, - path, table); + path, table, NULL); } /** diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c index 10b90d8..8fd9b71 100644 --- a/kernel/sysctl_check.c +++ b/kernel/sysctl_check.c @@ -127,8 +127,6 @@ int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table) set_fail(&fail, table, "Directory with proc_handler"); if (table->extra1) set_fail(&fail, table, "Directory with extra1"); - if (table->extra2) - set_fail(&fail, table, "Directory with extra2"); } else { if ((table->proc_handler == proc_dostring) || (table->proc_handler == proc_dointvec) || diff --git a/net/sysctl_net.c b/net/sysctl_net.c index ca84212..9c92cac 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c @@ -103,22 +103,30 @@ out: } 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 ctl_table_header *register_net_sysctl_table_pathdata(struct net *net, + const struct ctl_path *path, struct ctl_table *table, void *pathdata) { struct nsproxy namespaces; namespaces = *current->nsproxy; namespaces.net_ns = net; - return __register_sysctl_paths(&net_sysctl_root, - &namespaces, path, table); + return __register_sysctl_paths(&net_sysctl_root, &namespaces, + path, table, pathdata); +} +EXPORT_SYMBOL_GPL(register_net_sysctl_table_pathdata); + +struct ctl_table_header *register_net_sysctl_table(struct net *net, + const struct ctl_path *path, struct ctl_table *table) +{ + return register_net_sysctl_table_pathdata(net, path, table, NULL); } EXPORT_SYMBOL_GPL(register_net_sysctl_table); + struct ctl_table_header *register_net_sysctl_rotable(const struct ctl_path *path, struct ctl_table *table) { - return __register_sysctl_paths(&net_sysctl_ro_root, - &init_nsproxy, path, table); + return __register_sysctl_paths(&net_sysctl_ro_root, &init_nsproxy, + path, table, NULL); } EXPORT_SYMBOL_GPL(register_net_sysctl_rotable);