1 /* SCTP kernel implementation 2 * (C) Copyright IBM Corp. 2002, 2004 3 * Copyright (c) 2002 Intel Corp. 4 * 5 * This file is part of the SCTP kernel implementation 6 * 7 * Sysctl related interfaces for SCTP. 8 * 9 * This SCTP implementation is free software; 10 * you can redistribute it and/or modify it under the terms of 11 * the GNU General Public License as published by 12 * the Free Software Foundation; either version 2, or (at your option) 13 * any later version. 14 * 15 * This SCTP implementation is distributed in the hope that it 16 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 17 * ************************ 18 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 * See the GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with GNU CC; see the file COPYING. If not, see 23 * <http://www.gnu.org/licenses/>. 24 * 25 * Please send any bug reports or fixes you make to the 26 * email address(es): 27 * lksctp developers <linux-sctp@vger.kernel.org> 28 * 29 * Written or modified by: 30 * Mingqin Liu <liuming@us.ibm.com> 31 * Jon Grimm <jgrimm@us.ibm.com> 32 * Ardelle Fan <ardelle.fan@intel.com> 33 * Ryan Layer <rmlayer@us.ibm.com> 34 * Sridhar Samudrala <sri@us.ibm.com> 35 */ 36 37 #include <net/sctp/structs.h> 38 #include <net/sctp/sctp.h> 39 #include <linux/sysctl.h> 40 41 static int zero = 0; 42 static int one = 1; 43 static int timer_max = 86400000; /* ms in one day */ 44 static int int_max = INT_MAX; 45 static int sack_timer_min = 1; 46 static int sack_timer_max = 500; 47 static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ 48 static int rwnd_scale_max = 16; 49 static unsigned long max_autoclose_min = 0; 50 static unsigned long max_autoclose_max = 51 (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX) 52 ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ; 53 54 extern long sysctl_sctp_mem[3]; 55 extern int sysctl_sctp_rmem[3]; 56 extern int sysctl_sctp_wmem[3]; 57 58 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, 59 int write, 60 void __user *buffer, size_t *lenp, 61 62 loff_t *ppos); 63 static struct ctl_table sctp_table[] = { 64 { 65 .procname = "sctp_mem", 66 .data = &sysctl_sctp_mem, 67 .maxlen = sizeof(sysctl_sctp_mem), 68 .mode = 0644, 69 .proc_handler = proc_doulongvec_minmax 70 }, 71 { 72 .procname = "sctp_rmem", 73 .data = &sysctl_sctp_rmem, 74 .maxlen = sizeof(sysctl_sctp_rmem), 75 .mode = 0644, 76 .proc_handler = proc_dointvec, 77 }, 78 { 79 .procname = "sctp_wmem", 80 .data = &sysctl_sctp_wmem, 81 .maxlen = sizeof(sysctl_sctp_wmem), 82 .mode = 0644, 83 .proc_handler = proc_dointvec, 84 }, 85 86 { /* sentinel */ } 87 }; 88 89 static struct ctl_table sctp_net_table[] = { 90 { 91 .procname = "rto_initial", 92 .data = &init_net.sctp.rto_initial, 93 .maxlen = sizeof(unsigned int), 94 .mode = 0644, 95 .proc_handler = proc_dointvec_minmax, 96 .extra1 = &one, 97 .extra2 = &timer_max 98 }, 99 { 100 .procname = "rto_min", 101 .data = &init_net.sctp.rto_min, 102 .maxlen = sizeof(unsigned int), 103 .mode = 0644, 104 .proc_handler = proc_dointvec_minmax, 105 .extra1 = &one, 106 .extra2 = &timer_max 107 }, 108 { 109 .procname = "rto_max", 110 .data = &init_net.sctp.rto_max, 111 .maxlen = sizeof(unsigned int), 112 .mode = 0644, 113 .proc_handler = proc_dointvec_minmax, 114 .extra1 = &one, 115 .extra2 = &timer_max 116 }, 117 { 118 .procname = "rto_alpha_exp_divisor", 119 .data = &init_net.sctp.rto_alpha, 120 .maxlen = sizeof(int), 121 .mode = 0444, 122 .proc_handler = proc_dointvec, 123 }, 124 { 125 .procname = "rto_beta_exp_divisor", 126 .data = &init_net.sctp.rto_beta, 127 .maxlen = sizeof(int), 128 .mode = 0444, 129 .proc_handler = proc_dointvec, 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 = &zero, 138 .extra2 = &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 .maxlen = 8, 150 .mode = 0644, 151 .proc_handler = proc_sctp_do_hmac_alg, 152 }, 153 { 154 .procname = "valid_cookie_life", 155 .data = &init_net.sctp.valid_cookie_life, 156 .maxlen = sizeof(unsigned int), 157 .mode = 0644, 158 .proc_handler = proc_dointvec_minmax, 159 .extra1 = &one, 160 .extra2 = &timer_max 161 }, 162 { 163 .procname = "sack_timeout", 164 .data = &init_net.sctp.sack_timeout, 165 .maxlen = sizeof(int), 166 .mode = 0644, 167 .proc_handler = proc_dointvec_minmax, 168 .extra1 = &sack_timer_min, 169 .extra2 = &sack_timer_max, 170 }, 171 { 172 .procname = "hb_interval", 173 .data = &init_net.sctp.hb_interval, 174 .maxlen = sizeof(unsigned int), 175 .mode = 0644, 176 .proc_handler = proc_dointvec_minmax, 177 .extra1 = &one, 178 .extra2 = &timer_max 179 }, 180 { 181 .procname = "association_max_retrans", 182 .data = &init_net.sctp.max_retrans_association, 183 .maxlen = sizeof(int), 184 .mode = 0644, 185 .proc_handler = proc_dointvec_minmax, 186 .extra1 = &one, 187 .extra2 = &int_max 188 }, 189 { 190 .procname = "path_max_retrans", 191 .data = &init_net.sctp.max_retrans_path, 192 .maxlen = sizeof(int), 193 .mode = 0644, 194 .proc_handler = proc_dointvec_minmax, 195 .extra1 = &one, 196 .extra2 = &int_max 197 }, 198 { 199 .procname = "max_init_retransmits", 200 .data = &init_net.sctp.max_retrans_init, 201 .maxlen = sizeof(int), 202 .mode = 0644, 203 .proc_handler = proc_dointvec_minmax, 204 .extra1 = &one, 205 .extra2 = &int_max 206 }, 207 { 208 .procname = "pf_retrans", 209 .data = &init_net.sctp.pf_retrans, 210 .maxlen = sizeof(int), 211 .mode = 0644, 212 .proc_handler = proc_dointvec_minmax, 213 .extra1 = &zero, 214 .extra2 = &int_max 215 }, 216 { 217 .procname = "sndbuf_policy", 218 .data = &init_net.sctp.sndbuf_policy, 219 .maxlen = sizeof(int), 220 .mode = 0644, 221 .proc_handler = proc_dointvec, 222 }, 223 { 224 .procname = "rcvbuf_policy", 225 .data = &init_net.sctp.rcvbuf_policy, 226 .maxlen = sizeof(int), 227 .mode = 0644, 228 .proc_handler = proc_dointvec, 229 }, 230 { 231 .procname = "default_auto_asconf", 232 .data = &init_net.sctp.default_auto_asconf, 233 .maxlen = sizeof(int), 234 .mode = 0644, 235 .proc_handler = proc_dointvec, 236 }, 237 { 238 .procname = "addip_enable", 239 .data = &init_net.sctp.addip_enable, 240 .maxlen = sizeof(int), 241 .mode = 0644, 242 .proc_handler = proc_dointvec, 243 }, 244 { 245 .procname = "addip_noauth_enable", 246 .data = &init_net.sctp.addip_noauth, 247 .maxlen = sizeof(int), 248 .mode = 0644, 249 .proc_handler = proc_dointvec, 250 }, 251 { 252 .procname = "prsctp_enable", 253 .data = &init_net.sctp.prsctp_enable, 254 .maxlen = sizeof(int), 255 .mode = 0644, 256 .proc_handler = proc_dointvec, 257 }, 258 { 259 .procname = "auth_enable", 260 .data = &init_net.sctp.auth_enable, 261 .maxlen = sizeof(int), 262 .mode = 0644, 263 .proc_handler = proc_dointvec, 264 }, 265 { 266 .procname = "addr_scope_policy", 267 .data = &init_net.sctp.scope_policy, 268 .maxlen = sizeof(int), 269 .mode = 0644, 270 .proc_handler = proc_dointvec_minmax, 271 .extra1 = &zero, 272 .extra2 = &addr_scope_max, 273 }, 274 { 275 .procname = "rwnd_update_shift", 276 .data = &init_net.sctp.rwnd_upd_shift, 277 .maxlen = sizeof(int), 278 .mode = 0644, 279 .proc_handler = &proc_dointvec_minmax, 280 .extra1 = &one, 281 .extra2 = &rwnd_scale_max, 282 }, 283 { 284 .procname = "max_autoclose", 285 .data = &init_net.sctp.max_autoclose, 286 .maxlen = sizeof(unsigned long), 287 .mode = 0644, 288 .proc_handler = &proc_doulongvec_minmax, 289 .extra1 = &max_autoclose_min, 290 .extra2 = &max_autoclose_max, 291 }, 292 293 { /* sentinel */ } 294 }; 295 296 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, 297 int write, 298 void __user *buffer, size_t *lenp, 299 loff_t *ppos) 300 { 301 struct net *net = current->nsproxy->net_ns; 302 char tmp[8]; 303 struct ctl_table tbl; 304 int ret; 305 int changed = 0; 306 char *none = "none"; 307 308 memset(&tbl, 0, sizeof(struct ctl_table)); 309 310 if (write) { 311 tbl.data = tmp; 312 tbl.maxlen = 8; 313 } else { 314 tbl.data = net->sctp.sctp_hmac_alg ? : none; 315 tbl.maxlen = strlen(tbl.data); 316 } 317 ret = proc_dostring(&tbl, write, buffer, lenp, ppos); 318 319 if (write) { 320 #ifdef CONFIG_CRYPTO_MD5 321 if (!strncmp(tmp, "md5", 3)) { 322 net->sctp.sctp_hmac_alg = "md5"; 323 changed = 1; 324 } 325 #endif 326 #ifdef CONFIG_CRYPTO_SHA1 327 if (!strncmp(tmp, "sha1", 4)) { 328 net->sctp.sctp_hmac_alg = "sha1"; 329 changed = 1; 330 } 331 #endif 332 if (!strncmp(tmp, "none", 4)) { 333 net->sctp.sctp_hmac_alg = NULL; 334 changed = 1; 335 } 336 337 if (!changed) 338 ret = -EINVAL; 339 } 340 341 return ret; 342 } 343 344 int sctp_sysctl_net_register(struct net *net) 345 { 346 struct ctl_table *table; 347 int i; 348 349 table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); 350 if (!table) 351 return -ENOMEM; 352 353 for (i = 0; table[i].data; i++) 354 table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; 355 356 net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); 357 return 0; 358 } 359 360 void sctp_sysctl_net_unregister(struct net *net) 361 { 362 struct ctl_table *table; 363 364 table = net->sctp.sysctl_header->ctl_table_arg; 365 unregister_net_sysctl_table(net->sctp.sysctl_header); 366 kfree(table); 367 } 368 369 static struct ctl_table_header * sctp_sysctl_header; 370 371 /* Sysctl registration. */ 372 void sctp_sysctl_register(void) 373 { 374 sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table); 375 } 376 377 /* Sysctl deregistration. */ 378 void sctp_sysctl_unregister(void) 379 { 380 unregister_net_sysctl_table(sctp_sysctl_header); 381 } 382