1 /* -*- linux-c -*- 2 * sysctl_net_core.c: sysctl interface to net core subsystem. 3 * 4 * Begun April 1, 1996, Mike Shaver. 5 * Added /proc/sys/net/core directory entry (empty =) ). [MS] 6 */ 7 8 #include <linux/mm.h> 9 #include <linux/sysctl.h> 10 #include <linux/module.h> 11 #include <linux/socket.h> 12 #include <linux/netdevice.h> 13 #include <linux/ratelimit.h> 14 #include <linux/init.h> 15 16 #include <net/ip.h> 17 #include <net/sock.h> 18 19 static struct ctl_table net_core_table[] = { 20 #ifdef CONFIG_NET 21 { 22 .procname = "wmem_max", 23 .data = &sysctl_wmem_max, 24 .maxlen = sizeof(int), 25 .mode = 0644, 26 .proc_handler = proc_dointvec 27 }, 28 { 29 .procname = "rmem_max", 30 .data = &sysctl_rmem_max, 31 .maxlen = sizeof(int), 32 .mode = 0644, 33 .proc_handler = proc_dointvec 34 }, 35 { 36 .procname = "wmem_default", 37 .data = &sysctl_wmem_default, 38 .maxlen = sizeof(int), 39 .mode = 0644, 40 .proc_handler = proc_dointvec 41 }, 42 { 43 .procname = "rmem_default", 44 .data = &sysctl_rmem_default, 45 .maxlen = sizeof(int), 46 .mode = 0644, 47 .proc_handler = proc_dointvec 48 }, 49 { 50 .procname = "dev_weight", 51 .data = &weight_p, 52 .maxlen = sizeof(int), 53 .mode = 0644, 54 .proc_handler = proc_dointvec 55 }, 56 { 57 .procname = "netdev_max_backlog", 58 .data = &netdev_max_backlog, 59 .maxlen = sizeof(int), 60 .mode = 0644, 61 .proc_handler = proc_dointvec 62 }, 63 { 64 .procname = "message_cost", 65 .data = &net_ratelimit_state.interval, 66 .maxlen = sizeof(int), 67 .mode = 0644, 68 .proc_handler = proc_dointvec_jiffies, 69 }, 70 { 71 .procname = "message_burst", 72 .data = &net_ratelimit_state.burst, 73 .maxlen = sizeof(int), 74 .mode = 0644, 75 .proc_handler = proc_dointvec, 76 }, 77 { 78 .procname = "optmem_max", 79 .data = &sysctl_optmem_max, 80 .maxlen = sizeof(int), 81 .mode = 0644, 82 .proc_handler = proc_dointvec 83 }, 84 #endif /* CONFIG_NET */ 85 { 86 .procname = "netdev_budget", 87 .data = &netdev_budget, 88 .maxlen = sizeof(int), 89 .mode = 0644, 90 .proc_handler = proc_dointvec 91 }, 92 { 93 .procname = "warnings", 94 .data = &net_msg_warn, 95 .maxlen = sizeof(int), 96 .mode = 0644, 97 .proc_handler = proc_dointvec 98 }, 99 { } 100 }; 101 102 static struct ctl_table netns_core_table[] = { 103 { 104 .procname = "somaxconn", 105 .data = &init_net.core.sysctl_somaxconn, 106 .maxlen = sizeof(int), 107 .mode = 0644, 108 .proc_handler = proc_dointvec 109 }, 110 { } 111 }; 112 113 __net_initdata struct ctl_path net_core_path[] = { 114 { .procname = "net", }, 115 { .procname = "core", }, 116 { }, 117 }; 118 119 static __net_init int sysctl_core_net_init(struct net *net) 120 { 121 struct ctl_table *tbl; 122 123 net->core.sysctl_somaxconn = SOMAXCONN; 124 125 tbl = netns_core_table; 126 if (!net_eq(net, &init_net)) { 127 tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL); 128 if (tbl == NULL) 129 goto err_dup; 130 131 tbl[0].data = &net->core.sysctl_somaxconn; 132 } 133 134 net->core.sysctl_hdr = register_net_sysctl_table(net, 135 net_core_path, tbl); 136 if (net->core.sysctl_hdr == NULL) 137 goto err_reg; 138 139 return 0; 140 141 err_reg: 142 if (tbl != netns_core_table) 143 kfree(tbl); 144 err_dup: 145 return -ENOMEM; 146 } 147 148 static __net_exit void sysctl_core_net_exit(struct net *net) 149 { 150 struct ctl_table *tbl; 151 152 tbl = net->core.sysctl_hdr->ctl_table_arg; 153 unregister_net_sysctl_table(net->core.sysctl_hdr); 154 BUG_ON(tbl == netns_core_table); 155 kfree(tbl); 156 } 157 158 static __net_initdata struct pernet_operations sysctl_core_ops = { 159 .init = sysctl_core_net_init, 160 .exit = sysctl_core_net_exit, 161 }; 162 163 static __init int sysctl_core_init(void) 164 { 165 static struct ctl_table empty[1]; 166 167 register_sysctl_paths(net_core_path, empty); 168 register_net_sysctl_rotable(net_core_path, net_core_table); 169 return register_pernet_subsys(&sysctl_core_ops); 170 } 171 172 fs_initcall(sysctl_core_init); 173