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.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index d765fc53e74d..c9f20e28521b 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -406,8 +406,9 @@ void sctp_retransmit_mark(struct sctp_outq *q,
406 * not be retransmitted 406 * not be retransmitted
407 */ 407 */
408 if (!chunk->tsn_gap_acked) { 408 if (!chunk->tsn_gap_acked) {
409 chunk->transport->flight_size -= 409 if (chunk->transport)
410 sctp_data_size(chunk); 410 chunk->transport->flight_size -=
411 sctp_data_size(chunk);
411 q->outstanding_bytes -= sctp_data_size(chunk); 412 q->outstanding_bytes -= sctp_data_size(chunk);
412 q->asoc->peer.rwnd += (sctp_data_size(chunk) + 413 q->asoc->peer.rwnd += (sctp_data_size(chunk) +
413 sizeof(struct sk_buff)); 414 sizeof(struct sk_buff));
@@ -443,7 +444,8 @@ void sctp_retransmit_mark(struct sctp_outq *q,
443 q->asoc->peer.rwnd += (sctp_data_size(chunk) + 444 q->asoc->peer.rwnd += (sctp_data_size(chunk) +
444 sizeof(struct sk_buff)); 445 sizeof(struct sk_buff));
445 q->outstanding_bytes -= sctp_data_size(chunk); 446 q->outstanding_bytes -= sctp_data_size(chunk);
446 transport->flight_size -= sctp_data_size(chunk); 447 if (chunk->transport)
448 transport->flight_size -= sctp_data_size(chunk);
447 449
448 /* sctpimpguide-05 Section 2.8.2 450 /* sctpimpguide-05 Section 2.8.2
449 * M5) If a T3-rtx timer expires, the 451 * M5) If a T3-rtx timer expires, the
@@ -1310,6 +1312,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1310 __u32 rtt; 1312 __u32 rtt;
1311 __u8 restart_timer = 0; 1313 __u8 restart_timer = 0;
1312 int bytes_acked = 0; 1314 int bytes_acked = 0;
1315 int migrate_bytes = 0;
1313 1316
1314 /* These state variables are for coherent debug output. --xguo */ 1317 /* These state variables are for coherent debug output. --xguo */
1315 1318
@@ -1343,8 +1346,9 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1343 * considering it as 'outstanding'. 1346 * considering it as 'outstanding'.
1344 */ 1347 */
1345 if (!tchunk->tsn_gap_acked) { 1348 if (!tchunk->tsn_gap_acked) {
1346 tchunk->transport->flight_size -= 1349 if (tchunk->transport)
1347 sctp_data_size(tchunk); 1350 tchunk->transport->flight_size -=
1351 sctp_data_size(tchunk);
1348 q->outstanding_bytes -= sctp_data_size(tchunk); 1352 q->outstanding_bytes -= sctp_data_size(tchunk);
1349 } 1353 }
1350 continue; 1354 continue;
@@ -1378,6 +1382,20 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1378 rtt); 1382 rtt);
1379 } 1383 }
1380 } 1384 }
1385
1386 /* If the chunk hasn't been marked as ACKED,
1387 * mark it and account bytes_acked if the
1388 * chunk had a valid transport (it will not
1389 * have a transport if ASCONF had deleted it
1390 * while DATA was outstanding).
1391 */
1392 if (!tchunk->tsn_gap_acked) {
1393 tchunk->tsn_gap_acked = 1;
1394 bytes_acked += sctp_data_size(tchunk);
1395 if (!tchunk->transport)
1396 migrate_bytes += sctp_data_size(tchunk);
1397 }
1398
1381 if (TSN_lte(tsn, sack_ctsn)) { 1399 if (TSN_lte(tsn, sack_ctsn)) {
1382 /* RFC 2960 6.3.2 Retransmission Timer Rules 1400 /* RFC 2960 6.3.2 Retransmission Timer Rules
1383 * 1401 *
@@ -1391,8 +1409,6 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1391 restart_timer = 1; 1409 restart_timer = 1;
1392 1410
1393 if (!tchunk->tsn_gap_acked) { 1411 if (!tchunk->tsn_gap_acked) {
1394 tchunk->tsn_gap_acked = 1;
1395 bytes_acked += sctp_data_size(tchunk);
1396 /* 1412 /*
1397 * SFR-CACC algorithm: 1413 * SFR-CACC algorithm:
1398 * 2) If the SACK contains gap acks 1414 * 2) If the SACK contains gap acks
@@ -1432,10 +1448,6 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1432 * older than that newly acknowledged DATA 1448 * older than that newly acknowledged DATA
1433 * chunk, are qualified as 'Stray DATA chunks'. 1449 * chunk, are qualified as 'Stray DATA chunks'.
1434 */ 1450 */
1435 if (!tchunk->tsn_gap_acked) {
1436 tchunk->tsn_gap_acked = 1;
1437 bytes_acked += sctp_data_size(tchunk);
1438 }
1439 list_add_tail(lchunk, &tlist); 1451 list_add_tail(lchunk, &tlist);
1440 } 1452 }
1441 1453
@@ -1491,7 +1503,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1491 tsn); 1503 tsn);
1492 tchunk->tsn_gap_acked = 0; 1504 tchunk->tsn_gap_acked = 0;
1493 1505
1494 bytes_acked -= sctp_data_size(tchunk); 1506 if (tchunk->transport)
1507 bytes_acked -= sctp_data_size(tchunk);
1495 1508
1496 /* RFC 2960 6.3.2 Retransmission Timer Rules 1509 /* RFC 2960 6.3.2 Retransmission Timer Rules
1497 * 1510 *
@@ -1561,6 +1574,14 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1561#endif /* SCTP_DEBUG */ 1574#endif /* SCTP_DEBUG */
1562 if (transport) { 1575 if (transport) {
1563 if (bytes_acked) { 1576 if (bytes_acked) {
1577 /* We may have counted DATA that was migrated
1578 * to this transport due to DEL-IP operation.
1579 * Subtract those bytes, since the were never
1580 * send on this transport and shouldn't be
1581 * credited to this transport.
1582 */
1583 bytes_acked -= migrate_bytes;
1584
1564 /* 8.2. When an outstanding TSN is acknowledged, 1585 /* 8.2. When an outstanding TSN is acknowledged,
1565 * the endpoint shall clear the error counter of 1586 * the endpoint shall clear the error counter of
1566 * the destination transport address to which the 1587 * the destination transport address to which the
@@ -1589,7 +1610,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1589 transport->flight_size -= bytes_acked; 1610 transport->flight_size -= bytes_acked;
1590 if (transport->flight_size == 0) 1611 if (transport->flight_size == 0)
1591 transport->partial_bytes_acked = 0; 1612 transport->partial_bytes_acked = 0;
1592 q->outstanding_bytes -= bytes_acked; 1613 q->outstanding_bytes -= bytes_acked + migrate_bytes;
1593 } else { 1614 } else {
1594 /* RFC 2960 6.1, sctpimpguide-06 2.15.2 1615 /* RFC 2960 6.1, sctpimpguide-06 2.15.2
1595 * When a sender is doing zero window probing, it 1616 * When a sender is doing zero window probing, it