diff options
author | David S. Miller <davem@davemloft.net> | 2013-12-18 16:42:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-18 16:42:06 -0500 |
commit | 143c9054949436cb05e468439dc5e46231f33d09 (patch) | |
tree | c2e972d8188fb1b36368e9acb5b6b59466c9d903 /net/sctp | |
parent | 0b6807034791160d5e584138943d2daea765436d (diff) | |
parent | 35eecf052250f663f07a4cded7d3503fd1b50729 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/macvtap.c
Both minor merge hassles, simple overlapping changes.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/associola.c | 5 | ||||
-rw-r--r-- | net/sctp/output.c | 3 | ||||
-rw-r--r-- | net/sctp/probe.c | 17 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 12 | ||||
-rw-r--r-- | net/sctp/socket.c | 36 | ||||
-rw-r--r-- | net/sctp/sysctl.c | 76 |
6 files changed, 118 insertions, 31 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 3d7c6bd46311..5ae609200674 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -145,8 +145,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
145 | = 5 * asoc->rto_max; | 145 | = 5 * asoc->rto_max; |
146 | 146 | ||
147 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; | 147 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; |
148 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = | 148 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; |
149 | min_t(unsigned long, sp->autoclose, net->sctp.max_autoclose) * HZ; | ||
150 | 149 | ||
151 | /* Initializes the timers */ | 150 | /* Initializes the timers */ |
152 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) | 151 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) |
@@ -254,8 +253,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
254 | asoc->peer.ipv6_address = 1; | 253 | asoc->peer.ipv6_address = 1; |
255 | INIT_LIST_HEAD(&asoc->asocs); | 254 | INIT_LIST_HEAD(&asoc->asocs); |
256 | 255 | ||
257 | asoc->autoclose = sp->autoclose; | ||
258 | |||
259 | asoc->default_stream = sp->default_stream; | 256 | asoc->default_stream = sp->default_stream; |
260 | asoc->default_ppid = sp->default_ppid; | 257 | asoc->default_ppid = sp->default_ppid; |
261 | asoc->default_flags = sp->default_flags; | 258 | asoc->default_flags = sp->default_flags; |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 6371337e1fe7..3f55823279d9 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -580,7 +580,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
580 | unsigned long timeout; | 580 | unsigned long timeout; |
581 | 581 | ||
582 | /* Restart the AUTOCLOSE timer when sending data. */ | 582 | /* Restart the AUTOCLOSE timer when sending data. */ |
583 | if (sctp_state(asoc, ESTABLISHED) && asoc->autoclose) { | 583 | if (sctp_state(asoc, ESTABLISHED) && |
584 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { | ||
584 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | 585 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; |
585 | timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | 586 | timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; |
586 | 587 | ||
diff --git a/net/sctp/probe.c b/net/sctp/probe.c index 53c452efb40b..5e68b94ee640 100644 --- a/net/sctp/probe.c +++ b/net/sctp/probe.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <net/sctp/sctp.h> | 38 | #include <net/sctp/sctp.h> |
39 | #include <net/sctp/sm.h> | 39 | #include <net/sctp/sm.h> |
40 | 40 | ||
41 | MODULE_SOFTDEP("pre: sctp"); | ||
41 | MODULE_AUTHOR("Wei Yongjun <yjwei@cn.fujitsu.com>"); | 42 | MODULE_AUTHOR("Wei Yongjun <yjwei@cn.fujitsu.com>"); |
42 | MODULE_DESCRIPTION("SCTP snooper"); | 43 | MODULE_DESCRIPTION("SCTP snooper"); |
43 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
@@ -182,6 +183,20 @@ static struct jprobe sctp_recv_probe = { | |||
182 | .entry = jsctp_sf_eat_sack, | 183 | .entry = jsctp_sf_eat_sack, |
183 | }; | 184 | }; |
184 | 185 | ||
186 | static __init int sctp_setup_jprobe(void) | ||
187 | { | ||
188 | int ret = register_jprobe(&sctp_recv_probe); | ||
189 | |||
190 | if (ret) { | ||
191 | if (request_module("sctp")) | ||
192 | goto out; | ||
193 | ret = register_jprobe(&sctp_recv_probe); | ||
194 | } | ||
195 | |||
196 | out: | ||
197 | return ret; | ||
198 | } | ||
199 | |||
185 | static __init int sctpprobe_init(void) | 200 | static __init int sctpprobe_init(void) |
186 | { | 201 | { |
187 | int ret = -ENOMEM; | 202 | int ret = -ENOMEM; |
@@ -202,7 +217,7 @@ static __init int sctpprobe_init(void) | |||
202 | &sctpprobe_fops)) | 217 | &sctpprobe_fops)) |
203 | goto free_kfifo; | 218 | goto free_kfifo; |
204 | 219 | ||
205 | ret = register_jprobe(&sctp_recv_probe); | 220 | ret = sctp_setup_jprobe(); |
206 | if (ret) | 221 | if (ret) |
207 | goto remove_proc; | 222 | goto remove_proc; |
208 | 223 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index dd0eba919a8b..ee02771d8b9c 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -819,7 +819,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, | |||
819 | SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS); | 819 | SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS); |
820 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); | 820 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); |
821 | 821 | ||
822 | if (new_asoc->autoclose) | 822 | if (new_asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
823 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 823 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
824 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 824 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
825 | 825 | ||
@@ -907,7 +907,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net, | |||
907 | SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB); | 907 | SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB); |
908 | SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS); | 908 | SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS); |
909 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); | 909 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); |
910 | if (asoc->autoclose) | 910 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
911 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 911 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
912 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 912 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
913 | 913 | ||
@@ -2969,7 +2969,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net, | |||
2969 | if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) | 2969 | if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) |
2970 | force = SCTP_FORCE(); | 2970 | force = SCTP_FORCE(); |
2971 | 2971 | ||
2972 | if (asoc->autoclose) { | 2972 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { |
2973 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 2973 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
2974 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 2974 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
2975 | } | 2975 | } |
@@ -3877,7 +3877,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net, | |||
3877 | SCTP_CHUNK(chunk)); | 3877 | SCTP_CHUNK(chunk)); |
3878 | 3878 | ||
3879 | /* Count this as receiving DATA. */ | 3879 | /* Count this as receiving DATA. */ |
3880 | if (asoc->autoclose) { | 3880 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { |
3881 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 3881 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
3882 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 3882 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
3883 | } | 3883 | } |
@@ -5266,7 +5266,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown( | |||
5266 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 5266 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
5267 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | 5267 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); |
5268 | 5268 | ||
5269 | if (asoc->autoclose) | 5269 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
5270 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 5270 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
5271 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 5271 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
5272 | 5272 | ||
@@ -5345,7 +5345,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack( | |||
5345 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 5345 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
5346 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); | 5346 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); |
5347 | 5347 | ||
5348 | if (asoc->autoclose) | 5348 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
5349 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 5349 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
5350 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 5350 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
5351 | 5351 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 191cd9257806..d39fd0c2c4cf 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2195,6 +2195,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
2195 | unsigned int optlen) | 2195 | unsigned int optlen) |
2196 | { | 2196 | { |
2197 | struct sctp_sock *sp = sctp_sk(sk); | 2197 | struct sctp_sock *sp = sctp_sk(sk); |
2198 | struct net *net = sock_net(sk); | ||
2198 | 2199 | ||
2199 | /* Applicable to UDP-style socket only */ | 2200 | /* Applicable to UDP-style socket only */ |
2200 | if (sctp_style(sk, TCP)) | 2201 | if (sctp_style(sk, TCP)) |
@@ -2204,6 +2205,9 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
2204 | if (copy_from_user(&sp->autoclose, optval, optlen)) | 2205 | if (copy_from_user(&sp->autoclose, optval, optlen)) |
2205 | return -EFAULT; | 2206 | return -EFAULT; |
2206 | 2207 | ||
2208 | if (sp->autoclose > net->sctp.max_autoclose) | ||
2209 | sp->autoclose = net->sctp.max_autoclose; | ||
2210 | |||
2207 | return 0; | 2211 | return 0; |
2208 | } | 2212 | } |
2209 | 2213 | ||
@@ -2810,6 +2814,8 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne | |||
2810 | { | 2814 | { |
2811 | struct sctp_rtoinfo rtoinfo; | 2815 | struct sctp_rtoinfo rtoinfo; |
2812 | struct sctp_association *asoc; | 2816 | struct sctp_association *asoc; |
2817 | unsigned long rto_min, rto_max; | ||
2818 | struct sctp_sock *sp = sctp_sk(sk); | ||
2813 | 2819 | ||
2814 | if (optlen != sizeof (struct sctp_rtoinfo)) | 2820 | if (optlen != sizeof (struct sctp_rtoinfo)) |
2815 | return -EINVAL; | 2821 | return -EINVAL; |
@@ -2823,26 +2829,36 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne | |||
2823 | if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) | 2829 | if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) |
2824 | return -EINVAL; | 2830 | return -EINVAL; |
2825 | 2831 | ||
2832 | rto_max = rtoinfo.srto_max; | ||
2833 | rto_min = rtoinfo.srto_min; | ||
2834 | |||
2835 | if (rto_max) | ||
2836 | rto_max = asoc ? msecs_to_jiffies(rto_max) : rto_max; | ||
2837 | else | ||
2838 | rto_max = asoc ? asoc->rto_max : sp->rtoinfo.srto_max; | ||
2839 | |||
2840 | if (rto_min) | ||
2841 | rto_min = asoc ? msecs_to_jiffies(rto_min) : rto_min; | ||
2842 | else | ||
2843 | rto_min = asoc ? asoc->rto_min : sp->rtoinfo.srto_min; | ||
2844 | |||
2845 | if (rto_min > rto_max) | ||
2846 | return -EINVAL; | ||
2847 | |||
2826 | if (asoc) { | 2848 | if (asoc) { |
2827 | if (rtoinfo.srto_initial != 0) | 2849 | if (rtoinfo.srto_initial != 0) |
2828 | asoc->rto_initial = | 2850 | asoc->rto_initial = |
2829 | msecs_to_jiffies(rtoinfo.srto_initial); | 2851 | msecs_to_jiffies(rtoinfo.srto_initial); |
2830 | if (rtoinfo.srto_max != 0) | 2852 | asoc->rto_max = rto_max; |
2831 | asoc->rto_max = msecs_to_jiffies(rtoinfo.srto_max); | 2853 | asoc->rto_min = rto_min; |
2832 | if (rtoinfo.srto_min != 0) | ||
2833 | asoc->rto_min = msecs_to_jiffies(rtoinfo.srto_min); | ||
2834 | } else { | 2854 | } else { |
2835 | /* If there is no association or the association-id = 0 | 2855 | /* If there is no association or the association-id = 0 |
2836 | * set the values to the endpoint. | 2856 | * set the values to the endpoint. |
2837 | */ | 2857 | */ |
2838 | struct sctp_sock *sp = sctp_sk(sk); | ||
2839 | |||
2840 | if (rtoinfo.srto_initial != 0) | 2858 | if (rtoinfo.srto_initial != 0) |
2841 | sp->rtoinfo.srto_initial = rtoinfo.srto_initial; | 2859 | sp->rtoinfo.srto_initial = rtoinfo.srto_initial; |
2842 | if (rtoinfo.srto_max != 0) | 2860 | sp->rtoinfo.srto_max = rto_max; |
2843 | sp->rtoinfo.srto_max = rtoinfo.srto_max; | 2861 | sp->rtoinfo.srto_min = rto_min; |
2844 | if (rtoinfo.srto_min != 0) | ||
2845 | sp->rtoinfo.srto_min = rtoinfo.srto_min; | ||
2846 | } | 2862 | } |
2847 | 2863 | ||
2848 | return 0; | 2864 | return 0; |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 80b17b5df6bb..9dd5ac084663 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -55,11 +55,16 @@ extern long sysctl_sctp_mem[3]; | |||
55 | extern int sysctl_sctp_rmem[3]; | 55 | extern int sysctl_sctp_rmem[3]; |
56 | extern int sysctl_sctp_wmem[3]; | 56 | extern int sysctl_sctp_wmem[3]; |
57 | 57 | ||
58 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | 58 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, |
59 | int write, | 59 | void __user *buffer, size_t *lenp, |
60 | loff_t *ppos); | ||
61 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
62 | void __user *buffer, size_t *lenp, | ||
63 | loff_t *ppos); | ||
64 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
60 | void __user *buffer, size_t *lenp, | 65 | void __user *buffer, size_t *lenp, |
61 | |||
62 | loff_t *ppos); | 66 | loff_t *ppos); |
67 | |||
63 | static struct ctl_table sctp_table[] = { | 68 | static struct ctl_table sctp_table[] = { |
64 | { | 69 | { |
65 | .procname = "sctp_mem", | 70 | .procname = "sctp_mem", |
@@ -101,17 +106,17 @@ static struct ctl_table sctp_net_table[] = { | |||
101 | .data = &init_net.sctp.rto_min, | 106 | .data = &init_net.sctp.rto_min, |
102 | .maxlen = sizeof(unsigned int), | 107 | .maxlen = sizeof(unsigned int), |
103 | .mode = 0644, | 108 | .mode = 0644, |
104 | .proc_handler = proc_dointvec_minmax, | 109 | .proc_handler = proc_sctp_do_rto_min, |
105 | .extra1 = &one, | 110 | .extra1 = &one, |
106 | .extra2 = &timer_max | 111 | .extra2 = &init_net.sctp.rto_max |
107 | }, | 112 | }, |
108 | { | 113 | { |
109 | .procname = "rto_max", | 114 | .procname = "rto_max", |
110 | .data = &init_net.sctp.rto_max, | 115 | .data = &init_net.sctp.rto_max, |
111 | .maxlen = sizeof(unsigned int), | 116 | .maxlen = sizeof(unsigned int), |
112 | .mode = 0644, | 117 | .mode = 0644, |
113 | .proc_handler = proc_dointvec_minmax, | 118 | .proc_handler = proc_sctp_do_rto_max, |
114 | .extra1 = &one, | 119 | .extra1 = &init_net.sctp.rto_min, |
115 | .extra2 = &timer_max | 120 | .extra2 = &timer_max |
116 | }, | 121 | }, |
117 | { | 122 | { |
@@ -293,8 +298,7 @@ static struct ctl_table sctp_net_table[] = { | |||
293 | { /* sentinel */ } | 298 | { /* sentinel */ } |
294 | }; | 299 | }; |
295 | 300 | ||
296 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | 301 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, |
297 | int write, | ||
298 | void __user *buffer, size_t *lenp, | 302 | void __user *buffer, size_t *lenp, |
299 | loff_t *ppos) | 303 | loff_t *ppos) |
300 | { | 304 | { |
@@ -341,6 +345,60 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | |||
341 | return ret; | 345 | return ret; |
342 | } | 346 | } |
343 | 347 | ||
348 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
349 | void __user *buffer, size_t *lenp, | ||
350 | loff_t *ppos) | ||
351 | { | ||
352 | struct net *net = current->nsproxy->net_ns; | ||
353 | int new_value; | ||
354 | struct ctl_table tbl; | ||
355 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
356 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
357 | int ret; | ||
358 | |||
359 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
360 | tbl.maxlen = sizeof(unsigned int); | ||
361 | |||
362 | if (write) | ||
363 | tbl.data = &new_value; | ||
364 | else | ||
365 | tbl.data = &net->sctp.rto_min; | ||
366 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
367 | if (write) { | ||
368 | if (ret || new_value > max || new_value < min) | ||
369 | return -EINVAL; | ||
370 | net->sctp.rto_min = new_value; | ||
371 | } | ||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
376 | void __user *buffer, size_t *lenp, | ||
377 | loff_t *ppos) | ||
378 | { | ||
379 | struct net *net = current->nsproxy->net_ns; | ||
380 | int new_value; | ||
381 | struct ctl_table tbl; | ||
382 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
383 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
384 | int ret; | ||
385 | |||
386 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
387 | tbl.maxlen = sizeof(unsigned int); | ||
388 | |||
389 | if (write) | ||
390 | tbl.data = &new_value; | ||
391 | else | ||
392 | tbl.data = &net->sctp.rto_max; | ||
393 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
394 | if (write) { | ||
395 | if (ret || new_value > max || new_value < min) | ||
396 | return -EINVAL; | ||
397 | net->sctp.rto_max = new_value; | ||
398 | } | ||
399 | return ret; | ||
400 | } | ||
401 | |||
344 | int sctp_sysctl_net_register(struct net *net) | 402 | int sctp_sysctl_net_register(struct net *net) |
345 | { | 403 | { |
346 | struct ctl_table *table; | 404 | struct ctl_table *table; |