diff options
-rw-r--r-- | net/sctp/outqueue.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 4328ad5439c9..ef5ea7423cc8 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -1129,12 +1129,13 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
1129 | unsigned outstanding; | 1129 | unsigned outstanding; |
1130 | struct sctp_transport *primary = asoc->peer.primary_path; | 1130 | struct sctp_transport *primary = asoc->peer.primary_path; |
1131 | int count_of_newacks = 0; | 1131 | int count_of_newacks = 0; |
1132 | int gap_ack_blocks; | ||
1132 | 1133 | ||
1133 | /* Grab the association's destination address list. */ | 1134 | /* Grab the association's destination address list. */ |
1134 | transport_list = &asoc->peer.transport_addr_list; | 1135 | transport_list = &asoc->peer.transport_addr_list; |
1135 | 1136 | ||
1136 | sack_ctsn = ntohl(sack->cum_tsn_ack); | 1137 | sack_ctsn = ntohl(sack->cum_tsn_ack); |
1137 | 1138 | gap_ack_blocks = ntohs(sack->num_gap_ack_blocks); | |
1138 | /* | 1139 | /* |
1139 | * SFR-CACC algorithm: | 1140 | * SFR-CACC algorithm: |
1140 | * On receipt of a SACK the sender SHOULD execute the | 1141 | * On receipt of a SACK the sender SHOULD execute the |
@@ -1161,7 +1162,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
1161 | * A) Initialize the cacc_saw_newack to 0 for all destination | 1162 | * A) Initialize the cacc_saw_newack to 0 for all destination |
1162 | * addresses. | 1163 | * addresses. |
1163 | */ | 1164 | */ |
1164 | if (sack->num_gap_ack_blocks && | 1165 | if (gap_ack_blocks && |
1165 | primary->cacc.changeover_active) { | 1166 | primary->cacc.changeover_active) { |
1166 | list_for_each_entry(transport, transport_list, transports) { | 1167 | list_for_each_entry(transport, transport_list, transports) { |
1167 | transport->cacc.cacc_saw_newack = 0; | 1168 | transport->cacc.cacc_saw_newack = 0; |
@@ -1170,9 +1171,8 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
1170 | 1171 | ||
1171 | /* Get the highest TSN in the sack. */ | 1172 | /* Get the highest TSN in the sack. */ |
1172 | highest_tsn = sack_ctsn; | 1173 | highest_tsn = sack_ctsn; |
1173 | if (sack->num_gap_ack_blocks) | 1174 | if (gap_ack_blocks) |
1174 | highest_tsn += | 1175 | highest_tsn += ntohs(frags[gap_ack_blocks - 1].gab.end); |
1175 | ntohs(frags[ntohs(sack->num_gap_ack_blocks) - 1].gab.end); | ||
1176 | 1176 | ||
1177 | if (TSN_lt(asoc->highest_sacked, highest_tsn)) { | 1177 | if (TSN_lt(asoc->highest_sacked, highest_tsn)) { |
1178 | highest_new_tsn = highest_tsn; | 1178 | highest_new_tsn = highest_tsn; |
@@ -1181,11 +1181,11 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
1181 | highest_new_tsn = sctp_highest_new_tsn(sack, asoc); | 1181 | highest_new_tsn = sctp_highest_new_tsn(sack, asoc); |
1182 | } | 1182 | } |
1183 | 1183 | ||
1184 | |||
1184 | /* Run through the retransmit queue. Credit bytes received | 1185 | /* Run through the retransmit queue. Credit bytes received |
1185 | * and free those chunks that we can. | 1186 | * and free those chunks that we can. |
1186 | */ | 1187 | */ |
1187 | sctp_check_transmitted(q, &q->retransmit, NULL, sack, highest_new_tsn); | 1188 | sctp_check_transmitted(q, &q->retransmit, NULL, sack, highest_new_tsn); |
1188 | sctp_mark_missing(q, &q->retransmit, NULL, highest_new_tsn, 0); | ||
1189 | 1189 | ||
1190 | /* Run through the transmitted queue. | 1190 | /* Run through the transmitted queue. |
1191 | * Credit bytes received and free those chunks which we can. | 1191 | * Credit bytes received and free those chunks which we can. |
@@ -1204,9 +1204,12 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
1204 | count_of_newacks ++; | 1204 | count_of_newacks ++; |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | list_for_each_entry(transport, transport_list, transports) { | 1207 | if (gap_ack_blocks) { |
1208 | sctp_mark_missing(q, &transport->transmitted, transport, | 1208 | sctp_mark_missing(q, &q->retransmit, NULL, highest_new_tsn, 0); |
1209 | highest_new_tsn, count_of_newacks); | 1209 | |
1210 | list_for_each_entry(transport, transport_list, transports) | ||
1211 | sctp_mark_missing(q, &transport->transmitted, transport, | ||
1212 | highest_new_tsn, count_of_newacks); | ||
1210 | } | 1213 | } |
1211 | 1214 | ||
1212 | /* Move the Cumulative TSN Ack Point if appropriate. */ | 1215 | /* Move the Cumulative TSN Ack Point if appropriate. */ |