diff options
-rw-r--r-- | net/sctp/outqueue.c | 42 |
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 | ||
67 | static void sctp_mark_missing(struct sctp_outq *q, | 67 | static 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. */ | ||
1113 | static __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); |