1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* SCTP kernel implementation 3 * (C) Copyright IBM Corp. 2002, 2004 4 * Copyright (c) 2002 Intel Corp. 5 * 6 * This file is part of the SCTP kernel implementation 7 * 8 * Sysctl related interfaces for SCTP. 9 * 10 * Please send any bug reports or fixes you make to the 11 * email address(es): 12 * lksctp developers <linux-sctp@vger.kernel.org> 13 * 14 * Written or modified by: 15 * Mingqin Liu <liuming@us.ibm.com> 16 * Jon Grimm <jgrimm@us.ibm.com> 17 * Ardelle Fan <ardelle.fan@intel.com> 18 * Ryan Layer <rmlayer@us.ibm.com> 19 * Sridhar Samudrala <sri@us.ibm.com> 20 */ 21 22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 23 24 #include <net/sctp/structs.h> 25 #include <net/sctp/sctp.h> 26 #include <linux/sysctl.h> 27 28 static int timer_max = 86400000; /* ms in one day */ 29 static int sack_timer_min = 1; 30 static int sack_timer_max = 500; 31 static int addr_scope_max = SCTP_SCOPE_POLICY_MAX; 32 static int rwnd_scale_max = 16; 33 static int rto_alpha_min = 0; 34 static int rto_beta_min = 0; 35 static int rto_alpha_max = 1000; 36 static int rto_beta_max = 1000; 37 static int pf_expose_max = SCTP_PF_EXPOSE_MAX; 38 static int ps_retrans_max = SCTP_PS_RETRANS_MAX; 39 static int udp_port_max = 65535; 40 41 static unsigned long max_autoclose_min = 0; 42 static unsigned long max_autoclose_max = 43 (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX) 44 ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ; 45 46 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 47 void *buffer, size_t *lenp, loff_t *ppos); 48 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 49 void *buffer, size_t *lenp, loff_t *ppos); 50 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer, 51 size_t *lenp, loff_t *ppos); 52 static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, void *buffer, 53 size_t *lenp, loff_t *ppos); 54 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, 55 void *buffer, size_t *lenp, loff_t *ppos); 56 static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 57 void *buffer, size_t *lenp, loff_t *ppos); 58 59 static struct ctl_table sctp_table[] = { 60 { 61 .procname = "sctp_mem", 62 .data = &sysctl_sctp_mem, 63 .maxlen = sizeof(sysctl_sctp_mem), 64 .mode = 0644, 65 .proc_handler = proc_doulongvec_minmax 66 }, 67 { 68 .procname = "sctp_rmem", 69 .data = &sysctl_sctp_rmem, 70 .maxlen = sizeof(sysctl_sctp_rmem), 71 .mode = 0644, 72 .proc_handler = proc_dointvec, 73 }, 74 { 75 .procname = "sctp_wmem", 76 .data = &sysctl_sctp_wmem, 77 .maxlen = sizeof(sysctl_sctp_wmem), 78 .mode = 0644, 79 .proc_handler = proc_dointvec, 80 }, 81 82 { /* sentinel */ } 83 }; 84 85 static struct ctl_table sctp_net_table[] = { 86 { 87 .procname = "rto_initial", 88 .data = &init_net.sctp.rto_initial, 89 .maxlen = sizeof(unsigned int), 90 .mode = 0644, 91 .proc_handler = proc_dointvec_minmax, 92 .extra1 = SYSCTL_ONE, 93 .extra2 = &timer_max 94 }, 95 { 96 .procname = "rto_min", 97 .data = &init_net.sctp.rto_min, 98 .maxlen = sizeof(unsigned int), 99 .mode = 0644, 100 .proc_handler = proc_sctp_do_rto_min, 101 .extra1 = SYSCTL_ONE, 102 .extra2 = &init_net.sctp.rto_max 103 }, 104 { 105 .procname = "rto_max", 106 .data = &init_net.sctp.rto_max, 107 .maxlen = sizeof(unsigned int), 108 .mode = 0644, 109 .proc_handler = proc_sctp_do_rto_max, 110 .extra1 = &init_net.sctp.rto_min, 111 .extra2 = &timer_max 112 }, 113 { 114 .procname = "rto_alpha_exp_divisor", 115 .data = &init_net.sctp.rto_alpha, 116 .maxlen = sizeof(int), 117 .mode = 0644, 118 .proc_handler = proc_sctp_do_alpha_beta, 119 .extra1 = &rto_alpha_min, 120 .extra2 = &rto_alpha_max, 121 }, 122 { 123 .procname = "rto_beta_exp_divisor", 124 .data = &init_net.sctp.rto_beta, 125 .maxlen = sizeof(int), 126 .mode = 0644, 127 .proc_handler = proc_sctp_do_alpha_beta, 128 .extra1 = &rto_beta_min, 129 .extra2 = &rto_beta_max, 130 }, 131 { 132 .procname = "max_burst", 133 .data = &init_net.sctp.max_burst, 134 .maxlen = sizeof(int), 135 .mode = 0644, 136 .proc_handler = proc_dointvec_minmax, 137 .extra1 = SYSCTL_ZERO, 138 .extra2 = SYSCTL_INT_MAX, 139 }, 140 { 141 .procname = "cookie_preserve_enable", 142 .data = &init_net.sctp.cookie_preserve_enable, 143 .maxlen = sizeof(int), 144 .mode = 0644, 145 .proc_handler = proc_dointvec, 146 }, 147 { 148 .procname = "cookie_hmac_alg", 149 .data = &init_net.sctp.sctp_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 = SYSCTL_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 = SYSCTL_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 = SYSCTL_ONE, 188 .extra2 = SYSCTL_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 = SYSCTL_ONE, 197 .extra2 = SYSCTL_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 = SYSCTL_ONE, 206 .extra2 = SYSCTL_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 = SYSCTL_ZERO, 215 .extra2 = &init_net.sctp.ps_retrans, 216 }, 217 { 218 .procname = "ps_retrans", 219 .data = &init_net.sctp.ps_retrans, 220 .maxlen = sizeof(int), 221 .mode = 0644, 222 .proc_handler = proc_dointvec_minmax, 223 .extra1 = &init_net.sctp.pf_retrans, 224 .extra2 = &ps_retrans_max, 225 }, 226 { 227 .procname = "sndbuf_policy", 228 .data = &init_net.sctp.sndbuf_policy, 229 .maxlen = sizeof(int), 230 .mode = 0644, 231 .proc_handler = proc_dointvec, 232 }, 233 { 234 .procname = "rcvbuf_policy", 235 .data = &init_net.sctp.rcvbuf_policy, 236 .maxlen = sizeof(int), 237 .mode = 0644, 238 .proc_handler = proc_dointvec, 239 }, 240 { 241 .procname = "default_auto_asconf", 242 .data = &init_net.sctp.default_auto_asconf, 243 .maxlen = sizeof(int), 244 .mode = 0644, 245 .proc_handler = proc_dointvec, 246 }, 247 { 248 .procname = "addip_enable", 249 .data = &init_net.sctp.addip_enable, 250 .maxlen = sizeof(int), 251 .mode = 0644, 252 .proc_handler = proc_dointvec, 253 }, 254 { 255 .procname = "addip_noauth_enable", 256 .data = &init_net.sctp.addip_noauth, 257 .maxlen = sizeof(int), 258 .mode = 0644, 259 .proc_handler = proc_dointvec, 260 }, 261 { 262 .procname = "prsctp_enable", 263 .data = &init_net.sctp.prsctp_enable, 264 .maxlen = sizeof(int), 265 .mode = 0644, 266 .proc_handler = proc_dointvec, 267 }, 268 { 269 .procname = "reconf_enable", 270 .data = &init_net.sctp.reconf_enable, 271 .maxlen = sizeof(int), 272 .mode = 0644, 273 .proc_handler = proc_dointvec, 274 }, 275 { 276 .procname = "auth_enable", 277 .data = &init_net.sctp.auth_enable, 278 .maxlen = sizeof(int), 279 .mode = 0644, 280 .proc_handler = proc_sctp_do_auth, 281 }, 282 { 283 .procname = "intl_enable", 284 .data = &init_net.sctp.intl_enable, 285 .maxlen = sizeof(int), 286 .mode = 0644, 287 .proc_handler = proc_dointvec, 288 }, 289 { 290 .procname = "ecn_enable", 291 .data = &init_net.sctp.ecn_enable, 292 .maxlen = sizeof(int), 293 .mode = 0644, 294 .proc_handler = proc_dointvec, 295 }, 296 { 297 .procname = "udp_port", 298 .data = &init_net.sctp.udp_port, 299 .maxlen = sizeof(int), 300 .mode = 0644, 301 .proc_handler = proc_sctp_do_udp_port, 302 .extra1 = SYSCTL_ZERO, 303 .extra2 = &udp_port_max, 304 }, 305 { 306 .procname = "encap_port", 307 .data = &init_net.sctp.encap_port, 308 .maxlen = sizeof(int), 309 .mode = 0644, 310 .proc_handler = proc_dointvec, 311 .extra1 = SYSCTL_ZERO, 312 .extra2 = &udp_port_max, 313 }, 314 { 315 .procname = "addr_scope_policy", 316 .data = &init_net.sctp.scope_policy, 317 .maxlen = sizeof(int), 318 .mode = 0644, 319 .proc_handler = proc_dointvec_minmax, 320 .extra1 = SYSCTL_ZERO, 321 .extra2 = &addr_scope_max, 322 }, 323 { 324 .procname = "rwnd_update_shift", 325 .data = &init_net.sctp.rwnd_upd_shift, 326 .maxlen = sizeof(int), 327 .mode = 0644, 328 .proc_handler = &proc_dointvec_minmax, 329 .extra1 = SYSCTL_ONE, 330 .extra2 = &rwnd_scale_max, 331 }, 332 { 333 .procname = "max_autoclose", 334 .data = &init_net.sctp.max_autoclose, 335 .maxlen = sizeof(unsigned long), 336 .mode = 0644, 337 .proc_handler = &proc_doulongvec_minmax, 338 .extra1 = &max_autoclose_min, 339 .extra2 = &max_autoclose_max, 340 }, 341 { 342 .procname = "pf_enable", 343 .data = &init_net.sctp.pf_enable, 344 .maxlen = sizeof(int), 345 .mode = 0644, 346 .proc_handler = proc_dointvec, 347 }, 348 { 349 .procname = "pf_expose", 350 .data = &init_net.sctp.pf_expose, 351 .maxlen = sizeof(int), 352 .mode = 0644, 353 .proc_handler = proc_dointvec_minmax, 354 .extra1 = SYSCTL_ZERO, 355 .extra2 = &pf_expose_max, 356 }, 357 358 { /* sentinel */ } 359 }; 360 361 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 362 void *buffer, size_t *lenp, loff_t *ppos) 363 { 364 struct net *net = current->nsproxy->net_ns; 365 struct ctl_table tbl; 366 bool changed = false; 367 char *none = "none"; 368 char tmp[8] = {0}; 369 int ret; 370 371 memset(&tbl, 0, sizeof(struct ctl_table)); 372 373 if (write) { 374 tbl.data = tmp; 375 tbl.maxlen = sizeof(tmp); 376 } else { 377 tbl.data = net->sctp.sctp_hmac_alg ? : none; 378 tbl.maxlen = strlen(tbl.data); 379 } 380 381 ret = proc_dostring(&tbl, write, buffer, lenp, ppos); 382 if (write && ret == 0) { 383 #ifdef CONFIG_CRYPTO_MD5 384 if (!strncmp(tmp, "md5", 3)) { 385 net->sctp.sctp_hmac_alg = "md5"; 386 changed = true; 387 } 388 #endif 389 #ifdef CONFIG_CRYPTO_SHA1 390 if (!strncmp(tmp, "sha1", 4)) { 391 net->sctp.sctp_hmac_alg = "sha1"; 392 changed = true; 393 } 394 #endif 395 if (!strncmp(tmp, "none", 4)) { 396 net->sctp.sctp_hmac_alg = NULL; 397 changed = true; 398 } 399 if (!changed) 400 ret = -EINVAL; 401 } 402 403 return ret; 404 } 405 406 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 407 void *buffer, size_t *lenp, loff_t *ppos) 408 { 409 struct net *net = current->nsproxy->net_ns; 410 unsigned int min = *(unsigned int *) ctl->extra1; 411 unsigned int max = *(unsigned int *) ctl->extra2; 412 struct ctl_table tbl; 413 int ret, new_value; 414 415 memset(&tbl, 0, sizeof(struct ctl_table)); 416 tbl.maxlen = sizeof(unsigned int); 417 418 if (write) 419 tbl.data = &new_value; 420 else 421 tbl.data = &net->sctp.rto_min; 422 423 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 424 if (write && ret == 0) { 425 if (new_value > max || new_value < min) 426 return -EINVAL; 427 428 net->sctp.rto_min = new_value; 429 } 430 431 return ret; 432 } 433 434 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 435 void *buffer, size_t *lenp, loff_t *ppos) 436 { 437 struct net *net = current->nsproxy->net_ns; 438 unsigned int min = *(unsigned int *) ctl->extra1; 439 unsigned int max = *(unsigned int *) ctl->extra2; 440 struct ctl_table tbl; 441 int ret, new_value; 442 443 memset(&tbl, 0, sizeof(struct ctl_table)); 444 tbl.maxlen = sizeof(unsigned int); 445 446 if (write) 447 tbl.data = &new_value; 448 else 449 tbl.data = &net->sctp.rto_max; 450 451 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 452 if (write && ret == 0) { 453 if (new_value > max || new_value < min) 454 return -EINVAL; 455 456 net->sctp.rto_max = new_value; 457 } 458 459 return ret; 460 } 461 462 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, 463 void *buffer, size_t *lenp, loff_t *ppos) 464 { 465 if (write) 466 pr_warn_once("Changing rto_alpha or rto_beta may lead to " 467 "suboptimal rtt/srtt estimations!\n"); 468 469 return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); 470 } 471 472 static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 473 void *buffer, size_t *lenp, loff_t *ppos) 474 { 475 struct net *net = current->nsproxy->net_ns; 476 struct ctl_table tbl; 477 int new_value, ret; 478 479 memset(&tbl, 0, sizeof(struct ctl_table)); 480 tbl.maxlen = sizeof(unsigned int); 481 482 if (write) 483 tbl.data = &new_value; 484 else 485 tbl.data = &net->sctp.auth_enable; 486 487 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 488 if (write && ret == 0) { 489 struct sock *sk = net->sctp.ctl_sock; 490 491 net->sctp.auth_enable = new_value; 492 /* Update the value in the control socket */ 493 lock_sock(sk); 494 sctp_sk(sk)->ep->auth_enable = new_value; 495 release_sock(sk); 496 } 497 498 return ret; 499 } 500 501 static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, 502 void *buffer, size_t *lenp, loff_t *ppos) 503 { 504 struct net *net = current->nsproxy->net_ns; 505 unsigned int min = *(unsigned int *)ctl->extra1; 506 unsigned int max = *(unsigned int *)ctl->extra2; 507 struct ctl_table tbl; 508 int ret, new_value; 509 510 memset(&tbl, 0, sizeof(struct ctl_table)); 511 tbl.maxlen = sizeof(unsigned int); 512 513 if (write) 514 tbl.data = &new_value; 515 else 516 tbl.data = &net->sctp.udp_port; 517 518 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 519 if (write && ret == 0) { 520 struct sock *sk = net->sctp.ctl_sock; 521 522 if (new_value > max || new_value < min) 523 return -EINVAL; 524 525 net->sctp.udp_port = new_value; 526 sctp_udp_sock_stop(net); 527 if (new_value) { 528 ret = sctp_udp_sock_start(net); 529 if (ret) 530 net->sctp.udp_port = 0; 531 } 532 533 /* Update the value in the control socket */ 534 lock_sock(sk); 535 sctp_sk(sk)->udp_port = htons(net->sctp.udp_port); 536 release_sock(sk); 537 } 538 539 return ret; 540 } 541 542 int sctp_sysctl_net_register(struct net *net) 543 { 544 struct ctl_table *table; 545 int i; 546 547 table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); 548 if (!table) 549 return -ENOMEM; 550 551 for (i = 0; table[i].data; i++) 552 table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; 553 554 net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); 555 if (net->sctp.sysctl_header == NULL) { 556 kfree(table); 557 return -ENOMEM; 558 } 559 return 0; 560 } 561 562 void sctp_sysctl_net_unregister(struct net *net) 563 { 564 struct ctl_table *table; 565 566 table = net->sctp.sysctl_header->ctl_table_arg; 567 unregister_net_sysctl_table(net->sctp.sysctl_header); 568 kfree(table); 569 } 570 571 static struct ctl_table_header *sctp_sysctl_header; 572 573 /* Sysctl registration. */ 574 void sctp_sysctl_register(void) 575 { 576 sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table); 577 } 578 579 /* Sysctl deregistration. */ 580 void sctp_sysctl_unregister(void) 581 { 582 unregister_net_sysctl_table(sctp_sysctl_header); 583 } 584