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