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 = "addr_scope_policy", 282 .data = &init_net.sctp.scope_policy, 283 .maxlen = sizeof(int), 284 .mode = 0644, 285 .proc_handler = proc_dointvec_minmax, 286 .extra1 = SYSCTL_ZERO, 287 .extra2 = &addr_scope_max, 288 }, 289 { 290 .procname = "rwnd_update_shift", 291 .data = &init_net.sctp.rwnd_upd_shift, 292 .maxlen = sizeof(int), 293 .mode = 0644, 294 .proc_handler = &proc_dointvec_minmax, 295 .extra1 = SYSCTL_ONE, 296 .extra2 = &rwnd_scale_max, 297 }, 298 { 299 .procname = "max_autoclose", 300 .data = &init_net.sctp.max_autoclose, 301 .maxlen = sizeof(unsigned long), 302 .mode = 0644, 303 .proc_handler = &proc_doulongvec_minmax, 304 .extra1 = &max_autoclose_min, 305 .extra2 = &max_autoclose_max, 306 }, 307 { 308 .procname = "pf_enable", 309 .data = &init_net.sctp.pf_enable, 310 .maxlen = sizeof(int), 311 .mode = 0644, 312 .proc_handler = proc_dointvec, 313 }, 314 315 { /* sentinel */ } 316 }; 317 318 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 319 void __user *buffer, size_t *lenp, 320 loff_t *ppos) 321 { 322 struct net *net = current->nsproxy->net_ns; 323 struct ctl_table tbl; 324 bool changed = false; 325 char *none = "none"; 326 char tmp[8] = {0}; 327 int ret; 328 329 memset(&tbl, 0, sizeof(struct ctl_table)); 330 331 if (write) { 332 tbl.data = tmp; 333 tbl.maxlen = sizeof(tmp); 334 } else { 335 tbl.data = net->sctp.sctp_hmac_alg ? : none; 336 tbl.maxlen = strlen(tbl.data); 337 } 338 339 ret = proc_dostring(&tbl, write, buffer, lenp, ppos); 340 if (write && ret == 0) { 341 #ifdef CONFIG_CRYPTO_MD5 342 if (!strncmp(tmp, "md5", 3)) { 343 net->sctp.sctp_hmac_alg = "md5"; 344 changed = true; 345 } 346 #endif 347 #ifdef CONFIG_CRYPTO_SHA1 348 if (!strncmp(tmp, "sha1", 4)) { 349 net->sctp.sctp_hmac_alg = "sha1"; 350 changed = true; 351 } 352 #endif 353 if (!strncmp(tmp, "none", 4)) { 354 net->sctp.sctp_hmac_alg = NULL; 355 changed = true; 356 } 357 if (!changed) 358 ret = -EINVAL; 359 } 360 361 return ret; 362 } 363 364 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 365 void __user *buffer, size_t *lenp, 366 loff_t *ppos) 367 { 368 struct net *net = current->nsproxy->net_ns; 369 unsigned int min = *(unsigned int *) ctl->extra1; 370 unsigned int max = *(unsigned int *) ctl->extra2; 371 struct ctl_table tbl; 372 int ret, new_value; 373 374 memset(&tbl, 0, sizeof(struct ctl_table)); 375 tbl.maxlen = sizeof(unsigned int); 376 377 if (write) 378 tbl.data = &new_value; 379 else 380 tbl.data = &net->sctp.rto_min; 381 382 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 383 if (write && ret == 0) { 384 if (new_value > max || new_value < min) 385 return -EINVAL; 386 387 net->sctp.rto_min = new_value; 388 } 389 390 return ret; 391 } 392 393 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 394 void __user *buffer, size_t *lenp, 395 loff_t *ppos) 396 { 397 struct net *net = current->nsproxy->net_ns; 398 unsigned int min = *(unsigned int *) ctl->extra1; 399 unsigned int max = *(unsigned int *) ctl->extra2; 400 struct ctl_table tbl; 401 int ret, new_value; 402 403 memset(&tbl, 0, sizeof(struct ctl_table)); 404 tbl.maxlen = sizeof(unsigned int); 405 406 if (write) 407 tbl.data = &new_value; 408 else 409 tbl.data = &net->sctp.rto_max; 410 411 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 412 if (write && ret == 0) { 413 if (new_value > max || new_value < min) 414 return -EINVAL; 415 416 net->sctp.rto_max = new_value; 417 } 418 419 return ret; 420 } 421 422 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, 423 void __user *buffer, size_t *lenp, 424 loff_t *ppos) 425 { 426 if (write) 427 pr_warn_once("Changing rto_alpha or rto_beta may lead to " 428 "suboptimal rtt/srtt estimations!\n"); 429 430 return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); 431 } 432 433 static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 434 void __user *buffer, size_t *lenp, 435 loff_t *ppos) 436 { 437 struct net *net = current->nsproxy->net_ns; 438 struct ctl_table tbl; 439 int new_value, ret; 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.auth_enable; 448 449 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 450 if (write && ret == 0) { 451 struct sock *sk = net->sctp.ctl_sock; 452 453 net->sctp.auth_enable = new_value; 454 /* Update the value in the control socket */ 455 lock_sock(sk); 456 sctp_sk(sk)->ep->auth_enable = new_value; 457 release_sock(sk); 458 } 459 460 return ret; 461 } 462 463 int sctp_sysctl_net_register(struct net *net) 464 { 465 struct ctl_table *table; 466 int i; 467 468 table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); 469 if (!table) 470 return -ENOMEM; 471 472 for (i = 0; table[i].data; i++) 473 table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; 474 475 net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); 476 if (net->sctp.sysctl_header == NULL) { 477 kfree(table); 478 return -ENOMEM; 479 } 480 return 0; 481 } 482 483 void sctp_sysctl_net_unregister(struct net *net) 484 { 485 struct ctl_table *table; 486 487 table = net->sctp.sysctl_header->ctl_table_arg; 488 unregister_net_sysctl_table(net->sctp.sysctl_header); 489 kfree(table); 490 } 491 492 static struct ctl_table_header *sctp_sysctl_header; 493 494 /* Sysctl registration. */ 495 void sctp_sysctl_register(void) 496 { 497 sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table); 498 } 499 500 /* Sysctl deregistration. */ 501 void sctp_sysctl_unregister(void) 502 { 503 unregister_net_sysctl_table(sctp_sysctl_header); 504 } 505