aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-12-18 16:42:06 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-18 16:42:06 -0500
commit143c9054949436cb05e468439dc5e46231f33d09 (patch)
treec2e972d8188fb1b36368e9acb5b6b59466c9d903 /net/sctp
parent0b6807034791160d5e584138943d2daea765436d (diff)
parent35eecf052250f663f07a4cded7d3503fd1b50729 (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.c5
-rw-r--r--net/sctp/output.c3
-rw-r--r--net/sctp/probe.c17
-rw-r--r--net/sctp/sm_statefuns.c12
-rw-r--r--net/sctp/socket.c36
-rw-r--r--net/sctp/sysctl.c76
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
41MODULE_SOFTDEP("pre: sctp");
41MODULE_AUTHOR("Wei Yongjun <yjwei@cn.fujitsu.com>"); 42MODULE_AUTHOR("Wei Yongjun <yjwei@cn.fujitsu.com>");
42MODULE_DESCRIPTION("SCTP snooper"); 43MODULE_DESCRIPTION("SCTP snooper");
43MODULE_LICENSE("GPL"); 44MODULE_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
186static __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
196out:
197 return ret;
198}
199
185static __init int sctpprobe_init(void) 200static __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];
55extern int sysctl_sctp_rmem[3]; 55extern int sysctl_sctp_rmem[3];
56extern int sysctl_sctp_wmem[3]; 56extern int sysctl_sctp_wmem[3];
57 57
58static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, 58static 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);
61static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
62 void __user *buffer, size_t *lenp,
63 loff_t *ppos);
64static 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
63static struct ctl_table sctp_table[] = { 68static 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
296static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, 301static 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
348static 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
375static 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
344int sctp_sysctl_net_register(struct net *net) 402int sctp_sysctl_net_register(struct net *net)
345{ 403{
346 struct ctl_table *table; 404 struct ctl_table *table;