59
59
#include <net/sctp/sm.h>
60
60
#include <net/sctp/cmt.h>
61
61
62
+ #ifdef pr_debug
63
+ #undef pr_debug
64
+ #endif
65
+
66
+ #define pr_debug (fmt , ...) ;
67
+
68
+
62
69
/* Declare internal functions here. */
63
70
static int sctp_acked (struct sctp_sackhdr * sack , __u32 tsn );
64
71
static void sctp_check_transmitted (struct sctp_outq * q ,
@@ -201,6 +208,31 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary,
201
208
return 0 ;
202
209
}
203
210
211
+ /** CMT-SFR algorithm
212
+ */
213
+ static inline int sctp_cmt_sfr (struct sctp_transport * transport ,
214
+ __u32 tsn )
215
+ {
216
+ if (!transport ) {
217
+ // cmt_debug("***********transport is null!***************\n");
218
+ dump_stack ();
219
+ return 1 ;
220
+ }
221
+ // say 1. 6 was sent through A; 789 through B.
222
+ // 2. The corresponding ack is 6,[8-9]
223
+ //
224
+ // Then the B.hisfd == 9
225
+ // 7 is regarded as missing
226
+ if (transport -> cmt_sfr .saw_newack &&
227
+ TSN_lt (tsn , transport -> cmt_sfr .hisfd )) {
228
+ // cmt_debug("---->counter ++\n");
229
+ return 1 ;
230
+ }
231
+
232
+ // cmt_debug("---->eliminate unneceseary counter++!\n");
233
+ return 0 ;
234
+
235
+ }
204
236
/* Initialize an existing sctp_outq. This does the boring stuff.
205
237
* You still need to define handlers if you really want to DO
206
238
* something with this structure...
@@ -1033,7 +1065,7 @@ use_retran: if (new_transport->state == SCTP_UNCONFIRMED)
1033
1065
*/
1034
1066
if (transport == asoc -> peer .active_path
1035
1067
&& asoc -> peer .retran_path != asoc -> peer .active_path ) {
1036
- cmt_debug ("%s: switch to retran\n" , __func__ );
1068
+ // cmt_debug("%s: switch to retran\n", __func__);
1037
1069
new_transport = asoc -> peer .retran_path ;
1038
1070
goto use_retran ;
1039
1071
}
@@ -1168,34 +1200,38 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1168
1200
/* Grab the association's destination address list. */
1169
1201
transport_list = & asoc -> peer .transport_addr_list ;
1170
1202
1171
- // int c = 0;
1172
- // static char buf[256];
1173
- // memset(buf, 0, sizeof(buf));
1174
- // list_for_each_entry(transport, transport_list,
1175
- // transports)
1176
- // c += snprintf(
1177
- // buf + c,
1178
- // sizeof(buf) - c,
1179
- // "trxpt|%p|cwnd=%d|ssthresh=%d|,",
1180
- // transport,
1181
- // transport->cwnd,
1182
- // transport->ssthresh);
1183
- //
1184
- // cmt_debug("%s: %s\n", __func__, buf);
1185
-
1186
-
1187
- // cmt_debug("%s: %s\n", __func__, cmt_print_assoc(asoc));
1188
- // to_console = cmt_print_queued_tsn(&q->retransmit, NULL);
1189
- // cmt_debug("%s\n", to_console);
1190
- //
1191
- // list_for_each_entry(transport, transport_list, transports) {
1192
- // to_console = cmt_print_queued_tsn(&transport->transmitted, transport);
1193
- // cmt_debug("%s\n", to_console);
1194
- // }
1195
- //
1196
- // to_console = cmt_print_sackhdr(sack);
1197
- // cmt_debug("%s\n", to_console);
1198
-
1203
+ int c = 0 ;
1204
+ static char buf [256 ];
1205
+ memset (buf , 0 , sizeof (buf ));
1206
+ list_for_each_entry (transport , transport_list ,
1207
+ transports )
1208
+ c += snprintf (
1209
+ buf + c ,
1210
+ sizeof (buf ) - c ,
1211
+ "trxpt|%p|cwnd=%d|ssthresh=%d|," ,
1212
+ transport ,
1213
+ transport -> cwnd ,
1214
+ transport -> ssthresh );
1215
+
1216
+ cmt_debug ("%s: %s\n" , __func__ , buf );
1217
+
1218
+
1219
+ /* // print association
1220
+ cmt_debug("%s: %s\n", __func__, cmt_print_assoc(asoc));
1221
+
1222
+ // print what's in the retransmit queue
1223
+ to_console = cmt_print_queued_tsn(&q->retransmit, NULL);
1224
+ cmt_debug("%s\n", to_console);
1225
+
1226
+ // print what's in the queues.
1227
+ list_for_each_entry(transport, transport_list, transports) {
1228
+ to_console = cmt_print_queued_tsn(&transport->transmitted, transport);
1229
+ cmt_debug("%s\n", to_console);
1230
+ }
1231
+
1232
+ to_console = cmt_print_sackhdr(sack);
1233
+ cmt_debug("%s\n", to_console);
1234
+ */
1199
1235
/* Print the context END */
1200
1236
1201
1237
sack_ctsn = ntohl (sack -> cum_tsn_ack );
@@ -1238,6 +1274,18 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1238
1274
}
1239
1275
}
1240
1276
1277
+ /* CMT-SFR
1278
+ * On receipt of a SACK containing gap report
1279
+ * 1.for each destination address d(i), initialize
1280
+ * d(i).saw_newack = false
1281
+ */
1282
+ if (gap_ack_blocks ) {
1283
+ list_for_each_entry (transport , transport_list , transports ) {
1284
+ transport -> cmt_sfr .saw_newack = false;
1285
+ transport -> cmt_sfr .hisfd = asoc -> c .initial_tsn ;
1286
+ }
1287
+ }
1288
+
1241
1289
/* Get the highest TSN in the sack. */
1242
1290
highest_tsn = sack_ctsn ;
1243
1291
if (gap_ack_blocks )
@@ -1277,6 +1325,10 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1277
1325
accum_moved = 1 ;
1278
1326
}
1279
1327
1328
+ // list_for_each_entry(transport, transport_list, transports) {
1329
+ // cmt_debug("===========>%s \n", cmt_print_trxpt(transport));
1330
+ // }
1331
+
1280
1332
if (gap_ack_blocks ) {
1281
1333
1282
1334
if (asoc -> fast_recovery && accum_moved )
@@ -1447,9 +1499,43 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1447
1499
if (!tchunk -> transport )
1448
1500
migrate_bytes += sctp_data_size (tchunk );
1449
1501
forward_progress = true;
1502
+
1503
+
1504
+ // TODO: For each retransmit,
1505
+ // The tsn->transport would be set to the
1506
+ // latest path, to which it's sent.
1507
+ // CMT-SFR 2) for each TSN t(a) being newly
1508
+ // acked
1509
+ // set d(a).saw_newack=true;
1510
+ // CMT-SFR 3) set highest_in_sack_for_dest
1511
+ if (transport ) {// use tchunk -> transport instead
1512
+ transport -> cmt_sfr .saw_newack = true;
1513
+ if (TSN_lt (transport -> cmt_sfr .hisfd , tsn ))
1514
+ transport -> cmt_sfr .hisfd = tsn ;
1515
+ }
1516
+
1517
+ /*
1518
+ * SFR-CACC algorithm:
1519
+ * 2) If the SACK contains gap acks
1520
+ * and the flag CHANGEOVER_ACTIVE is
1521
+ * set the receiver of the SACK MUST
1522
+ * take the following action:
1523
+ *
1524
+ * B) For each TSN t being acked that
1525
+ * has not been acked in any SACK so
1526
+ * far, set cacc_saw_newack to 1 for
1527
+ * the destination that the TSN was
1528
+ * sent to.
1529
+ */
1530
+ if (transport && sack -> num_gap_ack_blocks &&
1531
+ q -> asoc -> peer .primary_path -> cacc .
1532
+ changeover_active )
1533
+ transport -> cacc .cacc_saw_newack = 1 ;
1534
+
1535
+
1450
1536
}
1451
1537
1452
- if (TSN_lte (tsn , sack_ctsn )) {
1538
+ if (TSN_lte (tsn , sack_ctsn )) {// CXZ: cum acked
1453
1539
/* RFC 2960 6.3.2 Retransmission Timer Rules
1454
1540
*
1455
1541
* R3) Whenever a SACK is received
@@ -1461,32 +1547,11 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1461
1547
*/
1462
1548
restart_timer = 1 ;
1463
1549
forward_progress = true;
1464
-
1465
- if (!tchunk -> tsn_gap_acked ) {
1466
- /*
1467
- * SFR-CACC algorithm:
1468
- * 2) If the SACK contains gap acks
1469
- * and the flag CHANGEOVER_ACTIVE is
1470
- * set the receiver of the SACK MUST
1471
- * take the following action:
1472
- *
1473
- * B) For each TSN t being acked that
1474
- * has not been acked in any SACK so
1475
- * far, set cacc_saw_newack to 1 for
1476
- * the destination that the TSN was
1477
- * sent to.
1478
- */
1479
- if (transport &&
1480
- sack -> num_gap_ack_blocks &&
1481
- q -> asoc -> peer .primary_path -> cacc .
1482
- changeover_active )
1483
- transport -> cacc .cacc_saw_newack
1484
- = 1 ;
1485
- }
1486
-
1487
1550
list_add_tail (& tchunk -> transmitted_list ,
1488
1551
& q -> sacked );
1489
- } else {
1552
+
1553
+
1554
+ } else {// gap acked
1490
1555
/* RFC2960 7.2.4, sctpimpguide-05 2.8.2
1491
1556
* M2) Each time a SACK arrives reporting
1492
1557
* 'Stray DATA chunk(s)' record the highest TSN
@@ -1668,13 +1733,20 @@ static void sctp_mark_missing(struct sctp_outq *q,
1668
1733
/* SFR-CACC may require us to skip marking
1669
1734
* this chunk as missing.
1670
1735
*/
1671
- if (!transport || !sctp_cacc_skip (primary ,
1736
+ if (!transport || (
1737
+ !sctp_cacc_skip (primary ,
1672
1738
chunk -> transport ,
1673
- count_of_newacks , tsn )) {
1739
+ count_of_newacks , tsn )
1740
+
1741
+ &&
1742
+
1743
+ sctp_cmt_sfr (chunk -> transport , tsn )
1744
+
1745
+ )) {
1674
1746
chunk -> tsn_missing_report ++ ;
1675
1747
1676
- pr_debug ("%s: tsn:0x%x missing counter:%d\n" ,
1677
- __func__ , tsn , chunk -> tsn_missing_report );
1748
+ pr_debug ("%s: tsn:0x%x missing counter:%d, reason: cacc=%d, sfr=%d \n" ,
1749
+ __func__ , tsn , chunk -> tsn_missing_report , cacc , sfr );
1678
1750
}
1679
1751
}
1680
1752
/*
0 commit comments