@@ -73,12 +73,15 @@ static void sctp_check_transmitted(struct sctp_outq *q,
73
73
struct sctp_transport * transport ,
74
74
union sctp_addr * saddr ,
75
75
struct sctp_sackhdr * sack ,
76
- __u32 * highest_new_tsn );
76
+ __u32 * highest_new_tsn ,
77
+ __u32 * lowest_new_tsn );
77
78
78
79
static void sctp_mark_missing (struct sctp_outq * q ,
79
80
struct list_head * transmitted_queue ,
80
81
struct sctp_transport * transport ,
81
82
__u32 highest_new_tsn ,
83
+ __u32 lowest_new_tsn ,
84
+ int num_pdu_acked ,
82
85
int count_of_newacks );
83
86
84
87
static void sctp_generate_fwdtsn (struct sctp_outq * q , __u32 sack_ctsn );
@@ -233,6 +236,57 @@ static inline int sctp_cmt_sfr_skip(struct sctp_transport *transport,
233
236
return 1 ;
234
237
235
238
}
239
+
240
+ /** CMT-DAC algorithm step (4) */
241
+ static inline int sctp_dac_missing (struct sctp_transport * transport ,
242
+ __u32 tsn , int num_pdu_acked ,
243
+ __u32 lowest_in_new , __u32 highest_in_new )
244
+ {
245
+ bool only_you ;
246
+ struct list_head * pos , * temp ;
247
+ struct sctp_transport * tmp_trxpt ;
248
+ int retval ;
249
+ BUG_ON (!transport );
250
+ BUG_ON (num_pdu_acked < 0 || num_pdu_acked > 2 );
251
+
252
+ only_you = true;
253
+ list_for_each_safe (pos , temp , & transport -> transports ) {
254
+ tmp_trxpt = list_entry (pos , struct sctp_transport , transports );
255
+ if (tmp_trxpt -> cmt_sfr .saw_newack && tmp_trxpt != transport ) {
256
+ only_you = false;
257
+ break ;
258
+ }
259
+ }
260
+ /* DAC 4)
261
+ * to determine whether missing report for a tsn tm should be ++
262
+ * let dm be the destination to which tm was sent;
263
+ * if (dm.saw_newack==true) and (dm.highest_in_sack_for_dest > tm)
264
+ * then
265
+ */
266
+ if (transport -> cmt_sfr .saw_newack && TSN_lt (tsn , transport -> cmt_sfr .hisfd )) {
267
+ /* i) if any other desintations does not "see_new" */
268
+ if (only_you ) {// the acked packets are only sent through this destination
269
+ if (lowest_in_new < tsn && tsn < highest_in_new )
270
+ retval = 1 ;
271
+ else
272
+ retval = num_pdu_acked ;
273
+ }
274
+ else // ii) others see new as well
275
+ retval = 1 ;
276
+ } else
277
+ retval = 0 ;
278
+
279
+ cmt_debug ("=======>retval=%d,tsn=0x%x, only_you=%d, lowest=0x%x, highest=0x%x, pdu_num=%d\n" ,
280
+ retval ,
281
+ tsn ,
282
+ only_you ,
283
+ lowest_in_new ,
284
+ highest_in_new ,
285
+ num_pdu_acked
286
+ );
287
+ return retval ;
288
+ }
289
+
236
290
/* Initialize an existing sctp_outq. This does the boring stuff.
237
291
* You still need to define handlers if you really want to DO
238
292
* something with this structure...
@@ -1220,14 +1274,15 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1220
1274
struct list_head * lchunk , * transport_list , * temp ;
1221
1275
sctp_sack_variable_t * frags = sack -> variable ;
1222
1276
__u32 sack_ctsn , ctsn , tsn ;
1223
- __u32 highest_tsn , highest_new_tsn ;
1277
+ __u32 highest_tsn , highest_new_tsn , lowest_new_tsn ;
1224
1278
__u32 sack_a_rwnd ;
1225
1279
char * to_console ;
1226
1280
unsigned int outstanding ;
1227
1281
struct sctp_transport * primary = asoc -> peer .primary_path ;
1228
1282
int count_of_newacks = 0 ;
1229
1283
int gap_ack_blocks ;
1230
1284
u8 accum_moved = 0 ;
1285
+ int num_pdu_acked ;
1231
1286
1232
1287
/* Grab the association's destination address list. */
1233
1288
transport_list = & asoc -> peer .transport_addr_list ;
@@ -1256,6 +1311,10 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1256
1311
sack_ctsn = ntohl (sack -> cum_tsn_ack );
1257
1312
gap_ack_blocks = ntohs (sack -> num_gap_ack_blocks );
1258
1313
asoc -> stats .gapcnt += gap_ack_blocks ;
1314
+
1315
+ /*For DAC - check if this SACK is for 2 the consecutive Data Chunks */
1316
+ num_pdu_acked =
1317
+ (chunk -> chunk_hdr -> flags & (1 << SCTP_SACK_NUM_PDU_BEG ))? 2 : 1 ;
1259
1318
/*
1260
1319
* SFR-CACC algorithm:
1261
1320
* On receipt of a SACK the sender SHOULD execute the
@@ -1320,6 +1379,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1320
1379
if (TSN_lt (asoc -> highest_sacked , highest_tsn ))
1321
1380
asoc -> highest_sacked = highest_tsn ;
1322
1381
1382
+ lowest_new_tsn = asoc -> next_tsn ;
1323
1383
highest_new_tsn = sack_ctsn ;
1324
1384
1325
1385
/* CMT-CUC (2)
@@ -1355,7 +1415,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1355
1415
/* Run through the retransmit queue. Credit bytes received
1356
1416
* and free those chunks that we can.
1357
1417
*/
1358
- sctp_check_transmitted (q , & q -> retransmit , NULL , NULL , sack , & highest_new_tsn );
1418
+ sctp_check_transmitted (q , & q -> retransmit , NULL , NULL , sack , & highest_new_tsn , & lowest_new_tsn );
1359
1419
1360
1420
/* Run through the transmitted queue.
1361
1421
* Credit bytes received and free those chunks which we can.
@@ -1365,7 +1425,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1365
1425
list_for_each_entry (transport , transport_list , transports ) {
1366
1426
sctp_check_transmitted (q , & transport -> transmitted ,
1367
1427
transport , & chunk -> source , sack ,
1368
- & highest_new_tsn );
1428
+ & highest_new_tsn , & lowest_new_tsn );
1369
1429
/*
1370
1430
* SFR-CACC algorithm:
1371
1431
* C) Let count_of_newacks be the number of
@@ -1391,8 +1451,10 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1391
1451
highest_new_tsn = highest_tsn ;
1392
1452
1393
1453
list_for_each_entry (transport , transport_list , transports )
1394
- sctp_mark_missing (q , & transport -> transmitted , transport ,
1395
- highest_new_tsn , count_of_newacks );
1454
+ sctp_mark_missing (q , & transport -> transmitted ,
1455
+ transport , highest_new_tsn ,
1456
+ lowest_new_tsn , num_pdu_acked ,
1457
+ count_of_newacks );
1396
1458
}
1397
1459
1398
1460
/* Update unack_data field in the assoc. */
@@ -1477,7 +1539,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1477
1539
struct sctp_transport * transport ,
1478
1540
union sctp_addr * saddr ,
1479
1541
struct sctp_sackhdr * sack ,
1480
- __u32 * highest_new_tsn_in_sack )
1542
+ __u32 * highest_new_tsn_in_sack ,
1543
+ __u32 * lowest_new_tsn_in_sack )
1481
1544
{
1482
1545
struct list_head * lchunk ;
1483
1546
struct sctp_chunk * tchunk ;
@@ -1550,6 +1613,9 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1550
1613
* while DATA was outstanding).
1551
1614
*/
1552
1615
if (!tchunk -> tsn_gap_acked ) {
1616
+ // Find the lowest & highest respective
1617
+ if (TSN_lt (tsn , * lowest_new_tsn_in_sack ))
1618
+ * lowest_new_tsn_in_sack = tsn ;
1553
1619
if (TSN_lt (* highest_new_tsn_in_sack , tsn ))
1554
1620
* highest_new_tsn_in_sack = tsn ;
1555
1621
bytes_acked += sctp_data_size (tchunk );
@@ -1811,13 +1877,16 @@ static void sctp_mark_missing(struct sctp_outq *q,
1811
1877
struct list_head * transmitted_queue ,
1812
1878
struct sctp_transport * transport ,
1813
1879
__u32 highest_new_tsn_in_sack ,
1880
+ __u32 lowest_new_tsn_in_sack ,
1881
+ int num_pdu_acked ,
1814
1882
int count_of_newacks )
1815
1883
{
1816
1884
struct sctp_chunk * chunk ;
1817
1885
__u32 tsn ;
1818
1886
char do_fast_retransmit = 0 ;
1819
1887
struct sctp_association * asoc = q -> asoc ;
1820
1888
struct sctp_transport * primary = asoc -> peer .primary_path ;
1889
+ int missing_inc = 1 ;
1821
1890
1822
1891
list_for_each_entry (chunk , transmitted_queue , transmitted_list ) {
1823
1892
@@ -1839,13 +1908,19 @@ static void sctp_mark_missing(struct sctp_outq *q,
1839
1908
*/
1840
1909
bool cacc = sctp_cacc_skip (primary , chunk -> transport , count_of_newacks , tsn );
1841
1910
/*Apply CMT-SFR*/
1842
- bool sfr = sctp_cmt_sfr_skip (chunk -> transport , tsn );
1843
- // bool sfr = false;
1911
+ // bool sfr = sctp_cmt_sfr_skip(chunk->transport, tsn);
1912
+ bool sfr = false;
1844
1913
if (sfr )
1845
1914
cmt_debug ("==>sfr works!\n" );
1846
1915
if (!transport || !(cacc || sfr )) {
1847
- chunk -> tsn_missing_report ++ ;
1848
-
1916
+ missing_inc = sctp_dac_missing (transport ,
1917
+ tsn , num_pdu_acked ,
1918
+ lowest_new_tsn_in_sack ,
1919
+ highest_new_tsn_in_sack );
1920
+ chunk -> tsn_missing_report += missing_inc ;
1921
+
1922
+ if (missing_inc >= 2 )
1923
+ cmt_debug ("--->DAC works!\n" );
1849
1924
pr_debug ("%s: tsn:0x%x missing counter:%d\n" ,
1850
1925
__func__ , tsn , chunk -> tsn_missing_report );
1851
1926
0 commit comments