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 static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write, 59 void *buffer, size_t *lenp, loff_t *ppos); 60 61 static struct ctl_table sctp_table[] = { 62 { 63 .procname = "sctp_mem", 64 .data = &sysctl_sctp_mem, 65 .maxlen = sizeof(sysctl_sctp_mem), 66 .mode = 0644, 67 .proc_handler = proc_doulongvec_minmax 68 }, 69 { 70 .procname = "sctp_rmem", 71 .data = &sysctl_sctp_rmem, 72 .maxlen = sizeof(sysctl_sctp_rmem), 73 .mode = 0644, 74 .proc_handler = proc_dointvec, 75 }, 76 { 77 .procname = "sctp_wmem", 78 .data = &sysctl_sctp_wmem, 79 .maxlen = sizeof(sysctl_sctp_wmem), 80 .mode = 0644, 81 .proc_handler = proc_dointvec, 82 }, 83 84 { /* sentinel */ } 85 }; 86 87 static struct ctl_table sctp_net_table[] = { 88 { 89 .procname = "rto_initial", 90 .data = &init_net.sctp.rto_initial, 91 .maxlen = sizeof(unsigned int), 92 .mode = 0644, 93 .proc_handler = proc_dointvec_minmax, 94 .extra1 = SYSCTL_ONE, 95 .extra2 = &timer_max 96 }, 97 { 98 .procname = "rto_min", 99 .data = &init_net.sctp.rto_min, 100 .maxlen = sizeof(unsigned int), 101 .mode = 0644, 102 .proc_handler = proc_sctp_do_rto_min, 103 .extra1 = SYSCTL_ONE, 104 .extra2 = &init_net.sctp.rto_max 105 }, 106 { 107 .procname = "rto_max", 108 .data = &init_net.sctp.rto_max, 109 .maxlen = sizeof(unsigned int), 110 .mode = 0644, 111 .proc_handler = proc_sctp_do_rto_max, 112 .extra1 = &init_net.sctp.rto_min, 113 .extra2 = &timer_max 114 }, 115 { 116 .procname = "rto_alpha_exp_divisor", 117 .data = &init_net.sctp.rto_alpha, 118 .maxlen = sizeof(int), 119 .mode = 0644, 120 .proc_handler = proc_sctp_do_alpha_beta, 121 .extra1 = &rto_alpha_min, 122 .extra2 = &rto_alpha_max, 123 }, 124 { 125 .procname = "rto_beta_exp_divisor", 126 .data = &init_net.sctp.rto_beta, 127 .maxlen = sizeof(int), 128 .mode = 0644, 129 .proc_handler = proc_sctp_do_alpha_beta, 130 .extra1 = &rto_beta_min, 131 .extra2 = &rto_beta_max, 132 }, 133 { 134 .procname = "max_burst", 135 .data = &init_net.sctp.max_burst, 136 .maxlen = sizeof(int), 137 .mode = 0644, 138 .proc_handler = proc_dointvec_minmax, 139 .extra1 = SYSCTL_ZERO, 140 .extra2 = SYSCTL_INT_MAX, 141 }, 142 { 143 .procname = "cookie_preserve_enable", 144 .data = &init_net.sctp.cookie_preserve_enable, 145 .maxlen = sizeof(int), 146 .mode = 0644, 147 .proc_handler = proc_dointvec, 148 }, 149 { 150 .procname = "cookie_hmac_alg", 151 .data = &init_net.sctp.sctp_hmac_alg, 152 .maxlen = 8, 153 .mode = 0644, 154 .proc_handler = proc_sctp_do_hmac_alg, 155 }, 156 { 157 .procname = "valid_cookie_life", 158 .data = &init_net.sctp.valid_cookie_life, 159 .maxlen = sizeof(unsigned int), 160 .mode = 0644, 161 .proc_handler = proc_dointvec_minmax, 162 .extra1 = SYSCTL_ONE, 163 .extra2 = &timer_max 164 }, 165 { 166 .procname = "sack_timeout", 167 .data = &init_net.sctp.sack_timeout, 168 .maxlen = sizeof(int), 169 .mode = 0644, 170 .proc_handler = proc_dointvec_minmax, 171 .extra1 = &sack_timer_min, 172 .extra2 = &sack_timer_max, 173 }, 174 { 175 .procname = "hb_interval", 176 .data = &init_net.sctp.hb_interval, 177 .maxlen = sizeof(unsigned int), 178 .mode = 0644, 179 .proc_handler = proc_dointvec_minmax, 180 .extra1 = SYSCTL_ONE, 181 .extra2 = &timer_max 182 }, 183 { 184 .procname = "association_max_retrans", 185 .data = &init_net.sctp.max_retrans_association, 186 .maxlen = sizeof(int), 187 .mode = 0644, 188 .proc_handler = proc_dointvec_minmax, 189 .extra1 = SYSCTL_ONE, 190 .extra2 = SYSCTL_INT_MAX, 191 }, 192 { 193 .procname = "path_max_retrans", 194 .data = &init_net.sctp.max_retrans_path, 195 .maxlen = sizeof(int), 196 .mode = 0644, 197 .proc_handler = proc_dointvec_minmax, 198 .extra1 = SYSCTL_ONE, 199 .extra2 = SYSCTL_INT_MAX, 200 }, 201 { 202 .procname = "max_init_retransmits", 203 .data = &init_net.sctp.max_retrans_init, 204 .maxlen = sizeof(int), 205 .mode = 0644, 206 .proc_handler = proc_dointvec_minmax, 207 .extra1 = SYSCTL_ONE, 208 .extra2 = SYSCTL_INT_MAX, 209 }, 210 { 211 .procname = "pf_retrans", 212 .data = &init_net.sctp.pf_retrans, 213 .maxlen = sizeof(int), 214 .mode = 0644, 215 .proc_handler = proc_dointvec_minmax, 216 .extra1 = SYSCTL_ZERO, 217 .extra2 = &init_net.sctp.ps_retrans, 218 }, 219 { 220 .procname = "ps_retrans", 221 .data = &init_net.sctp.ps_retrans, 222 .maxlen = sizeof(int), 223 .mode = 0644, 224 .proc_handler = proc_dointvec_minmax, 225 .extra1 = &init_net.sctp.pf_retrans, 226 .extra2 = &ps_retrans_max, 227 }, 228 { 229 .procname = "sndbuf_policy", 230 .data = &init_net.sctp.sndbuf_policy, 231 .maxlen = sizeof(int), 232 .mode = 0644, 233 .proc_handler = proc_dointvec, 234 }, 235 { 236 .procname = "rcvbuf_policy", 237 .data = &init_net.sctp.rcvbuf_policy, 238 .maxlen = sizeof(int), 239 .mode = 0644, 240 .proc_handler = proc_dointvec, 241 }, 242 { 243 .procname = "default_auto_asconf", 244 .data = &init_net.sctp.default_auto_asconf, 245 .maxlen = sizeof(int), 246 .mode = 0644, 247 .proc_handler = proc_dointvec, 248 }, 249 { 250 .procname = "addip_enable", 251 .data = &init_net.sctp.addip_enable, 252 .maxlen = sizeof(int), 253 .mode = 0644, 254 .proc_handler = proc_dointvec, 255 }, 256 { 257 .procname = "addip_noauth_enable", 258 .data = &init_net.sctp.addip_noauth, 259 .maxlen = sizeof(int), 260 .mode = 0644, 261 .proc_handler = proc_dointvec, 262 }, 263 { 264 .procname = "prsctp_enable", 265 .data = &init_net.sctp.prsctp_enable, 266 .maxlen = sizeof(int), 267 .mode = 0644, 268 .proc_handler = proc_dointvec, 269 }, 270 { 271 .procname = "reconf_enable", 272 .data = &init_net.sctp.reconf_enable, 273 .maxlen = sizeof(int), 274 .mode = 0644, 275 .proc_handler = proc_dointvec, 276 }, 277 { 278 .procname = "auth_enable", 279 .data = &init_net.sctp.auth_enable, 280 .maxlen = sizeof(int), 281 .mode = 0644, 282 .proc_handler = proc_sctp_do_auth, 283 }, 284 { 285 .procname = "intl_enable", 286 .data = &init_net.sctp.intl_enable, 287 .maxlen = sizeof(int), 288 .mode = 0644, 289 .proc_handler = proc_dointvec, 290 }, 291 { 292 .procname = "ecn_enable", 293 .data = &init_net.sctp.ecn_enable, 294 .maxlen = sizeof(int), 295 .mode = 0644, 296 .proc_handler = proc_dointvec, 297 }, 298 { 299 .procname = "plpmtud_probe_interval", 300 .data = &init_net.sctp.probe_interval, 301 .maxlen = sizeof(int), 302 .mode = 0644, 303 .proc_handler = proc_sctp_do_probe_interval, 304 }, 305 { 306 .procname = "udp_port", 307 .data = &init_net.sctp.udp_port, 308 .maxlen = sizeof(int), 309 .mode = 0644, 310 .proc_handler = proc_sctp_do_udp_port, 311 .extra1 = SYSCTL_ZERO, 312 .extra2 = &udp_port_max, 313 }, 314 { 315 .procname = "encap_port", 316 .data = &init_net.sctp.encap_port, 317 .maxlen = sizeof(int), 318 .mode = 0644, 319 .proc_handler = proc_dointvec_minmax, 320 .extra1 = SYSCTL_ZERO, 321 .extra2 = &udp_port_max, 322 }, 323 { 324 .procname = "addr_scope_policy", 325 .data = &init_net.sctp.scope_policy, 326 .maxlen = sizeof(int), 327 .mode = 0644, 328 .proc_handler = proc_dointvec_minmax, 329 .extra1 = SYSCTL_ZERO, 330 .extra2 = &addr_scope_max, 331 }, 332 { 333 .procname = "rwnd_update_shift", 334 .data = &init_net.sctp.rwnd_upd_shift, 335 .maxlen = sizeof(int), 336 .mode = 0644, 337 .proc_handler = &proc_dointvec_minmax, 338 .extra1 = SYSCTL_ONE, 339 .extra2 = &rwnd_scale_max, 340 }, 341 { 342 .procname = "max_autoclose", 343 .data = &init_net.sctp.max_autoclose, 344 .maxlen = sizeof(unsigned long), 345 .mode = 0644, 346 .proc_handler = &proc_doulongvec_minmax, 347 .extra1 = &max_autoclose_min, 348 .extra2 = &max_autoclose_max, 349 }, 350 #ifdef CONFIG_NET_L3_MASTER_DEV 351 { 352 .procname = "l3mdev_accept", 353 .data = &init_net.sctp.l3mdev_accept, 354 .maxlen = sizeof(int), 355 .mode = 0644, 356 .proc_handler = proc_dointvec_minmax, 357 .extra1 = SYSCTL_ZERO, 358 .extra2 = SYSCTL_ONE, 359 }, 360 #endif 361 { 362 .procname = "pf_enable", 363 .data = &init_net.sctp.pf_enable, 364 .maxlen = sizeof(int), 365 .mode = 0644, 366 .proc_handler = proc_dointvec, 367 }, 368 { 369 .procname = "pf_expose", 370 .data = &init_net.sctp.pf_expose, 371 .maxlen = sizeof(int), 372 .mode = 0644, 373 .proc_handler = proc_dointvec_minmax, 374 .extra1 = SYSCTL_ZERO, 375 .extra2 = &pf_expose_max, 376 }, 377 378 { /* sentinel */ } 379 }; 380 381 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 382 void *buffer, size_t *lenp, loff_t *ppos) 383 { 384 struct net *net = current->nsproxy->net_ns; 385 struct ctl_table tbl; 386 bool changed = false; 387 char *none = "none"; 388 char tmp[8] = {0}; 389 int ret; 390 391 memset(&tbl, 0, sizeof(struct ctl_table)); 392 393 if (write) { 394 tbl.data = tmp; 395 tbl.maxlen = sizeof(tmp); 396 } else { 397 tbl.data = net->sctp.sctp_hmac_alg ? : none; 398 tbl.maxlen = strlen(tbl.data); 399 } 400 401 ret = proc_dostring(&tbl, write, buffer, lenp, ppos); 402 if (write && ret == 0) { 403 #ifdef CONFIG_CRYPTO_MD5 404 if (!strncmp(tmp, "md5", 3)) { 405 net->sctp.sctp_hmac_alg = "md5"; 406 changed = true; 407 } 408 #endif 409 #ifdef CONFIG_CRYPTO_SHA1 410 if (!strncmp(tmp, "sha1", 4)) { 411 net->sctp.sctp_hmac_alg = "sha1"; 412 changed = true; 413 } 414 #endif 415 if (!strncmp(tmp, "none", 4)) { 416 net->sctp.sctp_hmac_alg = NULL; 417 changed = true; 418 } 419 if (!changed) 420 ret = -EINVAL; 421 } 422 423 return ret; 424 } 425 426 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 427 void *buffer, size_t *lenp, loff_t *ppos) 428 { 429 struct net *net = current->nsproxy->net_ns; 430 unsigned int min = *(unsigned int *) ctl->extra1; 431 unsigned int max = *(unsigned int *) ctl->extra2; 432 struct ctl_table tbl; 433 int ret, new_value; 434 435 memset(&tbl, 0, sizeof(struct ctl_table)); 436 tbl.maxlen = sizeof(unsigned int); 437 438 if (write) 439 tbl.data = &new_value; 440 else 441 tbl.data = &net->sctp.rto_min; 442 443 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 444 if (write && ret == 0) { 445 if (new_value > max || new_value < min) 446 return -EINVAL; 447 448 net->sctp.rto_min = new_value; 449 } 450 451 return ret; 452 } 453 454 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 455 void *buffer, size_t *lenp, loff_t *ppos) 456 { 457 struct net *net = current->nsproxy->net_ns; 458 unsigned int min = *(unsigned int *) ctl->extra1; 459 unsigned int max = *(unsigned int *) ctl->extra2; 460 struct ctl_table tbl; 461 int ret, new_value; 462 463 memset(&tbl, 0, sizeof(struct ctl_table)); 464 tbl.maxlen = sizeof(unsigned int); 465 466 if (write) 467 tbl.data = &new_value; 468 else 469 tbl.data = &net->sctp.rto_max; 470 471 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 472 if (write && ret == 0) { 473 if (new_value > max || new_value < min) 474 return -EINVAL; 475 476 net->sctp.rto_max = new_value; 477 } 478 479 return ret; 480 } 481 482 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, 483 void *buffer, size_t *lenp, loff_t *ppos) 484 { 485 if (write) 486 pr_warn_once("Changing rto_alpha or rto_beta may lead to " 487 "suboptimal rtt/srtt estimations!\n"); 488 489 return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); 490 } 491 492 static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 493 void *buffer, size_t *lenp, loff_t *ppos) 494 { 495 struct net *net = current->nsproxy->net_ns; 496 struct ctl_table tbl; 497 int new_value, ret; 498 499 memset(&tbl, 0, sizeof(struct ctl_table)); 500 tbl.maxlen = sizeof(unsigned int); 501 502 if (write) 503 tbl.data = &new_value; 504 else 505 tbl.data = &net->sctp.auth_enable; 506 507 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 508 if (write && ret == 0) { 509 struct sock *sk = net->sctp.ctl_sock; 510 511 net->sctp.auth_enable = new_value; 512 /* Update the value in the control socket */ 513 lock_sock(sk); 514 sctp_sk(sk)->ep->auth_enable = new_value; 515 release_sock(sk); 516 } 517 518 return ret; 519 } 520 521 static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, 522 void *buffer, size_t *lenp, loff_t *ppos) 523 { 524 struct net *net = current->nsproxy->net_ns; 525 unsigned int min = *(unsigned int *)ctl->extra1; 526 unsigned int max = *(unsigned int *)ctl->extra2; 527 struct ctl_table tbl; 528 int ret, new_value; 529 530 memset(&tbl, 0, sizeof(struct ctl_table)); 531 tbl.maxlen = sizeof(unsigned int); 532 533 if (write) 534 tbl.data = &new_value; 535 else 536 tbl.data = &net->sctp.udp_port; 537 538 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 539 if (write && ret == 0) { 540 struct sock *sk = net->sctp.ctl_sock; 541 542 if (new_value > max || new_value < min) 543 return -EINVAL; 544 545 net->sctp.udp_port = new_value; 546 sctp_udp_sock_stop(net); 547 if (new_value) { 548 ret = sctp_udp_sock_start(net); 549 if (ret) 550 net->sctp.udp_port = 0; 551 } 552 553 /* Update the value in the control socket */ 554 lock_sock(sk); 555 sctp_sk(sk)->udp_port = htons(net->sctp.udp_port); 556 release_sock(sk); 557 } 558 559 return ret; 560 } 561 562 static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write, 563 void *buffer, size_t *lenp, loff_t *ppos) 564 { 565 struct net *net = current->nsproxy->net_ns; 566 struct ctl_table tbl; 567 int ret, new_value; 568 569 memset(&tbl, 0, sizeof(struct ctl_table)); 570 tbl.maxlen = sizeof(unsigned int); 571 572 if (write) 573 tbl.data = &new_value; 574 else 575 tbl.data = &net->sctp.probe_interval; 576 577 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 578 if (write && ret == 0) { 579 if (new_value && new_value < SCTP_PROBE_TIMER_MIN) 580 return -EINVAL; 581 582 net->sctp.probe_interval = new_value; 583 } 584 585 return ret; 586 } 587 588 int sctp_sysctl_net_register(struct net *net) 589 { 590 struct ctl_table *table; 591 int i; 592 593 table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); 594 if (!table) 595 return -ENOMEM; 596 597 for (i = 0; table[i].data; i++) 598 table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; 599 600 net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); 601 if (net->sctp.sysctl_header == NULL) { 602 kfree(table); 603 return -ENOMEM; 604 } 605 return 0; 606 } 607 608 void sctp_sysctl_net_unregister(struct net *net) 609 { 610 struct ctl_table *table; 611 612 table = net->sctp.sysctl_header->ctl_table_arg; 613 unregister_net_sysctl_table(net->sctp.sysctl_header); 614 kfree(table); 615 } 616 617 static struct ctl_table_header *sctp_sysctl_header; 618 619 /* Sysctl registration. */ 620 void sctp_sysctl_register(void) 621 { 622 sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table); 623 } 624 625 /* Sysctl deregistration. */ 626 void sctp_sysctl_unregister(void) 627 { 628 unregister_net_sysctl_table(sctp_sysctl_header); 629 } 630