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/init.h> 14 #include <net/sock.h> 15 #include <net/xfrm.h> 16 17 static struct ctl_table net_core_table[] = { 18 #ifdef CONFIG_NET 19 { 20 .ctl_name = NET_CORE_WMEM_MAX, 21 .procname = "wmem_max", 22 .data = &sysctl_wmem_max, 23 .maxlen = sizeof(int), 24 .mode = 0644, 25 .proc_handler = &proc_dointvec 26 }, 27 { 28 .ctl_name = NET_CORE_RMEM_MAX, 29 .procname = "rmem_max", 30 .data = &sysctl_rmem_max, 31 .maxlen = sizeof(int), 32 .mode = 0644, 33 .proc_handler = &proc_dointvec 34 }, 35 { 36 .ctl_name = NET_CORE_WMEM_DEFAULT, 37 .procname = "wmem_default", 38 .data = &sysctl_wmem_default, 39 .maxlen = sizeof(int), 40 .mode = 0644, 41 .proc_handler = &proc_dointvec 42 }, 43 { 44 .ctl_name = NET_CORE_RMEM_DEFAULT, 45 .procname = "rmem_default", 46 .data = &sysctl_rmem_default, 47 .maxlen = sizeof(int), 48 .mode = 0644, 49 .proc_handler = &proc_dointvec 50 }, 51 { 52 .ctl_name = NET_CORE_DEV_WEIGHT, 53 .procname = "dev_weight", 54 .data = &weight_p, 55 .maxlen = sizeof(int), 56 .mode = 0644, 57 .proc_handler = &proc_dointvec 58 }, 59 { 60 .ctl_name = NET_CORE_MAX_BACKLOG, 61 .procname = "netdev_max_backlog", 62 .data = &netdev_max_backlog, 63 .maxlen = sizeof(int), 64 .mode = 0644, 65 .proc_handler = &proc_dointvec 66 }, 67 { 68 .ctl_name = NET_CORE_MSG_COST, 69 .procname = "message_cost", 70 .data = &net_msg_cost, 71 .maxlen = sizeof(int), 72 .mode = 0644, 73 .proc_handler = &proc_dointvec_jiffies, 74 .strategy = &sysctl_jiffies, 75 }, 76 { 77 .ctl_name = NET_CORE_MSG_BURST, 78 .procname = "message_burst", 79 .data = &net_msg_burst, 80 .maxlen = sizeof(int), 81 .mode = 0644, 82 .proc_handler = &proc_dointvec, 83 }, 84 { 85 .ctl_name = NET_CORE_OPTMEM_MAX, 86 .procname = "optmem_max", 87 .data = &sysctl_optmem_max, 88 .maxlen = sizeof(int), 89 .mode = 0644, 90 .proc_handler = &proc_dointvec 91 }, 92 #ifdef CONFIG_XFRM 93 { 94 .ctl_name = NET_CORE_AEVENT_ETIME, 95 .procname = "xfrm_aevent_etime", 96 .data = &sysctl_xfrm_aevent_etime, 97 .maxlen = sizeof(u32), 98 .mode = 0644, 99 .proc_handler = &proc_dointvec 100 }, 101 { 102 .ctl_name = NET_CORE_AEVENT_RSEQTH, 103 .procname = "xfrm_aevent_rseqth", 104 .data = &sysctl_xfrm_aevent_rseqth, 105 .maxlen = sizeof(u32), 106 .mode = 0644, 107 .proc_handler = &proc_dointvec 108 }, 109 { 110 .ctl_name = CTL_UNNUMBERED, 111 .procname = "xfrm_larval_drop", 112 .data = &sysctl_xfrm_larval_drop, 113 .maxlen = sizeof(int), 114 .mode = 0644, 115 .proc_handler = &proc_dointvec 116 }, 117 { 118 .ctl_name = CTL_UNNUMBERED, 119 .procname = "xfrm_acq_expires", 120 .data = &sysctl_xfrm_acq_expires, 121 .maxlen = sizeof(int), 122 .mode = 0644, 123 .proc_handler = &proc_dointvec 124 }, 125 #endif /* CONFIG_XFRM */ 126 #endif /* CONFIG_NET */ 127 { 128 .ctl_name = NET_CORE_SOMAXCONN, 129 .procname = "somaxconn", 130 .data = &init_net.core.sysctl_somaxconn, 131 .maxlen = sizeof(int), 132 .mode = 0644, 133 .proc_handler = &proc_dointvec 134 }, 135 { 136 .ctl_name = NET_CORE_BUDGET, 137 .procname = "netdev_budget", 138 .data = &netdev_budget, 139 .maxlen = sizeof(int), 140 .mode = 0644, 141 .proc_handler = &proc_dointvec 142 }, 143 { 144 .ctl_name = NET_CORE_WARNINGS, 145 .procname = "warnings", 146 .data = &net_msg_warn, 147 .maxlen = sizeof(int), 148 .mode = 0644, 149 .proc_handler = &proc_dointvec 150 }, 151 { .ctl_name = 0 } 152 }; 153 154 static __net_initdata struct ctl_path net_core_path[] = { 155 { .procname = "net", .ctl_name = CTL_NET, }, 156 { .procname = "core", .ctl_name = NET_CORE, }, 157 { }, 158 }; 159 160 static __net_init int sysctl_core_net_init(struct net *net) 161 { 162 struct ctl_table *tbl, *tmp; 163 164 net->core.sysctl_somaxconn = SOMAXCONN; 165 166 tbl = net_core_table; 167 if (net != &init_net) { 168 tbl = kmemdup(tbl, sizeof(net_core_table), GFP_KERNEL); 169 if (tbl == NULL) 170 goto err_dup; 171 172 for (tmp = tbl; tmp->procname; tmp++) { 173 if (tmp->data >= (void *)&init_net && 174 tmp->data < (void *)(&init_net + 1)) 175 tmp->data += (char *)net - (char *)&init_net; 176 else 177 tmp->mode &= ~0222; 178 } 179 } 180 181 net->core.sysctl_hdr = register_net_sysctl_table(net, 182 net_core_path, tbl); 183 if (net->core.sysctl_hdr == NULL) 184 goto err_reg; 185 186 return 0; 187 188 err_reg: 189 if (tbl != net_core_table) 190 kfree(tbl); 191 err_dup: 192 return -ENOMEM; 193 } 194 195 static __net_exit void sysctl_core_net_exit(struct net *net) 196 { 197 struct ctl_table *tbl; 198 199 tbl = net->core.sysctl_hdr->ctl_table_arg; 200 unregister_net_sysctl_table(net->core.sysctl_hdr); 201 BUG_ON(tbl == net_core_table); 202 kfree(tbl); 203 } 204 205 static __net_initdata struct pernet_operations sysctl_core_ops = { 206 .init = sysctl_core_net_init, 207 .exit = sysctl_core_net_exit, 208 }; 209 210 static __init int sysctl_core_init(void) 211 { 212 return register_pernet_subsys(&sysctl_core_ops); 213 } 214 215 __initcall(sysctl_core_init); 216