| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /* -*- linux-c -*-
 | 
					
						
							|  |  |  |  * sysctl_net.c: sysctl interface to net subsystem. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Begun April 1, 1996, Mike Shaver. | 
					
						
							|  |  |  |  * Added /proc/sys/net directories for each protocol family. [MS] | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Revision 1.2  1996/05/08  20:24:40  shaver | 
					
						
							|  |  |  |  * Added bits for NET_BRIDGE and the NET_IPV4_ARP stuff and | 
					
						
							|  |  |  |  * NET_IPV4_IP_FORWARD. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/mm.h>
 | 
					
						
							|  |  |  | #include <linux/sysctl.h>
 | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | #include <linux/nsproxy.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-03 14:16:34 -07:00
										 |  |  | #include <net/sock.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #ifdef CONFIG_INET
 | 
					
						
							| 
									
										
										
										
											2005-08-16 02:18:02 -03:00
										 |  |  | #include <net/ip.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_NET
 | 
					
						
							| 
									
										
										
										
											2005-08-16 02:18:02 -03:00
										 |  |  | #include <linux/if_ether.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_TR
 | 
					
						
							| 
									
										
										
										
											2005-08-16 02:18:02 -03:00
										 |  |  | #include <linux/if_tr.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-14 21:22:20 -04:00
										 |  |  | static struct ctl_table_set * | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-14 21:22:20 -04:00
										 |  |  | 	return &namespaces->net_ns->sysctls; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int is_seen(struct ctl_table_set *set) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ¤t->nsproxy->net_ns->sysctls == set; | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-25 01:48:32 -07:00
										 |  |  | /* Return standard mode bits for table entry. */ | 
					
						
							|  |  |  | static int net_ctl_permissions(struct ctl_table_root *root, | 
					
						
							|  |  |  | 			       struct nsproxy *nsproxy, | 
					
						
							|  |  |  | 			       struct ctl_table *table) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* Allow network administrator to have same access as root. */ | 
					
						
							|  |  |  | 	if (capable(CAP_NET_ADMIN)) { | 
					
						
							|  |  |  | 		int mode = (table->mode >> 6) & 7; | 
					
						
							|  |  |  | 		return (mode << 6) | (mode << 3) | mode; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return table->mode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | static struct ctl_table_root net_sysctl_root = { | 
					
						
							|  |  |  | 	.lookup = net_ctl_header_lookup, | 
					
						
							| 
									
										
										
										
											2008-07-25 01:48:32 -07:00
										 |  |  | 	.permissions = net_ctl_permissions, | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-19 13:45:33 -07:00
										 |  |  | static int net_ctl_ro_header_perms(struct ctl_table_root *root, | 
					
						
							|  |  |  | 		struct nsproxy *namespaces, struct ctl_table *table) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-16 16:23:30 +01:00
										 |  |  | 	if (net_eq(namespaces->net_ns, &init_net)) | 
					
						
							| 
									
										
										
										
											2008-05-19 13:45:33 -07:00
										 |  |  | 		return table->mode; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return table->mode & ~0222; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ctl_table_root net_sysctl_ro_root = { | 
					
						
							|  |  |  | 	.permissions = net_ctl_ro_header_perms, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-17 03:35:32 +00:00
										 |  |  | static int __net_init sysctl_net_init(struct net *net) | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-27 08:59:33 +01:00
										 |  |  | 	setup_sysctl_set(&net->sysctls, | 
					
						
							|  |  |  | 			 &net_sysctl_ro_root.default_set, | 
					
						
							|  |  |  | 			 is_seen); | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-17 03:35:32 +00:00
										 |  |  | static void __net_exit sysctl_net_exit(struct net *net) | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-14 21:22:20 -04:00
										 |  |  | 	WARN_ON(!list_empty(&net->sysctls.list)); | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2008-07-14 21:22:20 -04:00
										 |  |  | 	setup_sysctl_set(&net_sysctl_ro_root.default_set, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2008-05-19 13:45:33 -07:00
										 |  |  | 	register_sysctl_root(&net_sysctl_ro_root); | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | 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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-19 13:45:33 -07:00
										 |  |  | 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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL_GPL(register_net_sysctl_rotable); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | void unregister_net_sysctl_table(struct ctl_table_header *header) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-05-01 02:47:38 -07:00
										 |  |  | 	unregister_sysctl_table(header); | 
					
						
							| 
									
										
										
										
											2007-11-30 23:55:42 +11:00
										 |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL_GPL(unregister_net_sysctl_table); |