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, write to 23 * the Free Software Foundation, 59 Temple Place - Suite 330, 24 * Boston, MA 02111-1307, USA. 25 * 26 * Please send any bug reports or fixes you make to the 27 * email address(es): 28 * lksctp developers <lksctp-developers@lists.sourceforge.net> 29 * 30 * Or submit a bug report through the following website: 31 * http://www.sf.net/projects/lksctp 32 * 33 * Written or modified by: 34 * Mingqin Liu <liuming@us.ibm.com> 35 * Jon Grimm <jgrimm@us.ibm.com> 36 * Ardelle Fan <ardelle.fan@intel.com> 37 * Ryan Layer <rmlayer@us.ibm.com> 38 * Sridhar Samudrala <sri@us.ibm.com> 39 * 40 * Any bugs reported given to us we will try to fix... any fixes shared will 41 * be incorporated into the next SCTP release. 42 */ 43 44 #include <net/sctp/structs.h> 45 #include <net/sctp/sctp.h> 46 #include <linux/sysctl.h> 47 48 static int zero = 0; 49 static int one = 1; 50 static int timer_max = 86400000; /* ms in one day */ 51 static int int_max = INT_MAX; 52 static int sack_timer_min = 1; 53 static int sack_timer_max = 500; 54 static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ 55 static int rwnd_scale_max = 16; 56 static unsigned long max_autoclose_min = 0; 57 static unsigned long max_autoclose_max = 58 (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX) 59 ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ; 60 61 extern long sysctl_sctp_mem[3]; 62 extern int sysctl_sctp_rmem[3]; 63 extern int sysctl_sctp_wmem[3]; 64 65 static int proc_sctp_do_hmac_alg(ctl_table *ctl, 66 int write, 67 void __user *buffer, size_t *lenp, 68 69 loff_t *ppos); 70 static ctl_table sctp_table[] = { 71 { 72 .procname = "sctp_mem", 73 .data = &sysctl_sctp_mem, 74 .maxlen = sizeof(sysctl_sctp_mem), 75 .mode = 0644, 76 .proc_handler = proc_doulongvec_minmax 77 }, 78 { 79 .procname = "sctp_rmem", 80 .data = &sysctl_sctp_rmem, 81 .maxlen = sizeof(sysctl_sctp_rmem), 82 .mode = 0644, 83 .proc_handler = proc_dointvec, 84 }, 85 { 86 .procname = "sctp_wmem", 87 .data = &sysctl_sctp_wmem, 88 .maxlen = sizeof(sysctl_sctp_wmem), 89 .mode = 0644, 90 .proc_handler = proc_dointvec, 91 }, 92 93 { /* sentinel */ } 94 }; 95 96 static ctl_table sctp_net_table[] = { 97 { 98 .procname = "rto_initial", 99 .data = &init_net.sctp.rto_initial, 100 .maxlen = sizeof(unsigned int), 101 .mode = 0644, 102 .proc_handler = proc_dointvec_minmax, 103 .extra1 = &one, 104 .extra2 = &timer_max 105 }, 106 { 107 .procname = "rto_min", 108 .data = &init_net.sctp.rto_min, 109 .maxlen = sizeof(unsigned int), 110 .mode = 0644, 111 .proc_handler = proc_dointvec_minmax, 112 .extra1 = &one, 113 .extra2 = &timer_max 114 }, 115 { 116 .procname = "rto_max", 117 .data = &init_net.sctp.rto_max, 118 .maxlen = sizeof(unsigned int), 119 .mode = 0644, 120 .proc_handler = proc_dointvec_minmax, 121 .extra1 = &one, 122 .extra2 = &timer_max 123 }, 124 { 125 .procname = "rto_alpha_exp_divisor", 126 .data = &init_net.sctp.rto_alpha, 127 .maxlen = sizeof(int), 128 .mode = 0444, 129 .proc_handler = proc_dointvec, 130 }, 131 { 132 .procname = "rto_beta_exp_divisor", 133 .data = &init_net.sctp.rto_beta, 134 .maxlen = sizeof(int), 135 .mode = 0444, 136 .proc_handler = proc_dointvec, 137 }, 138 { 139 .procname = "max_burst", 140 .data = &init_net.sctp.max_burst, 141 .maxlen = sizeof(int), 142 .mode = 0644, 143 .proc_handler = proc_dointvec_minmax, 144 .extra1 = &zero, 145 .extra2 = &int_max 146 }, 147 { 148 .procname = "cookie_preserve_enable", 149 .data = &init_net.sctp.cookie_preserve_enable, 150 .maxlen = sizeof(int), 151 .mode = 0644, 152 .proc_handler = proc_dointvec, 153 }, 154 { 155 .procname = "cookie_hmac_alg", 156 .maxlen = 8, 157 .mode = 0644, 158 .proc_handler = proc_sctp_do_hmac_alg, 159 }, 160 { 161 .procname = "valid_cookie_life", 162 .data = &init_net.sctp.valid_cookie_life, 163 .maxlen = sizeof(unsigned int), 164 .mode = 0644, 165 .proc_handler = proc_dointvec_minmax, 166 .extra1 = &one, 167 .extra2 = &timer_max 168 }, 169 { 170 .procname = "sack_timeout", 171 .data = &init_net.sctp.sack_timeout, 172 .maxlen = sizeof(int), 173 .mode = 0644, 174 .proc_handler = proc_dointvec_minmax, 175 .extra1 = &sack_timer_min, 176 .extra2 = &sack_timer_max, 177 }, 178 { 179 .procname = "hb_interval", 180 .data = &init_net.sctp.hb_interval, 181 .maxlen = sizeof(unsigned int), 182 .mode = 0644, 183 .proc_handler = proc_dointvec_minmax, 184 .extra1 = &one, 185 .extra2 = &timer_max 186 }, 187 { 188 .procname = "association_max_retrans", 189 .data = &init_net.sctp.max_retrans_association, 190 .maxlen = sizeof(int), 191 .mode = 0644, 192 .proc_handler = proc_dointvec_minmax, 193 .extra1 = &one, 194 .extra2 = &int_max 195 }, 196 { 197 .procname = "path_max_retrans", 198 .data = &init_net.sctp.max_retrans_path, 199 .maxlen = sizeof(int), 200 .mode = 0644, 201 .proc_handler = proc_dointvec_minmax, 202 .extra1 = &one, 203 .extra2 = &int_max 204 }, 205 { 206 .procname = "max_init_retransmits", 207 .data = &init_net.sctp.max_retrans_init, 208 .maxlen = sizeof(int), 209 .mode = 0644, 210 .proc_handler = proc_dointvec_minmax, 211 .extra1 = &one, 212 .extra2 = &int_max 213 }, 214 { 215 .procname = "pf_retrans", 216 .data = &init_net.sctp.pf_retrans, 217 .maxlen = sizeof(int), 218 .mode = 0644, 219 .proc_handler = proc_dointvec_minmax, 220 .extra1 = &zero, 221 .extra2 = &int_max 222 }, 223 { 224 .procname = "sndbuf_policy", 225 .data = &init_net.sctp.sndbuf_policy, 226 .maxlen = sizeof(int), 227 .mode = 0644, 228 .proc_handler = proc_dointvec, 229 }, 230 { 231 .procname = "rcvbuf_policy", 232 .data = &init_net.sctp.rcvbuf_policy, 233 .maxlen = sizeof(int), 234 .mode = 0644, 235 .proc_handler = proc_dointvec, 236 }, 237 { 238 .procname = "default_auto_asconf", 239 .data = &init_net.sctp.default_auto_asconf, 240 .maxlen = sizeof(int), 241 .mode = 0644, 242 .proc_handler = proc_dointvec, 243 }, 244 { 245 .procname = "addip_enable", 246 .data = &init_net.sctp.addip_enable, 247 .maxlen = sizeof(int), 248 .mode = 0644, 249 .proc_handler = proc_dointvec, 250 }, 251 { 252 .procname = "addip_noauth_enable", 253 .data = &init_net.sctp.addip_noauth, 254 .maxlen = sizeof(int), 255 .mode = 0644, 256 .proc_handler = proc_dointvec, 257 }, 258 { 259 .procname = "prsctp_enable", 260 .data = &init_net.sctp.prsctp_enable, 261 .maxlen = sizeof(int), 262 .mode = 0644, 263 .proc_handler = proc_dointvec, 264 }, 265 { 266 .procname = "auth_enable", 267 .data = &init_net.sctp.auth_enable, 268 .maxlen = sizeof(int), 269 .mode = 0644, 270 .proc_handler = proc_dointvec, 271 }, 272 { 273 .procname = "addr_scope_policy", 274 .data = &init_net.sctp.scope_policy, 275 .maxlen = sizeof(int), 276 .mode = 0644, 277 .proc_handler = proc_dointvec_minmax, 278 .extra1 = &zero, 279 .extra2 = &addr_scope_max, 280 }, 281 { 282 .procname = "rwnd_update_shift", 283 .data = &init_net.sctp.rwnd_upd_shift, 284 .maxlen = sizeof(int), 285 .mode = 0644, 286 .proc_handler = &proc_dointvec_minmax, 287 .extra1 = &one, 288 .extra2 = &rwnd_scale_max, 289 }, 290 { 291 .procname = "max_autoclose", 292 .data = &init_net.sctp.max_autoclose, 293 .maxlen = sizeof(unsigned long), 294 .mode = 0644, 295 .proc_handler = &proc_doulongvec_minmax, 296 .extra1 = &max_autoclose_min, 297 .extra2 = &max_autoclose_max, 298 }, 299 300 { /* sentinel */ } 301 }; 302 303 static int proc_sctp_do_hmac_alg(ctl_table *ctl, 304 int write, 305 void __user *buffer, size_t *lenp, 306 loff_t *ppos) 307 { 308 struct net *net = current->nsproxy->net_ns; 309 char tmp[8]; 310 ctl_table tbl; 311 int ret; 312 int changed = 0; 313 char *none = "none"; 314 315 memset(&tbl, 0, sizeof(struct ctl_table)); 316 317 if (write) { 318 tbl.data = tmp; 319 tbl.maxlen = 8; 320 } else { 321 tbl.data = net->sctp.sctp_hmac_alg ? : none; 322 tbl.maxlen = strlen(tbl.data); 323 } 324 ret = proc_dostring(&tbl, write, buffer, lenp, ppos); 325 326 if (write) { 327 #ifdef CONFIG_CRYPTO_MD5 328 if (!strncmp(tmp, "md5", 3)) { 329 net->sctp.sctp_hmac_alg = "md5"; 330 changed = 1; 331 } 332 #endif 333 #ifdef CONFIG_CRYPTO_SHA1 334 if (!strncmp(tmp, "sha1", 4)) { 335 net->sctp.sctp_hmac_alg = "sha1"; 336 changed = 1; 337 } 338 #endif 339 if (!strncmp(tmp, "none", 4)) { 340 net->sctp.sctp_hmac_alg = NULL; 341 changed = 1; 342 } 343 344 if (!changed) 345 ret = -EINVAL; 346 } 347 348 return ret; 349 } 350 351 int sctp_sysctl_net_register(struct net *net) 352 { 353 struct ctl_table *table; 354 int i; 355 356 table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); 357 if (!table) 358 return -ENOMEM; 359 360 for (i = 0; table[i].data; i++) 361 table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; 362 363 net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); 364 return 0; 365 } 366 367 void sctp_sysctl_net_unregister(struct net *net) 368 { 369 unregister_net_sysctl_table(net->sctp.sysctl_header); 370 } 371 372 static struct ctl_table_header * sctp_sysctl_header; 373 374 /* Sysctl registration. */ 375 void sctp_sysctl_register(void) 376 { 377 sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table); 378 } 379 380 /* Sysctl deregistration. */ 381 void sctp_sysctl_unregister(void) 382 { 383 unregister_net_sysctl_table(sctp_sysctl_header); 384 } 385