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