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 38 static unsigned long max_autoclose_min = 0; 39 static unsigned long max_autoclose_max = 40 (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX) 41 ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ; 42 43 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 44 void __user *buffer, size_t *lenp, 45 loff_t *ppos); 46 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 47 void __user *buffer, size_t *lenp, 48 loff_t *ppos); 49 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 50 void __user *buffer, size_t *lenp, 51 loff_t *ppos); 52 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, 53 void __user *buffer, size_t *lenp, 54 loff_t *ppos); 55 static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 56 void __user *buffer, size_t *lenp, 57 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 = SYSCTL_INT_MAX, 216 }, 217 { 218 .procname = "sndbuf_policy", 219 .data = &init_net.sctp.sndbuf_policy, 220 .maxlen = sizeof(int), 221 .mode = 0644, 222 .proc_handler = proc_dointvec, 223 }, 224 { 225 .procname = "rcvbuf_policy", 226 .data = &init_net.sctp.rcvbuf_policy, 227 .maxlen = sizeof(int), 228 .mode = 0644, 229 .proc_handler = proc_dointvec, 230 }, 231 { 232 .procname = "default_auto_asconf", 233 .data = &init_net.sctp.default_auto_asconf, 234 .maxlen = sizeof(int), 235 .mode = 0644, 236 .proc_handler = proc_dointvec, 237 }, 238 { 239 .procname = "addip_enable", 240 .data = &init_net.sctp.addip_enable, 241 .maxlen = sizeof(int), 242 .mode = 0644, 243 .proc_handler = proc_dointvec, 244 }, 245 { 246 .procname = "addip_noauth_enable", 247 .data = &init_net.sctp.addip_noauth, 248 .maxlen = sizeof(int), 249 .mode = 0644, 250 .proc_handler = proc_dointvec, 251 }, 252 { 253 .procname = "prsctp_enable", 254 .data = &init_net.sctp.prsctp_enable, 255 .maxlen = sizeof(int), 256 .mode = 0644, 257 .proc_handler = proc_dointvec, 258 }, 259 { 260 .procname = "reconf_enable", 261 .data = &init_net.sctp.reconf_enable, 262 .maxlen = sizeof(int), 263 .mode = 0644, 264 .proc_handler = proc_dointvec, 265 }, 266 { 267 .procname = "auth_enable", 268 .data = &init_net.sctp.auth_enable, 269 .maxlen = sizeof(int), 270 .mode = 0644, 271 .proc_handler = proc_sctp_do_auth, 272 }, 273 { 274 .procname = "intl_enable", 275 .data = &init_net.sctp.intl_enable, 276 .maxlen = sizeof(int), 277 .mode = 0644, 278 .proc_handler = proc_dointvec, 279 }, 280 { 281 .procname = "ecn_enable", 282 .data = &init_net.sctp.ecn_enable, 283 .maxlen = sizeof(int), 284 .mode = 0644, 285 .proc_handler = proc_dointvec, 286 }, 287 { 288 .procname = "addr_scope_policy", 289 .data = &init_net.sctp.scope_policy, 290 .maxlen = sizeof(int), 291 .mode = 0644, 292 .proc_handler = proc_dointvec_minmax, 293 .extra1 = SYSCTL_ZERO, 294 .extra2 = &addr_scope_max, 295 }, 296 { 297 .procname = "rwnd_update_shift", 298 .data = &init_net.sctp.rwnd_upd_shift, 299 .maxlen = sizeof(int), 300 .mode = 0644, 301 .proc_handler = &proc_dointvec_minmax, 302 .extra1 = SYSCTL_ONE, 303 .extra2 = &rwnd_scale_max, 304 }, 305 { 306 .procname = "max_autoclose", 307 .data = &init_net.sctp.max_autoclose, 308 .maxlen = sizeof(unsigned long), 309 .mode = 0644, 310 .proc_handler = &proc_doulongvec_minmax, 311 .extra1 = &max_autoclose_min, 312 .extra2 = &max_autoclose_max, 313 }, 314 { 315 .procname = "pf_enable", 316 .data = &init_net.sctp.pf_enable, 317 .maxlen = sizeof(int), 318 .mode = 0644, 319 .proc_handler = proc_dointvec, 320 }, 321 322 { /* sentinel */ } 323 }; 324 325 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 326 void __user *buffer, size_t *lenp, 327 loff_t *ppos) 328 { 329 struct net *net = current->nsproxy->net_ns; 330 struct ctl_table tbl; 331 bool changed = false; 332 char *none = "none"; 333 char tmp[8] = {0}; 334 int ret; 335 336 memset(&tbl, 0, sizeof(struct ctl_table)); 337 338 if (write) { 339 tbl.data = tmp; 340 tbl.maxlen = sizeof(tmp); 341 } else { 342 tbl.data = net->sctp.sctp_hmac_alg ? : none; 343 tbl.maxlen = strlen(tbl.data); 344 } 345 346 ret = proc_dostring(&tbl, write, buffer, lenp, ppos); 347 if (write && ret == 0) { 348 #ifdef CONFIG_CRYPTO_MD5 349 if (!strncmp(tmp, "md5", 3)) { 350 net->sctp.sctp_hmac_alg = "md5"; 351 changed = true; 352 } 353 #endif 354 #ifdef CONFIG_CRYPTO_SHA1 355 if (!strncmp(tmp, "sha1", 4)) { 356 net->sctp.sctp_hmac_alg = "sha1"; 357 changed = true; 358 } 359 #endif 360 if (!strncmp(tmp, "none", 4)) { 361 net->sctp.sctp_hmac_alg = NULL; 362 changed = true; 363 } 364 if (!changed) 365 ret = -EINVAL; 366 } 367 368 return ret; 369 } 370 371 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 372 void __user *buffer, size_t *lenp, 373 loff_t *ppos) 374 { 375 struct net *net = current->nsproxy->net_ns; 376 unsigned int min = *(unsigned int *) ctl->extra1; 377 unsigned int max = *(unsigned int *) ctl->extra2; 378 struct ctl_table tbl; 379 int ret, new_value; 380 381 memset(&tbl, 0, sizeof(struct ctl_table)); 382 tbl.maxlen = sizeof(unsigned int); 383 384 if (write) 385 tbl.data = &new_value; 386 else 387 tbl.data = &net->sctp.rto_min; 388 389 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 390 if (write && ret == 0) { 391 if (new_value > max || new_value < min) 392 return -EINVAL; 393 394 net->sctp.rto_min = new_value; 395 } 396 397 return ret; 398 } 399 400 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 401 void __user *buffer, size_t *lenp, 402 loff_t *ppos) 403 { 404 struct net *net = current->nsproxy->net_ns; 405 unsigned int min = *(unsigned int *) ctl->extra1; 406 unsigned int max = *(unsigned int *) ctl->extra2; 407 struct ctl_table tbl; 408 int ret, new_value; 409 410 memset(&tbl, 0, sizeof(struct ctl_table)); 411 tbl.maxlen = sizeof(unsigned int); 412 413 if (write) 414 tbl.data = &new_value; 415 else 416 tbl.data = &net->sctp.rto_max; 417 418 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 419 if (write && ret == 0) { 420 if (new_value > max || new_value < min) 421 return -EINVAL; 422 423 net->sctp.rto_max = new_value; 424 } 425 426 return ret; 427 } 428 429 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, 430 void __user *buffer, size_t *lenp, 431 loff_t *ppos) 432 { 433 if (write) 434 pr_warn_once("Changing rto_alpha or rto_beta may lead to " 435 "suboptimal rtt/srtt estimations!\n"); 436 437 return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); 438 } 439 440 static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 441 void __user *buffer, size_t *lenp, 442 loff_t *ppos) 443 { 444 struct net *net = current->nsproxy->net_ns; 445 struct ctl_table tbl; 446 int new_value, ret; 447 448 memset(&tbl, 0, sizeof(struct ctl_table)); 449 tbl.maxlen = sizeof(unsigned int); 450 451 if (write) 452 tbl.data = &new_value; 453 else 454 tbl.data = &net->sctp.auth_enable; 455 456 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 457 if (write && ret == 0) { 458 struct sock *sk = net->sctp.ctl_sock; 459 460 net->sctp.auth_enable = new_value; 461 /* Update the value in the control socket */ 462 lock_sock(sk); 463 sctp_sk(sk)->ep->auth_enable = new_value; 464 release_sock(sk); 465 } 466 467 return ret; 468 } 469 470 int sctp_sysctl_net_register(struct net *net) 471 { 472 struct ctl_table *table; 473 int i; 474 475 table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); 476 if (!table) 477 return -ENOMEM; 478 479 for (i = 0; table[i].data; i++) 480 table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; 481 482 net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); 483 if (net->sctp.sysctl_header == NULL) { 484 kfree(table); 485 return -ENOMEM; 486 } 487 return 0; 488 } 489 490 void sctp_sysctl_net_unregister(struct net *net) 491 { 492 struct ctl_table *table; 493 494 table = net->sctp.sysctl_header->ctl_table_arg; 495 unregister_net_sysctl_table(net->sctp.sysctl_header); 496 kfree(table); 497 } 498 499 static struct ctl_table_header *sctp_sysctl_header; 500 501 /* Sysctl registration. */ 502 void sctp_sysctl_register(void) 503 { 504 sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table); 505 } 506 507 /* Sysctl deregistration. */ 508 void sctp_sysctl_unregister(void) 509 { 510 unregister_net_sysctl_table(sctp_sysctl_header); 511 } 512