aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/outqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r--net/sctp/outqueue.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index e7aa177c9522..1b4a7f8ec3fd 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -63,6 +63,7 @@ static int sctp_acked(struct sctp_sackhdr *sack, __u32 tsn);
63static void sctp_check_transmitted(struct sctp_outq *q, 63static void sctp_check_transmitted(struct sctp_outq *q,
64 struct list_head *transmitted_queue, 64 struct list_head *transmitted_queue,
65 struct sctp_transport *transport, 65 struct sctp_transport *transport,
66 union sctp_addr *saddr,
66 struct sctp_sackhdr *sack, 67 struct sctp_sackhdr *sack,
67 __u32 *highest_new_tsn); 68 __u32 *highest_new_tsn);
68 69
@@ -299,6 +300,7 @@ void sctp_outq_free(struct sctp_outq *q)
299/* Put a new chunk in an sctp_outq. */ 300/* Put a new chunk in an sctp_outq. */
300int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk) 301int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk)
301{ 302{
303 struct net *net = sock_net(q->asoc->base.sk);
302 int error = 0; 304 int error = 0;
303 305
304 SCTP_DEBUG_PRINTK("sctp_outq_tail(%p, %p[%s])\n", 306 SCTP_DEBUG_PRINTK("sctp_outq_tail(%p, %p[%s])\n",
@@ -337,15 +339,15 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk)
337 339
338 sctp_outq_tail_data(q, chunk); 340 sctp_outq_tail_data(q, chunk);
339 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) 341 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
340 SCTP_INC_STATS(SCTP_MIB_OUTUNORDERCHUNKS); 342 SCTP_INC_STATS(net, SCTP_MIB_OUTUNORDERCHUNKS);
341 else 343 else
342 SCTP_INC_STATS(SCTP_MIB_OUTORDERCHUNKS); 344 SCTP_INC_STATS(net, SCTP_MIB_OUTORDERCHUNKS);
343 q->empty = 0; 345 q->empty = 0;
344 break; 346 break;
345 } 347 }
346 } else { 348 } else {
347 list_add_tail(&chunk->list, &q->control_chunk_list); 349 list_add_tail(&chunk->list, &q->control_chunk_list);
348 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 350 SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
349 } 351 }
350 352
351 if (error < 0) 353 if (error < 0)
@@ -478,11 +480,12 @@ void sctp_retransmit_mark(struct sctp_outq *q,
478void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, 480void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
479 sctp_retransmit_reason_t reason) 481 sctp_retransmit_reason_t reason)
480{ 482{
483 struct net *net = sock_net(q->asoc->base.sk);
481 int error = 0; 484 int error = 0;
482 485
483 switch(reason) { 486 switch(reason) {
484 case SCTP_RTXR_T3_RTX: 487 case SCTP_RTXR_T3_RTX:
485 SCTP_INC_STATS(SCTP_MIB_T3_RETRANSMITS); 488 SCTP_INC_STATS(net, SCTP_MIB_T3_RETRANSMITS);
486 sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX); 489 sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX);
487 /* Update the retran path if the T3-rtx timer has expired for 490 /* Update the retran path if the T3-rtx timer has expired for
488 * the current retran path. 491 * the current retran path.
@@ -493,15 +496,15 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
493 transport->asoc->unack_data; 496 transport->asoc->unack_data;
494 break; 497 break;
495 case SCTP_RTXR_FAST_RTX: 498 case SCTP_RTXR_FAST_RTX:
496 SCTP_INC_STATS(SCTP_MIB_FAST_RETRANSMITS); 499 SCTP_INC_STATS(net, SCTP_MIB_FAST_RETRANSMITS);
497 sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX); 500 sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
498 q->fast_rtx = 1; 501 q->fast_rtx = 1;
499 break; 502 break;
500 case SCTP_RTXR_PMTUD: 503 case SCTP_RTXR_PMTUD:
501 SCTP_INC_STATS(SCTP_MIB_PMTUD_RETRANSMITS); 504 SCTP_INC_STATS(net, SCTP_MIB_PMTUD_RETRANSMITS);
502 break; 505 break;
503 case SCTP_RTXR_T1_RTX: 506 case SCTP_RTXR_T1_RTX:
504 SCTP_INC_STATS(SCTP_MIB_T1_RETRANSMITS); 507 SCTP_INC_STATS(net, SCTP_MIB_T1_RETRANSMITS);
505 transport->asoc->init_retries++; 508 transport->asoc->init_retries++;
506 break; 509 break;
507 default: 510 default:
@@ -589,9 +592,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
589 * next chunk. 592 * next chunk.
590 */ 593 */
591 if (chunk->tsn_gap_acked) { 594 if (chunk->tsn_gap_acked) {
592 list_del(&chunk->transmitted_list); 595 list_move_tail(&chunk->transmitted_list,
593 list_add_tail(&chunk->transmitted_list, 596 &transport->transmitted);
594 &transport->transmitted);
595 continue; 597 continue;
596 } 598 }
597 599
@@ -655,9 +657,8 @@ redo:
655 /* The append was successful, so add this chunk to 657 /* The append was successful, so add this chunk to
656 * the transmitted list. 658 * the transmitted list.
657 */ 659 */
658 list_del(&chunk->transmitted_list); 660 list_move_tail(&chunk->transmitted_list,
659 list_add_tail(&chunk->transmitted_list, 661 &transport->transmitted);
660 &transport->transmitted);
661 662
662 /* Mark the chunk as ineligible for fast retransmit 663 /* Mark the chunk as ineligible for fast retransmit
663 * after it is retransmitted. 664 * after it is retransmitted.
@@ -1139,9 +1140,10 @@ static void sctp_sack_update_unack_data(struct sctp_association *assoc,
1139 * Process the SACK against the outqueue. Mostly, this just frees 1140 * Process the SACK against the outqueue. Mostly, this just frees
1140 * things off the transmitted queue. 1141 * things off the transmitted queue.
1141 */ 1142 */
1142int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) 1143int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1143{ 1144{
1144 struct sctp_association *asoc = q->asoc; 1145 struct sctp_association *asoc = q->asoc;
1146 struct sctp_sackhdr *sack = chunk->subh.sack_hdr;
1145 struct sctp_transport *transport; 1147 struct sctp_transport *transport;
1146 struct sctp_chunk *tchunk = NULL; 1148 struct sctp_chunk *tchunk = NULL;
1147 struct list_head *lchunk, *transport_list, *temp; 1149 struct list_head *lchunk, *transport_list, *temp;
@@ -1210,7 +1212,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1210 /* Run through the retransmit queue. Credit bytes received 1212 /* Run through the retransmit queue. Credit bytes received
1211 * and free those chunks that we can. 1213 * and free those chunks that we can.
1212 */ 1214 */
1213 sctp_check_transmitted(q, &q->retransmit, NULL, sack, &highest_new_tsn); 1215 sctp_check_transmitted(q, &q->retransmit, NULL, NULL, sack, &highest_new_tsn);
1214 1216
1215 /* Run through the transmitted queue. 1217 /* Run through the transmitted queue.
1216 * Credit bytes received and free those chunks which we can. 1218 * Credit bytes received and free those chunks which we can.
@@ -1219,7 +1221,8 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1219 */ 1221 */
1220 list_for_each_entry(transport, transport_list, transports) { 1222 list_for_each_entry(transport, transport_list, transports) {
1221 sctp_check_transmitted(q, &transport->transmitted, 1223 sctp_check_transmitted(q, &transport->transmitted,
1222 transport, sack, &highest_new_tsn); 1224 transport, &chunk->source, sack,
1225 &highest_new_tsn);
1223 /* 1226 /*
1224 * SFR-CACC algorithm: 1227 * SFR-CACC algorithm:
1225 * C) Let count_of_newacks be the number of 1228 * C) Let count_of_newacks be the number of
@@ -1326,6 +1329,7 @@ int sctp_outq_is_empty(const struct sctp_outq *q)
1326static void sctp_check_transmitted(struct sctp_outq *q, 1329static void sctp_check_transmitted(struct sctp_outq *q,
1327 struct list_head *transmitted_queue, 1330 struct list_head *transmitted_queue,
1328 struct sctp_transport *transport, 1331 struct sctp_transport *transport,
1332 union sctp_addr *saddr,
1329 struct sctp_sackhdr *sack, 1333 struct sctp_sackhdr *sack,
1330 __u32 *highest_new_tsn_in_sack) 1334 __u32 *highest_new_tsn_in_sack)
1331{ 1335{
@@ -1633,8 +1637,9 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1633 /* Mark the destination transport address as 1637 /* Mark the destination transport address as
1634 * active if it is not so marked. 1638 * active if it is not so marked.
1635 */ 1639 */
1636 if ((transport->state == SCTP_INACTIVE) || 1640 if ((transport->state == SCTP_INACTIVE ||
1637 (transport->state == SCTP_UNCONFIRMED)) { 1641 transport->state == SCTP_UNCONFIRMED) &&
1642 sctp_cmp_addr_exact(&transport->ipaddr, saddr)) {
1638 sctp_assoc_control_transport( 1643 sctp_assoc_control_transport(
1639 transport->asoc, 1644 transport->asoc,
1640 transport, 1645 transport,
@@ -1914,6 +1919,6 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
1914 1919
1915 if (ftsn_chunk) { 1920 if (ftsn_chunk) {
1916 list_add_tail(&ftsn_chunk->list, &q->control_chunk_list); 1921 list_add_tail(&ftsn_chunk->list, &q->control_chunk_list);
1917 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 1922 SCTP_INC_STATS(sock_net(asoc->base.sk), SCTP_MIB_OUTCTRLCHUNKS);
1918 } 1923 }
1919} 1924}