diff options
Diffstat (limited to 'net/sctp/sysctl.c')
-rw-r--r-- | net/sctp/sysctl.c | 76 |
1 files changed, 67 insertions, 9 deletions
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 6b36561a1b3b..b0565afb61c7 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -56,11 +56,16 @@ extern long sysctl_sctp_mem[3]; | |||
56 | extern int sysctl_sctp_rmem[3]; | 56 | extern int sysctl_sctp_rmem[3]; |
57 | extern int sysctl_sctp_wmem[3]; | 57 | extern int sysctl_sctp_wmem[3]; |
58 | 58 | ||
59 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | 59 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, |
60 | int write, | 60 | void __user *buffer, size_t *lenp, |
61 | loff_t *ppos); | ||
62 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
63 | void __user *buffer, size_t *lenp, | ||
64 | loff_t *ppos); | ||
65 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
61 | void __user *buffer, size_t *lenp, | 66 | void __user *buffer, size_t *lenp, |
62 | |||
63 | loff_t *ppos); | 67 | loff_t *ppos); |
68 | |||
64 | static struct ctl_table sctp_table[] = { | 69 | static struct ctl_table sctp_table[] = { |
65 | { | 70 | { |
66 | .procname = "sctp_mem", | 71 | .procname = "sctp_mem", |
@@ -102,17 +107,17 @@ static struct ctl_table sctp_net_table[] = { | |||
102 | .data = &init_net.sctp.rto_min, | 107 | .data = &init_net.sctp.rto_min, |
103 | .maxlen = sizeof(unsigned int), | 108 | .maxlen = sizeof(unsigned int), |
104 | .mode = 0644, | 109 | .mode = 0644, |
105 | .proc_handler = proc_dointvec_minmax, | 110 | .proc_handler = proc_sctp_do_rto_min, |
106 | .extra1 = &one, | 111 | .extra1 = &one, |
107 | .extra2 = &timer_max | 112 | .extra2 = &init_net.sctp.rto_max |
108 | }, | 113 | }, |
109 | { | 114 | { |
110 | .procname = "rto_max", | 115 | .procname = "rto_max", |
111 | .data = &init_net.sctp.rto_max, | 116 | .data = &init_net.sctp.rto_max, |
112 | .maxlen = sizeof(unsigned int), | 117 | .maxlen = sizeof(unsigned int), |
113 | .mode = 0644, | 118 | .mode = 0644, |
114 | .proc_handler = proc_dointvec_minmax, | 119 | .proc_handler = proc_sctp_do_rto_max, |
115 | .extra1 = &one, | 120 | .extra1 = &init_net.sctp.rto_min, |
116 | .extra2 = &timer_max | 121 | .extra2 = &timer_max |
117 | }, | 122 | }, |
118 | { | 123 | { |
@@ -294,8 +299,7 @@ static struct ctl_table sctp_net_table[] = { | |||
294 | { /* sentinel */ } | 299 | { /* sentinel */ } |
295 | }; | 300 | }; |
296 | 301 | ||
297 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | 302 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, |
298 | int write, | ||
299 | void __user *buffer, size_t *lenp, | 303 | void __user *buffer, size_t *lenp, |
300 | loff_t *ppos) | 304 | loff_t *ppos) |
301 | { | 305 | { |
@@ -342,6 +346,60 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | |||
342 | return ret; | 346 | return ret; |
343 | } | 347 | } |
344 | 348 | ||
349 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
350 | void __user *buffer, size_t *lenp, | ||
351 | loff_t *ppos) | ||
352 | { | ||
353 | struct net *net = current->nsproxy->net_ns; | ||
354 | int new_value; | ||
355 | struct ctl_table tbl; | ||
356 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
357 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
358 | int ret; | ||
359 | |||
360 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
361 | tbl.maxlen = sizeof(unsigned int); | ||
362 | |||
363 | if (write) | ||
364 | tbl.data = &new_value; | ||
365 | else | ||
366 | tbl.data = &net->sctp.rto_min; | ||
367 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
368 | if (write) { | ||
369 | if (ret || new_value > max || new_value < min) | ||
370 | return -EINVAL; | ||
371 | net->sctp.rto_min = new_value; | ||
372 | } | ||
373 | return ret; | ||
374 | } | ||
375 | |||
376 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
377 | void __user *buffer, size_t *lenp, | ||
378 | loff_t *ppos) | ||
379 | { | ||
380 | struct net *net = current->nsproxy->net_ns; | ||
381 | int new_value; | ||
382 | struct ctl_table tbl; | ||
383 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
384 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
385 | int ret; | ||
386 | |||
387 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
388 | tbl.maxlen = sizeof(unsigned int); | ||
389 | |||
390 | if (write) | ||
391 | tbl.data = &new_value; | ||
392 | else | ||
393 | tbl.data = &net->sctp.rto_max; | ||
394 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
395 | if (write) { | ||
396 | if (ret || new_value > max || new_value < min) | ||
397 | return -EINVAL; | ||
398 | net->sctp.rto_max = new_value; | ||
399 | } | ||
400 | return ret; | ||
401 | } | ||
402 | |||
345 | int sctp_sysctl_net_register(struct net *net) | 403 | int sctp_sysctl_net_register(struct net *net) |
346 | { | 404 | { |
347 | struct ctl_table *table; | 405 | struct ctl_table *table; |