// SPDX-License-Identifier: GPL-2.0-or-later
/* SCTP kernel implementation
 * (C) Copyright IBM Corp. 2001, 2004
 * Copyright (c) 1999-2000 Cisco, Inc.
 * Copyright (c) 1999-2001 Motorola, Inc.
 *
 * This file is part of the SCTP kernel implementation
 *
 * These functions handle output processing.
 *
 * Please send any bug reports or fixes you make to the
 * email address(es):
 *    lksctp developers <linux-sctp@vger.kernel.org>
 *
 * Written or modified by:
 *    La Monte H.P. Yarroll <piggy@acm.org>
 *    Karl Knutson          <karl@athena.chicago.il.us>
 *    Jon Grimm             <jgrimm@austin.ibm.com>
 *    Sridhar Samudrala     <sri@us.ibm.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/wait.h>
#include <linux/time.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <net/inet_ecn.h>
#include <net/ip.h>
#include <net/icmp.h>
#include <net/net_namespace.h>

#include <linux/socket.h> /* for sa_family_t */
#include <net/sock.h>

#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
#include <net/sctp/checksum.h>

/* Forward declarations for private helpers. */
static enum sctp_xmit __sctp_packet_append_chunk(struct sctp_packet *packet,
						 struct sctp_chunk *chunk);
static enum sctp_xmit sctp_packet_can_append_data(struct sctp_packet *packet,
						  struct sctp_chunk *chunk);
static void sctp_packet_append_data(struct sctp_packet *packet,
				    struct sctp_chunk *chunk);
static enum sctp_xmit sctp_packet_will_fit(struct sctp_packet *packet,
					   struct sctp_chunk *chunk,
					   u16 chunk_len);

static void sctp_packet_reset(struct sctp_packet *packet)
{
	/* sctp_packet_transmit() relies on this to reset size to the
	 * current overhead after sending packets.
	 */
	packet->size = packet->overhead;

	packet->has_cookie_echo = 0;
	packet->has_sack = 0;
	packet->has_data = 0;
	packet->has_auth = 0;
	packet->ipfragok = 0;
	packet->auth = NULL;
}

/* Config a packet.
 * This appears to be a followup set of initializations.
 */
void sctp_packet_config(struct sctp_packet *packet, __u32 vtag,
			int ecn_capable)
{
	struct sctp_transport *tp = packet->transport;
	struct sctp_association *asoc = tp->asoc;
	struct sctp_sock *sp = NULL;
	struct sock *sk;

	pr_debug("%s: packet:%p vtag:0x%x\n", __func__, packet, vtag);
	packet->vtag = vtag;

	/* do the following jobs only once for a flush schedule */
	if (!sctp_packet_empty(packet))
		return;

	/* set packet max_size with pathmtu, then calculate overhead */
	packet->max_size = tp->pathmtu;

	if (asoc) {
		sk = asoc->base.sk;
		sp = sctp_sk(sk);
	}
	packet->overhead = sctp_mtu_payload(sp, 0, 0);
	packet->size = packet->overhead;

	if (!asoc)
		return;

	/* update dst or transport pathmtu if in need */
	if (!sctp_transport_dst_check(tp)) {
		sctp_transport_route(tp, NULL, sp);
		if (asoc->param_flags & SPP_PMTUD_ENABLE)
			sctp_assoc_sync_pmtu(asoc);
	} else if (!sctp_transport_pmtu_check(tp)) {
		if (asoc->param_flags & SPP_PMTUD_ENABLE)
			sctp_assoc_sync_pmtu(asoc);
	}

	if (asoc->pmtu_pending) {
		if (asoc->param_flags & SPP_PMTUD_ENABLE)
			sctp_assoc_sync_pmtu(asoc);
		asoc->pmtu_pending = 0;
	}

	/* If there a is a prepend chunk stick it on the list before
	 * any other chunks get appended.
	 */
	if (ecn_capable) {
		struct sctp_chunk *chunk = sctp_get_ecne_prepend(asoc);

		if (chunk)
			sctp_packet_append_chunk(packet, chunk);
	}

	if (!tp->dst)
		return;

	/* set packet max_size with gso_max_size if gso is enabled*/
	rcu_read_lock();
	if (__sk_dst_get(sk) != tp->dst) {
		dst_hold(tp->dst);
		sk_setup_caps(sk, tp->dst);
	}
	packet->max_size = sk_can_gso(sk) ? tp->dst->dev->gso_max_size
					  : asoc->pathmtu;
	rcu_read_unlock();
}

/* Initialize the packet structure. */
void sctp_packet_init(struct sctp_packet *packet,
		      struct sctp_transport *transport,
		      __u16 sport, __u16 dport)
{
	pr_debug("%s: packet:%p transport:%p\n", __func__, packet, transport);

	packet->transport = transport;
	packet->source_port = sport;
	packet->destination_port = dport;
	INIT_LIST_HEAD(&packet->chunk_list);
	/* The overhead will be calculated by sctp_packet_config() */
	packet->overhead = 0;
	sctp_packet_reset(packet);
	packet->vtag = 0;
}

/* Free a packet.  */
void sctp_packet_free(struct sctp_packet *packet)
{
	struct sctp_chunk *chunk, *tmp;

	pr_debug("%s: packet:%p\n", __func__, packet);

	list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
		list_del_init(&chunk->list);
		sctp_chunk_free(chunk);
	}
}

/* This routine tries to append the chunk to the offered packet. If adding
 * the chunk causes the packet to exceed the path MTU and COOKIE_ECHO chunk
 * is not present in the packet, it transmits the input packet.
 * Data can be bundled with a packet containing a COOKIE_ECHO chunk as long
 * as it can fit in the packet, but any more data that does not fit in this
 * packet can be sent only after receiving the COOKIE_ACK.
 */
enum sctp_xmit sctp_packet_transmit_chunk(struct sctp_packet *packet,
					  struct sctp_chunk *chunk,
					  int one_packet, gfp_t gfp)
{
	enum sctp_xmit retval;

	pr_debug("%s: packet:%p size:%zu chunk:%p size:%d\n", __func__,
		 packet, packet->size, chunk, chunk->skb ? chunk->skb->len : -1);

	switch ((retval = (sctp_packet_append_chunk(packet, chunk)))) {
	case SCTP_XMIT_PMTU_FULL:
		if (!packet->has_cookie_echo) {
			int error = 0;

			error = sctp_packet_transmit(packet, gfp);
			if (error < 0)
				chunk->skb->sk->sk_err = -error;

			/* If we have an empty packet, then we can NOT ever
			 * return PMTU_FULL.
			 */
			if (!one_packet)
				retval = sctp_packet_append_chunk(packet,
								  chunk);
		}
		break;

	case SCTP_XMIT_RWND_FULL:
	case SCTP_XMIT_OK:
	case SCTP_XMIT_DELAY:
		break;
	}

	return retval;
}

/* Try to bundle an auth chunk into the packet. */
static enum sctp_xmit sctp_packet_bundle_auth(struct sctp_packet *pkt,
					      struct sctp_chunk *chunk)
{
	struct sctp_association *asoc = pkt->transport->asoc;
	enum sctp_xmit retval = SCTP_XMIT_OK;
	struct sctp_chunk *auth;

	/* if we don't have an association, we can't do authentication */
	if (!asoc)
		return retval;

	/* See if this is an auth chunk we are bundling or if
	 * auth is already bundled.
	 */
	if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->has_auth)
		return retval;

	/* if the peer did not request this chunk to be authenticated,
	 * don't do it
	 */
	if (!chunk->auth)
		return retval;

	auth = sctp_make_auth(asoc, chunk->shkey->key_id);
	if (!auth)
		return retval;

	auth->shkey = chunk->shkey;
	sctp_auth_shkey_hold(auth->shkey);

	retval = __sctp_packet_append_chunk(pkt, auth);

	if (retval != SCTP_XMIT_OK)
		sctp_chunk_free(auth);

	return retval;
}

/* Try to bundle a SACK with the packet. */
static enum sctp_xmit sctp_packet_bundle_sack(struct sctp_packet *pkt,
					      struct sctp_chunk *chunk)
{
	enum sctp_xmit retval = SCTP_XMIT_OK;

	/* If sending DATA and haven't aleady bundled a SACK, try to
	 * bundle one in to the packet.
	 */
	if (sctp_chunk_is_data(chunk) && !pkt->has_sack &&
	    !pkt->has_cookie_echo) {
		struct sctp_association *asoc;
		struct timer_list *timer;
		asoc = pkt->transport->asoc;
		timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];

		/* If the SACK timer is running, we have a pending SACK */
		if (timer_pending(timer)) {
			struct sctp_chunk *sack;

			if (pkt->transport->sack_generation !=
			    pkt->transport->asoc->peer.sack_generation)
				return retval;

			asoc->a_rwnd = asoc->rwnd;
			sack = sctp_make_sack(asoc);
			if (sack) {
				retval = __sctp_packet_append_chunk(pkt, sack);
				if (retval != SCTP_XMIT_OK) {
					sctp_chunk_free(sack);
					goto out;
				}
				SCTP_INC_STATS(sock_net(asoc->base.sk),
					       SCTP_MIB_OUTCTRLCHUNKS);
				asoc->stats.octrlchunks++;
				asoc->peer.sack_needed = 0;
				if (del_timer(timer))
					sctp_association_put(asoc);
			}
		}
	}
out:
	return retval;
}


/* Append a chunk to the offered packet reporting back any inability to do
 * so.
 */
static enum sctp_xmit __sctp_packet_append_chunk(struct sctp_packet *packet,
						 struct sctp_chunk *chunk)
{
	__u16 chunk_len = SCTP_PAD4(ntohs(chunk->chunk_hdr->length));
	enum sctp_xmit retval = SCTP_XMIT_OK;

	/* Check to see if this chunk will fit into the packet */
	retval = sctp_packet_will_fit(packet, chunk, chunk_len);
	if (retval != SCTP_XMIT_OK)
		goto finish;

	/* We believe that this chunk is OK to add to the packet */
	switch (chunk->chunk_hdr->type) {
	case SCTP_CID_DATA:
	case SCTP_CID_I_DATA:
		/* Account for the data being in the packet */
		sctp_packet_append_data(packet, chunk);
		/* Disallow SACK bundling after DATA. */
		packet->has_sack = 1;
		/* Disallow AUTH bundling after DATA */
		packet->has_auth = 1;
		/* Let it be knows that packet has DATA in it */
		packet->has_data = 1;
		/* timestamp the chunk for rtx purposes */
		chunk->sent_at = jiffies;
		/* Mainly used for prsctp RTX policy */
		chunk->sent_count++;
		break;
	case SCTP_CID_COOKIE_ECHO:
		packet->has_cookie_echo = 1;
		break;

	case SCTP_CID_SACK:
		packet->has_sack = 1;
		if (chunk->asoc)
			chunk->asoc->stats.osacks++;
		break;

	case SCTP_CID_AUTH:
		packet->has_auth = 1;
		packet->auth = chunk;
		break;
	}

	/* It is OK to send this chunk.  */
	list_add_tail(&chunk->list, &packet->chunk_list);
	packet->size += chunk_len;
	chunk->transport = packet->transport;
finish:
	return retval;
}

/* Append a chunk to the offered packet reporting back any inability to do
 * so.
 */
enum sctp_xmit sctp_packet_append_chunk(struct sctp_packet *packet,
					struct sctp_chunk *chunk)
{
	enum sctp_xmit retval = SCTP_XMIT_OK;

	pr_debug("%s: packet:%p chunk:%p\n", __func__, packet, chunk);

	/* Data chunks are special.  Before seeing what else we can
	 * bundle into this packet, check to see if we are allowed to
	 * send this DATA.
	 */
	if (sctp_chunk_is_data(chunk)) {
		retval = sctp_packet_can_append_data(packet, chunk);
		if (retval != SCTP_XMIT_OK)
			goto finish;
	}

	/* Try to bundle AUTH chunk */
	retval = sctp_packet_bundle_auth(packet, chunk);
	if (retval != SCTP_XMIT_OK)
		goto finish;

	/* Try to bundle SACK chunk */
	retval = sctp_packet_bundle_sack(packet, chunk);
	if (retval != SCTP_XMIT_OK)
		goto finish;

	retval = __sctp_packet_append_chunk(packet, chunk);

finish:
	return retval;
}

static void sctp_packet_gso_append(struct sk_buff *head, struct sk_buff *skb)
{
	if (SCTP_OUTPUT_CB(head)->last == head)
		skb_shinfo(head)->frag_list = skb;
	else
		SCTP_OUTPUT_CB(head)->last->next = skb;
	SCTP_OUTPUT_CB(head)->last = skb;

	head->truesize += skb->truesize;
	head->data_len += skb->len;
	head->len += skb->len;
	refcount_add(skb->truesize, &head->sk->sk_wmem_alloc);

	__skb_header_release(skb);
}

static int sctp_packet_pack(struct sctp_packet *packet,
			    struct sk_buff *head, int gso, gfp_t gfp)
{
	struct sctp_transport *tp = packet->transport;
	struct sctp_auth_chunk *auth = NULL;
	struct sctp_chunk *chunk, *tmp;
	int pkt_count = 0, pkt_size;
	struct sock *sk = head->sk;
	struct sk_buff *nskb;
	int auth_len = 0;

	if (gso) {
		skb_shinfo(head)->gso_type = sk->sk_gso_type;
		SCTP_OUTPUT_CB(head)->last = head;
	} else {
		nskb = head;
		pkt_size = packet->size;
		goto merge;
	}

	do {
		/* calculate the pkt_size and alloc nskb */
		pkt_size = packet->overhead;
		list_for_each_entry_safe(chunk, tmp, &packet->chunk_list,
					 list) {
			int padded = SCTP_PAD4(chunk->skb->len);

			if (chunk == packet->auth)
				auth_len = padded;
			else if (auth_len + padded + packet->overhead >
				 tp->pathmtu)
				return 0;
			else if (pkt_size + padded > tp->pathmtu)
				break;
			pkt_size += padded;
		}
		nskb = alloc_skb(pkt_size + MAX_HEADER, gfp);
		if (!nskb)
			return 0;
		skb_reserve(nskb, packet->overhead + MAX_HEADER);

merge:
		/* merge chunks into nskb and append nskb into head list */
		pkt_size -= packet->overhead;
		list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
			int padding;

			list_del_init(&chunk->list);
			if (sctp_chunk_is_data(chunk)) {
				if (!sctp_chunk_retransmitted(chunk) &&
				    !tp->rto_pending) {
					chunk->rtt_in_progress = 1;
					tp->rto_pending = 1;
				}
			}

			padding = SCTP_PAD4(chunk->skb->len) - chunk->skb->len;
			if (padding)
				skb_put_zero(chunk->skb, padding);

			if (chunk == packet->auth)
				auth = (struct sctp_auth_chunk *)
							skb_tail_pointer(nskb);

			skb_put_data(nskb, chunk->skb->data, chunk->skb->len);

			pr_debug("*** Chunk:%p[%s] %s 0x%x, length:%d, chunk->skb->len:%d, rtt_in_progress:%d\n",
				 chunk,
				 sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)),
				 chunk->has_tsn ? "TSN" : "No TSN",
				 chunk->has_tsn ? ntohl(chunk->subh.data_hdr->tsn) : 0,
				 ntohs(chunk->chunk_hdr->length), chunk->skb->len,
				 chunk->rtt_in_progress);

			pkt_size -= SCTP_PAD4(chunk->skb->len);

			if (!sctp_chunk_is_data(chunk) && chunk != packet->auth)
				sctp_chunk_free(chunk);

			if (!pkt_size)
				break;
		}

		if (auth) {
			sctp_auth_calculate_hmac(tp->asoc, nskb, auth,
						 packet->auth->shkey, gfp);
			/* free auth if no more chunks, or add it back */
			if (list_empty(&packet->chunk_list))
				sctp_chunk_free(packet->auth);
			else
				list_add(&packet->auth->list,
					 &packet->chunk_list);
		}

		if (gso)
			sctp_packet_gso_append(head, nskb);

		pkt_count++;
	} while (!list_empty(&packet->chunk_list));

	if (gso) {
		memset(head->cb, 0, max(sizeof(struct inet_skb_parm),
					sizeof(struct inet6_skb_parm)));
		skb_shinfo(head)->gso_segs = pkt_count;
		skb_shinfo(head)->gso_size = GSO_BY_FRAGS;
		rcu_read_lock();
		if (skb_dst(head) != tp->dst) {
			dst_hold(tp->dst);
			sk_setup_caps(sk, tp->dst);
		}
		rcu_read_unlock();
		goto chksum;
	}

	if (sctp_checksum_disable)
		return 1;

	if (!(skb_dst(head)->dev->features & NETIF_F_SCTP_CRC) ||
	    dst_xfrm(skb_dst(head)) || packet->ipfragok) {
		struct sctphdr *sh =
			(struct sctphdr *)skb_transport_header(head);

		sh->checksum = sctp_compute_cksum(head, 0);
	} else {
chksum:
		head->ip_summed = CHECKSUM_PARTIAL;
		head->csum_not_inet = 1;
		head->csum_start = skb_transport_header(head) - head->head;
		head->csum_offset = offsetof(struct sctphdr, checksum);
	}

	return pkt_count;
}

/* All packets are sent to the network through this function from
 * sctp_outq_tail().
 *
 * The return value is always 0 for now.
 */
int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
{
	struct sctp_transport *tp = packet->transport;
	struct sctp_association *asoc = tp->asoc;
	struct sctp_chunk *chunk, *tmp;
	int pkt_count, gso = 0;
	struct dst_entry *dst;
	struct sk_buff *head;
	struct sctphdr *sh;
	struct sock *sk;

	pr_debug("%s: packet:%p\n", __func__, packet);
	if (list_empty(&packet->chunk_list))
		return 0;
	chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
	sk = chunk->skb->sk;

	/* check gso */
	if (packet->size > tp->pathmtu && !packet->ipfragok) {
		if (!sk_can_gso(sk)) {
			pr_err_once("Trying to GSO but underlying device doesn't support it.");
			goto out;
		}
		gso = 1;
	}

	/* alloc head skb */
	head = alloc_skb((gso ? packet->overhead : packet->size) +
			 MAX_HEADER, gfp);
	if (!head)
		goto out;
	skb_reserve(head, packet->overhead + MAX_HEADER);
	skb_set_owner_w(head, sk);

	/* set sctp header */
	sh = skb_push(head, sizeof(struct sctphdr));
	skb_reset_transport_header(head);
	sh->source = htons(packet->source_port);
	sh->dest = htons(packet->destination_port);
	sh->vtag = htonl(packet->vtag);
	sh->checksum = 0;

	/* drop packet if no dst */
	dst = dst_clone(tp->dst);
	if (!dst) {
		IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
		kfree_skb(head);
		goto out;
	}
	skb_dst_set(head, dst);

	/* pack up chunks */
	pkt_count = sctp_packet_pack(packet, head, gso, gfp);
	if (!pkt_count) {
		kfree_skb(head);
		goto out;
	}
	pr_debug("***sctp_transmit_packet*** skb->len:%d\n", head->len);

	/* start autoclose timer */
	if (packet->has_data && sctp_state(asoc, ESTABLISHED) &&
	    asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
		struct timer_list *timer =
			&asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
		unsigned long timeout =
			asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];

		if (!mod_timer(timer, jiffies + timeout))
			sctp_association_hold(asoc);
	}

	/* sctp xmit */
	tp->af_specific->ecn_capable(sk);
	if (asoc) {
		asoc->stats.opackets += pkt_count;
		if (asoc->peer.last_sent_to != tp)
			asoc->peer.last_sent_to = tp;
	}
	head->ignore_df = packet->ipfragok;
	if (tp->dst_pending_confirm)
		skb_set_dst_pending_confirm(head, 1);
	/* neighbour should be confirmed on successful transmission or
	 * positive error
	 */
	if (tp->af_specific->sctp_xmit(head, tp) >= 0 &&
	    tp->dst_pending_confirm)
		tp->dst_pending_confirm = 0;

out:
	list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
		list_del_init(&chunk->list);
		if (!sctp_chunk_is_data(chunk))
			sctp_chunk_free(chunk);
	}
	sctp_packet_reset(packet);
	return 0;
}

/********************************************************************
 * 2nd Level Abstractions
 ********************************************************************/

/* This private function check to see if a chunk can be added */
static enum sctp_xmit sctp_packet_can_append_data(struct sctp_packet *packet,
						  struct sctp_chunk *chunk)
{
	size_t datasize, rwnd, inflight, flight_size;
	struct sctp_transport *transport = packet->transport;
	struct sctp_association *asoc = transport->asoc;
	struct sctp_outq *q = &asoc->outqueue;

	/* RFC 2960 6.1  Transmission of DATA Chunks
	 *
	 * A) At any given time, the data sender MUST NOT transmit new data to
	 * any destination transport address if its peer's rwnd indicates
	 * that the peer has no buffer space (i.e. rwnd is 0, see Section
	 * 6.2.1).  However, regardless of the value of rwnd (including if it
	 * is 0), the data sender can always have one DATA chunk in flight to
	 * the receiver if allowed by cwnd (see rule B below).  This rule
	 * allows the sender to probe for a change in rwnd that the sender
	 * missed due to the SACK having been lost in transit from the data
	 * receiver to the data sender.
	 */

	rwnd = asoc->peer.rwnd;
	inflight = q->outstanding_bytes;
	flight_size = transport->flight_size;

	datasize = sctp_data_size(chunk);

	if (datasize > rwnd && inflight > 0)
		/* We have (at least) one data chunk in flight,
		 * so we can't fall back to rule 6.1 B).
		 */
		return SCTP_XMIT_RWND_FULL;

	/* RFC 2960 6.1  Transmission of DATA Chunks
	 *
	 * B) At any given time, the sender MUST NOT transmit new data
	 * to a given transport address if it has cwnd or more bytes
	 * of data outstanding to that transport address.
	 */
	/* RFC 7.2.4 & the Implementers Guide 2.8.
	 *
	 * 3) ...
	 *    When a Fast Retransmit is being performed the sender SHOULD
	 *    ignore the value of cwnd and SHOULD NOT delay retransmission.
	 */
	if (chunk->fast_retransmit != SCTP_NEED_FRTX &&
	    flight_size >= transport->cwnd)
		return SCTP_XMIT_RWND_FULL;

	/* Nagle's algorithm to solve small-packet problem:
	 * Inhibit the sending of new chunks when new outgoing data arrives
	 * if any previously transmitted data on the connection remains
	 * unacknowledged.
	 */

	if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) &&
	    !asoc->force_delay)
		/* Nothing unacked */
		return SCTP_XMIT_OK;

	if (!sctp_packet_empty(packet))
		/* Append to packet */
		return SCTP_XMIT_OK;

	if (!sctp_state(asoc, ESTABLISHED))
		return SCTP_XMIT_OK;

	/* Check whether this chunk and all the rest of pending data will fit
	 * or delay in hopes of bundling a full sized packet.
	 */
	if (chunk->skb->len + q->out_qlen > transport->pathmtu -
	    packet->overhead - sctp_datachk_len(&chunk->asoc->stream) - 4)
		/* Enough data queued to fill a packet */
		return SCTP_XMIT_OK;

	/* Don't delay large message writes that may have been fragmented */
	if (!chunk->msg->can_delay)
		return SCTP_XMIT_OK;

	/* Defer until all data acked or packet full */
	return SCTP_XMIT_DELAY;
}

/* This private function does management things when adding DATA chunk */
static void sctp_packet_append_data(struct sctp_packet *packet,
				struct sctp_chunk *chunk)
{
	struct sctp_transport *transport = packet->transport;
	size_t datasize = sctp_data_size(chunk);
	struct sctp_association *asoc = transport->asoc;
	u32 rwnd = asoc->peer.rwnd;

	/* Keep track of how many bytes are in flight over this transport. */
	transport->flight_size += datasize;

	/* Keep track of how many bytes are in flight to the receiver. */
	asoc->outqueue.outstanding_bytes += datasize;

	/* Update our view of the receiver's rwnd. */
	if (datasize < rwnd)
		rwnd -= datasize;
	else
		rwnd = 0;

	asoc->peer.rwnd = rwnd;
	sctp_chunk_assign_tsn(chunk);
	asoc->stream.si->assign_number(chunk);
}

static enum sctp_xmit sctp_packet_will_fit(struct sctp_packet *packet,
					   struct sctp_chunk *chunk,
					   u16 chunk_len)
{
	enum sctp_xmit retval = SCTP_XMIT_OK;
	size_t psize, pmtu, maxsize;

	/* Don't bundle in this packet if this chunk's auth key doesn't
	 * match other chunks already enqueued on this packet. Also,
	 * don't bundle the chunk with auth key if other chunks in this
	 * packet don't have auth key.
	 */
	if ((packet->auth && chunk->shkey != packet->auth->shkey) ||
	    (!packet->auth && chunk->shkey &&
	     chunk->chunk_hdr->type != SCTP_CID_AUTH))
		return SCTP_XMIT_PMTU_FULL;

	psize = packet->size;
	if (packet->transport->asoc)
		pmtu = packet->transport->asoc->pathmtu;
	else
		pmtu = packet->transport->pathmtu;

	/* Decide if we need to fragment or resubmit later. */
	if (psize + chunk_len > pmtu) {
		/* It's OK to fragment at IP level if any one of the following
		 * is true:
		 *	1. The packet is empty (meaning this chunk is greater
		 *	   the MTU)
		 *	2. The packet doesn't have any data in it yet and data
		 *	   requires authentication.
		 */
		if (sctp_packet_empty(packet) ||
		    (!packet->has_data && chunk->auth)) {
			/* We no longer do re-fragmentation.
			 * Just fragment at the IP layer, if we
			 * actually hit this condition
			 */
			packet->ipfragok = 1;
			goto out;
		}

		/* Similarly, if this chunk was built before a PMTU
		 * reduction, we have to fragment it at IP level now. So
		 * if the packet already contains something, we need to
		 * flush.
		 */
		maxsize = pmtu - packet->overhead;
		if (packet->auth)
			maxsize -= SCTP_PAD4(packet->auth->skb->len);
		if (chunk_len > maxsize)
			retval = SCTP_XMIT_PMTU_FULL;

		/* It is also okay to fragment if the chunk we are
		 * adding is a control chunk, but only if current packet
		 * is not a GSO one otherwise it causes fragmentation of
		 * a large frame. So in this case we allow the
		 * fragmentation by forcing it to be in a new packet.
		 */
		if (!sctp_chunk_is_data(chunk) && packet->has_data)
			retval = SCTP_XMIT_PMTU_FULL;

		if (psize + chunk_len > packet->max_size)
			/* Hit GSO/PMTU limit, gotta flush */
			retval = SCTP_XMIT_PMTU_FULL;

		if (!packet->transport->burst_limited &&
		    psize + chunk_len > (packet->transport->cwnd >> 1))
			/* Do not allow a single GSO packet to use more
			 * than half of cwnd.
			 */
			retval = SCTP_XMIT_PMTU_FULL;

		if (packet->transport->burst_limited &&
		    psize + chunk_len > (packet->transport->burst_limited >> 1))
			/* Do not allow a single GSO packet to use more
			 * than half of original cwnd.
			 */
			retval = SCTP_XMIT_PMTU_FULL;
		/* Otherwise it will fit in the GSO packet */
	}

out:
	return retval;
}
