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 28static int timer_max = 86400000; /* ms in one day */ 29static int sack_timer_min = 1; 30static int sack_timer_max = 500; 31static int addr_scope_max = SCTP_SCOPE_POLICY_MAX; 32static int rwnd_scale_max = 16; 33static int rto_alpha_min = 0; 34static int rto_beta_min = 0; 35static int rto_alpha_max = 1000; 36static int rto_beta_max = 1000; 37static int pf_expose_max = SCTP_PF_EXPOSE_MAX; 38static int ps_retrans_max = SCTP_PS_RETRANS_MAX; 39 40static unsigned long max_autoclose_min = 0; 41static unsigned long max_autoclose_max = 42 (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX) 43 ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ; 44 45static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 46 void *buffer, size_t *lenp, loff_t *ppos); 47static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 48 void *buffer, size_t *lenp, loff_t *ppos); 49static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer, 50 size_t *lenp, loff_t *ppos); 51static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, 52 void *buffer, size_t *lenp, loff_t *ppos); 53static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 54 void *buffer, size_t *lenp, loff_t *ppos); 55 56static struct ctl_table sctp_table[] = { 57 { 58 .procname = "sctp_mem", 59 .data = &sysctl_sctp_mem, 60 .maxlen = sizeof(sysctl_sctp_mem), 61 .mode = 0644, 62 .proc_handler = proc_doulongvec_minmax 63 }, 64 { 65 .procname = "sctp_rmem", 66 .data = &sysctl_sctp_rmem, 67 .maxlen = sizeof(sysctl_sctp_rmem), 68 .mode = 0644, 69 .proc_handler = proc_dointvec, 70 }, 71 { 72 .procname = "sctp_wmem", 73 .data = &sysctl_sctp_wmem, 74 .maxlen = sizeof(sysctl_sctp_wmem), 75 .mode = 0644, 76 .proc_handler = proc_dointvec, 77 }, 78 79 { /* sentinel */ } 80}; 81 82/* The following index defines are used in sctp_sysctl_net_register(). 83 * If you add new items to the sctp_net_table, please ensure that 84 * the index values of these defines hold the same meaning indicated by 85 * their macro names when they appear in sctp_net_table. 86 */ 87#define SCTP_RTO_MIN_IDX 0 88#define SCTP_RTO_MAX_IDX 1 89#define SCTP_PF_RETRANS_IDX 2 90#define SCTP_PS_RETRANS_IDX 3 91 92static struct ctl_table sctp_net_table[] = { 93 [SCTP_RTO_MIN_IDX] = { 94 .procname = "rto_min", 95 .data = &init_net.sctp.rto_min, 96 .maxlen = sizeof(unsigned int), 97 .mode = 0644, 98 .proc_handler = proc_sctp_do_rto_min, 99 .extra1 = SYSCTL_ONE, 100 .extra2 = &init_net.sctp.rto_max 101 }, 102 [SCTP_RTO_MAX_IDX] = { 103 .procname = "rto_max", 104 .data = &init_net.sctp.rto_max, 105 .maxlen = sizeof(unsigned int), 106 .mode = 0644, 107 .proc_handler = proc_sctp_do_rto_max, 108 .extra1 = &init_net.sctp.rto_min, 109 .extra2 = &timer_max 110 }, 111 [SCTP_PF_RETRANS_IDX] = { 112 .procname = "pf_retrans", 113 .data = &init_net.sctp.pf_retrans, 114 .maxlen = sizeof(int), 115 .mode = 0644, 116 .proc_handler = proc_dointvec_minmax, 117 .extra1 = SYSCTL_ZERO, 118 .extra2 = &init_net.sctp.ps_retrans, 119 }, 120 [SCTP_PS_RETRANS_IDX] = { 121 .procname = "ps_retrans", 122 .data = &init_net.sctp.ps_retrans, 123 .maxlen = sizeof(int), 124 .mode = 0644, 125 .proc_handler = proc_dointvec_minmax, 126 .extra1 = &init_net.sctp.pf_retrans, 127 .extra2 = &ps_retrans_max, 128 }, 129 { 130 .procname = "rto_initial", 131 .data = &init_net.sctp.rto_initial, 132 .maxlen = sizeof(unsigned int), 133 .mode = 0644, 134 .proc_handler = proc_dointvec_minmax, 135 .extra1 = SYSCTL_ONE, 136 .extra2 = &timer_max 137 }, 138 { 139 .procname = "rto_alpha_exp_divisor", 140 .data = &init_net.sctp.rto_alpha, 141 .maxlen = sizeof(int), 142 .mode = 0644, 143 .proc_handler = proc_sctp_do_alpha_beta, 144 .extra1 = &rto_alpha_min, 145 .extra2 = &rto_alpha_max, 146 }, 147 { 148 .procname = "rto_beta_exp_divisor", 149 .data = &init_net.sctp.rto_beta, 150 .maxlen = sizeof(int), 151 .mode = 0644, 152 .proc_handler = proc_sctp_do_alpha_beta, 153 .extra1 = &rto_beta_min, 154 .extra2 = &rto_beta_max, 155 }, 156 { 157 .procname = "max_burst", 158 .data = &init_net.sctp.max_burst, 159 .maxlen = sizeof(int), 160 .mode = 0644, 161 .proc_handler = proc_dointvec_minmax, 162 .extra1 = SYSCTL_ZERO, 163 .extra2 = SYSCTL_INT_MAX, 164 }, 165 { 166 .procname = "cookie_preserve_enable", 167 .data = &init_net.sctp.cookie_preserve_enable, 168 .maxlen = sizeof(int), 169 .mode = 0644, 170 .proc_handler = proc_dointvec, 171 }, 172 { 173 .procname = "cookie_hmac_alg", 174 .data = &init_net.sctp.sctp_hmac_alg, 175 .maxlen = 8, 176 .mode = 0644, 177 .proc_handler = proc_sctp_do_hmac_alg, 178 }, 179 { 180 .procname = "valid_cookie_life", 181 .data = &init_net.sctp.valid_cookie_life, 182 .maxlen = sizeof(unsigned int), 183 .mode = 0644, 184 .proc_handler = proc_dointvec_minmax, 185 .extra1 = SYSCTL_ONE, 186 .extra2 = &timer_max 187 }, 188 { 189 .procname = "sack_timeout", 190 .data = &init_net.sctp.sack_timeout, 191 .maxlen = sizeof(int), 192 .mode = 0644, 193 .proc_handler = proc_dointvec_minmax, 194 .extra1 = &sack_timer_min, 195 .extra2 = &sack_timer_max, 196 }, 197 { 198 .procname = "hb_interval", 199 .data = &init_net.sctp.hb_interval, 200 .maxlen = sizeof(unsigned int), 201 .mode = 0644, 202 .proc_handler = proc_dointvec_minmax, 203 .extra1 = SYSCTL_ONE, 204 .extra2 = &timer_max 205 }, 206 { 207 .procname = "association_max_retrans", 208 .data = &init_net.sctp.max_retrans_association, 209 .maxlen = sizeof(int), 210 .mode = 0644, 211 .proc_handler = proc_dointvec_minmax, 212 .extra1 = SYSCTL_ONE, 213 .extra2 = SYSCTL_INT_MAX, 214 }, 215 { 216 .procname = "path_max_retrans", 217 .data = &init_net.sctp.max_retrans_path, 218 .maxlen = sizeof(int), 219 .mode = 0644, 220 .proc_handler = proc_dointvec_minmax, 221 .extra1 = SYSCTL_ONE, 222 .extra2 = SYSCTL_INT_MAX, 223 }, 224 { 225 .procname = "max_init_retransmits", 226 .data = &init_net.sctp.max_retrans_init, 227 .maxlen = sizeof(int), 228 .mode = 0644, 229 .proc_handler = proc_dointvec_minmax, 230 .extra1 = SYSCTL_ONE, 231 .extra2 = SYSCTL_INT_MAX, 232 }, 233 { 234 .procname = "sndbuf_policy", 235 .data = &init_net.sctp.sndbuf_policy, 236 .maxlen = sizeof(int), 237 .mode = 0644, 238 .proc_handler = proc_dointvec, 239 }, 240 { 241 .procname = "rcvbuf_policy", 242 .data = &init_net.sctp.rcvbuf_policy, 243 .maxlen = sizeof(int), 244 .mode = 0644, 245 .proc_handler = proc_dointvec, 246 }, 247 { 248 .procname = "default_auto_asconf", 249 .data = &init_net.sctp.default_auto_asconf, 250 .maxlen = sizeof(int), 251 .mode = 0644, 252 .proc_handler = proc_dointvec, 253 }, 254 { 255 .procname = "addip_enable", 256 .data = &init_net.sctp.addip_enable, 257 .maxlen = sizeof(int), 258 .mode = 0644, 259 .proc_handler = proc_dointvec, 260 }, 261 { 262 .procname = "addip_noauth_enable", 263 .data = &init_net.sctp.addip_noauth, 264 .maxlen = sizeof(int), 265 .mode = 0644, 266 .proc_handler = proc_dointvec, 267 }, 268 { 269 .procname = "prsctp_enable", 270 .data = &init_net.sctp.prsctp_enable, 271 .maxlen = sizeof(int), 272 .mode = 0644, 273 .proc_handler = proc_dointvec, 274 }, 275 { 276 .procname = "reconf_enable", 277 .data = &init_net.sctp.reconf_enable, 278 .maxlen = sizeof(int), 279 .mode = 0644, 280 .proc_handler = proc_dointvec, 281 }, 282 { 283 .procname = "auth_enable", 284 .data = &init_net.sctp.auth_enable, 285 .maxlen = sizeof(int), 286 .mode = 0644, 287 .proc_handler = proc_sctp_do_auth, 288 }, 289 { 290 .procname = "intl_enable", 291 .data = &init_net.sctp.intl_enable, 292 .maxlen = sizeof(int), 293 .mode = 0644, 294 .proc_handler = proc_dointvec, 295 }, 296 { 297 .procname = "ecn_enable", 298 .data = &init_net.sctp.ecn_enable, 299 .maxlen = sizeof(int), 300 .mode = 0644, 301 .proc_handler = proc_dointvec, 302 }, 303 { 304 .procname = "addr_scope_policy", 305 .data = &init_net.sctp.scope_policy, 306 .maxlen = sizeof(int), 307 .mode = 0644, 308 .proc_handler = proc_dointvec_minmax, 309 .extra1 = SYSCTL_ZERO, 310 .extra2 = &addr_scope_max, 311 }, 312 { 313 .procname = "rwnd_update_shift", 314 .data = &init_net.sctp.rwnd_upd_shift, 315 .maxlen = sizeof(int), 316 .mode = 0644, 317 .proc_handler = &proc_dointvec_minmax, 318 .extra1 = SYSCTL_ONE, 319 .extra2 = &rwnd_scale_max, 320 }, 321 { 322 .procname = "max_autoclose", 323 .data = &init_net.sctp.max_autoclose, 324 .maxlen = sizeof(unsigned long), 325 .mode = 0644, 326 .proc_handler = &proc_doulongvec_minmax, 327 .extra1 = &max_autoclose_min, 328 .extra2 = &max_autoclose_max, 329 }, 330 { 331 .procname = "pf_enable", 332 .data = &init_net.sctp.pf_enable, 333 .maxlen = sizeof(int), 334 .mode = 0644, 335 .proc_handler = proc_dointvec, 336 }, 337 { 338 .procname = "pf_expose", 339 .data = &init_net.sctp.pf_expose, 340 .maxlen = sizeof(int), 341 .mode = 0644, 342 .proc_handler = proc_dointvec_minmax, 343 .extra1 = SYSCTL_ZERO, 344 .extra2 = &pf_expose_max, 345 }, 346 347 { /* sentinel */ } 348}; 349 350static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 351 void *buffer, size_t *lenp, loff_t *ppos) 352{ 353 struct net *net = current->nsproxy->net_ns; 354 struct ctl_table tbl; 355 bool changed = false; 356 char *none = "none"; 357 char tmp[8] = {0}; 358 int ret; 359 360 memset(&tbl, 0, sizeof(struct ctl_table)); 361 362 if (write) { 363 tbl.data = tmp; 364 tbl.maxlen = sizeof(tmp); 365 } else { 366 tbl.data = net->sctp.sctp_hmac_alg ? : none; 367 tbl.maxlen = strlen(tbl.data); 368 } 369 370 ret = proc_dostring(&tbl, write, buffer, lenp, ppos); 371 if (write && ret == 0) { 372#ifdef CONFIG_CRYPTO_MD5 373 if (!strncmp(tmp, "md5", 3)) { 374 net->sctp.sctp_hmac_alg = "md5"; 375 changed = true; 376 } 377#endif 378#ifdef CONFIG_CRYPTO_SHA1 379 if (!strncmp(tmp, "sha1", 4)) { 380 net->sctp.sctp_hmac_alg = "sha1"; 381 changed = true; 382 } 383#endif 384 if (!strncmp(tmp, "none", 4)) { 385 net->sctp.sctp_hmac_alg = NULL; 386 changed = true; 387 } 388 if (!changed) 389 ret = -EINVAL; 390 } 391 392 return ret; 393} 394 395static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 396 void *buffer, size_t *lenp, loff_t *ppos) 397{ 398 struct net *net = current->nsproxy->net_ns; 399 unsigned int min = *(unsigned int *) ctl->extra1; 400 unsigned int max = *(unsigned int *) ctl->extra2; 401 struct ctl_table tbl; 402 int ret, new_value; 403 404 memset(&tbl, 0, sizeof(struct ctl_table)); 405 tbl.maxlen = sizeof(unsigned int); 406 407 if (write) 408 tbl.data = &new_value; 409 else 410 tbl.data = &net->sctp.rto_min; 411 412 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 413 if (write && ret == 0) { 414 if (new_value > max || new_value < min) 415 return -EINVAL; 416 417 net->sctp.rto_min = new_value; 418 } 419 420 return ret; 421} 422 423static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 424 void *buffer, size_t *lenp, loff_t *ppos) 425{ 426 struct net *net = current->nsproxy->net_ns; 427 unsigned int min = *(unsigned int *) ctl->extra1; 428 unsigned int max = *(unsigned int *) ctl->extra2; 429 struct ctl_table tbl; 430 int ret, new_value; 431 432 memset(&tbl, 0, sizeof(struct ctl_table)); 433 tbl.maxlen = sizeof(unsigned int); 434 435 if (write) 436 tbl.data = &new_value; 437 else 438 tbl.data = &net->sctp.rto_max; 439 440 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 441 if (write && ret == 0) { 442 if (new_value > max || new_value < min) 443 return -EINVAL; 444 445 net->sctp.rto_max = new_value; 446 } 447 448 return ret; 449} 450 451static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, 452 void *buffer, size_t *lenp, loff_t *ppos) 453{ 454 if (write) 455 pr_warn_once("Changing rto_alpha or rto_beta may lead to " 456 "suboptimal rtt/srtt estimations!\n"); 457 458 return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); 459} 460 461static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 462 void *buffer, size_t *lenp, loff_t *ppos) 463{ 464 struct net *net = current->nsproxy->net_ns; 465 struct ctl_table tbl; 466 int new_value, ret; 467 468 memset(&tbl, 0, sizeof(struct ctl_table)); 469 tbl.maxlen = sizeof(unsigned int); 470 471 if (write) 472 tbl.data = &new_value; 473 else 474 tbl.data = &net->sctp.auth_enable; 475 476 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 477 if (write && ret == 0) { 478 struct sock *sk = net->sctp.ctl_sock; 479 480 net->sctp.auth_enable = new_value; 481 /* Update the value in the control socket */ 482 lock_sock(sk); 483 sctp_sk(sk)->ep->auth_enable = new_value; 484 release_sock(sk); 485 } 486 487 return ret; 488} 489 490int sctp_sysctl_net_register(struct net *net) 491{ 492 struct ctl_table *table; 493 int i; 494 495 table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); 496 if (!table) 497 return -ENOMEM; 498 499 for (i = 0; table[i].data; i++) 500 table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; 501 502 table[SCTP_RTO_MIN_IDX].extra2 = &net->sctp.rto_max; 503 table[SCTP_RTO_MAX_IDX].extra1 = &net->sctp.rto_min; 504 table[SCTP_PF_RETRANS_IDX].extra2 = &net->sctp.ps_retrans; 505 table[SCTP_PS_RETRANS_IDX].extra1 = &net->sctp.pf_retrans; 506 507 net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); 508 if (net->sctp.sysctl_header == NULL) { 509 kfree(table); 510 return -ENOMEM; 511 } 512 return 0; 513} 514 515void sctp_sysctl_net_unregister(struct net *net) 516{ 517 struct ctl_table *table; 518 519 table = net->sctp.sysctl_header->ctl_table_arg; 520 unregister_net_sysctl_table(net->sctp.sysctl_header); 521 kfree(table); 522} 523 524static struct ctl_table_header *sctp_sysctl_header; 525 526/* Sysctl registration. */ 527void sctp_sysctl_register(void) 528{ 529 sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table); 530} 531 532/* Sysctl deregistration. */ 533void sctp_sysctl_unregister(void) 534{ 535 unregister_net_sysctl_table(sctp_sysctl_header); 536} 537