aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/associola.c5
-rw-r--r--net/sctp/output.c6
-rw-r--r--net/sctp/outqueue.c6
-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
-rw-r--r--net/sctp/transport.c2
8 files changed, 126 insertions, 34 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 68a27f9796d2..31ed008c8e13 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -154,8 +154,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
154 154
155 asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; 155 asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
156 asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; 156 asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
157 asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = 157 asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ;
158 min_t(unsigned long, sp->autoclose, net->sctp.max_autoclose) * HZ;
159 158
160 /* Initializes the timers */ 159 /* Initializes the timers */
161 for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) 160 for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
@@ -291,8 +290,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
291 asoc->peer.ipv6_address = 1; 290 asoc->peer.ipv6_address = 1;
292 INIT_LIST_HEAD(&asoc->asocs); 291 INIT_LIST_HEAD(&asoc->asocs);
293 292
294 asoc->autoclose = sp->autoclose;
295
296 asoc->default_stream = sp->default_stream; 293 asoc->default_stream = sp->default_stream;
297 asoc->default_ppid = sp->default_ppid; 294 asoc->default_ppid = sp->default_ppid;
298 asoc->default_flags = sp->default_flags; 295 asoc->default_flags = sp->default_flags;
diff --git a/net/sctp/output.c b/net/sctp/output.c
index e650978daf27..0fb140f8f088 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -474,10 +474,11 @@ int sctp_packet_transmit(struct sctp_packet *packet)
474 * for a given destination transport address. 474 * for a given destination transport address.
475 */ 475 */
476 476
477 if (!tp->rto_pending) { 477 if (!chunk->resent && !tp->rto_pending) {
478 chunk->rtt_in_progress = 1; 478 chunk->rtt_in_progress = 1;
479 tp->rto_pending = 1; 479 tp->rto_pending = 1;
480 } 480 }
481
481 has_data = 1; 482 has_data = 1;
482 } 483 }
483 484
@@ -580,7 +581,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
580 unsigned long timeout; 581 unsigned long timeout;
581 582
582 /* Restart the AUTOCLOSE timer when sending data. */ 583 /* Restart the AUTOCLOSE timer when sending data. */
583 if (sctp_state(asoc, ESTABLISHED) && asoc->autoclose) { 584 if (sctp_state(asoc, ESTABLISHED) &&
585 asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
584 timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; 586 timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
585 timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; 587 timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
586 588
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 94df75877869..f51ba985a36e 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -446,6 +446,8 @@ void sctp_retransmit_mark(struct sctp_outq *q,
446 transport->rto_pending = 0; 446 transport->rto_pending = 0;
447 } 447 }
448 448
449 chunk->resent = 1;
450
449 /* Move the chunk to the retransmit queue. The chunks 451 /* Move the chunk to the retransmit queue. The chunks
450 * on the retransmit queue are always kept in order. 452 * on the retransmit queue are always kept in order.
451 */ 453 */
@@ -1375,6 +1377,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1375 * instance). 1377 * instance).
1376 */ 1378 */
1377 if (!tchunk->tsn_gap_acked && 1379 if (!tchunk->tsn_gap_acked &&
1380 !tchunk->resent &&
1378 tchunk->rtt_in_progress) { 1381 tchunk->rtt_in_progress) {
1379 tchunk->rtt_in_progress = 0; 1382 tchunk->rtt_in_progress = 0;
1380 rtt = jiffies - tchunk->sent_at; 1383 rtt = jiffies - tchunk->sent_at;
@@ -1391,7 +1394,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1391 */ 1394 */
1392 if (!tchunk->tsn_gap_acked) { 1395 if (!tchunk->tsn_gap_acked) {
1393 tchunk->tsn_gap_acked = 1; 1396 tchunk->tsn_gap_acked = 1;
1394 *highest_new_tsn_in_sack = tsn; 1397 if (TSN_lt(*highest_new_tsn_in_sack, tsn))
1398 *highest_new_tsn_in_sack = tsn;
1395 bytes_acked += sctp_data_size(tchunk); 1399 bytes_acked += sctp_data_size(tchunk);
1396 if (!tchunk->transport) 1400 if (!tchunk->transport)
1397 migrate_bytes += sctp_data_size(tchunk); 1401 migrate_bytes += sctp_data_size(tchunk);
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 dfe3f36ff2aa..a26065be7289 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -820,7 +820,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
820 SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS); 820 SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS);
821 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); 821 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
822 822
823 if (new_asoc->autoclose) 823 if (new_asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
824 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, 824 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
825 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); 825 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
826 826
@@ -908,7 +908,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net,
908 SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB); 908 SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
909 SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS); 909 SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS);
910 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); 910 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
911 if (asoc->autoclose) 911 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
912 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, 912 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
913 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); 913 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
914 914
@@ -2970,7 +2970,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net,
2970 if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) 2970 if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM)
2971 force = SCTP_FORCE(); 2971 force = SCTP_FORCE();
2972 2972
2973 if (asoc->autoclose) { 2973 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
2974 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, 2974 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
2975 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); 2975 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
2976 } 2976 }
@@ -3878,7 +3878,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net,
3878 SCTP_CHUNK(chunk)); 3878 SCTP_CHUNK(chunk));
3879 3879
3880 /* Count this as receiving DATA. */ 3880 /* Count this as receiving DATA. */
3881 if (asoc->autoclose) { 3881 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
3882 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, 3882 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
3883 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); 3883 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
3884 } 3884 }
@@ -5267,7 +5267,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
5267 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, 5267 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
5268 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); 5268 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
5269 5269
5270 if (asoc->autoclose) 5270 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
5271 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 5271 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
5272 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); 5272 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
5273 5273
@@ -5346,7 +5346,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack(
5346 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, 5346 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
5347 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); 5347 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
5348 5348
5349 if (asoc->autoclose) 5349 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
5350 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 5350 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
5351 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); 5351 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
5352 5352
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 72046b9729a8..42b709c95cf3 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2196,6 +2196,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
2196 unsigned int optlen) 2196 unsigned int optlen)
2197{ 2197{
2198 struct sctp_sock *sp = sctp_sk(sk); 2198 struct sctp_sock *sp = sctp_sk(sk);
2199 struct net *net = sock_net(sk);
2199 2200
2200 /* Applicable to UDP-style socket only */ 2201 /* Applicable to UDP-style socket only */
2201 if (sctp_style(sk, TCP)) 2202 if (sctp_style(sk, TCP))
@@ -2205,6 +2206,9 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
2205 if (copy_from_user(&sp->autoclose, optval, optlen)) 2206 if (copy_from_user(&sp->autoclose, optval, optlen))
2206 return -EFAULT; 2207 return -EFAULT;
2207 2208
2209 if (sp->autoclose > net->sctp.max_autoclose)
2210 sp->autoclose = net->sctp.max_autoclose;
2211
2208 return 0; 2212 return 0;
2209} 2213}
2210 2214
@@ -2811,6 +2815,8 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne
2811{ 2815{
2812 struct sctp_rtoinfo rtoinfo; 2816 struct sctp_rtoinfo rtoinfo;
2813 struct sctp_association *asoc; 2817 struct sctp_association *asoc;
2818 unsigned long rto_min, rto_max;
2819 struct sctp_sock *sp = sctp_sk(sk);
2814 2820
2815 if (optlen != sizeof (struct sctp_rtoinfo)) 2821 if (optlen != sizeof (struct sctp_rtoinfo))
2816 return -EINVAL; 2822 return -EINVAL;
@@ -2824,26 +2830,36 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne
2824 if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) 2830 if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP))
2825 return -EINVAL; 2831 return -EINVAL;
2826 2832
2833 rto_max = rtoinfo.srto_max;
2834 rto_min = rtoinfo.srto_min;
2835
2836 if (rto_max)
2837 rto_max = asoc ? msecs_to_jiffies(rto_max) : rto_max;
2838 else
2839 rto_max = asoc ? asoc->rto_max : sp->rtoinfo.srto_max;
2840
2841 if (rto_min)
2842 rto_min = asoc ? msecs_to_jiffies(rto_min) : rto_min;
2843 else
2844 rto_min = asoc ? asoc->rto_min : sp->rtoinfo.srto_min;
2845
2846 if (rto_min > rto_max)
2847 return -EINVAL;
2848
2827 if (asoc) { 2849 if (asoc) {
2828 if (rtoinfo.srto_initial != 0) 2850 if (rtoinfo.srto_initial != 0)
2829 asoc->rto_initial = 2851 asoc->rto_initial =
2830 msecs_to_jiffies(rtoinfo.srto_initial); 2852 msecs_to_jiffies(rtoinfo.srto_initial);
2831 if (rtoinfo.srto_max != 0) 2853 asoc->rto_max = rto_max;
2832 asoc->rto_max = msecs_to_jiffies(rtoinfo.srto_max); 2854 asoc->rto_min = rto_min;
2833 if (rtoinfo.srto_min != 0)
2834 asoc->rto_min = msecs_to_jiffies(rtoinfo.srto_min);
2835 } else { 2855 } else {
2836 /* If there is no association or the association-id = 0 2856 /* If there is no association or the association-id = 0
2837 * set the values to the endpoint. 2857 * set the values to the endpoint.
2838 */ 2858 */
2839 struct sctp_sock *sp = sctp_sk(sk);
2840
2841 if (rtoinfo.srto_initial != 0) 2859 if (rtoinfo.srto_initial != 0)
2842 sp->rtoinfo.srto_initial = rtoinfo.srto_initial; 2860 sp->rtoinfo.srto_initial = rtoinfo.srto_initial;
2843 if (rtoinfo.srto_max != 0) 2861 sp->rtoinfo.srto_max = rto_max;
2844 sp->rtoinfo.srto_max = rtoinfo.srto_max; 2862 sp->rtoinfo.srto_min = rto_min;
2845 if (rtoinfo.srto_min != 0)
2846 sp->rtoinfo.srto_min = rtoinfo.srto_min;
2847 } 2863 }
2848 2864
2849 return 0; 2865 return 0;
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];
56extern int sysctl_sctp_rmem[3]; 56extern int sysctl_sctp_rmem[3];
57extern int sysctl_sctp_wmem[3]; 57extern int sysctl_sctp_wmem[3];
58 58
59static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, 59static 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);
62static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
63 void __user *buffer, size_t *lenp,
64 loff_t *ppos);
65static 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
64static struct ctl_table sctp_table[] = { 69static 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
297static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, 302static 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
349static 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
376static 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
345int sctp_sysctl_net_register(struct net *net) 403int sctp_sysctl_net_register(struct net *net)
346{ 404{
347 struct ctl_table *table; 405 struct ctl_table *table;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index e332efb124cc..efc46ffed1fd 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -573,7 +573,7 @@ void sctp_transport_burst_limited(struct sctp_transport *t)
573 u32 old_cwnd = t->cwnd; 573 u32 old_cwnd = t->cwnd;
574 u32 max_burst_bytes; 574 u32 max_burst_bytes;
575 575
576 if (t->burst_limited) 576 if (t->burst_limited || asoc->max_burst == 0)
577 return; 577 return;
578 578
579 max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu); 579 max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu);