aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/structs.h1
-rw-r--r--net/sctp/sm_make_chunk.c4
-rw-r--r--net/sctp/transport.c16
3 files changed, 20 insertions, 1 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index e90e7a9935dd..3382615bd710 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1085,6 +1085,7 @@ void sctp_transport_burst_reset(struct sctp_transport *);
1085unsigned long sctp_transport_timeout(struct sctp_transport *); 1085unsigned long sctp_transport_timeout(struct sctp_transport *);
1086void sctp_transport_reset(struct sctp_transport *); 1086void sctp_transport_reset(struct sctp_transport *);
1087void sctp_transport_update_pmtu(struct sctp_transport *, u32); 1087void sctp_transport_update_pmtu(struct sctp_transport *, u32);
1088void sctp_transport_immediate_rtx(struct sctp_transport *);
1088 1089
1089 1090
1090/* This is the structure we use to queue packets as they come into 1091/* This is the structure we use to queue packets as they come into
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 0121e0ab0351..a85eeeb55dd0 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3400,8 +3400,10 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
3400 asconf_len -= length; 3400 asconf_len -= length;
3401 } 3401 }
3402 3402
3403 if (no_err && asoc->src_out_of_asoc_ok) 3403 if (no_err && asoc->src_out_of_asoc_ok) {
3404 asoc->src_out_of_asoc_ok = 0; 3404 asoc->src_out_of_asoc_ok = 0;
3405 sctp_transport_immediate_rtx(asoc->peer.primary_path);
3406 }
3405 3407
3406 /* Free the cached last sent asconf chunk. */ 3408 /* Free the cached last sent asconf chunk. */
3407 list_del_init(&asconf->transmitted_list); 3409 list_del_init(&asconf->transmitted_list);
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 394c57ca2f54..3889330b7b04 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -641,3 +641,19 @@ void sctp_transport_reset(struct sctp_transport *t)
641 t->cacc.next_tsn_at_change = 0; 641 t->cacc.next_tsn_at_change = 0;
642 t->cacc.cacc_saw_newack = 0; 642 t->cacc.cacc_saw_newack = 0;
643} 643}
644
645/* Schedule retransmission on the given transport */
646void sctp_transport_immediate_rtx(struct sctp_transport *t)
647{
648 /* Stop pending T3_rtx_timer */
649 if (timer_pending(&t->T3_rtx_timer)) {
650 (void)del_timer(&t->T3_rtx_timer);
651 sctp_transport_put(t);
652 }
653 sctp_retransmit(&t->asoc->outqueue, t, SCTP_RTXR_T3_RTX);
654 if (!timer_pending(&t->T3_rtx_timer)) {
655 if (!mod_timer(&t->T3_rtx_timer, jiffies + t->rto))
656 sctp_transport_hold(t);
657 }
658 return;
659}