summaryrefslogtreecommitdiffstats
path: root/net/sctp/outqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r--net/sctp/outqueue.c71
1 files changed, 31 insertions, 40 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 1bb3c5c35d2a..59edfd25a19c 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -221,12 +221,12 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
void sctp_outq_teardown(struct sctp_outq *q)
{
struct sctp_transport *transport;
- struct list_head *lchunk, *pos, *temp;
+ struct list_head *lchunk, *temp;
struct sctp_chunk *chunk, *tmp;
/* Throw away unacknowledged chunks. */
- list_for_each(pos, &q->asoc->peer.transport_addr_list) {
- transport = list_entry(pos, struct sctp_transport, transports);
+ list_for_each_entry(transport, &q->asoc->peer.transport_addr_list,
+ transports) {
while ((lchunk = sctp_list_dequeue(&transport->transmitted)) != NULL) {
chunk = list_entry(lchunk, struct sctp_chunk,
transmitted_list);
@@ -469,7 +469,7 @@ void sctp_retransmit_mark(struct sctp_outq *q,
SCTP_DEBUG_PRINTK("%s: transport: %p, reason: %d, "
"cwnd: %d, ssthresh: %d, flight_size: %d, "
- "pba: %d\n", __FUNCTION__,
+ "pba: %d\n", __func__,
transport, reason,
transport->cwnd, transport->ssthresh,
transport->flight_size,
@@ -494,6 +494,8 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
*/
if (transport == transport->asoc->peer.retran_path)
sctp_assoc_update_retran_path(transport->asoc);
+ transport->asoc->rtx_data_chunks +=
+ transport->asoc->unack_data;
break;
case SCTP_RTXR_FAST_RTX:
SCTP_INC_STATS(SCTP_MIB_FAST_RETRANSMITS);
@@ -504,6 +506,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
break;
case SCTP_RTXR_T1_RTX:
SCTP_INC_STATS(SCTP_MIB_T1_RETRANSMITS);
+ transport->asoc->init_retries++;
break;
default:
BUG();
@@ -535,7 +538,7 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
int rtx_timeout, int *start_timer)
{
struct list_head *lqueue;
- struct list_head *lchunk, *lchunk1;
+ struct list_head *lchunk;
struct sctp_transport *transport = pkt->transport;
sctp_xmit_t status;
struct sctp_chunk *chunk, *chunk1;
@@ -646,9 +649,7 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
* to be marked as ineligible for a subsequent fast retransmit.
*/
if (rtx_timeout && !lchunk) {
- list_for_each(lchunk1, lqueue) {
- chunk1 = list_entry(lchunk1, struct sctp_chunk,
- transmitted_list);
+ list_for_each_entry(chunk1, lqueue, transmitted_list) {
if (chunk1->fast_retransmit > 0)
chunk1->fast_retransmit = -1;
}
@@ -793,6 +794,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
break;
case SCTP_CID_ABORT:
+ if (sctp_test_T_bit(chunk)) {
+ packet->vtag = asoc->c.my_vtag;
+ }
case SCTP_CID_SACK:
case SCTP_CID_HEARTBEAT:
case SCTP_CID_HEARTBEAT_ACK:
@@ -1034,7 +1038,6 @@ static void sctp_sack_update_unack_data(struct sctp_association *assoc,
static __u32 sctp_highest_new_tsn(struct sctp_sackhdr *sack,
struct sctp_association *asoc)
{
- struct list_head *ltransport, *lchunk;
struct sctp_transport *transport;
struct sctp_chunk *chunk;
__u32 highest_new_tsn, tsn;
@@ -1042,12 +1045,9 @@ static __u32 sctp_highest_new_tsn(struct sctp_sackhdr *sack,
highest_new_tsn = ntohl(sack->cum_tsn_ack);
- list_for_each(ltransport, transport_list) {
- transport = list_entry(ltransport, struct sctp_transport,
- transports);
- list_for_each(lchunk, &transport->transmitted) {
- chunk = list_entry(lchunk, struct sctp_chunk,
- transmitted_list);
+ list_for_each_entry(transport, transport_list, transports) {
+ list_for_each_entry(chunk, &transport->transmitted,
+ transmitted_list) {
tsn = ntohl(chunk->subh.data_hdr->tsn);
if (!chunk->tsn_gap_acked &&
@@ -1070,7 +1070,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
struct sctp_association *asoc = q->asoc;
struct sctp_transport *transport;
struct sctp_chunk *tchunk = NULL;
- struct list_head *lchunk, *transport_list, *pos, *temp;
+ struct list_head *lchunk, *transport_list, *temp;
sctp_sack_variable_t *frags = sack->variable;
__u32 sack_ctsn, ctsn, tsn;
__u32 highest_tsn, highest_new_tsn;
@@ -1096,9 +1096,8 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
*/
if (TSN_lte(primary->cacc.next_tsn_at_change, sack_ctsn)) {
primary->cacc.changeover_active = 0;
- list_for_each(pos, transport_list) {
- transport = list_entry(pos, struct sctp_transport,
- transports);
+ list_for_each_entry(transport, transport_list,
+ transports) {
transport->cacc.cycling_changeover = 0;
}
}
@@ -1113,9 +1112,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
*/
if (sack->num_gap_ack_blocks &&
primary->cacc.changeover_active) {
- list_for_each(pos, transport_list) {
- transport = list_entry(pos, struct sctp_transport,
- transports);
+ list_for_each_entry(transport, transport_list, transports) {
transport->cacc.cacc_saw_newack = 0;
}
}
@@ -1144,9 +1141,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
*
* This is a MASSIVE candidate for optimization.
*/
- list_for_each(pos, transport_list) {
- transport = list_entry(pos, struct sctp_transport,
- transports);
+ list_for_each_entry(transport, transport_list, transports) {
sctp_check_transmitted(q, &transport->transmitted,
transport, sack, highest_new_tsn);
/*
@@ -1158,9 +1153,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
count_of_newacks ++;
}
- list_for_each(pos, transport_list) {
- transport = list_entry(pos, struct sctp_transport,
- transports);
+ list_for_each_entry(transport, transport_list, transports) {
sctp_mark_missing(q, &transport->transmitted, transport,
highest_new_tsn, count_of_newacks);
}
@@ -1203,10 +1196,10 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
sctp_generate_fwdtsn(q, sack_ctsn);
SCTP_DEBUG_PRINTK("%s: sack Cumulative TSN Ack is 0x%x.\n",
- __FUNCTION__, sack_ctsn);
+ __func__, sack_ctsn);
SCTP_DEBUG_PRINTK("%s: Cumulative TSN Ack of association, "
"%p is 0x%x. Adv peer ack point: 0x%x\n",
- __FUNCTION__, asoc, ctsn, asoc->adv_peer_ack_point);
+ __func__, asoc, ctsn, asoc->adv_peer_ack_point);
/* See if all chunks are acked.
* Make sure the empty queue handler will get run later.
@@ -1217,9 +1210,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
if (!q->empty)
goto finish;
- list_for_each(pos, transport_list) {
- transport = list_entry(pos, struct sctp_transport,
- transports);
+ list_for_each_entry(transport, transport_list, transports) {
q->empty = q->empty && list_empty(&transport->transmitted);
if (!q->empty)
goto finish;
@@ -1441,7 +1432,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
if (tchunk->tsn_gap_acked) {
SCTP_DEBUG_PRINTK("%s: Receiver reneged on "
"data TSN: 0x%x\n",
- __FUNCTION__,
+ __func__,
tsn);
tchunk->tsn_gap_acked = 0;
@@ -1541,6 +1532,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
bytes_acked);
transport->flight_size -= bytes_acked;
+ if (transport->flight_size == 0)
+ transport->partial_bytes_acked = 0;
q->outstanding_bytes -= bytes_acked;
} else {
/* RFC 2960 6.1, sctpimpguide-06 2.15.2
@@ -1558,7 +1551,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
(sack_ctsn+2 == q->asoc->next_tsn)) {
SCTP_DEBUG_PRINTK("%s: SACK received for zero "
"window probe: %u\n",
- __FUNCTION__, sack_ctsn);
+ __func__, sack_ctsn);
q->asoc->overall_error_count = 0;
transport->error_count = 0;
}
@@ -1593,14 +1586,12 @@ static void sctp_mark_missing(struct sctp_outq *q,
int count_of_newacks)
{
struct sctp_chunk *chunk;
- struct list_head *pos;
__u32 tsn;
char do_fast_retransmit = 0;
struct sctp_transport *primary = q->asoc->peer.primary_path;
- list_for_each(pos, transmitted_queue) {
+ list_for_each_entry(chunk, transmitted_queue, transmitted_list) {
- chunk = list_entry(pos, struct sctp_chunk, transmitted_list);
tsn = ntohl(chunk->subh.data_hdr->tsn);
/* RFC 2960 7.2.4, sctpimpguide-05 2.8.2 M3) Examine all
@@ -1623,7 +1614,7 @@ static void sctp_mark_missing(struct sctp_outq *q,
SCTP_DEBUG_PRINTK(
"%s: TSN 0x%x missing counter: %d\n",
- __FUNCTION__, tsn,
+ __func__, tsn,
chunk->tsn_missing_report);
}
}
@@ -1646,7 +1637,7 @@ static void sctp_mark_missing(struct sctp_outq *q,
SCTP_DEBUG_PRINTK("%s: transport: %p, cwnd: %d, "
"ssthresh: %d, flight_size: %d, pba: %d\n",
- __FUNCTION__, transport, transport->cwnd,
+ __func__, transport, transport->cwnd,
transport->ssthresh, transport->flight_size,
transport->partial_bytes_acked);
}
OpenPOWER on IntegriCloud