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, see 23 * <http://www.gnu.org/licenses/>. 24 * 25 * Please send any bug reports or fixes you make to the 26 * email address(es): 27 * lksctp developers <linux-sctp@vger.kernel.org> 28 * 29 * Written or modified by: 30 * Mingqin Liu <liuming@us.ibm.com> 31 * Jon Grimm <jgrimm@us.ibm.com> 32 * Ardelle Fan <ardelle.fan@intel.com> 33 * Ryan Layer <rmlayer@us.ibm.com> 34 * Sridhar Samudrala <sri@us.ibm.com> 35 */ 36 37 #include <net/sctp/structs.h> 38 #include <net/sctp/sctp.h> 39 #include <linux/sysctl.h> 40 41 static int zero = 0; 42 static int one = 1; 43 static int timer_max = 86400000; /* ms in one day */ 44 static int int_max = INT_MAX; 45 static int sack_timer_min = 1; 46 static int sack_timer_max = 500; 47 static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ 48 static int rwnd_scale_max = 16; 49 static unsigned long max_autoclose_min = 0; 50 static unsigned long max_autoclose_max = 51 (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX) 52 ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ; 53 54 extern long sysctl_sctp_mem[3]; 55 extern int sysctl_sctp_rmem[3]; 56 extern int sysctl_sctp_wmem[3]; 57 58 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 59 void __user *buffer, size_t *lenp, 60 loff_t *ppos); 61 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 62 void __user *buffer, size_t *lenp, 63 loff_t *ppos); 64 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 65 void __user *buffer, size_t *lenp, 66 loff_t *ppos); 67 static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 68 void __user *buffer, size_t *lenp, 69 loff_t *ppos); 70 71 static struct ctl_table sctp_table[] = { 72 { 73 .procname = "sctp_mem", 74 .data = &sysctl_sctp_mem, 75 .maxlen = sizeof(sysctl_sctp_mem), 76 .mode = 0644, 77 .proc_handler = proc_doulongvec_minmax 78 }, 79 { 80 .procname = "sctp_rmem", 81 .data = &sysctl_sctp_rmem, 82 .maxlen = sizeof(sysctl_sctp_rmem), 83 .mode = 0644, 84 .proc_handler = proc_dointvec, 85 }, 86 { 87 .procname = "sctp_wmem", 88 .data = &sysctl_sctp_wmem, 89 .maxlen = sizeof(sysctl_sctp_wmem), 90 .mode = 0644, 91 .proc_handler = proc_dointvec, 92 }, 93 94 { /* sentinel */ } 95 }; 96 97 static struct ctl_table sctp_net_table[] = { 98 { 99 .procname = "rto_initial", 100 .data = &init_net.sctp.rto_initial, 101 .maxlen = sizeof(unsigned int), 102 .mode = 0644, 103 .proc_handler = proc_dointvec_minmax, 104 .extra1 = &one, 105 .extra2 = &timer_max 106 }, 107 { 108 .procname = "rto_min", 109 .data = &init_net.sctp.rto_min, 110 .maxlen = sizeof(unsigned int), 111 .mode = 0644, 112 .proc_handler = proc_sctp_do_rto_min, 113 .extra1 = &one, 114 .extra2 = &init_net.sctp.rto_max 115 }, 116 { 117 .procname = "rto_max", 118 .data = &init_net.sctp.rto_max, 119 .maxlen = sizeof(unsigned int), 120 .mode = 0644, 121 .proc_handler = proc_sctp_do_rto_max, 122 .extra1 = &init_net.sctp.rto_min, 123 .extra2 = &timer_max 124 }, 125 { 126 .procname = "rto_alpha_exp_divisor", 127 .data = &init_net.sctp.rto_alpha, 128 .maxlen = sizeof(int), 129 .mode = 0444, 130 .proc_handler = proc_dointvec, 131 }, 132 { 133 .procname = "rto_beta_exp_divisor", 134 .data = &init_net.sctp.rto_beta, 135 .maxlen = sizeof(int), 136 .mode = 0444, 137 .proc_handler = proc_dointvec, 138 }, 139 { 140 .procname = "max_burst", 141 .data = &init_net.sctp.max_burst, 142 .maxlen = sizeof(int), 143 .mode = 0644, 144 .proc_handler = proc_dointvec_minmax, 145 .extra1 = &zero, 146 .extra2 = &int_max 147 }, 148 { 149 .procname = "cookie_preserve_enable", 150 .data = &init_net.sctp.cookie_preserve_enable, 151 .maxlen = sizeof(int), 152 .mode = 0644, 153 .proc_handler = proc_dointvec, 154 }, 155 { 156 .procname = "cookie_hmac_alg", 157 .data = &init_net.sctp.sctp_hmac_alg, 158 .maxlen = 8, 159 .mode = 0644, 160 .proc_handler = proc_sctp_do_hmac_alg, 161 }, 162 { 163 .procname = "valid_cookie_life", 164 .data = &init_net.sctp.valid_cookie_life, 165 .maxlen = sizeof(unsigned int), 166 .mode = 0644, 167 .proc_handler = proc_dointvec_minmax, 168 .extra1 = &one, 169 .extra2 = &timer_max 170 }, 171 { 172 .procname = "sack_timeout", 173 .data = &init_net.sctp.sack_timeout, 174 .maxlen = sizeof(int), 175 .mode = 0644, 176 .proc_handler = proc_dointvec_minmax, 177 .extra1 = &sack_timer_min, 178 .extra2 = &sack_timer_max, 179 }, 180 { 181 .procname = "hb_interval", 182 .data = &init_net.sctp.hb_interval, 183 .maxlen = sizeof(unsigned int), 184 .mode = 0644, 185 .proc_handler = proc_dointvec_minmax, 186 .extra1 = &one, 187 .extra2 = &timer_max 188 }, 189 { 190 .procname = "association_max_retrans", 191 .data = &init_net.sctp.max_retrans_association, 192 .maxlen = sizeof(int), 193 .mode = 0644, 194 .proc_handler = proc_dointvec_minmax, 195 .extra1 = &one, 196 .extra2 = &int_max 197 }, 198 { 199 .procname = "path_max_retrans", 200 .data = &init_net.sctp.max_retrans_path, 201 .maxlen = sizeof(int), 202 .mode = 0644, 203 .proc_handler = proc_dointvec_minmax, 204 .extra1 = &one, 205 .extra2 = &int_max 206 }, 207 { 208 .procname = "max_init_retransmits", 209 .data = &init_net.sctp.max_retrans_init, 210 .maxlen = sizeof(int), 211 .mode = 0644, 212 .proc_handler = proc_dointvec_minmax, 213 .extra1 = &one, 214 .extra2 = &int_max 215 }, 216 { 217 .procname = "pf_retrans", 218 .data = &init_net.sctp.pf_retrans, 219 .maxlen = sizeof(int), 220 .mode = 0644, 221 .proc_handler = proc_dointvec_minmax, 222 .extra1 = &zero, 223 .extra2 = &int_max 224 }, 225 { 226 .procname = "sndbuf_policy", 227 .data = &init_net.sctp.sndbuf_policy, 228 .maxlen = sizeof(int), 229 .mode = 0644, 230 .proc_handler = proc_dointvec, 231 }, 232 { 233 .procname = "rcvbuf_policy", 234 .data = &init_net.sctp.rcvbuf_policy, 235 .maxlen = sizeof(int), 236 .mode = 0644, 237 .proc_handler = proc_dointvec, 238 }, 239 { 240 .procname = "default_auto_asconf", 241 .data = &init_net.sctp.default_auto_asconf, 242 .maxlen = sizeof(int), 243 .mode = 0644, 244 .proc_handler = proc_dointvec, 245 }, 246 { 247 .procname = "addip_enable", 248 .data = &init_net.sctp.addip_enable, 249 .maxlen = sizeof(int), 250 .mode = 0644, 251 .proc_handler = proc_dointvec, 252 }, 253 { 254 .procname = "addip_noauth_enable", 255 .data = &init_net.sctp.addip_noauth, 256 .maxlen = sizeof(int), 257 .mode = 0644, 258 .proc_handler = proc_dointvec, 259 }, 260 { 261 .procname = "prsctp_enable", 262 .data = &init_net.sctp.prsctp_enable, 263 .maxlen = sizeof(int), 264 .mode = 0644, 265 .proc_handler = proc_dointvec, 266 }, 267 { 268 .procname = "auth_enable", 269 .data = &init_net.sctp.auth_enable, 270 .maxlen = sizeof(int), 271 .mode = 0644, 272 .proc_handler = proc_sctp_do_auth, 273 }, 274 { 275 .procname = "addr_scope_policy", 276 .data = &init_net.sctp.scope_policy, 277 .maxlen = sizeof(int), 278 .mode = 0644, 279 .proc_handler = proc_dointvec_minmax, 280 .extra1 = &zero, 281 .extra2 = &addr_scope_max, 282 }, 283 { 284 .procname = "rwnd_update_shift", 285 .data = &init_net.sctp.rwnd_upd_shift, 286 .maxlen = sizeof(int), 287 .mode = 0644, 288 .proc_handler = &proc_dointvec_minmax, 289 .extra1 = &one, 290 .extra2 = &rwnd_scale_max, 291 }, 292 { 293 .procname = "max_autoclose", 294 .data = &init_net.sctp.max_autoclose, 295 .maxlen = sizeof(unsigned long), 296 .mode = 0644, 297 .proc_handler = &proc_doulongvec_minmax, 298 .extra1 = &max_autoclose_min, 299 .extra2 = &max_autoclose_max, 300 }, 301 302 { /* sentinel */ } 303 }; 304 305 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 306 void __user *buffer, size_t *lenp, 307 loff_t *ppos) 308 { 309 struct net *net = current->nsproxy->net_ns; 310 char tmp[8]; 311 struct ctl_table tbl; 312 int ret; 313 int changed = 0; 314 char *none = "none"; 315 316 memset(&tbl, 0, sizeof(struct ctl_table)); 317 318 if (write) { 319 tbl.data = tmp; 320 tbl.maxlen = 8; 321 } else { 322 tbl.data = net->sctp.sctp_hmac_alg ? : none; 323 tbl.maxlen = strlen(tbl.data); 324 } 325 ret = proc_dostring(&tbl, write, buffer, lenp, ppos); 326 327 if (write) { 328 #ifdef CONFIG_CRYPTO_MD5 329 if (!strncmp(tmp, "md5", 3)) { 330 net->sctp.sctp_hmac_alg = "md5"; 331 changed = 1; 332 } 333 #endif 334 #ifdef CONFIG_CRYPTO_SHA1 335 if (!strncmp(tmp, "sha1", 4)) { 336 net->sctp.sctp_hmac_alg = "sha1"; 337 changed = 1; 338 } 339 #endif 340 if (!strncmp(tmp, "none", 4)) { 341 net->sctp.sctp_hmac_alg = NULL; 342 changed = 1; 343 } 344 345 if (!changed) 346 ret = -EINVAL; 347 } 348 349 return ret; 350 } 351 352 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 353 void __user *buffer, size_t *lenp, 354 loff_t *ppos) 355 { 356 struct net *net = current->nsproxy->net_ns; 357 int new_value; 358 struct ctl_table tbl; 359 unsigned int min = *(unsigned int *) ctl->extra1; 360 unsigned int max = *(unsigned int *) ctl->extra2; 361 int ret; 362 363 memset(&tbl, 0, sizeof(struct ctl_table)); 364 tbl.maxlen = sizeof(unsigned int); 365 366 if (write) 367 tbl.data = &new_value; 368 else 369 tbl.data = &net->sctp.rto_min; 370 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 371 if (write) { 372 if (ret || new_value > max || new_value < min) 373 return -EINVAL; 374 net->sctp.rto_min = new_value; 375 } 376 return ret; 377 } 378 379 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 380 void __user *buffer, size_t *lenp, 381 loff_t *ppos) 382 { 383 struct net *net = current->nsproxy->net_ns; 384 int new_value; 385 struct ctl_table tbl; 386 unsigned int min = *(unsigned int *) ctl->extra1; 387 unsigned int max = *(unsigned int *) ctl->extra2; 388 int ret; 389 390 memset(&tbl, 0, sizeof(struct ctl_table)); 391 tbl.maxlen = sizeof(unsigned int); 392 393 if (write) 394 tbl.data = &new_value; 395 else 396 tbl.data = &net->sctp.rto_max; 397 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 398 if (write) { 399 if (ret || new_value > max || new_value < min) 400 return -EINVAL; 401 net->sctp.rto_max = new_value; 402 } 403 return ret; 404 } 405 406 static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 407 void __user *buffer, size_t *lenp, 408 loff_t *ppos) 409 { 410 struct net *net = current->nsproxy->net_ns; 411 struct ctl_table tbl; 412 int new_value, ret; 413 414 memset(&tbl, 0, sizeof(struct ctl_table)); 415 tbl.maxlen = sizeof(unsigned int); 416 417 if (write) 418 tbl.data = &new_value; 419 else 420 tbl.data = &net->sctp.auth_enable; 421 422 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 423 424 if (write) { 425 struct sock *sk = net->sctp.ctl_sock; 426 427 net->sctp.auth_enable = new_value; 428 /* Update the value in the control socket */ 429 lock_sock(sk); 430 sctp_sk(sk)->ep->auth_enable = new_value; 431 release_sock(sk); 432 } 433 434 return ret; 435 } 436 437 int sctp_sysctl_net_register(struct net *net) 438 { 439 struct ctl_table *table = sctp_net_table; 440 441 if (!net_eq(net, &init_net)) { 442 int i; 443 444 table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); 445 if (!table) 446 return -ENOMEM; 447 448 for (i = 0; table[i].data; i++) 449 table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; 450 } 451 452 net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); 453 return 0; 454 } 455 456 void sctp_sysctl_net_unregister(struct net *net) 457 { 458 struct ctl_table *table; 459 460 table = net->sctp.sysctl_header->ctl_table_arg; 461 unregister_net_sysctl_table(net->sctp.sysctl_header); 462 kfree(table); 463 } 464 465 static struct ctl_table_header *sctp_sysctl_header; 466 467 /* Sysctl registration. */ 468 void sctp_sysctl_register(void) 469 { 470 sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table); 471 } 472 473 /* Sysctl deregistration. */ 474 void sctp_sysctl_unregister(void) 475 { 476 unregister_net_sysctl_table(sctp_sysctl_header); 477 } 478