aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sctp/outqueue.c42
1 files changed, 7 insertions, 35 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index b491a1aac3e4..5d057178ce0c 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -62,7 +62,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
62 struct list_head *transmitted_queue, 62 struct list_head *transmitted_queue,
63 struct sctp_transport *transport, 63 struct sctp_transport *transport,
64 struct sctp_sackhdr *sack, 64 struct sctp_sackhdr *sack,
65 __u32 highest_new_tsn); 65 __u32 *highest_new_tsn);
66 66
67static void sctp_mark_missing(struct sctp_outq *q, 67static void sctp_mark_missing(struct sctp_outq *q,
68 struct list_head *transmitted_queue, 68 struct list_head *transmitted_queue,
@@ -1109,32 +1109,6 @@ static void sctp_sack_update_unack_data(struct sctp_association *assoc,
1109 assoc->unack_data = unack_data; 1109 assoc->unack_data = unack_data;
1110} 1110}
1111 1111
1112/* Return the highest new tsn that is acknowledged by the given SACK chunk. */
1113static __u32 sctp_highest_new_tsn(struct sctp_sackhdr *sack,
1114 struct sctp_association *asoc)
1115{
1116 struct sctp_transport *transport;
1117 struct sctp_chunk *chunk;
1118 __u32 highest_new_tsn, tsn;
1119 struct list_head *transport_list = &asoc->peer.transport_addr_list;
1120
1121 highest_new_tsn = ntohl(sack->cum_tsn_ack);
1122
1123 list_for_each_entry(transport, transport_list, transports) {
1124 list_for_each_entry(chunk, &transport->transmitted,
1125 transmitted_list) {
1126 tsn = ntohl(chunk->subh.data_hdr->tsn);
1127
1128 if (!chunk->tsn_gap_acked &&
1129 TSN_lt(highest_new_tsn, tsn) &&
1130 sctp_acked(sack, tsn))
1131 highest_new_tsn = tsn;
1132 }
1133 }
1134
1135 return highest_new_tsn;
1136}
1137
1138/* This is where we REALLY process a SACK. 1112/* This is where we REALLY process a SACK.
1139 * 1113 *
1140 * Process the SACK against the outqueue. Mostly, this just frees 1114 * Process the SACK against the outqueue. Mostly, this just frees
@@ -1203,18 +1177,15 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1203 if (gap_ack_blocks) 1177 if (gap_ack_blocks)
1204 highest_tsn += ntohs(frags[gap_ack_blocks - 1].gab.end); 1178 highest_tsn += ntohs(frags[gap_ack_blocks - 1].gab.end);
1205 1179
1206 if (TSN_lt(asoc->highest_sacked, highest_tsn)) { 1180 if (TSN_lt(asoc->highest_sacked, highest_tsn))
1207 highest_new_tsn = highest_tsn;
1208 asoc->highest_sacked = highest_tsn; 1181 asoc->highest_sacked = highest_tsn;
1209 } else {
1210 highest_new_tsn = sctp_highest_new_tsn(sack, asoc);
1211 }
1212 1182
1183 highest_new_tsn = sack_ctsn;
1213 1184
1214 /* Run through the retransmit queue. Credit bytes received 1185 /* Run through the retransmit queue. Credit bytes received
1215 * and free those chunks that we can. 1186 * and free those chunks that we can.
1216 */ 1187 */
1217 sctp_check_transmitted(q, &q->retransmit, NULL, sack, highest_new_tsn); 1188 sctp_check_transmitted(q, &q->retransmit, NULL, sack, &highest_new_tsn);
1218 1189
1219 /* Run through the transmitted queue. 1190 /* Run through the transmitted queue.
1220 * Credit bytes received and free those chunks which we can. 1191 * Credit bytes received and free those chunks which we can.
@@ -1223,7 +1194,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1223 */ 1194 */
1224 list_for_each_entry(transport, transport_list, transports) { 1195 list_for_each_entry(transport, transport_list, transports) {
1225 sctp_check_transmitted(q, &transport->transmitted, 1196 sctp_check_transmitted(q, &transport->transmitted,
1226 transport, sack, highest_new_tsn); 1197 transport, sack, &highest_new_tsn);
1227 /* 1198 /*
1228 * SFR-CACC algorithm: 1199 * SFR-CACC algorithm:
1229 * C) Let count_of_newacks be the number of 1200 * C) Let count_of_newacks be the number of
@@ -1331,7 +1302,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1331 struct list_head *transmitted_queue, 1302 struct list_head *transmitted_queue,
1332 struct sctp_transport *transport, 1303 struct sctp_transport *transport,
1333 struct sctp_sackhdr *sack, 1304 struct sctp_sackhdr *sack,
1334 __u32 highest_new_tsn_in_sack) 1305 __u32 *highest_new_tsn_in_sack)
1335{ 1306{
1336 struct list_head *lchunk; 1307 struct list_head *lchunk;
1337 struct sctp_chunk *tchunk; 1308 struct sctp_chunk *tchunk;
@@ -1419,6 +1390,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1419 */ 1390 */
1420 if (!tchunk->tsn_gap_acked) { 1391 if (!tchunk->tsn_gap_acked) {
1421 tchunk->tsn_gap_acked = 1; 1392 tchunk->tsn_gap_acked = 1;
1393 *highest_new_tsn_in_sack = tsn;
1422 bytes_acked += sctp_data_size(tchunk); 1394 bytes_acked += sctp_data_size(tchunk);
1423 if (!tchunk->transport) 1395 if (!tchunk->transport)
1424 migrate_bytes += sctp_data_size(tchunk); 1396 migrate_bytes += sctp_data_size(tchunk);