@@ -406,8 +406,9 @@ void sctp_retransmit_mark(struct sctp_outq *q,
406
406
* not be retransmitted
407
407
*/
408
408
if (!chunk -> tsn_gap_acked ) {
409
- chunk -> transport -> flight_size -=
410
- sctp_data_size (chunk );
409
+ if (chunk -> transport )
410
+ chunk -> transport -> flight_size -=
411
+ sctp_data_size (chunk );
411
412
q -> outstanding_bytes -= sctp_data_size (chunk );
412
413
q -> asoc -> peer .rwnd += (sctp_data_size (chunk ) +
413
414
sizeof (struct sk_buff ));
@@ -443,7 +444,8 @@ void sctp_retransmit_mark(struct sctp_outq *q,
443
444
q -> asoc -> peer .rwnd += (sctp_data_size (chunk ) +
444
445
sizeof (struct sk_buff ));
445
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
450
/* sctpimpguide-05 Section 2.8.2
449
451
* M5) If a T3-rtx timer expires, the
@@ -1310,6 +1312,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1310
1312
__u32 rtt ;
1311
1313
__u8 restart_timer = 0 ;
1312
1314
int bytes_acked = 0 ;
1315
+ int migrate_bytes = 0 ;
1313
1316
1314
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
1346
* considering it as 'outstanding'.
1344
1347
*/
1345
1348
if (!tchunk -> tsn_gap_acked ) {
1346
- tchunk -> transport -> flight_size -=
1347
- sctp_data_size (tchunk );
1349
+ if (tchunk -> transport )
1350
+ tchunk -> transport -> flight_size -=
1351
+ sctp_data_size (tchunk );
1348
1352
q -> outstanding_bytes -= sctp_data_size (tchunk );
1349
1353
}
1350
1354
continue ;
@@ -1378,6 +1382,20 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1378
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
1399
if (TSN_lte (tsn , sack_ctsn )) {
1382
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
1409
restart_timer = 1 ;
1392
1410
1393
1411
if (!tchunk -> tsn_gap_acked ) {
1394
- tchunk -> tsn_gap_acked = 1 ;
1395
- bytes_acked += sctp_data_size (tchunk );
1396
1412
/*
1397
1413
* SFR-CACC algorithm:
1398
1414
* 2) If the SACK contains gap acks
@@ -1432,10 +1448,6 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1432
1448
* older than that newly acknowledged DATA
1433
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
1451
list_add_tail (lchunk , & tlist );
1440
1452
}
1441
1453
@@ -1491,7 +1503,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1491
1503
tsn );
1492
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
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
1574
#endif /* SCTP_DEBUG */
1562
1575
if (transport ) {
1563
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
1585
/* 8.2. When an outstanding TSN is acknowledged,
1565
1586
* the endpoint shall clear the error counter of
1566
1587
* the destination transport address to which the
@@ -1589,7 +1610,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1589
1610
transport -> flight_size -= bytes_acked ;
1590
1611
if (transport -> flight_size == 0 )
1591
1612
transport -> partial_bytes_acked = 0 ;
1592
- q -> outstanding_bytes -= bytes_acked ;
1613
+ q -> outstanding_bytes -= bytes_acked + migrate_bytes ;
1593
1614
} else {
1594
1615
/* RFC 2960 6.1, sctpimpguide-06 2.15.2
1595
1616
* When a sender is doing zero window probing, it
0 commit comments