1 /* SCTP kernel implementation 2 * (C) Copyright IBM Corp. 2002, 2004 3 * Copyright (c) 2002 Intel Corp. 4 * 5 * This file is part of the SCTP kernel implementation 6 * 7 * Sysctl related interfaces for SCTP. 8 * 9 * This SCTP implementation is free software; 10 * you can redistribute it and/or modify it under the terms of 11 * the GNU General Public License as published by 12 * the Free Software Foundation; either version 2, or (at your option) 13 * any later version. 14 * 15 * This SCTP implementation is distributed in the hope that it 16 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 17 * ************************ 18 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 * See the GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with GNU CC; see the file COPYING. If not, write to 23 * the Free Software Foundation, 59 Temple Place - Suite 330, 24 * Boston, MA 02111-1307, USA. 25 * 26 * Please send any bug reports or fixes you make to the 27 * email address(es): 28 * lksctp developers <linux-sctp@vger.kernel.org> 29 * 30 * Written or modified by: 31 * Mingqin Liu <liuming@us.ibm.com> 32 * Jon Grimm <jgrimm@us.ibm.com> 33 * Ardelle Fan <ardelle.fan@intel.com> 34 * Ryan Layer <rmlayer@us.ibm.com> 35 * Sridhar Samudrala <sri@us.ibm.com> 36 */ 37 38 #include <net/sctp/structs.h> 39 #include <net/sctp/sctp.h> 40 #include <linux/sysctl.h> 41 42 static int zero = 0; 43 static int one = 1; 44 static int timer_max = 86400000; /* ms in one day */ 45 static int int_max = INT_MAX; 46 static int sack_timer_min = 1; 47 static int sack_timer_max = 500; 48 static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ 49 static int rwnd_scale_max = 16; 50 static unsigned long max_autoclose_min = 0; 51 static unsigned long max_autoclose_max = 52 (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX) 53 ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ; 54 55 extern long sysctl_sctp_mem[3]; 56 extern int sysctl_sctp_rmem[3]; 57 extern int sysctl_sctp_wmem[3]; 58 59 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, 60 int write, 61 void __user *buffer, size_t *lenp, 62 63 loff_t *ppos); 64 static struct ctl_table sctp_table[] = { 65 { 66 .procname = "sctp_mem", 67 .data = &sysctl_sctp_mem, 68 .maxlen = sizeof(sysctl_sctp_mem), 69 .mode = 0644, 70 .proc_handler = proc_doulongvec_minmax 71 }, 72 { 73 .procname = "sctp_rmem", 74 .data = &sysctl_sctp_rmem, 75 .maxlen = sizeof(sysctl_sctp_rmem), 76 .mode = 0644, 77 .proc_handler = proc_dointvec, 78 }, 79 { 80 .procname = "sctp_wmem", 81 .data = &sysctl_sctp_wmem, 82 .maxlen = sizeof(sysctl_sctp_wmem), 83 .mode = 0644, 84 .proc_handler = proc_dointvec, 85 }, 86 87 { /* sentinel */ } 88 }; 89 90 static struct ctl_table sctp_net_table[] = { 91 { 92 .procname = "rto_initial", 93 .data = &init_net.sctp.rto_initial, 94 .maxlen = sizeof(unsigned int), 95 .mode = 0644, 96 .proc_handler = proc_dointvec_minmax, 97 .extra1 = &one, 98 .extra2 = &timer_max 99 }, 100 { 101 .procname = "rto_min", 102 .data = &init_net.sctp.rto_min, 103 .maxlen = sizeof(unsigned int), 104 .mode = 0644, 105 .proc_handler = proc_dointvec_minmax, 106 .extra1 = &one, 107 .extra2 = &timer_max 108 }, 109 { 110 .procname = "rto_max", 111 .data = &init_net.sctp.rto_max, 112 .maxlen = sizeof(unsigned int), 113 .mode = 0644, 114 .proc_handler = proc_dointvec_minmax, 115 .extra1 = &one, 116 .extra2 = &timer_max 117 }, 118 { 119 .procname = "rto_alpha_exp_divisor", 120 .data = &init_net.sctp.rto_alpha, 121 .maxlen = sizeof(int), 122 .mode = 0444, 123 .proc_handler = proc_dointvec, 124 }, 125 { 126 .procname = "rto_beta_exp_divisor", 127 .data = &init_net.sctp.rto_beta, 128 .maxlen = sizeof(int), 129 .mode = 0444, 130 .proc_handler = proc_dointvec, 131 }, 132 { 133 .procname = "max_burst", 134 .data = &init_net.sctp.max_burst, 135 .maxlen = sizeof(int), 136 .mode = 0644, 137 .proc_handler = proc_dointvec_minmax, 138 .extra1 = &zero, 139 .extra2 = &int_max 140 }, 141 { 142 .procname = "cookie_preserve_enable", 143 .data = &init_net.sctp.cookie_preserve_enable, 144 .maxlen = sizeof(int), 145 .mode = 0644, 146 .proc_handler = proc_dointvec, 147 }, 148 { 149 .procname = "cookie_hmac_alg", 150 .maxlen = 8, 151 .mode = 0644, 152 .proc_handler = proc_sctp_do_hmac_alg, 153 }, 154 { 155 .procname = "valid_cookie_life", 156 .data = &init_net.sctp.valid_cookie_life, 157 .maxlen = sizeof(unsigned int), 158 .mode = 0644, 159 .proc_handler = proc_dointvec_minmax, 160 .extra1 = &one, 161 .extra2 = &timer_max 162 }, 163 { 164 .procname = "sack_timeout", 165 .data = &init_net.sctp.sack_timeout, 166 .maxlen = sizeof(int), 167 .mode = 0644, 168 .proc_handler = proc_dointvec_minmax, 169 .extra1 = &sack_timer_min, 170 .extra2 = &sack_timer_max, 171 }, 172 { 173 .procname = "hb_interval", 174 .data = &init_net.sctp.hb_interval, 175 .maxlen = sizeof(unsigned int), 176 .mode = 0644, 177 .proc_handler = proc_dointvec_minmax, 178 .extra1 = &one, 179 .extra2 = &timer_max 180 }, 181 { 182 .procname = "association_max_retrans", 183 .data = &init_net.sctp.max_retrans_association, 184 .maxlen = sizeof(int), 185 .mode = 0644, 186 .proc_handler = proc_dointvec_minmax, 187 .extra1 = &one, 188 .extra2 = &int_max 189 }, 190 { 191 .procname = "path_max_retrans", 192 .data = &init_net.sctp.max_retrans_path, 193 .maxlen = sizeof(int), 194 .mode = 0644, 195 .proc_handler = proc_dointvec_minmax, 196 .extra1 = &one, 197 .extra2 = &int_max 198 }, 199 { 200 .procname = "max_init_retransmits", 201 .data = &init_net.sctp.max_retrans_init, 202 .maxlen = sizeof(int), 203 .mode = 0644, 204 .proc_handler = proc_dointvec_minmax, 205 .extra1 = &one, 206 .extra2 = &int_max 207 }, 208 { 209 .procname = "pf_retrans", 210 .data = &init_net.sctp.pf_retrans, 211 .maxlen = sizeof(int), 212 .mode = 0644, 213 .proc_handler = proc_dointvec_minmax, 214 .extra1 = &zero, 215 .extra2 = &int_max 216 }, 217 { 218 .procname = "sndbuf_policy", 219 .data = &init_net.sctp.sndbuf_policy, 220 .maxlen = sizeof(int), 221 .mode = 0644, 222 .proc_handler = proc_dointvec, 223 }, 224 { 225 .procname = "rcvbuf_policy", 226 .data = &init_net.sctp.rcvbuf_policy, 227 .maxlen = sizeof(int), 228 .mode = 0644, 229 .proc_handler = proc_dointvec, 230 }, 231 { 232 .procname = "default_auto_asconf", 233 .data = &init_net.sctp.default_auto_asconf, 234 .maxlen = sizeof(int), 235 .mode = 0644, 236 .proc_handler = proc_dointvec, 237 }, 238 { 239 .procname = "addip_enable", 240 .data = &init_net.sctp.addip_enable, 241 .maxlen = sizeof(int), 242 .mode = 0644, 243 .proc_handler = proc_dointvec, 244 }, 245 { 246 .procname = "addip_noauth_enable", 247 .data = &init_net.sctp.addip_noauth, 248 .maxlen = sizeof(int), 249 .mode = 0644, 250 .proc_handler = proc_dointvec, 251 }, 252 { 253 .procname = "prsctp_enable", 254 .data = &init_net.sctp.prsctp_enable, 255 .maxlen = sizeof(int), 256 .mode = 0644, 257 .proc_handler = proc_dointvec, 258 }, 259 { 260 .procname = "auth_enable", 261 .data = &init_net.sctp.auth_enable, 262 .maxlen = sizeof(int), 263 .mode = 0644, 264 .proc_handler = proc_dointvec, 265 }, 266 { 267 .procname = "addr_scope_policy", 268 .data = &init_net.sctp.scope_policy, 269 .maxlen = sizeof(int), 270 .mode = 0644, 271 .proc_handler = proc_dointvec_minmax, 272 .extra1 = &zero, 273 .extra2 = &addr_scope_max, 274 }, 275 { 276 .procname = "rwnd_update_shift", 277 .data = &init_net.sctp.rwnd_upd_shift, 278 .maxlen = sizeof(int), 279 .mode = 0644, 280 .proc_handler = &proc_dointvec_minmax, 281 .extra1 = &one, 282 .extra2 = &rwnd_scale_max, 283 }, 284 { 285 .procname = "max_autoclose", 286 .data = &init_net.sctp.max_autoclose, 287 .maxlen = sizeof(unsigned long), 288 .mode = 0644, 289 .proc_handler = &proc_doulongvec_minmax, 290 .extra1 = &max_autoclose_min, 291 .extra2 = &max_autoclose_max, 292 }, 293 294 { /* sentinel */ } 295 }; 296 297 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, 298 int write, 299 void __user *buffer, size_t *lenp, 300 loff_t *ppos) 301 { 302 struct net *net = current->nsproxy->net_ns; 303 char tmp[8]; 304 struct ctl_table tbl; 305 int ret; 306 int changed = 0; 307 char *none = "none"; 308 309 memset(&tbl, 0, sizeof(struct ctl_table)); 310 311 if (write) { 312 tbl.data = tmp; 313 tbl.maxlen = 8; 314 } else { 315 tbl.data = net->sctp.sctp_hmac_alg ? : none; 316 tbl.maxlen = strlen(tbl.data); 317 } 318 ret = proc_dostring(&tbl, write, buffer, lenp, ppos); 319 320 if (write) { 321 #ifdef CONFIG_CRYPTO_MD5 322 if (!strncmp(tmp, "md5", 3)) { 323 net->sctp.sctp_hmac_alg = "md5"; 324 changed = 1; 325 } 326 #endif 327 #ifdef CONFIG_CRYPTO_SHA1 328 if (!strncmp(tmp, "sha1", 4)) { 329 net->sctp.sctp_hmac_alg = "sha1"; 330 changed = 1; 331 } 332 #endif 333 if (!strncmp(tmp, "none", 4)) { 334 net->sctp.sctp_hmac_alg = NULL; 335 changed = 1; 336 } 337 338 if (!changed) 339 ret = -EINVAL; 340 } 341 342 return ret; 343 } 344 345 int sctp_sysctl_net_register(struct net *net) 346 { 347 struct ctl_table *table; 348 int i; 349 350 table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); 351 if (!table) 352 return -ENOMEM; 353 354 for (i = 0; table[i].data; i++) 355 table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; 356 357 net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); 358 return 0; 359 } 360 361 void sctp_sysctl_net_unregister(struct net *net) 362 { 363 struct ctl_table *table; 364 365 table = net->sctp.sysctl_header->ctl_table_arg; 366 unregister_net_sysctl_table(net->sctp.sysctl_header); 367 kfree(table); 368 } 369 370 static struct ctl_table_header * sctp_sysctl_header; 371 372 /* Sysctl registration. */ 373 void sctp_sysctl_register(void) 374 { 375 sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table); 376 } 377 378 /* Sysctl deregistration. */ 379 void sctp_sysctl_unregister(void) 380 { 381 unregister_net_sysctl_table(sctp_sysctl_header); 382 } 383