diff options
author | wangweidong <wangweidong1@huawei.com> | 2013-12-10 20:50:39 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-10 22:54:34 -0500 |
commit | 4f3fdf3bc59cafd14c3bc2c2369efad34c7aa8b5 (patch) | |
tree | 0c699a90897705084991612b759488c7f2479a1b /net | |
parent | 85f935d41af097a87067367be66de52896b964e1 (diff) |
sctp: add check rto_min and rto_max in sysctl
rto_min should be smaller than rto_max while rto_max should be larger
than rto_min. Add two proc_handler for the checking.
Suggested-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: Wang Weidong <wangweidong1@huawei.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sctp/sysctl.c | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 6b36561a1b3b..43b5e3243871 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -61,6 +61,13 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | |||
61 | void __user *buffer, size_t *lenp, | 61 | void __user *buffer, size_t *lenp, |
62 | 62 | ||
63 | loff_t *ppos); | 63 | loff_t *ppos); |
64 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
65 | void __user *buffer, size_t *lenp, | ||
66 | loff_t *ppos); | ||
67 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
68 | void __user *buffer, size_t *lenp, | ||
69 | loff_t *ppos); | ||
70 | |||
64 | static struct ctl_table sctp_table[] = { | 71 | static struct ctl_table sctp_table[] = { |
65 | { | 72 | { |
66 | .procname = "sctp_mem", | 73 | .procname = "sctp_mem", |
@@ -102,17 +109,17 @@ static struct ctl_table sctp_net_table[] = { | |||
102 | .data = &init_net.sctp.rto_min, | 109 | .data = &init_net.sctp.rto_min, |
103 | .maxlen = sizeof(unsigned int), | 110 | .maxlen = sizeof(unsigned int), |
104 | .mode = 0644, | 111 | .mode = 0644, |
105 | .proc_handler = proc_dointvec_minmax, | 112 | .proc_handler = proc_sctp_do_rto_min, |
106 | .extra1 = &one, | 113 | .extra1 = &one, |
107 | .extra2 = &timer_max | 114 | .extra2 = &init_net.sctp.rto_max |
108 | }, | 115 | }, |
109 | { | 116 | { |
110 | .procname = "rto_max", | 117 | .procname = "rto_max", |
111 | .data = &init_net.sctp.rto_max, | 118 | .data = &init_net.sctp.rto_max, |
112 | .maxlen = sizeof(unsigned int), | 119 | .maxlen = sizeof(unsigned int), |
113 | .mode = 0644, | 120 | .mode = 0644, |
114 | .proc_handler = proc_dointvec_minmax, | 121 | .proc_handler = proc_sctp_do_rto_max, |
115 | .extra1 = &one, | 122 | .extra1 = &init_net.sctp.rto_min, |
116 | .extra2 = &timer_max | 123 | .extra2 = &timer_max |
117 | }, | 124 | }, |
118 | { | 125 | { |
@@ -342,6 +349,60 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | |||
342 | return ret; | 349 | return ret; |
343 | } | 350 | } |
344 | 351 | ||
352 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
353 | void __user *buffer, size_t *lenp, | ||
354 | loff_t *ppos) | ||
355 | { | ||
356 | struct net *net = current->nsproxy->net_ns; | ||
357 | int new_value; | ||
358 | struct ctl_table tbl; | ||
359 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
360 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
361 | int ret; | ||
362 | |||
363 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
364 | tbl.maxlen = sizeof(unsigned int); | ||
365 | |||
366 | if (write) | ||
367 | tbl.data = &new_value; | ||
368 | else | ||
369 | tbl.data = &net->sctp.rto_min; | ||
370 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
371 | if (write) { | ||
372 | if (ret || new_value > max || new_value < min) | ||
373 | return -EINVAL; | ||
374 | net->sctp.rto_min = new_value; | ||
375 | } | ||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
380 | void __user *buffer, size_t *lenp, | ||
381 | loff_t *ppos) | ||
382 | { | ||
383 | struct net *net = current->nsproxy->net_ns; | ||
384 | int new_value; | ||
385 | struct ctl_table tbl; | ||
386 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
387 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
388 | int ret; | ||
389 | |||
390 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
391 | tbl.maxlen = sizeof(unsigned int); | ||
392 | |||
393 | if (write) | ||
394 | tbl.data = &new_value; | ||
395 | else | ||
396 | tbl.data = &net->sctp.rto_max; | ||
397 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
398 | if (write) { | ||
399 | if (ret || new_value > max || new_value < min) | ||
400 | return -EINVAL; | ||
401 | net->sctp.rto_max = new_value; | ||
402 | } | ||
403 | return ret; | ||
404 | } | ||
405 | |||
345 | int sctp_sysctl_net_register(struct net *net) | 406 | int sctp_sysctl_net_register(struct net *net) |
346 | { | 407 | { |
347 | struct ctl_table *table; | 408 | struct ctl_table *table; |