162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/* SCTP kernel implementation
362306a36Sopenharmony_ci * (C) Copyright IBM Corp. 2001, 2004
462306a36Sopenharmony_ci * Copyright (c) 1999-2000 Cisco, Inc.
562306a36Sopenharmony_ci * Copyright (c) 1999-2001 Motorola, Inc.
662306a36Sopenharmony_ci * Copyright (c) 2001-2003 Intel Corp.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * This file is part of the SCTP kernel implementation
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * These functions implement the sctp_outq class.   The outqueue handles
1162306a36Sopenharmony_ci * bundling and queueing of outgoing SCTP chunks.
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * Please send any bug reports or fixes you make to the
1462306a36Sopenharmony_ci * email address(es):
1562306a36Sopenharmony_ci *    lksctp developers <linux-sctp@vger.kernel.org>
1662306a36Sopenharmony_ci *
1762306a36Sopenharmony_ci * Written or modified by:
1862306a36Sopenharmony_ci *    La Monte H.P. Yarroll <piggy@acm.org>
1962306a36Sopenharmony_ci *    Karl Knutson          <karl@athena.chicago.il.us>
2062306a36Sopenharmony_ci *    Perry Melange         <pmelange@null.cc.uic.edu>
2162306a36Sopenharmony_ci *    Xingang Guo           <xingang.guo@intel.com>
2262306a36Sopenharmony_ci *    Hui Huang 	    <hui.huang@nokia.com>
2362306a36Sopenharmony_ci *    Sridhar Samudrala     <sri@us.ibm.com>
2462306a36Sopenharmony_ci *    Jon Grimm             <jgrimm@us.ibm.com>
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#include <linux/types.h>
3062306a36Sopenharmony_ci#include <linux/list.h>   /* For struct list_head */
3162306a36Sopenharmony_ci#include <linux/socket.h>
3262306a36Sopenharmony_ci#include <linux/ip.h>
3362306a36Sopenharmony_ci#include <linux/slab.h>
3462306a36Sopenharmony_ci#include <net/sock.h>	  /* For skb_set_owner_w */
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#include <net/sctp/sctp.h>
3762306a36Sopenharmony_ci#include <net/sctp/sm.h>
3862306a36Sopenharmony_ci#include <net/sctp/stream_sched.h>
3962306a36Sopenharmony_ci#include <trace/events/sctp.h>
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/* Declare internal functions here.  */
4262306a36Sopenharmony_cistatic int sctp_acked(struct sctp_sackhdr *sack, __u32 tsn);
4362306a36Sopenharmony_cistatic void sctp_check_transmitted(struct sctp_outq *q,
4462306a36Sopenharmony_ci				   struct list_head *transmitted_queue,
4562306a36Sopenharmony_ci				   struct sctp_transport *transport,
4662306a36Sopenharmony_ci				   union sctp_addr *saddr,
4762306a36Sopenharmony_ci				   struct sctp_sackhdr *sack,
4862306a36Sopenharmony_ci				   __u32 *highest_new_tsn);
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic void sctp_mark_missing(struct sctp_outq *q,
5162306a36Sopenharmony_ci			      struct list_head *transmitted_queue,
5262306a36Sopenharmony_ci			      struct sctp_transport *transport,
5362306a36Sopenharmony_ci			      __u32 highest_new_tsn,
5462306a36Sopenharmony_ci			      int count_of_newacks);
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cistatic void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp);
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/* Add data to the front of the queue. */
5962306a36Sopenharmony_cistatic inline void sctp_outq_head_data(struct sctp_outq *q,
6062306a36Sopenharmony_ci				       struct sctp_chunk *ch)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	struct sctp_stream_out_ext *oute;
6362306a36Sopenharmony_ci	__u16 stream;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	list_add(&ch->list, &q->out_chunk_list);
6662306a36Sopenharmony_ci	q->out_qlen += ch->skb->len;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	stream = sctp_chunk_stream_no(ch);
6962306a36Sopenharmony_ci	oute = SCTP_SO(&q->asoc->stream, stream)->ext;
7062306a36Sopenharmony_ci	list_add(&ch->stream_list, &oute->outq);
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/* Take data from the front of the queue. */
7462306a36Sopenharmony_cistatic inline struct sctp_chunk *sctp_outq_dequeue_data(struct sctp_outq *q)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	return q->sched->dequeue(q);
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci/* Add data chunk to the end of the queue. */
8062306a36Sopenharmony_cistatic inline void sctp_outq_tail_data(struct sctp_outq *q,
8162306a36Sopenharmony_ci				       struct sctp_chunk *ch)
8262306a36Sopenharmony_ci{
8362306a36Sopenharmony_ci	struct sctp_stream_out_ext *oute;
8462306a36Sopenharmony_ci	__u16 stream;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	list_add_tail(&ch->list, &q->out_chunk_list);
8762306a36Sopenharmony_ci	q->out_qlen += ch->skb->len;
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	stream = sctp_chunk_stream_no(ch);
9062306a36Sopenharmony_ci	oute = SCTP_SO(&q->asoc->stream, stream)->ext;
9162306a36Sopenharmony_ci	list_add_tail(&ch->stream_list, &oute->outq);
9262306a36Sopenharmony_ci}
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci/*
9562306a36Sopenharmony_ci * SFR-CACC algorithm:
9662306a36Sopenharmony_ci * D) If count_of_newacks is greater than or equal to 2
9762306a36Sopenharmony_ci * and t was not sent to the current primary then the
9862306a36Sopenharmony_ci * sender MUST NOT increment missing report count for t.
9962306a36Sopenharmony_ci */
10062306a36Sopenharmony_cistatic inline int sctp_cacc_skip_3_1_d(struct sctp_transport *primary,
10162306a36Sopenharmony_ci				       struct sctp_transport *transport,
10262306a36Sopenharmony_ci				       int count_of_newacks)
10362306a36Sopenharmony_ci{
10462306a36Sopenharmony_ci	if (count_of_newacks >= 2 && transport != primary)
10562306a36Sopenharmony_ci		return 1;
10662306a36Sopenharmony_ci	return 0;
10762306a36Sopenharmony_ci}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci/*
11062306a36Sopenharmony_ci * SFR-CACC algorithm:
11162306a36Sopenharmony_ci * F) If count_of_newacks is less than 2, let d be the
11262306a36Sopenharmony_ci * destination to which t was sent. If cacc_saw_newack
11362306a36Sopenharmony_ci * is 0 for destination d, then the sender MUST NOT
11462306a36Sopenharmony_ci * increment missing report count for t.
11562306a36Sopenharmony_ci */
11662306a36Sopenharmony_cistatic inline int sctp_cacc_skip_3_1_f(struct sctp_transport *transport,
11762306a36Sopenharmony_ci				       int count_of_newacks)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	if (count_of_newacks < 2 &&
12062306a36Sopenharmony_ci			(transport && !transport->cacc.cacc_saw_newack))
12162306a36Sopenharmony_ci		return 1;
12262306a36Sopenharmony_ci	return 0;
12362306a36Sopenharmony_ci}
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci/*
12662306a36Sopenharmony_ci * SFR-CACC algorithm:
12762306a36Sopenharmony_ci * 3.1) If CYCLING_CHANGEOVER is 0, the sender SHOULD
12862306a36Sopenharmony_ci * execute steps C, D, F.
12962306a36Sopenharmony_ci *
13062306a36Sopenharmony_ci * C has been implemented in sctp_outq_sack
13162306a36Sopenharmony_ci */
13262306a36Sopenharmony_cistatic inline int sctp_cacc_skip_3_1(struct sctp_transport *primary,
13362306a36Sopenharmony_ci				     struct sctp_transport *transport,
13462306a36Sopenharmony_ci				     int count_of_newacks)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	if (!primary->cacc.cycling_changeover) {
13762306a36Sopenharmony_ci		if (sctp_cacc_skip_3_1_d(primary, transport, count_of_newacks))
13862306a36Sopenharmony_ci			return 1;
13962306a36Sopenharmony_ci		if (sctp_cacc_skip_3_1_f(transport, count_of_newacks))
14062306a36Sopenharmony_ci			return 1;
14162306a36Sopenharmony_ci		return 0;
14262306a36Sopenharmony_ci	}
14362306a36Sopenharmony_ci	return 0;
14462306a36Sopenharmony_ci}
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci/*
14762306a36Sopenharmony_ci * SFR-CACC algorithm:
14862306a36Sopenharmony_ci * 3.2) Else if CYCLING_CHANGEOVER is 1, and t is less
14962306a36Sopenharmony_ci * than next_tsn_at_change of the current primary, then
15062306a36Sopenharmony_ci * the sender MUST NOT increment missing report count
15162306a36Sopenharmony_ci * for t.
15262306a36Sopenharmony_ci */
15362306a36Sopenharmony_cistatic inline int sctp_cacc_skip_3_2(struct sctp_transport *primary, __u32 tsn)
15462306a36Sopenharmony_ci{
15562306a36Sopenharmony_ci	if (primary->cacc.cycling_changeover &&
15662306a36Sopenharmony_ci	    TSN_lt(tsn, primary->cacc.next_tsn_at_change))
15762306a36Sopenharmony_ci		return 1;
15862306a36Sopenharmony_ci	return 0;
15962306a36Sopenharmony_ci}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci/*
16262306a36Sopenharmony_ci * SFR-CACC algorithm:
16362306a36Sopenharmony_ci * 3) If the missing report count for TSN t is to be
16462306a36Sopenharmony_ci * incremented according to [RFC2960] and
16562306a36Sopenharmony_ci * [SCTP_STEWART-2002], and CHANGEOVER_ACTIVE is set,
16662306a36Sopenharmony_ci * then the sender MUST further execute steps 3.1 and
16762306a36Sopenharmony_ci * 3.2 to determine if the missing report count for
16862306a36Sopenharmony_ci * TSN t SHOULD NOT be incremented.
16962306a36Sopenharmony_ci *
17062306a36Sopenharmony_ci * 3.3) If 3.1 and 3.2 do not dictate that the missing
17162306a36Sopenharmony_ci * report count for t should not be incremented, then
17262306a36Sopenharmony_ci * the sender SHOULD increment missing report count for
17362306a36Sopenharmony_ci * t (according to [RFC2960] and [SCTP_STEWART_2002]).
17462306a36Sopenharmony_ci */
17562306a36Sopenharmony_cistatic inline int sctp_cacc_skip(struct sctp_transport *primary,
17662306a36Sopenharmony_ci				 struct sctp_transport *transport,
17762306a36Sopenharmony_ci				 int count_of_newacks,
17862306a36Sopenharmony_ci				 __u32 tsn)
17962306a36Sopenharmony_ci{
18062306a36Sopenharmony_ci	if (primary->cacc.changeover_active &&
18162306a36Sopenharmony_ci	    (sctp_cacc_skip_3_1(primary, transport, count_of_newacks) ||
18262306a36Sopenharmony_ci	     sctp_cacc_skip_3_2(primary, tsn)))
18362306a36Sopenharmony_ci		return 1;
18462306a36Sopenharmony_ci	return 0;
18562306a36Sopenharmony_ci}
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci/* Initialize an existing sctp_outq.  This does the boring stuff.
18862306a36Sopenharmony_ci * You still need to define handlers if you really want to DO
18962306a36Sopenharmony_ci * something with this structure...
19062306a36Sopenharmony_ci */
19162306a36Sopenharmony_civoid sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
19262306a36Sopenharmony_ci{
19362306a36Sopenharmony_ci	memset(q, 0, sizeof(struct sctp_outq));
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	q->asoc = asoc;
19662306a36Sopenharmony_ci	INIT_LIST_HEAD(&q->out_chunk_list);
19762306a36Sopenharmony_ci	INIT_LIST_HEAD(&q->control_chunk_list);
19862306a36Sopenharmony_ci	INIT_LIST_HEAD(&q->retransmit);
19962306a36Sopenharmony_ci	INIT_LIST_HEAD(&q->sacked);
20062306a36Sopenharmony_ci	INIT_LIST_HEAD(&q->abandoned);
20162306a36Sopenharmony_ci	sctp_sched_set_sched(asoc, sctp_sk(asoc->base.sk)->default_ss);
20262306a36Sopenharmony_ci}
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci/* Free the outqueue structure and any related pending chunks.
20562306a36Sopenharmony_ci */
20662306a36Sopenharmony_cistatic void __sctp_outq_teardown(struct sctp_outq *q)
20762306a36Sopenharmony_ci{
20862306a36Sopenharmony_ci	struct sctp_transport *transport;
20962306a36Sopenharmony_ci	struct list_head *lchunk, *temp;
21062306a36Sopenharmony_ci	struct sctp_chunk *chunk, *tmp;
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	/* Throw away unacknowledged chunks. */
21362306a36Sopenharmony_ci	list_for_each_entry(transport, &q->asoc->peer.transport_addr_list,
21462306a36Sopenharmony_ci			transports) {
21562306a36Sopenharmony_ci		while ((lchunk = sctp_list_dequeue(&transport->transmitted)) != NULL) {
21662306a36Sopenharmony_ci			chunk = list_entry(lchunk, struct sctp_chunk,
21762306a36Sopenharmony_ci					   transmitted_list);
21862306a36Sopenharmony_ci			/* Mark as part of a failed message. */
21962306a36Sopenharmony_ci			sctp_chunk_fail(chunk, q->error);
22062306a36Sopenharmony_ci			sctp_chunk_free(chunk);
22162306a36Sopenharmony_ci		}
22262306a36Sopenharmony_ci	}
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	/* Throw away chunks that have been gap ACKed.  */
22562306a36Sopenharmony_ci	list_for_each_safe(lchunk, temp, &q->sacked) {
22662306a36Sopenharmony_ci		list_del_init(lchunk);
22762306a36Sopenharmony_ci		chunk = list_entry(lchunk, struct sctp_chunk,
22862306a36Sopenharmony_ci				   transmitted_list);
22962306a36Sopenharmony_ci		sctp_chunk_fail(chunk, q->error);
23062306a36Sopenharmony_ci		sctp_chunk_free(chunk);
23162306a36Sopenharmony_ci	}
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	/* Throw away any chunks in the retransmit queue. */
23462306a36Sopenharmony_ci	list_for_each_safe(lchunk, temp, &q->retransmit) {
23562306a36Sopenharmony_ci		list_del_init(lchunk);
23662306a36Sopenharmony_ci		chunk = list_entry(lchunk, struct sctp_chunk,
23762306a36Sopenharmony_ci				   transmitted_list);
23862306a36Sopenharmony_ci		sctp_chunk_fail(chunk, q->error);
23962306a36Sopenharmony_ci		sctp_chunk_free(chunk);
24062306a36Sopenharmony_ci	}
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	/* Throw away any chunks that are in the abandoned queue. */
24362306a36Sopenharmony_ci	list_for_each_safe(lchunk, temp, &q->abandoned) {
24462306a36Sopenharmony_ci		list_del_init(lchunk);
24562306a36Sopenharmony_ci		chunk = list_entry(lchunk, struct sctp_chunk,
24662306a36Sopenharmony_ci				   transmitted_list);
24762306a36Sopenharmony_ci		sctp_chunk_fail(chunk, q->error);
24862306a36Sopenharmony_ci		sctp_chunk_free(chunk);
24962306a36Sopenharmony_ci	}
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	/* Throw away any leftover data chunks. */
25262306a36Sopenharmony_ci	while ((chunk = sctp_outq_dequeue_data(q)) != NULL) {
25362306a36Sopenharmony_ci		sctp_sched_dequeue_done(q, chunk);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci		/* Mark as send failure. */
25662306a36Sopenharmony_ci		sctp_chunk_fail(chunk, q->error);
25762306a36Sopenharmony_ci		sctp_chunk_free(chunk);
25862306a36Sopenharmony_ci	}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci	/* Throw away any leftover control chunks. */
26162306a36Sopenharmony_ci	list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
26262306a36Sopenharmony_ci		list_del_init(&chunk->list);
26362306a36Sopenharmony_ci		sctp_chunk_free(chunk);
26462306a36Sopenharmony_ci	}
26562306a36Sopenharmony_ci}
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_civoid sctp_outq_teardown(struct sctp_outq *q)
26862306a36Sopenharmony_ci{
26962306a36Sopenharmony_ci	__sctp_outq_teardown(q);
27062306a36Sopenharmony_ci	sctp_outq_init(q->asoc, q);
27162306a36Sopenharmony_ci}
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci/* Free the outqueue structure and any related pending chunks.  */
27462306a36Sopenharmony_civoid sctp_outq_free(struct sctp_outq *q)
27562306a36Sopenharmony_ci{
27662306a36Sopenharmony_ci	/* Throw away leftover chunks. */
27762306a36Sopenharmony_ci	__sctp_outq_teardown(q);
27862306a36Sopenharmony_ci}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci/* Put a new chunk in an sctp_outq.  */
28162306a36Sopenharmony_civoid sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk, gfp_t gfp)
28262306a36Sopenharmony_ci{
28362306a36Sopenharmony_ci	struct net *net = q->asoc->base.net;
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci	pr_debug("%s: outq:%p, chunk:%p[%s]\n", __func__, q, chunk,
28662306a36Sopenharmony_ci		 chunk && chunk->chunk_hdr ?
28762306a36Sopenharmony_ci		 sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) :
28862306a36Sopenharmony_ci		 "illegal chunk");
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci	/* If it is data, queue it up, otherwise, send it
29162306a36Sopenharmony_ci	 * immediately.
29262306a36Sopenharmony_ci	 */
29362306a36Sopenharmony_ci	if (sctp_chunk_is_data(chunk)) {
29462306a36Sopenharmony_ci		pr_debug("%s: outqueueing: outq:%p, chunk:%p[%s])\n",
29562306a36Sopenharmony_ci			 __func__, q, chunk, chunk && chunk->chunk_hdr ?
29662306a36Sopenharmony_ci			 sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) :
29762306a36Sopenharmony_ci			 "illegal chunk");
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci		sctp_outq_tail_data(q, chunk);
30062306a36Sopenharmony_ci		if (chunk->asoc->peer.prsctp_capable &&
30162306a36Sopenharmony_ci		    SCTP_PR_PRIO_ENABLED(chunk->sinfo.sinfo_flags))
30262306a36Sopenharmony_ci			chunk->asoc->sent_cnt_removable++;
30362306a36Sopenharmony_ci		if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
30462306a36Sopenharmony_ci			SCTP_INC_STATS(net, SCTP_MIB_OUTUNORDERCHUNKS);
30562306a36Sopenharmony_ci		else
30662306a36Sopenharmony_ci			SCTP_INC_STATS(net, SCTP_MIB_OUTORDERCHUNKS);
30762306a36Sopenharmony_ci	} else {
30862306a36Sopenharmony_ci		list_add_tail(&chunk->list, &q->control_chunk_list);
30962306a36Sopenharmony_ci		SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
31062306a36Sopenharmony_ci	}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	if (!q->cork)
31362306a36Sopenharmony_ci		sctp_outq_flush(q, 0, gfp);
31462306a36Sopenharmony_ci}
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci/* Insert a chunk into the sorted list based on the TSNs.  The retransmit list
31762306a36Sopenharmony_ci * and the abandoned list are in ascending order.
31862306a36Sopenharmony_ci */
31962306a36Sopenharmony_cistatic void sctp_insert_list(struct list_head *head, struct list_head *new)
32062306a36Sopenharmony_ci{
32162306a36Sopenharmony_ci	struct list_head *pos;
32262306a36Sopenharmony_ci	struct sctp_chunk *nchunk, *lchunk;
32362306a36Sopenharmony_ci	__u32 ntsn, ltsn;
32462306a36Sopenharmony_ci	int done = 0;
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci	nchunk = list_entry(new, struct sctp_chunk, transmitted_list);
32762306a36Sopenharmony_ci	ntsn = ntohl(nchunk->subh.data_hdr->tsn);
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	list_for_each(pos, head) {
33062306a36Sopenharmony_ci		lchunk = list_entry(pos, struct sctp_chunk, transmitted_list);
33162306a36Sopenharmony_ci		ltsn = ntohl(lchunk->subh.data_hdr->tsn);
33262306a36Sopenharmony_ci		if (TSN_lt(ntsn, ltsn)) {
33362306a36Sopenharmony_ci			list_add(new, pos->prev);
33462306a36Sopenharmony_ci			done = 1;
33562306a36Sopenharmony_ci			break;
33662306a36Sopenharmony_ci		}
33762306a36Sopenharmony_ci	}
33862306a36Sopenharmony_ci	if (!done)
33962306a36Sopenharmony_ci		list_add_tail(new, head);
34062306a36Sopenharmony_ci}
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_cistatic int sctp_prsctp_prune_sent(struct sctp_association *asoc,
34362306a36Sopenharmony_ci				  struct sctp_sndrcvinfo *sinfo,
34462306a36Sopenharmony_ci				  struct list_head *queue, int msg_len)
34562306a36Sopenharmony_ci{
34662306a36Sopenharmony_ci	struct sctp_chunk *chk, *temp;
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	list_for_each_entry_safe(chk, temp, queue, transmitted_list) {
34962306a36Sopenharmony_ci		struct sctp_stream_out *streamout;
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci		if (!chk->msg->abandoned &&
35262306a36Sopenharmony_ci		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
35362306a36Sopenharmony_ci		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
35462306a36Sopenharmony_ci			continue;
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci		chk->msg->abandoned = 1;
35762306a36Sopenharmony_ci		list_del_init(&chk->transmitted_list);
35862306a36Sopenharmony_ci		sctp_insert_list(&asoc->outqueue.abandoned,
35962306a36Sopenharmony_ci				 &chk->transmitted_list);
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci		streamout = SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
36262306a36Sopenharmony_ci		asoc->sent_cnt_removable--;
36362306a36Sopenharmony_ci		asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
36462306a36Sopenharmony_ci		streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci		if (queue != &asoc->outqueue.retransmit &&
36762306a36Sopenharmony_ci		    !chk->tsn_gap_acked) {
36862306a36Sopenharmony_ci			if (chk->transport)
36962306a36Sopenharmony_ci				chk->transport->flight_size -=
37062306a36Sopenharmony_ci						sctp_data_size(chk);
37162306a36Sopenharmony_ci			asoc->outqueue.outstanding_bytes -= sctp_data_size(chk);
37262306a36Sopenharmony_ci		}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci		msg_len -= chk->skb->truesize + sizeof(struct sctp_chunk);
37562306a36Sopenharmony_ci		if (msg_len <= 0)
37662306a36Sopenharmony_ci			break;
37762306a36Sopenharmony_ci	}
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci	return msg_len;
38062306a36Sopenharmony_ci}
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_cistatic int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
38362306a36Sopenharmony_ci				    struct sctp_sndrcvinfo *sinfo, int msg_len)
38462306a36Sopenharmony_ci{
38562306a36Sopenharmony_ci	struct sctp_outq *q = &asoc->outqueue;
38662306a36Sopenharmony_ci	struct sctp_chunk *chk, *temp;
38762306a36Sopenharmony_ci	struct sctp_stream_out *sout;
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	q->sched->unsched_all(&asoc->stream);
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
39262306a36Sopenharmony_ci		if (!chk->msg->abandoned &&
39362306a36Sopenharmony_ci		    (!(chk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG) ||
39462306a36Sopenharmony_ci		     !SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
39562306a36Sopenharmony_ci		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
39662306a36Sopenharmony_ci			continue;
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci		chk->msg->abandoned = 1;
39962306a36Sopenharmony_ci		sctp_sched_dequeue_common(q, chk);
40062306a36Sopenharmony_ci		asoc->sent_cnt_removable--;
40162306a36Sopenharmony_ci		asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci		sout = SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
40462306a36Sopenharmony_ci		sout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci		/* clear out_curr if all frag chunks are pruned */
40762306a36Sopenharmony_ci		if (asoc->stream.out_curr == sout &&
40862306a36Sopenharmony_ci		    list_is_last(&chk->frag_list, &chk->msg->chunks))
40962306a36Sopenharmony_ci			asoc->stream.out_curr = NULL;
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci		msg_len -= chk->skb->truesize + sizeof(struct sctp_chunk);
41262306a36Sopenharmony_ci		sctp_chunk_free(chk);
41362306a36Sopenharmony_ci		if (msg_len <= 0)
41462306a36Sopenharmony_ci			break;
41562306a36Sopenharmony_ci	}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	q->sched->sched_all(&asoc->stream);
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci	return msg_len;
42062306a36Sopenharmony_ci}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci/* Abandon the chunks according their priorities */
42362306a36Sopenharmony_civoid sctp_prsctp_prune(struct sctp_association *asoc,
42462306a36Sopenharmony_ci		       struct sctp_sndrcvinfo *sinfo, int msg_len)
42562306a36Sopenharmony_ci{
42662306a36Sopenharmony_ci	struct sctp_transport *transport;
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci	if (!asoc->peer.prsctp_capable || !asoc->sent_cnt_removable)
42962306a36Sopenharmony_ci		return;
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci	msg_len = sctp_prsctp_prune_sent(asoc, sinfo,
43262306a36Sopenharmony_ci					 &asoc->outqueue.retransmit,
43362306a36Sopenharmony_ci					 msg_len);
43462306a36Sopenharmony_ci	if (msg_len <= 0)
43562306a36Sopenharmony_ci		return;
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci	list_for_each_entry(transport, &asoc->peer.transport_addr_list,
43862306a36Sopenharmony_ci			    transports) {
43962306a36Sopenharmony_ci		msg_len = sctp_prsctp_prune_sent(asoc, sinfo,
44062306a36Sopenharmony_ci						 &transport->transmitted,
44162306a36Sopenharmony_ci						 msg_len);
44262306a36Sopenharmony_ci		if (msg_len <= 0)
44362306a36Sopenharmony_ci			return;
44462306a36Sopenharmony_ci	}
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci	sctp_prsctp_prune_unsent(asoc, sinfo, msg_len);
44762306a36Sopenharmony_ci}
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci/* Mark all the eligible packets on a transport for retransmission.  */
45062306a36Sopenharmony_civoid sctp_retransmit_mark(struct sctp_outq *q,
45162306a36Sopenharmony_ci			  struct sctp_transport *transport,
45262306a36Sopenharmony_ci			  __u8 reason)
45362306a36Sopenharmony_ci{
45462306a36Sopenharmony_ci	struct list_head *lchunk, *ltemp;
45562306a36Sopenharmony_ci	struct sctp_chunk *chunk;
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	/* Walk through the specified transmitted queue.  */
45862306a36Sopenharmony_ci	list_for_each_safe(lchunk, ltemp, &transport->transmitted) {
45962306a36Sopenharmony_ci		chunk = list_entry(lchunk, struct sctp_chunk,
46062306a36Sopenharmony_ci				   transmitted_list);
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci		/* If the chunk is abandoned, move it to abandoned list. */
46362306a36Sopenharmony_ci		if (sctp_chunk_abandoned(chunk)) {
46462306a36Sopenharmony_ci			list_del_init(lchunk);
46562306a36Sopenharmony_ci			sctp_insert_list(&q->abandoned, lchunk);
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci			/* If this chunk has not been previousely acked,
46862306a36Sopenharmony_ci			 * stop considering it 'outstanding'.  Our peer
46962306a36Sopenharmony_ci			 * will most likely never see it since it will
47062306a36Sopenharmony_ci			 * not be retransmitted
47162306a36Sopenharmony_ci			 */
47262306a36Sopenharmony_ci			if (!chunk->tsn_gap_acked) {
47362306a36Sopenharmony_ci				if (chunk->transport)
47462306a36Sopenharmony_ci					chunk->transport->flight_size -=
47562306a36Sopenharmony_ci							sctp_data_size(chunk);
47662306a36Sopenharmony_ci				q->outstanding_bytes -= sctp_data_size(chunk);
47762306a36Sopenharmony_ci				q->asoc->peer.rwnd += sctp_data_size(chunk);
47862306a36Sopenharmony_ci			}
47962306a36Sopenharmony_ci			continue;
48062306a36Sopenharmony_ci		}
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci		/* If we are doing  retransmission due to a timeout or pmtu
48362306a36Sopenharmony_ci		 * discovery, only the  chunks that are not yet acked should
48462306a36Sopenharmony_ci		 * be added to the retransmit queue.
48562306a36Sopenharmony_ci		 */
48662306a36Sopenharmony_ci		if ((reason == SCTP_RTXR_FAST_RTX  &&
48762306a36Sopenharmony_ci			    (chunk->fast_retransmit == SCTP_NEED_FRTX)) ||
48862306a36Sopenharmony_ci		    (reason != SCTP_RTXR_FAST_RTX  && !chunk->tsn_gap_acked)) {
48962306a36Sopenharmony_ci			/* RFC 2960 6.2.1 Processing a Received SACK
49062306a36Sopenharmony_ci			 *
49162306a36Sopenharmony_ci			 * C) Any time a DATA chunk is marked for
49262306a36Sopenharmony_ci			 * retransmission (via either T3-rtx timer expiration
49362306a36Sopenharmony_ci			 * (Section 6.3.3) or via fast retransmit
49462306a36Sopenharmony_ci			 * (Section 7.2.4)), add the data size of those
49562306a36Sopenharmony_ci			 * chunks to the rwnd.
49662306a36Sopenharmony_ci			 */
49762306a36Sopenharmony_ci			q->asoc->peer.rwnd += sctp_data_size(chunk);
49862306a36Sopenharmony_ci			q->outstanding_bytes -= sctp_data_size(chunk);
49962306a36Sopenharmony_ci			if (chunk->transport)
50062306a36Sopenharmony_ci				transport->flight_size -= sctp_data_size(chunk);
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci			/* sctpimpguide-05 Section 2.8.2
50362306a36Sopenharmony_ci			 * M5) If a T3-rtx timer expires, the
50462306a36Sopenharmony_ci			 * 'TSN.Missing.Report' of all affected TSNs is set
50562306a36Sopenharmony_ci			 * to 0.
50662306a36Sopenharmony_ci			 */
50762306a36Sopenharmony_ci			chunk->tsn_missing_report = 0;
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci			/* If a chunk that is being used for RTT measurement
51062306a36Sopenharmony_ci			 * has to be retransmitted, we cannot use this chunk
51162306a36Sopenharmony_ci			 * anymore for RTT measurements. Reset rto_pending so
51262306a36Sopenharmony_ci			 * that a new RTT measurement is started when a new
51362306a36Sopenharmony_ci			 * data chunk is sent.
51462306a36Sopenharmony_ci			 */
51562306a36Sopenharmony_ci			if (chunk->rtt_in_progress) {
51662306a36Sopenharmony_ci				chunk->rtt_in_progress = 0;
51762306a36Sopenharmony_ci				transport->rto_pending = 0;
51862306a36Sopenharmony_ci			}
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci			/* Move the chunk to the retransmit queue. The chunks
52162306a36Sopenharmony_ci			 * on the retransmit queue are always kept in order.
52262306a36Sopenharmony_ci			 */
52362306a36Sopenharmony_ci			list_del_init(lchunk);
52462306a36Sopenharmony_ci			sctp_insert_list(&q->retransmit, lchunk);
52562306a36Sopenharmony_ci		}
52662306a36Sopenharmony_ci	}
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	pr_debug("%s: transport:%p, reason:%d, cwnd:%d, ssthresh:%d, "
52962306a36Sopenharmony_ci		 "flight_size:%d, pba:%d\n", __func__, transport, reason,
53062306a36Sopenharmony_ci		 transport->cwnd, transport->ssthresh, transport->flight_size,
53162306a36Sopenharmony_ci		 transport->partial_bytes_acked);
53262306a36Sopenharmony_ci}
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci/* Mark all the eligible packets on a transport for retransmission and force
53562306a36Sopenharmony_ci * one packet out.
53662306a36Sopenharmony_ci */
53762306a36Sopenharmony_civoid sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
53862306a36Sopenharmony_ci		     enum sctp_retransmit_reason reason)
53962306a36Sopenharmony_ci{
54062306a36Sopenharmony_ci	struct net *net = q->asoc->base.net;
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci	switch (reason) {
54362306a36Sopenharmony_ci	case SCTP_RTXR_T3_RTX:
54462306a36Sopenharmony_ci		SCTP_INC_STATS(net, SCTP_MIB_T3_RETRANSMITS);
54562306a36Sopenharmony_ci		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX);
54662306a36Sopenharmony_ci		/* Update the retran path if the T3-rtx timer has expired for
54762306a36Sopenharmony_ci		 * the current retran path.
54862306a36Sopenharmony_ci		 */
54962306a36Sopenharmony_ci		if (transport == transport->asoc->peer.retran_path)
55062306a36Sopenharmony_ci			sctp_assoc_update_retran_path(transport->asoc);
55162306a36Sopenharmony_ci		transport->asoc->rtx_data_chunks +=
55262306a36Sopenharmony_ci			transport->asoc->unack_data;
55362306a36Sopenharmony_ci		if (transport->pl.state == SCTP_PL_COMPLETE &&
55462306a36Sopenharmony_ci		    transport->asoc->unack_data)
55562306a36Sopenharmony_ci			sctp_transport_reset_probe_timer(transport);
55662306a36Sopenharmony_ci		break;
55762306a36Sopenharmony_ci	case SCTP_RTXR_FAST_RTX:
55862306a36Sopenharmony_ci		SCTP_INC_STATS(net, SCTP_MIB_FAST_RETRANSMITS);
55962306a36Sopenharmony_ci		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
56062306a36Sopenharmony_ci		q->fast_rtx = 1;
56162306a36Sopenharmony_ci		break;
56262306a36Sopenharmony_ci	case SCTP_RTXR_PMTUD:
56362306a36Sopenharmony_ci		SCTP_INC_STATS(net, SCTP_MIB_PMTUD_RETRANSMITS);
56462306a36Sopenharmony_ci		break;
56562306a36Sopenharmony_ci	case SCTP_RTXR_T1_RTX:
56662306a36Sopenharmony_ci		SCTP_INC_STATS(net, SCTP_MIB_T1_RETRANSMITS);
56762306a36Sopenharmony_ci		transport->asoc->init_retries++;
56862306a36Sopenharmony_ci		break;
56962306a36Sopenharmony_ci	default:
57062306a36Sopenharmony_ci		BUG();
57162306a36Sopenharmony_ci	}
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci	sctp_retransmit_mark(q, transport, reason);
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci	/* PR-SCTP A5) Any time the T3-rtx timer expires, on any destination,
57662306a36Sopenharmony_ci	 * the sender SHOULD try to advance the "Advanced.Peer.Ack.Point" by
57762306a36Sopenharmony_ci	 * following the procedures outlined in C1 - C5.
57862306a36Sopenharmony_ci	 */
57962306a36Sopenharmony_ci	if (reason == SCTP_RTXR_T3_RTX)
58062306a36Sopenharmony_ci		q->asoc->stream.si->generate_ftsn(q, q->asoc->ctsn_ack_point);
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci	/* Flush the queues only on timeout, since fast_rtx is only
58362306a36Sopenharmony_ci	 * triggered during sack processing and the queue
58462306a36Sopenharmony_ci	 * will be flushed at the end.
58562306a36Sopenharmony_ci	 */
58662306a36Sopenharmony_ci	if (reason != SCTP_RTXR_FAST_RTX)
58762306a36Sopenharmony_ci		sctp_outq_flush(q, /* rtx_timeout */ 1, GFP_ATOMIC);
58862306a36Sopenharmony_ci}
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_ci/*
59162306a36Sopenharmony_ci * Transmit DATA chunks on the retransmit queue.  Upon return from
59262306a36Sopenharmony_ci * __sctp_outq_flush_rtx() the packet 'pkt' may contain chunks which
59362306a36Sopenharmony_ci * need to be transmitted by the caller.
59462306a36Sopenharmony_ci * We assume that pkt->transport has already been set.
59562306a36Sopenharmony_ci *
59662306a36Sopenharmony_ci * The return value is a normal kernel error return value.
59762306a36Sopenharmony_ci */
59862306a36Sopenharmony_cistatic int __sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
59962306a36Sopenharmony_ci				 int rtx_timeout, int *start_timer, gfp_t gfp)
60062306a36Sopenharmony_ci{
60162306a36Sopenharmony_ci	struct sctp_transport *transport = pkt->transport;
60262306a36Sopenharmony_ci	struct sctp_chunk *chunk, *chunk1;
60362306a36Sopenharmony_ci	struct list_head *lqueue;
60462306a36Sopenharmony_ci	enum sctp_xmit status;
60562306a36Sopenharmony_ci	int error = 0;
60662306a36Sopenharmony_ci	int timer = 0;
60762306a36Sopenharmony_ci	int done = 0;
60862306a36Sopenharmony_ci	int fast_rtx;
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	lqueue = &q->retransmit;
61162306a36Sopenharmony_ci	fast_rtx = q->fast_rtx;
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci	/* This loop handles time-out retransmissions, fast retransmissions,
61462306a36Sopenharmony_ci	 * and retransmissions due to opening of whindow.
61562306a36Sopenharmony_ci	 *
61662306a36Sopenharmony_ci	 * RFC 2960 6.3.3 Handle T3-rtx Expiration
61762306a36Sopenharmony_ci	 *
61862306a36Sopenharmony_ci	 * E3) Determine how many of the earliest (i.e., lowest TSN)
61962306a36Sopenharmony_ci	 * outstanding DATA chunks for the address for which the
62062306a36Sopenharmony_ci	 * T3-rtx has expired will fit into a single packet, subject
62162306a36Sopenharmony_ci	 * to the MTU constraint for the path corresponding to the
62262306a36Sopenharmony_ci	 * destination transport address to which the retransmission
62362306a36Sopenharmony_ci	 * is being sent (this may be different from the address for
62462306a36Sopenharmony_ci	 * which the timer expires [see Section 6.4]). Call this value
62562306a36Sopenharmony_ci	 * K. Bundle and retransmit those K DATA chunks in a single
62662306a36Sopenharmony_ci	 * packet to the destination endpoint.
62762306a36Sopenharmony_ci	 *
62862306a36Sopenharmony_ci	 * [Just to be painfully clear, if we are retransmitting
62962306a36Sopenharmony_ci	 * because a timeout just happened, we should send only ONE
63062306a36Sopenharmony_ci	 * packet of retransmitted data.]
63162306a36Sopenharmony_ci	 *
63262306a36Sopenharmony_ci	 * For fast retransmissions we also send only ONE packet.  However,
63362306a36Sopenharmony_ci	 * if we are just flushing the queue due to open window, we'll
63462306a36Sopenharmony_ci	 * try to send as much as possible.
63562306a36Sopenharmony_ci	 */
63662306a36Sopenharmony_ci	list_for_each_entry_safe(chunk, chunk1, lqueue, transmitted_list) {
63762306a36Sopenharmony_ci		/* If the chunk is abandoned, move it to abandoned list. */
63862306a36Sopenharmony_ci		if (sctp_chunk_abandoned(chunk)) {
63962306a36Sopenharmony_ci			list_del_init(&chunk->transmitted_list);
64062306a36Sopenharmony_ci			sctp_insert_list(&q->abandoned,
64162306a36Sopenharmony_ci					 &chunk->transmitted_list);
64262306a36Sopenharmony_ci			continue;
64362306a36Sopenharmony_ci		}
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci		/* Make sure that Gap Acked TSNs are not retransmitted.  A
64662306a36Sopenharmony_ci		 * simple approach is just to move such TSNs out of the
64762306a36Sopenharmony_ci		 * way and into a 'transmitted' queue and skip to the
64862306a36Sopenharmony_ci		 * next chunk.
64962306a36Sopenharmony_ci		 */
65062306a36Sopenharmony_ci		if (chunk->tsn_gap_acked) {
65162306a36Sopenharmony_ci			list_move_tail(&chunk->transmitted_list,
65262306a36Sopenharmony_ci				       &transport->transmitted);
65362306a36Sopenharmony_ci			continue;
65462306a36Sopenharmony_ci		}
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci		/* If we are doing fast retransmit, ignore non-fast_rtransmit
65762306a36Sopenharmony_ci		 * chunks
65862306a36Sopenharmony_ci		 */
65962306a36Sopenharmony_ci		if (fast_rtx && !chunk->fast_retransmit)
66062306a36Sopenharmony_ci			continue;
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ciredo:
66362306a36Sopenharmony_ci		/* Attempt to append this chunk to the packet. */
66462306a36Sopenharmony_ci		status = sctp_packet_append_chunk(pkt, chunk);
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_ci		switch (status) {
66762306a36Sopenharmony_ci		case SCTP_XMIT_PMTU_FULL:
66862306a36Sopenharmony_ci			if (!pkt->has_data && !pkt->has_cookie_echo) {
66962306a36Sopenharmony_ci				/* If this packet did not contain DATA then
67062306a36Sopenharmony_ci				 * retransmission did not happen, so do it
67162306a36Sopenharmony_ci				 * again.  We'll ignore the error here since
67262306a36Sopenharmony_ci				 * control chunks are already freed so there
67362306a36Sopenharmony_ci				 * is nothing we can do.
67462306a36Sopenharmony_ci				 */
67562306a36Sopenharmony_ci				sctp_packet_transmit(pkt, gfp);
67662306a36Sopenharmony_ci				goto redo;
67762306a36Sopenharmony_ci			}
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci			/* Send this packet.  */
68062306a36Sopenharmony_ci			error = sctp_packet_transmit(pkt, gfp);
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci			/* If we are retransmitting, we should only
68362306a36Sopenharmony_ci			 * send a single packet.
68462306a36Sopenharmony_ci			 * Otherwise, try appending this chunk again.
68562306a36Sopenharmony_ci			 */
68662306a36Sopenharmony_ci			if (rtx_timeout || fast_rtx)
68762306a36Sopenharmony_ci				done = 1;
68862306a36Sopenharmony_ci			else
68962306a36Sopenharmony_ci				goto redo;
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_ci			/* Bundle next chunk in the next round.  */
69262306a36Sopenharmony_ci			break;
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci		case SCTP_XMIT_RWND_FULL:
69562306a36Sopenharmony_ci			/* Send this packet. */
69662306a36Sopenharmony_ci			error = sctp_packet_transmit(pkt, gfp);
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci			/* Stop sending DATA as there is no more room
69962306a36Sopenharmony_ci			 * at the receiver.
70062306a36Sopenharmony_ci			 */
70162306a36Sopenharmony_ci			done = 1;
70262306a36Sopenharmony_ci			break;
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ci		case SCTP_XMIT_DELAY:
70562306a36Sopenharmony_ci			/* Send this packet. */
70662306a36Sopenharmony_ci			error = sctp_packet_transmit(pkt, gfp);
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_ci			/* Stop sending DATA because of nagle delay. */
70962306a36Sopenharmony_ci			done = 1;
71062306a36Sopenharmony_ci			break;
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci		default:
71362306a36Sopenharmony_ci			/* The append was successful, so add this chunk to
71462306a36Sopenharmony_ci			 * the transmitted list.
71562306a36Sopenharmony_ci			 */
71662306a36Sopenharmony_ci			list_move_tail(&chunk->transmitted_list,
71762306a36Sopenharmony_ci				       &transport->transmitted);
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci			/* Mark the chunk as ineligible for fast retransmit
72062306a36Sopenharmony_ci			 * after it is retransmitted.
72162306a36Sopenharmony_ci			 */
72262306a36Sopenharmony_ci			if (chunk->fast_retransmit == SCTP_NEED_FRTX)
72362306a36Sopenharmony_ci				chunk->fast_retransmit = SCTP_DONT_FRTX;
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_ci			q->asoc->stats.rtxchunks++;
72662306a36Sopenharmony_ci			break;
72762306a36Sopenharmony_ci		}
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci		/* Set the timer if there were no errors */
73062306a36Sopenharmony_ci		if (!error && !timer)
73162306a36Sopenharmony_ci			timer = 1;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci		if (done)
73462306a36Sopenharmony_ci			break;
73562306a36Sopenharmony_ci	}
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	/* If we are here due to a retransmit timeout or a fast
73862306a36Sopenharmony_ci	 * retransmit and if there are any chunks left in the retransmit
73962306a36Sopenharmony_ci	 * queue that could not fit in the PMTU sized packet, they need
74062306a36Sopenharmony_ci	 * to be marked as ineligible for a subsequent fast retransmit.
74162306a36Sopenharmony_ci	 */
74262306a36Sopenharmony_ci	if (rtx_timeout || fast_rtx) {
74362306a36Sopenharmony_ci		list_for_each_entry(chunk1, lqueue, transmitted_list) {
74462306a36Sopenharmony_ci			if (chunk1->fast_retransmit == SCTP_NEED_FRTX)
74562306a36Sopenharmony_ci				chunk1->fast_retransmit = SCTP_DONT_FRTX;
74662306a36Sopenharmony_ci		}
74762306a36Sopenharmony_ci	}
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci	*start_timer = timer;
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	/* Clear fast retransmit hint */
75262306a36Sopenharmony_ci	if (fast_rtx)
75362306a36Sopenharmony_ci		q->fast_rtx = 0;
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ci	return error;
75662306a36Sopenharmony_ci}
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci/* Cork the outqueue so queued chunks are really queued. */
75962306a36Sopenharmony_civoid sctp_outq_uncork(struct sctp_outq *q, gfp_t gfp)
76062306a36Sopenharmony_ci{
76162306a36Sopenharmony_ci	if (q->cork)
76262306a36Sopenharmony_ci		q->cork = 0;
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci	sctp_outq_flush(q, 0, gfp);
76562306a36Sopenharmony_ci}
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_cistatic int sctp_packet_singleton(struct sctp_transport *transport,
76862306a36Sopenharmony_ci				 struct sctp_chunk *chunk, gfp_t gfp)
76962306a36Sopenharmony_ci{
77062306a36Sopenharmony_ci	const struct sctp_association *asoc = transport->asoc;
77162306a36Sopenharmony_ci	const __u16 sport = asoc->base.bind_addr.port;
77262306a36Sopenharmony_ci	const __u16 dport = asoc->peer.port;
77362306a36Sopenharmony_ci	const __u32 vtag = asoc->peer.i.init_tag;
77462306a36Sopenharmony_ci	struct sctp_packet singleton;
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ci	sctp_packet_init(&singleton, transport, sport, dport);
77762306a36Sopenharmony_ci	sctp_packet_config(&singleton, vtag, 0);
77862306a36Sopenharmony_ci	if (sctp_packet_append_chunk(&singleton, chunk) != SCTP_XMIT_OK) {
77962306a36Sopenharmony_ci		list_del_init(&chunk->list);
78062306a36Sopenharmony_ci		sctp_chunk_free(chunk);
78162306a36Sopenharmony_ci		return -ENOMEM;
78262306a36Sopenharmony_ci	}
78362306a36Sopenharmony_ci	return sctp_packet_transmit(&singleton, gfp);
78462306a36Sopenharmony_ci}
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci/* Struct to hold the context during sctp outq flush */
78762306a36Sopenharmony_cistruct sctp_flush_ctx {
78862306a36Sopenharmony_ci	struct sctp_outq *q;
78962306a36Sopenharmony_ci	/* Current transport being used. It's NOT the same as curr active one */
79062306a36Sopenharmony_ci	struct sctp_transport *transport;
79162306a36Sopenharmony_ci	/* These transports have chunks to send. */
79262306a36Sopenharmony_ci	struct list_head transport_list;
79362306a36Sopenharmony_ci	struct sctp_association *asoc;
79462306a36Sopenharmony_ci	/* Packet on the current transport above */
79562306a36Sopenharmony_ci	struct sctp_packet *packet;
79662306a36Sopenharmony_ci	gfp_t gfp;
79762306a36Sopenharmony_ci};
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci/* transport: current transport */
80062306a36Sopenharmony_cistatic void sctp_outq_select_transport(struct sctp_flush_ctx *ctx,
80162306a36Sopenharmony_ci				       struct sctp_chunk *chunk)
80262306a36Sopenharmony_ci{
80362306a36Sopenharmony_ci	struct sctp_transport *new_transport = chunk->transport;
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ci	if (!new_transport) {
80662306a36Sopenharmony_ci		if (!sctp_chunk_is_data(chunk)) {
80762306a36Sopenharmony_ci			/* If we have a prior transport pointer, see if
80862306a36Sopenharmony_ci			 * the destination address of the chunk
80962306a36Sopenharmony_ci			 * matches the destination address of the
81062306a36Sopenharmony_ci			 * current transport.  If not a match, then
81162306a36Sopenharmony_ci			 * try to look up the transport with a given
81262306a36Sopenharmony_ci			 * destination address.  We do this because
81362306a36Sopenharmony_ci			 * after processing ASCONFs, we may have new
81462306a36Sopenharmony_ci			 * transports created.
81562306a36Sopenharmony_ci			 */
81662306a36Sopenharmony_ci			if (ctx->transport && sctp_cmp_addr_exact(&chunk->dest,
81762306a36Sopenharmony_ci							&ctx->transport->ipaddr))
81862306a36Sopenharmony_ci				new_transport = ctx->transport;
81962306a36Sopenharmony_ci			else
82062306a36Sopenharmony_ci				new_transport = sctp_assoc_lookup_paddr(ctx->asoc,
82162306a36Sopenharmony_ci								  &chunk->dest);
82262306a36Sopenharmony_ci		}
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_ci		/* if we still don't have a new transport, then
82562306a36Sopenharmony_ci		 * use the current active path.
82662306a36Sopenharmony_ci		 */
82762306a36Sopenharmony_ci		if (!new_transport)
82862306a36Sopenharmony_ci			new_transport = ctx->asoc->peer.active_path;
82962306a36Sopenharmony_ci	} else {
83062306a36Sopenharmony_ci		__u8 type;
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ci		switch (new_transport->state) {
83362306a36Sopenharmony_ci		case SCTP_INACTIVE:
83462306a36Sopenharmony_ci		case SCTP_UNCONFIRMED:
83562306a36Sopenharmony_ci		case SCTP_PF:
83662306a36Sopenharmony_ci			/* If the chunk is Heartbeat or Heartbeat Ack,
83762306a36Sopenharmony_ci			 * send it to chunk->transport, even if it's
83862306a36Sopenharmony_ci			 * inactive.
83962306a36Sopenharmony_ci			 *
84062306a36Sopenharmony_ci			 * 3.3.6 Heartbeat Acknowledgement:
84162306a36Sopenharmony_ci			 * ...
84262306a36Sopenharmony_ci			 * A HEARTBEAT ACK is always sent to the source IP
84362306a36Sopenharmony_ci			 * address of the IP datagram containing the
84462306a36Sopenharmony_ci			 * HEARTBEAT chunk to which this ack is responding.
84562306a36Sopenharmony_ci			 * ...
84662306a36Sopenharmony_ci			 *
84762306a36Sopenharmony_ci			 * ASCONF_ACKs also must be sent to the source.
84862306a36Sopenharmony_ci			 */
84962306a36Sopenharmony_ci			type = chunk->chunk_hdr->type;
85062306a36Sopenharmony_ci			if (type != SCTP_CID_HEARTBEAT &&
85162306a36Sopenharmony_ci			    type != SCTP_CID_HEARTBEAT_ACK &&
85262306a36Sopenharmony_ci			    type != SCTP_CID_ASCONF_ACK)
85362306a36Sopenharmony_ci				new_transport = ctx->asoc->peer.active_path;
85462306a36Sopenharmony_ci			break;
85562306a36Sopenharmony_ci		default:
85662306a36Sopenharmony_ci			break;
85762306a36Sopenharmony_ci		}
85862306a36Sopenharmony_ci	}
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci	/* Are we switching transports? Take care of transport locks. */
86162306a36Sopenharmony_ci	if (new_transport != ctx->transport) {
86262306a36Sopenharmony_ci		ctx->transport = new_transport;
86362306a36Sopenharmony_ci		ctx->packet = &ctx->transport->packet;
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_ci		if (list_empty(&ctx->transport->send_ready))
86662306a36Sopenharmony_ci			list_add_tail(&ctx->transport->send_ready,
86762306a36Sopenharmony_ci				      &ctx->transport_list);
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci		sctp_packet_config(ctx->packet,
87062306a36Sopenharmony_ci				   ctx->asoc->peer.i.init_tag,
87162306a36Sopenharmony_ci				   ctx->asoc->peer.ecn_capable);
87262306a36Sopenharmony_ci		/* We've switched transports, so apply the
87362306a36Sopenharmony_ci		 * Burst limit to the new transport.
87462306a36Sopenharmony_ci		 */
87562306a36Sopenharmony_ci		sctp_transport_burst_limited(ctx->transport);
87662306a36Sopenharmony_ci	}
87762306a36Sopenharmony_ci}
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_cistatic void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx)
88062306a36Sopenharmony_ci{
88162306a36Sopenharmony_ci	struct sctp_chunk *chunk, *tmp;
88262306a36Sopenharmony_ci	enum sctp_xmit status;
88362306a36Sopenharmony_ci	int one_packet, error;
88462306a36Sopenharmony_ci
88562306a36Sopenharmony_ci	list_for_each_entry_safe(chunk, tmp, &ctx->q->control_chunk_list, list) {
88662306a36Sopenharmony_ci		one_packet = 0;
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci		/* RFC 5061, 5.3
88962306a36Sopenharmony_ci		 * F1) This means that until such time as the ASCONF
89062306a36Sopenharmony_ci		 * containing the add is acknowledged, the sender MUST
89162306a36Sopenharmony_ci		 * NOT use the new IP address as a source for ANY SCTP
89262306a36Sopenharmony_ci		 * packet except on carrying an ASCONF Chunk.
89362306a36Sopenharmony_ci		 */
89462306a36Sopenharmony_ci		if (ctx->asoc->src_out_of_asoc_ok &&
89562306a36Sopenharmony_ci		    chunk->chunk_hdr->type != SCTP_CID_ASCONF)
89662306a36Sopenharmony_ci			continue;
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_ci		list_del_init(&chunk->list);
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci		/* Pick the right transport to use. Should always be true for
90162306a36Sopenharmony_ci		 * the first chunk as we don't have a transport by then.
90262306a36Sopenharmony_ci		 */
90362306a36Sopenharmony_ci		sctp_outq_select_transport(ctx, chunk);
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_ci		switch (chunk->chunk_hdr->type) {
90662306a36Sopenharmony_ci		/* 6.10 Bundling
90762306a36Sopenharmony_ci		 *   ...
90862306a36Sopenharmony_ci		 *   An endpoint MUST NOT bundle INIT, INIT ACK or SHUTDOWN
90962306a36Sopenharmony_ci		 *   COMPLETE with any other chunks.  [Send them immediately.]
91062306a36Sopenharmony_ci		 */
91162306a36Sopenharmony_ci		case SCTP_CID_INIT:
91262306a36Sopenharmony_ci		case SCTP_CID_INIT_ACK:
91362306a36Sopenharmony_ci		case SCTP_CID_SHUTDOWN_COMPLETE:
91462306a36Sopenharmony_ci			error = sctp_packet_singleton(ctx->transport, chunk,
91562306a36Sopenharmony_ci						      ctx->gfp);
91662306a36Sopenharmony_ci			if (error < 0) {
91762306a36Sopenharmony_ci				ctx->asoc->base.sk->sk_err = -error;
91862306a36Sopenharmony_ci				return;
91962306a36Sopenharmony_ci			}
92062306a36Sopenharmony_ci			ctx->asoc->stats.octrlchunks++;
92162306a36Sopenharmony_ci			break;
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci		case SCTP_CID_ABORT:
92462306a36Sopenharmony_ci			if (sctp_test_T_bit(chunk))
92562306a36Sopenharmony_ci				ctx->packet->vtag = ctx->asoc->c.my_vtag;
92662306a36Sopenharmony_ci			fallthrough;
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ci		/* The following chunks are "response" chunks, i.e.
92962306a36Sopenharmony_ci		 * they are generated in response to something we
93062306a36Sopenharmony_ci		 * received.  If we are sending these, then we can
93162306a36Sopenharmony_ci		 * send only 1 packet containing these chunks.
93262306a36Sopenharmony_ci		 */
93362306a36Sopenharmony_ci		case SCTP_CID_HEARTBEAT_ACK:
93462306a36Sopenharmony_ci		case SCTP_CID_SHUTDOWN_ACK:
93562306a36Sopenharmony_ci		case SCTP_CID_COOKIE_ACK:
93662306a36Sopenharmony_ci		case SCTP_CID_COOKIE_ECHO:
93762306a36Sopenharmony_ci		case SCTP_CID_ERROR:
93862306a36Sopenharmony_ci		case SCTP_CID_ECN_CWR:
93962306a36Sopenharmony_ci		case SCTP_CID_ASCONF_ACK:
94062306a36Sopenharmony_ci			one_packet = 1;
94162306a36Sopenharmony_ci			fallthrough;
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_ci		case SCTP_CID_HEARTBEAT:
94462306a36Sopenharmony_ci			if (chunk->pmtu_probe) {
94562306a36Sopenharmony_ci				error = sctp_packet_singleton(ctx->transport,
94662306a36Sopenharmony_ci							      chunk, ctx->gfp);
94762306a36Sopenharmony_ci				if (!error)
94862306a36Sopenharmony_ci					ctx->asoc->stats.octrlchunks++;
94962306a36Sopenharmony_ci				break;
95062306a36Sopenharmony_ci			}
95162306a36Sopenharmony_ci			fallthrough;
95262306a36Sopenharmony_ci		case SCTP_CID_SACK:
95362306a36Sopenharmony_ci		case SCTP_CID_SHUTDOWN:
95462306a36Sopenharmony_ci		case SCTP_CID_ECN_ECNE:
95562306a36Sopenharmony_ci		case SCTP_CID_ASCONF:
95662306a36Sopenharmony_ci		case SCTP_CID_FWD_TSN:
95762306a36Sopenharmony_ci		case SCTP_CID_I_FWD_TSN:
95862306a36Sopenharmony_ci		case SCTP_CID_RECONF:
95962306a36Sopenharmony_ci			status = sctp_packet_transmit_chunk(ctx->packet, chunk,
96062306a36Sopenharmony_ci							    one_packet, ctx->gfp);
96162306a36Sopenharmony_ci			if (status != SCTP_XMIT_OK) {
96262306a36Sopenharmony_ci				/* put the chunk back */
96362306a36Sopenharmony_ci				list_add(&chunk->list, &ctx->q->control_chunk_list);
96462306a36Sopenharmony_ci				break;
96562306a36Sopenharmony_ci			}
96662306a36Sopenharmony_ci
96762306a36Sopenharmony_ci			ctx->asoc->stats.octrlchunks++;
96862306a36Sopenharmony_ci			/* PR-SCTP C5) If a FORWARD TSN is sent, the
96962306a36Sopenharmony_ci			 * sender MUST assure that at least one T3-rtx
97062306a36Sopenharmony_ci			 * timer is running.
97162306a36Sopenharmony_ci			 */
97262306a36Sopenharmony_ci			if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN ||
97362306a36Sopenharmony_ci			    chunk->chunk_hdr->type == SCTP_CID_I_FWD_TSN) {
97462306a36Sopenharmony_ci				sctp_transport_reset_t3_rtx(ctx->transport);
97562306a36Sopenharmony_ci				ctx->transport->last_time_sent = jiffies;
97662306a36Sopenharmony_ci			}
97762306a36Sopenharmony_ci
97862306a36Sopenharmony_ci			if (chunk == ctx->asoc->strreset_chunk)
97962306a36Sopenharmony_ci				sctp_transport_reset_reconf_timer(ctx->transport);
98062306a36Sopenharmony_ci
98162306a36Sopenharmony_ci			break;
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_ci		default:
98462306a36Sopenharmony_ci			/* We built a chunk with an illegal type! */
98562306a36Sopenharmony_ci			BUG();
98662306a36Sopenharmony_ci		}
98762306a36Sopenharmony_ci	}
98862306a36Sopenharmony_ci}
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci/* Returns false if new data shouldn't be sent */
99162306a36Sopenharmony_cistatic bool sctp_outq_flush_rtx(struct sctp_flush_ctx *ctx,
99262306a36Sopenharmony_ci				int rtx_timeout)
99362306a36Sopenharmony_ci{
99462306a36Sopenharmony_ci	int error, start_timer = 0;
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	if (ctx->asoc->peer.retran_path->state == SCTP_UNCONFIRMED)
99762306a36Sopenharmony_ci		return false;
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_ci	if (ctx->transport != ctx->asoc->peer.retran_path) {
100062306a36Sopenharmony_ci		/* Switch transports & prepare the packet.  */
100162306a36Sopenharmony_ci		ctx->transport = ctx->asoc->peer.retran_path;
100262306a36Sopenharmony_ci		ctx->packet = &ctx->transport->packet;
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci		if (list_empty(&ctx->transport->send_ready))
100562306a36Sopenharmony_ci			list_add_tail(&ctx->transport->send_ready,
100662306a36Sopenharmony_ci				      &ctx->transport_list);
100762306a36Sopenharmony_ci
100862306a36Sopenharmony_ci		sctp_packet_config(ctx->packet, ctx->asoc->peer.i.init_tag,
100962306a36Sopenharmony_ci				   ctx->asoc->peer.ecn_capable);
101062306a36Sopenharmony_ci	}
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	error = __sctp_outq_flush_rtx(ctx->q, ctx->packet, rtx_timeout,
101362306a36Sopenharmony_ci				      &start_timer, ctx->gfp);
101462306a36Sopenharmony_ci	if (error < 0)
101562306a36Sopenharmony_ci		ctx->asoc->base.sk->sk_err = -error;
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci	if (start_timer) {
101862306a36Sopenharmony_ci		sctp_transport_reset_t3_rtx(ctx->transport);
101962306a36Sopenharmony_ci		ctx->transport->last_time_sent = jiffies;
102062306a36Sopenharmony_ci	}
102162306a36Sopenharmony_ci
102262306a36Sopenharmony_ci	/* This can happen on COOKIE-ECHO resend.  Only
102362306a36Sopenharmony_ci	 * one chunk can get bundled with a COOKIE-ECHO.
102462306a36Sopenharmony_ci	 */
102562306a36Sopenharmony_ci	if (ctx->packet->has_cookie_echo)
102662306a36Sopenharmony_ci		return false;
102762306a36Sopenharmony_ci
102862306a36Sopenharmony_ci	/* Don't send new data if there is still data
102962306a36Sopenharmony_ci	 * waiting to retransmit.
103062306a36Sopenharmony_ci	 */
103162306a36Sopenharmony_ci	if (!list_empty(&ctx->q->retransmit))
103262306a36Sopenharmony_ci		return false;
103362306a36Sopenharmony_ci
103462306a36Sopenharmony_ci	return true;
103562306a36Sopenharmony_ci}
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_cistatic void sctp_outq_flush_data(struct sctp_flush_ctx *ctx,
103862306a36Sopenharmony_ci				 int rtx_timeout)
103962306a36Sopenharmony_ci{
104062306a36Sopenharmony_ci	struct sctp_chunk *chunk;
104162306a36Sopenharmony_ci	enum sctp_xmit status;
104262306a36Sopenharmony_ci
104362306a36Sopenharmony_ci	/* Is it OK to send data chunks?  */
104462306a36Sopenharmony_ci	switch (ctx->asoc->state) {
104562306a36Sopenharmony_ci	case SCTP_STATE_COOKIE_ECHOED:
104662306a36Sopenharmony_ci		/* Only allow bundling when this packet has a COOKIE-ECHO
104762306a36Sopenharmony_ci		 * chunk.
104862306a36Sopenharmony_ci		 */
104962306a36Sopenharmony_ci		if (!ctx->packet || !ctx->packet->has_cookie_echo)
105062306a36Sopenharmony_ci			return;
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_ci		fallthrough;
105362306a36Sopenharmony_ci	case SCTP_STATE_ESTABLISHED:
105462306a36Sopenharmony_ci	case SCTP_STATE_SHUTDOWN_PENDING:
105562306a36Sopenharmony_ci	case SCTP_STATE_SHUTDOWN_RECEIVED:
105662306a36Sopenharmony_ci		break;
105762306a36Sopenharmony_ci
105862306a36Sopenharmony_ci	default:
105962306a36Sopenharmony_ci		/* Do nothing. */
106062306a36Sopenharmony_ci		return;
106162306a36Sopenharmony_ci	}
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_ci	/* RFC 2960 6.1  Transmission of DATA Chunks
106462306a36Sopenharmony_ci	 *
106562306a36Sopenharmony_ci	 * C) When the time comes for the sender to transmit,
106662306a36Sopenharmony_ci	 * before sending new DATA chunks, the sender MUST
106762306a36Sopenharmony_ci	 * first transmit any outstanding DATA chunks which
106862306a36Sopenharmony_ci	 * are marked for retransmission (limited by the
106962306a36Sopenharmony_ci	 * current cwnd).
107062306a36Sopenharmony_ci	 */
107162306a36Sopenharmony_ci	if (!list_empty(&ctx->q->retransmit) &&
107262306a36Sopenharmony_ci	    !sctp_outq_flush_rtx(ctx, rtx_timeout))
107362306a36Sopenharmony_ci		return;
107462306a36Sopenharmony_ci
107562306a36Sopenharmony_ci	/* Apply Max.Burst limitation to the current transport in
107662306a36Sopenharmony_ci	 * case it will be used for new data.  We are going to
107762306a36Sopenharmony_ci	 * rest it before we return, but we want to apply the limit
107862306a36Sopenharmony_ci	 * to the currently queued data.
107962306a36Sopenharmony_ci	 */
108062306a36Sopenharmony_ci	if (ctx->transport)
108162306a36Sopenharmony_ci		sctp_transport_burst_limited(ctx->transport);
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_ci	/* Finally, transmit new packets.  */
108462306a36Sopenharmony_ci	while ((chunk = sctp_outq_dequeue_data(ctx->q)) != NULL) {
108562306a36Sopenharmony_ci		__u32 sid = ntohs(chunk->subh.data_hdr->stream);
108662306a36Sopenharmony_ci		__u8 stream_state = SCTP_SO(&ctx->asoc->stream, sid)->state;
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci		/* Has this chunk expired? */
108962306a36Sopenharmony_ci		if (sctp_chunk_abandoned(chunk)) {
109062306a36Sopenharmony_ci			sctp_sched_dequeue_done(ctx->q, chunk);
109162306a36Sopenharmony_ci			sctp_chunk_fail(chunk, 0);
109262306a36Sopenharmony_ci			sctp_chunk_free(chunk);
109362306a36Sopenharmony_ci			continue;
109462306a36Sopenharmony_ci		}
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_ci		if (stream_state == SCTP_STREAM_CLOSED) {
109762306a36Sopenharmony_ci			sctp_outq_head_data(ctx->q, chunk);
109862306a36Sopenharmony_ci			break;
109962306a36Sopenharmony_ci		}
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_ci		sctp_outq_select_transport(ctx, chunk);
110262306a36Sopenharmony_ci
110362306a36Sopenharmony_ci		pr_debug("%s: outq:%p, chunk:%p[%s], tx-tsn:0x%x skb->head:%p skb->users:%d\n",
110462306a36Sopenharmony_ci			 __func__, ctx->q, chunk, chunk && chunk->chunk_hdr ?
110562306a36Sopenharmony_ci			 sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) :
110662306a36Sopenharmony_ci			 "illegal chunk", ntohl(chunk->subh.data_hdr->tsn),
110762306a36Sopenharmony_ci			 chunk->skb ? chunk->skb->head : NULL, chunk->skb ?
110862306a36Sopenharmony_ci			 refcount_read(&chunk->skb->users) : -1);
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci		/* Add the chunk to the packet.  */
111162306a36Sopenharmony_ci		status = sctp_packet_transmit_chunk(ctx->packet, chunk, 0,
111262306a36Sopenharmony_ci						    ctx->gfp);
111362306a36Sopenharmony_ci		if (status != SCTP_XMIT_OK) {
111462306a36Sopenharmony_ci			/* We could not append this chunk, so put
111562306a36Sopenharmony_ci			 * the chunk back on the output queue.
111662306a36Sopenharmony_ci			 */
111762306a36Sopenharmony_ci			pr_debug("%s: could not transmit tsn:0x%x, status:%d\n",
111862306a36Sopenharmony_ci				 __func__, ntohl(chunk->subh.data_hdr->tsn),
111962306a36Sopenharmony_ci				 status);
112062306a36Sopenharmony_ci
112162306a36Sopenharmony_ci			sctp_outq_head_data(ctx->q, chunk);
112262306a36Sopenharmony_ci			break;
112362306a36Sopenharmony_ci		}
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci		/* The sender is in the SHUTDOWN-PENDING state,
112662306a36Sopenharmony_ci		 * The sender MAY set the I-bit in the DATA
112762306a36Sopenharmony_ci		 * chunk header.
112862306a36Sopenharmony_ci		 */
112962306a36Sopenharmony_ci		if (ctx->asoc->state == SCTP_STATE_SHUTDOWN_PENDING)
113062306a36Sopenharmony_ci			chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM;
113162306a36Sopenharmony_ci		if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
113262306a36Sopenharmony_ci			ctx->asoc->stats.ouodchunks++;
113362306a36Sopenharmony_ci		else
113462306a36Sopenharmony_ci			ctx->asoc->stats.oodchunks++;
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_ci		/* Only now it's safe to consider this
113762306a36Sopenharmony_ci		 * chunk as sent, sched-wise.
113862306a36Sopenharmony_ci		 */
113962306a36Sopenharmony_ci		sctp_sched_dequeue_done(ctx->q, chunk);
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_ci		list_add_tail(&chunk->transmitted_list,
114262306a36Sopenharmony_ci			      &ctx->transport->transmitted);
114362306a36Sopenharmony_ci
114462306a36Sopenharmony_ci		sctp_transport_reset_t3_rtx(ctx->transport);
114562306a36Sopenharmony_ci		ctx->transport->last_time_sent = jiffies;
114662306a36Sopenharmony_ci
114762306a36Sopenharmony_ci		/* Only let one DATA chunk get bundled with a
114862306a36Sopenharmony_ci		 * COOKIE-ECHO chunk.
114962306a36Sopenharmony_ci		 */
115062306a36Sopenharmony_ci		if (ctx->packet->has_cookie_echo)
115162306a36Sopenharmony_ci			break;
115262306a36Sopenharmony_ci	}
115362306a36Sopenharmony_ci}
115462306a36Sopenharmony_ci
115562306a36Sopenharmony_cistatic void sctp_outq_flush_transports(struct sctp_flush_ctx *ctx)
115662306a36Sopenharmony_ci{
115762306a36Sopenharmony_ci	struct sock *sk = ctx->asoc->base.sk;
115862306a36Sopenharmony_ci	struct list_head *ltransport;
115962306a36Sopenharmony_ci	struct sctp_packet *packet;
116062306a36Sopenharmony_ci	struct sctp_transport *t;
116162306a36Sopenharmony_ci	int error = 0;
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_ci	while ((ltransport = sctp_list_dequeue(&ctx->transport_list)) != NULL) {
116462306a36Sopenharmony_ci		t = list_entry(ltransport, struct sctp_transport, send_ready);
116562306a36Sopenharmony_ci		packet = &t->packet;
116662306a36Sopenharmony_ci		if (!sctp_packet_empty(packet)) {
116762306a36Sopenharmony_ci			rcu_read_lock();
116862306a36Sopenharmony_ci			if (t->dst && __sk_dst_get(sk) != t->dst) {
116962306a36Sopenharmony_ci				dst_hold(t->dst);
117062306a36Sopenharmony_ci				sk_setup_caps(sk, t->dst);
117162306a36Sopenharmony_ci			}
117262306a36Sopenharmony_ci			rcu_read_unlock();
117362306a36Sopenharmony_ci			error = sctp_packet_transmit(packet, ctx->gfp);
117462306a36Sopenharmony_ci			if (error < 0)
117562306a36Sopenharmony_ci				ctx->q->asoc->base.sk->sk_err = -error;
117662306a36Sopenharmony_ci		}
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci		/* Clear the burst limited state, if any */
117962306a36Sopenharmony_ci		sctp_transport_burst_reset(t);
118062306a36Sopenharmony_ci	}
118162306a36Sopenharmony_ci}
118262306a36Sopenharmony_ci
118362306a36Sopenharmony_ci/* Try to flush an outqueue.
118462306a36Sopenharmony_ci *
118562306a36Sopenharmony_ci * Description: Send everything in q which we legally can, subject to
118662306a36Sopenharmony_ci * congestion limitations.
118762306a36Sopenharmony_ci * * Note: This function can be called from multiple contexts so appropriate
118862306a36Sopenharmony_ci * locking concerns must be made.  Today we use the sock lock to protect
118962306a36Sopenharmony_ci * this function.
119062306a36Sopenharmony_ci */
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_cistatic void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
119362306a36Sopenharmony_ci{
119462306a36Sopenharmony_ci	struct sctp_flush_ctx ctx = {
119562306a36Sopenharmony_ci		.q = q,
119662306a36Sopenharmony_ci		.transport = NULL,
119762306a36Sopenharmony_ci		.transport_list = LIST_HEAD_INIT(ctx.transport_list),
119862306a36Sopenharmony_ci		.asoc = q->asoc,
119962306a36Sopenharmony_ci		.packet = NULL,
120062306a36Sopenharmony_ci		.gfp = gfp,
120162306a36Sopenharmony_ci	};
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci	/* 6.10 Bundling
120462306a36Sopenharmony_ci	 *   ...
120562306a36Sopenharmony_ci	 *   When bundling control chunks with DATA chunks, an
120662306a36Sopenharmony_ci	 *   endpoint MUST place control chunks first in the outbound
120762306a36Sopenharmony_ci	 *   SCTP packet.  The transmitter MUST transmit DATA chunks
120862306a36Sopenharmony_ci	 *   within a SCTP packet in increasing order of TSN.
120962306a36Sopenharmony_ci	 *   ...
121062306a36Sopenharmony_ci	 */
121162306a36Sopenharmony_ci
121262306a36Sopenharmony_ci	sctp_outq_flush_ctrl(&ctx);
121362306a36Sopenharmony_ci
121462306a36Sopenharmony_ci	if (q->asoc->src_out_of_asoc_ok)
121562306a36Sopenharmony_ci		goto sctp_flush_out;
121662306a36Sopenharmony_ci
121762306a36Sopenharmony_ci	sctp_outq_flush_data(&ctx, rtx_timeout);
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_cisctp_flush_out:
122062306a36Sopenharmony_ci
122162306a36Sopenharmony_ci	sctp_outq_flush_transports(&ctx);
122262306a36Sopenharmony_ci}
122362306a36Sopenharmony_ci
122462306a36Sopenharmony_ci/* Update unack_data based on the incoming SACK chunk */
122562306a36Sopenharmony_cistatic void sctp_sack_update_unack_data(struct sctp_association *assoc,
122662306a36Sopenharmony_ci					struct sctp_sackhdr *sack)
122762306a36Sopenharmony_ci{
122862306a36Sopenharmony_ci	union sctp_sack_variable *frags;
122962306a36Sopenharmony_ci	__u16 unack_data;
123062306a36Sopenharmony_ci	int i;
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_ci	unack_data = assoc->next_tsn - assoc->ctsn_ack_point - 1;
123362306a36Sopenharmony_ci
123462306a36Sopenharmony_ci	frags = (union sctp_sack_variable *)(sack + 1);
123562306a36Sopenharmony_ci	for (i = 0; i < ntohs(sack->num_gap_ack_blocks); i++) {
123662306a36Sopenharmony_ci		unack_data -= ((ntohs(frags[i].gab.end) -
123762306a36Sopenharmony_ci				ntohs(frags[i].gab.start) + 1));
123862306a36Sopenharmony_ci	}
123962306a36Sopenharmony_ci
124062306a36Sopenharmony_ci	assoc->unack_data = unack_data;
124162306a36Sopenharmony_ci}
124262306a36Sopenharmony_ci
124362306a36Sopenharmony_ci/* This is where we REALLY process a SACK.
124462306a36Sopenharmony_ci *
124562306a36Sopenharmony_ci * Process the SACK against the outqueue.  Mostly, this just frees
124662306a36Sopenharmony_ci * things off the transmitted queue.
124762306a36Sopenharmony_ci */
124862306a36Sopenharmony_ciint sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
124962306a36Sopenharmony_ci{
125062306a36Sopenharmony_ci	struct sctp_association *asoc = q->asoc;
125162306a36Sopenharmony_ci	struct sctp_sackhdr *sack = chunk->subh.sack_hdr;
125262306a36Sopenharmony_ci	struct sctp_transport *transport;
125362306a36Sopenharmony_ci	struct sctp_chunk *tchunk = NULL;
125462306a36Sopenharmony_ci	struct list_head *lchunk, *transport_list, *temp;
125562306a36Sopenharmony_ci	__u32 sack_ctsn, ctsn, tsn;
125662306a36Sopenharmony_ci	__u32 highest_tsn, highest_new_tsn;
125762306a36Sopenharmony_ci	__u32 sack_a_rwnd;
125862306a36Sopenharmony_ci	unsigned int outstanding;
125962306a36Sopenharmony_ci	struct sctp_transport *primary = asoc->peer.primary_path;
126062306a36Sopenharmony_ci	int count_of_newacks = 0;
126162306a36Sopenharmony_ci	int gap_ack_blocks;
126262306a36Sopenharmony_ci	u8 accum_moved = 0;
126362306a36Sopenharmony_ci
126462306a36Sopenharmony_ci	/* Grab the association's destination address list. */
126562306a36Sopenharmony_ci	transport_list = &asoc->peer.transport_addr_list;
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	/* SCTP path tracepoint for congestion control debugging. */
126862306a36Sopenharmony_ci	if (trace_sctp_probe_path_enabled()) {
126962306a36Sopenharmony_ci		list_for_each_entry(transport, transport_list, transports)
127062306a36Sopenharmony_ci			trace_sctp_probe_path(transport, asoc);
127162306a36Sopenharmony_ci	}
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci	sack_ctsn = ntohl(sack->cum_tsn_ack);
127462306a36Sopenharmony_ci	gap_ack_blocks = ntohs(sack->num_gap_ack_blocks);
127562306a36Sopenharmony_ci	asoc->stats.gapcnt += gap_ack_blocks;
127662306a36Sopenharmony_ci	/*
127762306a36Sopenharmony_ci	 * SFR-CACC algorithm:
127862306a36Sopenharmony_ci	 * On receipt of a SACK the sender SHOULD execute the
127962306a36Sopenharmony_ci	 * following statements.
128062306a36Sopenharmony_ci	 *
128162306a36Sopenharmony_ci	 * 1) If the cumulative ack in the SACK passes next tsn_at_change
128262306a36Sopenharmony_ci	 * on the current primary, the CHANGEOVER_ACTIVE flag SHOULD be
128362306a36Sopenharmony_ci	 * cleared. The CYCLING_CHANGEOVER flag SHOULD also be cleared for
128462306a36Sopenharmony_ci	 * all destinations.
128562306a36Sopenharmony_ci	 * 2) If the SACK contains gap acks and the flag CHANGEOVER_ACTIVE
128662306a36Sopenharmony_ci	 * is set the receiver of the SACK MUST take the following actions:
128762306a36Sopenharmony_ci	 *
128862306a36Sopenharmony_ci	 * A) Initialize the cacc_saw_newack to 0 for all destination
128962306a36Sopenharmony_ci	 * addresses.
129062306a36Sopenharmony_ci	 *
129162306a36Sopenharmony_ci	 * Only bother if changeover_active is set. Otherwise, this is
129262306a36Sopenharmony_ci	 * totally suboptimal to do on every SACK.
129362306a36Sopenharmony_ci	 */
129462306a36Sopenharmony_ci	if (primary->cacc.changeover_active) {
129562306a36Sopenharmony_ci		u8 clear_cycling = 0;
129662306a36Sopenharmony_ci
129762306a36Sopenharmony_ci		if (TSN_lte(primary->cacc.next_tsn_at_change, sack_ctsn)) {
129862306a36Sopenharmony_ci			primary->cacc.changeover_active = 0;
129962306a36Sopenharmony_ci			clear_cycling = 1;
130062306a36Sopenharmony_ci		}
130162306a36Sopenharmony_ci
130262306a36Sopenharmony_ci		if (clear_cycling || gap_ack_blocks) {
130362306a36Sopenharmony_ci			list_for_each_entry(transport, transport_list,
130462306a36Sopenharmony_ci					transports) {
130562306a36Sopenharmony_ci				if (clear_cycling)
130662306a36Sopenharmony_ci					transport->cacc.cycling_changeover = 0;
130762306a36Sopenharmony_ci				if (gap_ack_blocks)
130862306a36Sopenharmony_ci					transport->cacc.cacc_saw_newack = 0;
130962306a36Sopenharmony_ci			}
131062306a36Sopenharmony_ci		}
131162306a36Sopenharmony_ci	}
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci	/* Get the highest TSN in the sack. */
131462306a36Sopenharmony_ci	highest_tsn = sack_ctsn;
131562306a36Sopenharmony_ci	if (gap_ack_blocks) {
131662306a36Sopenharmony_ci		union sctp_sack_variable *frags =
131762306a36Sopenharmony_ci			(union sctp_sack_variable *)(sack + 1);
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ci		highest_tsn += ntohs(frags[gap_ack_blocks - 1].gab.end);
132062306a36Sopenharmony_ci	}
132162306a36Sopenharmony_ci
132262306a36Sopenharmony_ci	if (TSN_lt(asoc->highest_sacked, highest_tsn))
132362306a36Sopenharmony_ci		asoc->highest_sacked = highest_tsn;
132462306a36Sopenharmony_ci
132562306a36Sopenharmony_ci	highest_new_tsn = sack_ctsn;
132662306a36Sopenharmony_ci
132762306a36Sopenharmony_ci	/* Run through the retransmit queue.  Credit bytes received
132862306a36Sopenharmony_ci	 * and free those chunks that we can.
132962306a36Sopenharmony_ci	 */
133062306a36Sopenharmony_ci	sctp_check_transmitted(q, &q->retransmit, NULL, NULL, sack, &highest_new_tsn);
133162306a36Sopenharmony_ci
133262306a36Sopenharmony_ci	/* Run through the transmitted queue.
133362306a36Sopenharmony_ci	 * Credit bytes received and free those chunks which we can.
133462306a36Sopenharmony_ci	 *
133562306a36Sopenharmony_ci	 * This is a MASSIVE candidate for optimization.
133662306a36Sopenharmony_ci	 */
133762306a36Sopenharmony_ci	list_for_each_entry(transport, transport_list, transports) {
133862306a36Sopenharmony_ci		sctp_check_transmitted(q, &transport->transmitted,
133962306a36Sopenharmony_ci				       transport, &chunk->source, sack,
134062306a36Sopenharmony_ci				       &highest_new_tsn);
134162306a36Sopenharmony_ci		/*
134262306a36Sopenharmony_ci		 * SFR-CACC algorithm:
134362306a36Sopenharmony_ci		 * C) Let count_of_newacks be the number of
134462306a36Sopenharmony_ci		 * destinations for which cacc_saw_newack is set.
134562306a36Sopenharmony_ci		 */
134662306a36Sopenharmony_ci		if (transport->cacc.cacc_saw_newack)
134762306a36Sopenharmony_ci			count_of_newacks++;
134862306a36Sopenharmony_ci	}
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_ci	/* Move the Cumulative TSN Ack Point if appropriate.  */
135162306a36Sopenharmony_ci	if (TSN_lt(asoc->ctsn_ack_point, sack_ctsn)) {
135262306a36Sopenharmony_ci		asoc->ctsn_ack_point = sack_ctsn;
135362306a36Sopenharmony_ci		accum_moved = 1;
135462306a36Sopenharmony_ci	}
135562306a36Sopenharmony_ci
135662306a36Sopenharmony_ci	if (gap_ack_blocks) {
135762306a36Sopenharmony_ci
135862306a36Sopenharmony_ci		if (asoc->fast_recovery && accum_moved)
135962306a36Sopenharmony_ci			highest_new_tsn = highest_tsn;
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_ci		list_for_each_entry(transport, transport_list, transports)
136262306a36Sopenharmony_ci			sctp_mark_missing(q, &transport->transmitted, transport,
136362306a36Sopenharmony_ci					  highest_new_tsn, count_of_newacks);
136462306a36Sopenharmony_ci	}
136562306a36Sopenharmony_ci
136662306a36Sopenharmony_ci	/* Update unack_data field in the assoc. */
136762306a36Sopenharmony_ci	sctp_sack_update_unack_data(asoc, sack);
136862306a36Sopenharmony_ci
136962306a36Sopenharmony_ci	ctsn = asoc->ctsn_ack_point;
137062306a36Sopenharmony_ci
137162306a36Sopenharmony_ci	/* Throw away stuff rotting on the sack queue.  */
137262306a36Sopenharmony_ci	list_for_each_safe(lchunk, temp, &q->sacked) {
137362306a36Sopenharmony_ci		tchunk = list_entry(lchunk, struct sctp_chunk,
137462306a36Sopenharmony_ci				    transmitted_list);
137562306a36Sopenharmony_ci		tsn = ntohl(tchunk->subh.data_hdr->tsn);
137662306a36Sopenharmony_ci		if (TSN_lte(tsn, ctsn)) {
137762306a36Sopenharmony_ci			list_del_init(&tchunk->transmitted_list);
137862306a36Sopenharmony_ci			if (asoc->peer.prsctp_capable &&
137962306a36Sopenharmony_ci			    SCTP_PR_PRIO_ENABLED(chunk->sinfo.sinfo_flags))
138062306a36Sopenharmony_ci				asoc->sent_cnt_removable--;
138162306a36Sopenharmony_ci			sctp_chunk_free(tchunk);
138262306a36Sopenharmony_ci		}
138362306a36Sopenharmony_ci	}
138462306a36Sopenharmony_ci
138562306a36Sopenharmony_ci	/* ii) Set rwnd equal to the newly received a_rwnd minus the
138662306a36Sopenharmony_ci	 *     number of bytes still outstanding after processing the
138762306a36Sopenharmony_ci	 *     Cumulative TSN Ack and the Gap Ack Blocks.
138862306a36Sopenharmony_ci	 */
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ci	sack_a_rwnd = ntohl(sack->a_rwnd);
139162306a36Sopenharmony_ci	asoc->peer.zero_window_announced = !sack_a_rwnd;
139262306a36Sopenharmony_ci	outstanding = q->outstanding_bytes;
139362306a36Sopenharmony_ci
139462306a36Sopenharmony_ci	if (outstanding < sack_a_rwnd)
139562306a36Sopenharmony_ci		sack_a_rwnd -= outstanding;
139662306a36Sopenharmony_ci	else
139762306a36Sopenharmony_ci		sack_a_rwnd = 0;
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_ci	asoc->peer.rwnd = sack_a_rwnd;
140062306a36Sopenharmony_ci
140162306a36Sopenharmony_ci	asoc->stream.si->generate_ftsn(q, sack_ctsn);
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci	pr_debug("%s: sack cumulative tsn ack:0x%x\n", __func__, sack_ctsn);
140462306a36Sopenharmony_ci	pr_debug("%s: cumulative tsn ack of assoc:%p is 0x%x, "
140562306a36Sopenharmony_ci		 "advertised peer ack point:0x%x\n", __func__, asoc, ctsn,
140662306a36Sopenharmony_ci		 asoc->adv_peer_ack_point);
140762306a36Sopenharmony_ci
140862306a36Sopenharmony_ci	return sctp_outq_is_empty(q);
140962306a36Sopenharmony_ci}
141062306a36Sopenharmony_ci
141162306a36Sopenharmony_ci/* Is the outqueue empty?
141262306a36Sopenharmony_ci * The queue is empty when we have not pending data, no in-flight data
141362306a36Sopenharmony_ci * and nothing pending retransmissions.
141462306a36Sopenharmony_ci */
141562306a36Sopenharmony_ciint sctp_outq_is_empty(const struct sctp_outq *q)
141662306a36Sopenharmony_ci{
141762306a36Sopenharmony_ci	return q->out_qlen == 0 && q->outstanding_bytes == 0 &&
141862306a36Sopenharmony_ci	       list_empty(&q->retransmit);
141962306a36Sopenharmony_ci}
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_ci/********************************************************************
142262306a36Sopenharmony_ci * 2nd Level Abstractions
142362306a36Sopenharmony_ci ********************************************************************/
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_ci/* Go through a transport's transmitted list or the association's retransmit
142662306a36Sopenharmony_ci * list and move chunks that are acked by the Cumulative TSN Ack to q->sacked.
142762306a36Sopenharmony_ci * The retransmit list will not have an associated transport.
142862306a36Sopenharmony_ci *
142962306a36Sopenharmony_ci * I added coherent debug information output.	--xguo
143062306a36Sopenharmony_ci *
143162306a36Sopenharmony_ci * Instead of printing 'sacked' or 'kept' for each TSN on the
143262306a36Sopenharmony_ci * transmitted_queue, we print a range: SACKED: TSN1-TSN2, TSN3, TSN4-TSN5.
143362306a36Sopenharmony_ci * KEPT TSN6-TSN7, etc.
143462306a36Sopenharmony_ci */
143562306a36Sopenharmony_cistatic void sctp_check_transmitted(struct sctp_outq *q,
143662306a36Sopenharmony_ci				   struct list_head *transmitted_queue,
143762306a36Sopenharmony_ci				   struct sctp_transport *transport,
143862306a36Sopenharmony_ci				   union sctp_addr *saddr,
143962306a36Sopenharmony_ci				   struct sctp_sackhdr *sack,
144062306a36Sopenharmony_ci				   __u32 *highest_new_tsn_in_sack)
144162306a36Sopenharmony_ci{
144262306a36Sopenharmony_ci	struct list_head *lchunk;
144362306a36Sopenharmony_ci	struct sctp_chunk *tchunk;
144462306a36Sopenharmony_ci	struct list_head tlist;
144562306a36Sopenharmony_ci	__u32 tsn;
144662306a36Sopenharmony_ci	__u32 sack_ctsn;
144762306a36Sopenharmony_ci	__u32 rtt;
144862306a36Sopenharmony_ci	__u8 restart_timer = 0;
144962306a36Sopenharmony_ci	int bytes_acked = 0;
145062306a36Sopenharmony_ci	int migrate_bytes = 0;
145162306a36Sopenharmony_ci	bool forward_progress = false;
145262306a36Sopenharmony_ci
145362306a36Sopenharmony_ci	sack_ctsn = ntohl(sack->cum_tsn_ack);
145462306a36Sopenharmony_ci
145562306a36Sopenharmony_ci	INIT_LIST_HEAD(&tlist);
145662306a36Sopenharmony_ci
145762306a36Sopenharmony_ci	/* The while loop will skip empty transmitted queues. */
145862306a36Sopenharmony_ci	while (NULL != (lchunk = sctp_list_dequeue(transmitted_queue))) {
145962306a36Sopenharmony_ci		tchunk = list_entry(lchunk, struct sctp_chunk,
146062306a36Sopenharmony_ci				    transmitted_list);
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ci		if (sctp_chunk_abandoned(tchunk)) {
146362306a36Sopenharmony_ci			/* Move the chunk to abandoned list. */
146462306a36Sopenharmony_ci			sctp_insert_list(&q->abandoned, lchunk);
146562306a36Sopenharmony_ci
146662306a36Sopenharmony_ci			/* If this chunk has not been acked, stop
146762306a36Sopenharmony_ci			 * considering it as 'outstanding'.
146862306a36Sopenharmony_ci			 */
146962306a36Sopenharmony_ci			if (transmitted_queue != &q->retransmit &&
147062306a36Sopenharmony_ci			    !tchunk->tsn_gap_acked) {
147162306a36Sopenharmony_ci				if (tchunk->transport)
147262306a36Sopenharmony_ci					tchunk->transport->flight_size -=
147362306a36Sopenharmony_ci							sctp_data_size(tchunk);
147462306a36Sopenharmony_ci				q->outstanding_bytes -= sctp_data_size(tchunk);
147562306a36Sopenharmony_ci			}
147662306a36Sopenharmony_ci			continue;
147762306a36Sopenharmony_ci		}
147862306a36Sopenharmony_ci
147962306a36Sopenharmony_ci		tsn = ntohl(tchunk->subh.data_hdr->tsn);
148062306a36Sopenharmony_ci		if (sctp_acked(sack, tsn)) {
148162306a36Sopenharmony_ci			/* If this queue is the retransmit queue, the
148262306a36Sopenharmony_ci			 * retransmit timer has already reclaimed
148362306a36Sopenharmony_ci			 * the outstanding bytes for this chunk, so only
148462306a36Sopenharmony_ci			 * count bytes associated with a transport.
148562306a36Sopenharmony_ci			 */
148662306a36Sopenharmony_ci			if (transport && !tchunk->tsn_gap_acked) {
148762306a36Sopenharmony_ci				/* If this chunk is being used for RTT
148862306a36Sopenharmony_ci				 * measurement, calculate the RTT and update
148962306a36Sopenharmony_ci				 * the RTO using this value.
149062306a36Sopenharmony_ci				 *
149162306a36Sopenharmony_ci				 * 6.3.1 C5) Karn's algorithm: RTT measurements
149262306a36Sopenharmony_ci				 * MUST NOT be made using packets that were
149362306a36Sopenharmony_ci				 * retransmitted (and thus for which it is
149462306a36Sopenharmony_ci				 * ambiguous whether the reply was for the
149562306a36Sopenharmony_ci				 * first instance of the packet or a later
149662306a36Sopenharmony_ci				 * instance).
149762306a36Sopenharmony_ci				 */
149862306a36Sopenharmony_ci				if (!sctp_chunk_retransmitted(tchunk) &&
149962306a36Sopenharmony_ci				    tchunk->rtt_in_progress) {
150062306a36Sopenharmony_ci					tchunk->rtt_in_progress = 0;
150162306a36Sopenharmony_ci					rtt = jiffies - tchunk->sent_at;
150262306a36Sopenharmony_ci					sctp_transport_update_rto(transport,
150362306a36Sopenharmony_ci								  rtt);
150462306a36Sopenharmony_ci				}
150562306a36Sopenharmony_ci
150662306a36Sopenharmony_ci				if (TSN_lte(tsn, sack_ctsn)) {
150762306a36Sopenharmony_ci					/*
150862306a36Sopenharmony_ci					 * SFR-CACC algorithm:
150962306a36Sopenharmony_ci					 * 2) If the SACK contains gap acks
151062306a36Sopenharmony_ci					 * and the flag CHANGEOVER_ACTIVE is
151162306a36Sopenharmony_ci					 * set the receiver of the SACK MUST
151262306a36Sopenharmony_ci					 * take the following action:
151362306a36Sopenharmony_ci					 *
151462306a36Sopenharmony_ci					 * B) For each TSN t being acked that
151562306a36Sopenharmony_ci					 * has not been acked in any SACK so
151662306a36Sopenharmony_ci					 * far, set cacc_saw_newack to 1 for
151762306a36Sopenharmony_ci					 * the destination that the TSN was
151862306a36Sopenharmony_ci					 * sent to.
151962306a36Sopenharmony_ci					 */
152062306a36Sopenharmony_ci					if (sack->num_gap_ack_blocks &&
152162306a36Sopenharmony_ci					    q->asoc->peer.primary_path->cacc.
152262306a36Sopenharmony_ci					    changeover_active)
152362306a36Sopenharmony_ci						transport->cacc.cacc_saw_newack
152462306a36Sopenharmony_ci							= 1;
152562306a36Sopenharmony_ci				}
152662306a36Sopenharmony_ci			}
152762306a36Sopenharmony_ci
152862306a36Sopenharmony_ci			/* If the chunk hasn't been marked as ACKED,
152962306a36Sopenharmony_ci			 * mark it and account bytes_acked if the
153062306a36Sopenharmony_ci			 * chunk had a valid transport (it will not
153162306a36Sopenharmony_ci			 * have a transport if ASCONF had deleted it
153262306a36Sopenharmony_ci			 * while DATA was outstanding).
153362306a36Sopenharmony_ci			 */
153462306a36Sopenharmony_ci			if (!tchunk->tsn_gap_acked) {
153562306a36Sopenharmony_ci				tchunk->tsn_gap_acked = 1;
153662306a36Sopenharmony_ci				if (TSN_lt(*highest_new_tsn_in_sack, tsn))
153762306a36Sopenharmony_ci					*highest_new_tsn_in_sack = tsn;
153862306a36Sopenharmony_ci				bytes_acked += sctp_data_size(tchunk);
153962306a36Sopenharmony_ci				if (!tchunk->transport)
154062306a36Sopenharmony_ci					migrate_bytes += sctp_data_size(tchunk);
154162306a36Sopenharmony_ci				forward_progress = true;
154262306a36Sopenharmony_ci			}
154362306a36Sopenharmony_ci
154462306a36Sopenharmony_ci			if (TSN_lte(tsn, sack_ctsn)) {
154562306a36Sopenharmony_ci				/* RFC 2960  6.3.2 Retransmission Timer Rules
154662306a36Sopenharmony_ci				 *
154762306a36Sopenharmony_ci				 * R3) Whenever a SACK is received
154862306a36Sopenharmony_ci				 * that acknowledges the DATA chunk
154962306a36Sopenharmony_ci				 * with the earliest outstanding TSN
155062306a36Sopenharmony_ci				 * for that address, restart T3-rtx
155162306a36Sopenharmony_ci				 * timer for that address with its
155262306a36Sopenharmony_ci				 * current RTO.
155362306a36Sopenharmony_ci				 */
155462306a36Sopenharmony_ci				restart_timer = 1;
155562306a36Sopenharmony_ci				forward_progress = true;
155662306a36Sopenharmony_ci
155762306a36Sopenharmony_ci				list_add_tail(&tchunk->transmitted_list,
155862306a36Sopenharmony_ci					      &q->sacked);
155962306a36Sopenharmony_ci			} else {
156062306a36Sopenharmony_ci				/* RFC2960 7.2.4, sctpimpguide-05 2.8.2
156162306a36Sopenharmony_ci				 * M2) Each time a SACK arrives reporting
156262306a36Sopenharmony_ci				 * 'Stray DATA chunk(s)' record the highest TSN
156362306a36Sopenharmony_ci				 * reported as newly acknowledged, call this
156462306a36Sopenharmony_ci				 * value 'HighestTSNinSack'. A newly
156562306a36Sopenharmony_ci				 * acknowledged DATA chunk is one not
156662306a36Sopenharmony_ci				 * previously acknowledged in a SACK.
156762306a36Sopenharmony_ci				 *
156862306a36Sopenharmony_ci				 * When the SCTP sender of data receives a SACK
156962306a36Sopenharmony_ci				 * chunk that acknowledges, for the first time,
157062306a36Sopenharmony_ci				 * the receipt of a DATA chunk, all the still
157162306a36Sopenharmony_ci				 * unacknowledged DATA chunks whose TSN is
157262306a36Sopenharmony_ci				 * older than that newly acknowledged DATA
157362306a36Sopenharmony_ci				 * chunk, are qualified as 'Stray DATA chunks'.
157462306a36Sopenharmony_ci				 */
157562306a36Sopenharmony_ci				list_add_tail(lchunk, &tlist);
157662306a36Sopenharmony_ci			}
157762306a36Sopenharmony_ci		} else {
157862306a36Sopenharmony_ci			if (tchunk->tsn_gap_acked) {
157962306a36Sopenharmony_ci				pr_debug("%s: receiver reneged on data TSN:0x%x\n",
158062306a36Sopenharmony_ci					 __func__, tsn);
158162306a36Sopenharmony_ci
158262306a36Sopenharmony_ci				tchunk->tsn_gap_acked = 0;
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci				if (tchunk->transport)
158562306a36Sopenharmony_ci					bytes_acked -= sctp_data_size(tchunk);
158662306a36Sopenharmony_ci
158762306a36Sopenharmony_ci				/* RFC 2960 6.3.2 Retransmission Timer Rules
158862306a36Sopenharmony_ci				 *
158962306a36Sopenharmony_ci				 * R4) Whenever a SACK is received missing a
159062306a36Sopenharmony_ci				 * TSN that was previously acknowledged via a
159162306a36Sopenharmony_ci				 * Gap Ack Block, start T3-rtx for the
159262306a36Sopenharmony_ci				 * destination address to which the DATA
159362306a36Sopenharmony_ci				 * chunk was originally
159462306a36Sopenharmony_ci				 * transmitted if it is not already running.
159562306a36Sopenharmony_ci				 */
159662306a36Sopenharmony_ci				restart_timer = 1;
159762306a36Sopenharmony_ci			}
159862306a36Sopenharmony_ci
159962306a36Sopenharmony_ci			list_add_tail(lchunk, &tlist);
160062306a36Sopenharmony_ci		}
160162306a36Sopenharmony_ci	}
160262306a36Sopenharmony_ci
160362306a36Sopenharmony_ci	if (transport) {
160462306a36Sopenharmony_ci		if (bytes_acked) {
160562306a36Sopenharmony_ci			struct sctp_association *asoc = transport->asoc;
160662306a36Sopenharmony_ci
160762306a36Sopenharmony_ci			/* We may have counted DATA that was migrated
160862306a36Sopenharmony_ci			 * to this transport due to DEL-IP operation.
160962306a36Sopenharmony_ci			 * Subtract those bytes, since the were never
161062306a36Sopenharmony_ci			 * send on this transport and shouldn't be
161162306a36Sopenharmony_ci			 * credited to this transport.
161262306a36Sopenharmony_ci			 */
161362306a36Sopenharmony_ci			bytes_acked -= migrate_bytes;
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_ci			/* 8.2. When an outstanding TSN is acknowledged,
161662306a36Sopenharmony_ci			 * the endpoint shall clear the error counter of
161762306a36Sopenharmony_ci			 * the destination transport address to which the
161862306a36Sopenharmony_ci			 * DATA chunk was last sent.
161962306a36Sopenharmony_ci			 * The association's overall error counter is
162062306a36Sopenharmony_ci			 * also cleared.
162162306a36Sopenharmony_ci			 */
162262306a36Sopenharmony_ci			transport->error_count = 0;
162362306a36Sopenharmony_ci			transport->asoc->overall_error_count = 0;
162462306a36Sopenharmony_ci			forward_progress = true;
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ci			/*
162762306a36Sopenharmony_ci			 * While in SHUTDOWN PENDING, we may have started
162862306a36Sopenharmony_ci			 * the T5 shutdown guard timer after reaching the
162962306a36Sopenharmony_ci			 * retransmission limit. Stop that timer as soon
163062306a36Sopenharmony_ci			 * as the receiver acknowledged any data.
163162306a36Sopenharmony_ci			 */
163262306a36Sopenharmony_ci			if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING &&
163362306a36Sopenharmony_ci			    del_timer(&asoc->timers
163462306a36Sopenharmony_ci				[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD]))
163562306a36Sopenharmony_ci					sctp_association_put(asoc);
163662306a36Sopenharmony_ci
163762306a36Sopenharmony_ci			/* Mark the destination transport address as
163862306a36Sopenharmony_ci			 * active if it is not so marked.
163962306a36Sopenharmony_ci			 */
164062306a36Sopenharmony_ci			if ((transport->state == SCTP_INACTIVE ||
164162306a36Sopenharmony_ci			     transport->state == SCTP_UNCONFIRMED) &&
164262306a36Sopenharmony_ci			    sctp_cmp_addr_exact(&transport->ipaddr, saddr)) {
164362306a36Sopenharmony_ci				sctp_assoc_control_transport(
164462306a36Sopenharmony_ci					transport->asoc,
164562306a36Sopenharmony_ci					transport,
164662306a36Sopenharmony_ci					SCTP_TRANSPORT_UP,
164762306a36Sopenharmony_ci					SCTP_RECEIVED_SACK);
164862306a36Sopenharmony_ci			}
164962306a36Sopenharmony_ci
165062306a36Sopenharmony_ci			sctp_transport_raise_cwnd(transport, sack_ctsn,
165162306a36Sopenharmony_ci						  bytes_acked);
165262306a36Sopenharmony_ci
165362306a36Sopenharmony_ci			transport->flight_size -= bytes_acked;
165462306a36Sopenharmony_ci			if (transport->flight_size == 0)
165562306a36Sopenharmony_ci				transport->partial_bytes_acked = 0;
165662306a36Sopenharmony_ci			q->outstanding_bytes -= bytes_acked + migrate_bytes;
165762306a36Sopenharmony_ci		} else {
165862306a36Sopenharmony_ci			/* RFC 2960 6.1, sctpimpguide-06 2.15.2
165962306a36Sopenharmony_ci			 * When a sender is doing zero window probing, it
166062306a36Sopenharmony_ci			 * should not timeout the association if it continues
166162306a36Sopenharmony_ci			 * to receive new packets from the receiver. The
166262306a36Sopenharmony_ci			 * reason is that the receiver MAY keep its window
166362306a36Sopenharmony_ci			 * closed for an indefinite time.
166462306a36Sopenharmony_ci			 * A sender is doing zero window probing when the
166562306a36Sopenharmony_ci			 * receiver's advertised window is zero, and there is
166662306a36Sopenharmony_ci			 * only one data chunk in flight to the receiver.
166762306a36Sopenharmony_ci			 *
166862306a36Sopenharmony_ci			 * Allow the association to timeout while in SHUTDOWN
166962306a36Sopenharmony_ci			 * PENDING or SHUTDOWN RECEIVED in case the receiver
167062306a36Sopenharmony_ci			 * stays in zero window mode forever.
167162306a36Sopenharmony_ci			 */
167262306a36Sopenharmony_ci			if (!q->asoc->peer.rwnd &&
167362306a36Sopenharmony_ci			    !list_empty(&tlist) &&
167462306a36Sopenharmony_ci			    (sack_ctsn+2 == q->asoc->next_tsn) &&
167562306a36Sopenharmony_ci			    q->asoc->state < SCTP_STATE_SHUTDOWN_PENDING) {
167662306a36Sopenharmony_ci				pr_debug("%s: sack received for zero window "
167762306a36Sopenharmony_ci					 "probe:%u\n", __func__, sack_ctsn);
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_ci				q->asoc->overall_error_count = 0;
168062306a36Sopenharmony_ci				transport->error_count = 0;
168162306a36Sopenharmony_ci			}
168262306a36Sopenharmony_ci		}
168362306a36Sopenharmony_ci
168462306a36Sopenharmony_ci		/* RFC 2960 6.3.2 Retransmission Timer Rules
168562306a36Sopenharmony_ci		 *
168662306a36Sopenharmony_ci		 * R2) Whenever all outstanding data sent to an address have
168762306a36Sopenharmony_ci		 * been acknowledged, turn off the T3-rtx timer of that
168862306a36Sopenharmony_ci		 * address.
168962306a36Sopenharmony_ci		 */
169062306a36Sopenharmony_ci		if (!transport->flight_size) {
169162306a36Sopenharmony_ci			if (del_timer(&transport->T3_rtx_timer))
169262306a36Sopenharmony_ci				sctp_transport_put(transport);
169362306a36Sopenharmony_ci		} else if (restart_timer) {
169462306a36Sopenharmony_ci			if (!mod_timer(&transport->T3_rtx_timer,
169562306a36Sopenharmony_ci				       jiffies + transport->rto))
169662306a36Sopenharmony_ci				sctp_transport_hold(transport);
169762306a36Sopenharmony_ci		}
169862306a36Sopenharmony_ci
169962306a36Sopenharmony_ci		if (forward_progress) {
170062306a36Sopenharmony_ci			if (transport->dst)
170162306a36Sopenharmony_ci				sctp_transport_dst_confirm(transport);
170262306a36Sopenharmony_ci		}
170362306a36Sopenharmony_ci	}
170462306a36Sopenharmony_ci
170562306a36Sopenharmony_ci	list_splice(&tlist, transmitted_queue);
170662306a36Sopenharmony_ci}
170762306a36Sopenharmony_ci
170862306a36Sopenharmony_ci/* Mark chunks as missing and consequently may get retransmitted. */
170962306a36Sopenharmony_cistatic void sctp_mark_missing(struct sctp_outq *q,
171062306a36Sopenharmony_ci			      struct list_head *transmitted_queue,
171162306a36Sopenharmony_ci			      struct sctp_transport *transport,
171262306a36Sopenharmony_ci			      __u32 highest_new_tsn_in_sack,
171362306a36Sopenharmony_ci			      int count_of_newacks)
171462306a36Sopenharmony_ci{
171562306a36Sopenharmony_ci	struct sctp_chunk *chunk;
171662306a36Sopenharmony_ci	__u32 tsn;
171762306a36Sopenharmony_ci	char do_fast_retransmit = 0;
171862306a36Sopenharmony_ci	struct sctp_association *asoc = q->asoc;
171962306a36Sopenharmony_ci	struct sctp_transport *primary = asoc->peer.primary_path;
172062306a36Sopenharmony_ci
172162306a36Sopenharmony_ci	list_for_each_entry(chunk, transmitted_queue, transmitted_list) {
172262306a36Sopenharmony_ci
172362306a36Sopenharmony_ci		tsn = ntohl(chunk->subh.data_hdr->tsn);
172462306a36Sopenharmony_ci
172562306a36Sopenharmony_ci		/* RFC 2960 7.2.4, sctpimpguide-05 2.8.2 M3) Examine all
172662306a36Sopenharmony_ci		 * 'Unacknowledged TSN's', if the TSN number of an
172762306a36Sopenharmony_ci		 * 'Unacknowledged TSN' is smaller than the 'HighestTSNinSack'
172862306a36Sopenharmony_ci		 * value, increment the 'TSN.Missing.Report' count on that
172962306a36Sopenharmony_ci		 * chunk if it has NOT been fast retransmitted or marked for
173062306a36Sopenharmony_ci		 * fast retransmit already.
173162306a36Sopenharmony_ci		 */
173262306a36Sopenharmony_ci		if (chunk->fast_retransmit == SCTP_CAN_FRTX &&
173362306a36Sopenharmony_ci		    !chunk->tsn_gap_acked &&
173462306a36Sopenharmony_ci		    TSN_lt(tsn, highest_new_tsn_in_sack)) {
173562306a36Sopenharmony_ci
173662306a36Sopenharmony_ci			/* SFR-CACC may require us to skip marking
173762306a36Sopenharmony_ci			 * this chunk as missing.
173862306a36Sopenharmony_ci			 */
173962306a36Sopenharmony_ci			if (!transport || !sctp_cacc_skip(primary,
174062306a36Sopenharmony_ci						chunk->transport,
174162306a36Sopenharmony_ci						count_of_newacks, tsn)) {
174262306a36Sopenharmony_ci				chunk->tsn_missing_report++;
174362306a36Sopenharmony_ci
174462306a36Sopenharmony_ci				pr_debug("%s: tsn:0x%x missing counter:%d\n",
174562306a36Sopenharmony_ci					 __func__, tsn, chunk->tsn_missing_report);
174662306a36Sopenharmony_ci			}
174762306a36Sopenharmony_ci		}
174862306a36Sopenharmony_ci		/*
174962306a36Sopenharmony_ci		 * M4) If any DATA chunk is found to have a
175062306a36Sopenharmony_ci		 * 'TSN.Missing.Report'
175162306a36Sopenharmony_ci		 * value larger than or equal to 3, mark that chunk for
175262306a36Sopenharmony_ci		 * retransmission and start the fast retransmit procedure.
175362306a36Sopenharmony_ci		 */
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_ci		if (chunk->tsn_missing_report >= 3) {
175662306a36Sopenharmony_ci			chunk->fast_retransmit = SCTP_NEED_FRTX;
175762306a36Sopenharmony_ci			do_fast_retransmit = 1;
175862306a36Sopenharmony_ci		}
175962306a36Sopenharmony_ci	}
176062306a36Sopenharmony_ci
176162306a36Sopenharmony_ci	if (transport) {
176262306a36Sopenharmony_ci		if (do_fast_retransmit)
176362306a36Sopenharmony_ci			sctp_retransmit(q, transport, SCTP_RTXR_FAST_RTX);
176462306a36Sopenharmony_ci
176562306a36Sopenharmony_ci		pr_debug("%s: transport:%p, cwnd:%d, ssthresh:%d, "
176662306a36Sopenharmony_ci			 "flight_size:%d, pba:%d\n",  __func__, transport,
176762306a36Sopenharmony_ci			 transport->cwnd, transport->ssthresh,
176862306a36Sopenharmony_ci			 transport->flight_size, transport->partial_bytes_acked);
176962306a36Sopenharmony_ci	}
177062306a36Sopenharmony_ci}
177162306a36Sopenharmony_ci
177262306a36Sopenharmony_ci/* Is the given TSN acked by this packet?  */
177362306a36Sopenharmony_cistatic int sctp_acked(struct sctp_sackhdr *sack, __u32 tsn)
177462306a36Sopenharmony_ci{
177562306a36Sopenharmony_ci	__u32 ctsn = ntohl(sack->cum_tsn_ack);
177662306a36Sopenharmony_ci	union sctp_sack_variable *frags;
177762306a36Sopenharmony_ci	__u16 tsn_offset, blocks;
177862306a36Sopenharmony_ci	int i;
177962306a36Sopenharmony_ci
178062306a36Sopenharmony_ci	if (TSN_lte(tsn, ctsn))
178162306a36Sopenharmony_ci		goto pass;
178262306a36Sopenharmony_ci
178362306a36Sopenharmony_ci	/* 3.3.4 Selective Acknowledgment (SACK) (3):
178462306a36Sopenharmony_ci	 *
178562306a36Sopenharmony_ci	 * Gap Ack Blocks:
178662306a36Sopenharmony_ci	 *  These fields contain the Gap Ack Blocks. They are repeated
178762306a36Sopenharmony_ci	 *  for each Gap Ack Block up to the number of Gap Ack Blocks
178862306a36Sopenharmony_ci	 *  defined in the Number of Gap Ack Blocks field. All DATA
178962306a36Sopenharmony_ci	 *  chunks with TSNs greater than or equal to (Cumulative TSN
179062306a36Sopenharmony_ci	 *  Ack + Gap Ack Block Start) and less than or equal to
179162306a36Sopenharmony_ci	 *  (Cumulative TSN Ack + Gap Ack Block End) of each Gap Ack
179262306a36Sopenharmony_ci	 *  Block are assumed to have been received correctly.
179362306a36Sopenharmony_ci	 */
179462306a36Sopenharmony_ci
179562306a36Sopenharmony_ci	frags = (union sctp_sack_variable *)(sack + 1);
179662306a36Sopenharmony_ci	blocks = ntohs(sack->num_gap_ack_blocks);
179762306a36Sopenharmony_ci	tsn_offset = tsn - ctsn;
179862306a36Sopenharmony_ci	for (i = 0; i < blocks; ++i) {
179962306a36Sopenharmony_ci		if (tsn_offset >= ntohs(frags[i].gab.start) &&
180062306a36Sopenharmony_ci		    tsn_offset <= ntohs(frags[i].gab.end))
180162306a36Sopenharmony_ci			goto pass;
180262306a36Sopenharmony_ci	}
180362306a36Sopenharmony_ci
180462306a36Sopenharmony_ci	return 0;
180562306a36Sopenharmony_cipass:
180662306a36Sopenharmony_ci	return 1;
180762306a36Sopenharmony_ci}
180862306a36Sopenharmony_ci
180962306a36Sopenharmony_cistatic inline int sctp_get_skip_pos(struct sctp_fwdtsn_skip *skiplist,
181062306a36Sopenharmony_ci				    int nskips, __be16 stream)
181162306a36Sopenharmony_ci{
181262306a36Sopenharmony_ci	int i;
181362306a36Sopenharmony_ci
181462306a36Sopenharmony_ci	for (i = 0; i < nskips; i++) {
181562306a36Sopenharmony_ci		if (skiplist[i].stream == stream)
181662306a36Sopenharmony_ci			return i;
181762306a36Sopenharmony_ci	}
181862306a36Sopenharmony_ci	return i;
181962306a36Sopenharmony_ci}
182062306a36Sopenharmony_ci
182162306a36Sopenharmony_ci/* Create and add a fwdtsn chunk to the outq's control queue if needed. */
182262306a36Sopenharmony_civoid sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
182362306a36Sopenharmony_ci{
182462306a36Sopenharmony_ci	struct sctp_association *asoc = q->asoc;
182562306a36Sopenharmony_ci	struct sctp_chunk *ftsn_chunk = NULL;
182662306a36Sopenharmony_ci	struct sctp_fwdtsn_skip ftsn_skip_arr[10];
182762306a36Sopenharmony_ci	int nskips = 0;
182862306a36Sopenharmony_ci	int skip_pos = 0;
182962306a36Sopenharmony_ci	__u32 tsn;
183062306a36Sopenharmony_ci	struct sctp_chunk *chunk;
183162306a36Sopenharmony_ci	struct list_head *lchunk, *temp;
183262306a36Sopenharmony_ci
183362306a36Sopenharmony_ci	if (!asoc->peer.prsctp_capable)
183462306a36Sopenharmony_ci		return;
183562306a36Sopenharmony_ci
183662306a36Sopenharmony_ci	/* PR-SCTP C1) Let SackCumAck be the Cumulative TSN ACK carried in the
183762306a36Sopenharmony_ci	 * received SACK.
183862306a36Sopenharmony_ci	 *
183962306a36Sopenharmony_ci	 * If (Advanced.Peer.Ack.Point < SackCumAck), then update
184062306a36Sopenharmony_ci	 * Advanced.Peer.Ack.Point to be equal to SackCumAck.
184162306a36Sopenharmony_ci	 */
184262306a36Sopenharmony_ci	if (TSN_lt(asoc->adv_peer_ack_point, ctsn))
184362306a36Sopenharmony_ci		asoc->adv_peer_ack_point = ctsn;
184462306a36Sopenharmony_ci
184562306a36Sopenharmony_ci	/* PR-SCTP C2) Try to further advance the "Advanced.Peer.Ack.Point"
184662306a36Sopenharmony_ci	 * locally, that is, to move "Advanced.Peer.Ack.Point" up as long as
184762306a36Sopenharmony_ci	 * the chunk next in the out-queue space is marked as "abandoned" as
184862306a36Sopenharmony_ci	 * shown in the following example:
184962306a36Sopenharmony_ci	 *
185062306a36Sopenharmony_ci	 * Assuming that a SACK arrived with the Cumulative TSN ACK 102
185162306a36Sopenharmony_ci	 * and the Advanced.Peer.Ack.Point is updated to this value:
185262306a36Sopenharmony_ci	 *
185362306a36Sopenharmony_ci	 *   out-queue at the end of  ==>   out-queue after Adv.Ack.Point
185462306a36Sopenharmony_ci	 *   normal SACK processing           local advancement
185562306a36Sopenharmony_ci	 *                ...                           ...
185662306a36Sopenharmony_ci	 *   Adv.Ack.Pt-> 102 acked                     102 acked
185762306a36Sopenharmony_ci	 *                103 abandoned                 103 abandoned
185862306a36Sopenharmony_ci	 *                104 abandoned     Adv.Ack.P-> 104 abandoned
185962306a36Sopenharmony_ci	 *                105                           105
186062306a36Sopenharmony_ci	 *                106 acked                     106 acked
186162306a36Sopenharmony_ci	 *                ...                           ...
186262306a36Sopenharmony_ci	 *
186362306a36Sopenharmony_ci	 * In this example, the data sender successfully advanced the
186462306a36Sopenharmony_ci	 * "Advanced.Peer.Ack.Point" from 102 to 104 locally.
186562306a36Sopenharmony_ci	 */
186662306a36Sopenharmony_ci	list_for_each_safe(lchunk, temp, &q->abandoned) {
186762306a36Sopenharmony_ci		chunk = list_entry(lchunk, struct sctp_chunk,
186862306a36Sopenharmony_ci					transmitted_list);
186962306a36Sopenharmony_ci		tsn = ntohl(chunk->subh.data_hdr->tsn);
187062306a36Sopenharmony_ci
187162306a36Sopenharmony_ci		/* Remove any chunks in the abandoned queue that are acked by
187262306a36Sopenharmony_ci		 * the ctsn.
187362306a36Sopenharmony_ci		 */
187462306a36Sopenharmony_ci		if (TSN_lte(tsn, ctsn)) {
187562306a36Sopenharmony_ci			list_del_init(lchunk);
187662306a36Sopenharmony_ci			sctp_chunk_free(chunk);
187762306a36Sopenharmony_ci		} else {
187862306a36Sopenharmony_ci			if (TSN_lte(tsn, asoc->adv_peer_ack_point+1)) {
187962306a36Sopenharmony_ci				asoc->adv_peer_ack_point = tsn;
188062306a36Sopenharmony_ci				if (chunk->chunk_hdr->flags &
188162306a36Sopenharmony_ci					 SCTP_DATA_UNORDERED)
188262306a36Sopenharmony_ci					continue;
188362306a36Sopenharmony_ci				skip_pos = sctp_get_skip_pos(&ftsn_skip_arr[0],
188462306a36Sopenharmony_ci						nskips,
188562306a36Sopenharmony_ci						chunk->subh.data_hdr->stream);
188662306a36Sopenharmony_ci				ftsn_skip_arr[skip_pos].stream =
188762306a36Sopenharmony_ci					chunk->subh.data_hdr->stream;
188862306a36Sopenharmony_ci				ftsn_skip_arr[skip_pos].ssn =
188962306a36Sopenharmony_ci					 chunk->subh.data_hdr->ssn;
189062306a36Sopenharmony_ci				if (skip_pos == nskips)
189162306a36Sopenharmony_ci					nskips++;
189262306a36Sopenharmony_ci				if (nskips == 10)
189362306a36Sopenharmony_ci					break;
189462306a36Sopenharmony_ci			} else
189562306a36Sopenharmony_ci				break;
189662306a36Sopenharmony_ci		}
189762306a36Sopenharmony_ci	}
189862306a36Sopenharmony_ci
189962306a36Sopenharmony_ci	/* PR-SCTP C3) If, after step C1 and C2, the "Advanced.Peer.Ack.Point"
190062306a36Sopenharmony_ci	 * is greater than the Cumulative TSN ACK carried in the received
190162306a36Sopenharmony_ci	 * SACK, the data sender MUST send the data receiver a FORWARD TSN
190262306a36Sopenharmony_ci	 * chunk containing the latest value of the
190362306a36Sopenharmony_ci	 * "Advanced.Peer.Ack.Point".
190462306a36Sopenharmony_ci	 *
190562306a36Sopenharmony_ci	 * C4) For each "abandoned" TSN the sender of the FORWARD TSN SHOULD
190662306a36Sopenharmony_ci	 * list each stream and sequence number in the forwarded TSN. This
190762306a36Sopenharmony_ci	 * information will enable the receiver to easily find any
190862306a36Sopenharmony_ci	 * stranded TSN's waiting on stream reorder queues. Each stream
190962306a36Sopenharmony_ci	 * SHOULD only be reported once; this means that if multiple
191062306a36Sopenharmony_ci	 * abandoned messages occur in the same stream then only the
191162306a36Sopenharmony_ci	 * highest abandoned stream sequence number is reported. If the
191262306a36Sopenharmony_ci	 * total size of the FORWARD TSN does NOT fit in a single MTU then
191362306a36Sopenharmony_ci	 * the sender of the FORWARD TSN SHOULD lower the
191462306a36Sopenharmony_ci	 * Advanced.Peer.Ack.Point to the last TSN that will fit in a
191562306a36Sopenharmony_ci	 * single MTU.
191662306a36Sopenharmony_ci	 */
191762306a36Sopenharmony_ci	if (asoc->adv_peer_ack_point > ctsn)
191862306a36Sopenharmony_ci		ftsn_chunk = sctp_make_fwdtsn(asoc, asoc->adv_peer_ack_point,
191962306a36Sopenharmony_ci					      nskips, &ftsn_skip_arr[0]);
192062306a36Sopenharmony_ci
192162306a36Sopenharmony_ci	if (ftsn_chunk) {
192262306a36Sopenharmony_ci		list_add_tail(&ftsn_chunk->list, &q->control_chunk_list);
192362306a36Sopenharmony_ci		SCTP_INC_STATS(asoc->base.net, SCTP_MIB_OUTCTRLCHUNKS);
192462306a36Sopenharmony_ci	}
192562306a36Sopenharmony_ci}
1926