Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf9b4812 authored by Vlad Yasevich's avatar Vlad Yasevich
Browse files

sctp: fast recovery algorithm is per association.



SCTP fast recovery algorithm really applies per association
and impacts all transports.

Signed-off-by: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
parent b2cf9b6b
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -895,9 +895,6 @@ struct sctp_transport {
		 */
		 */
		hb_sent:1,
		hb_sent:1,


		/* Flag to track the current fast recovery state */
		fast_recovery:1,

		/* Is the Path MTU update pending on this tranport */
		/* Is the Path MTU update pending on this tranport */
		pmtu_pending:1,
		pmtu_pending:1,


@@ -952,9 +949,6 @@ struct sctp_transport {


	__u32 burst_limited;	/* Holds old cwnd when max.burst is applied */
	__u32 burst_limited;	/* Holds old cwnd when max.burst is applied */


	/* TSN marking the fast recovery exit point */
	__u32 fast_recovery_exit;

	/* Destination */
	/* Destination */
	struct dst_entry *dst;
	struct dst_entry *dst;
	/* Source address. */
	/* Source address. */
@@ -1723,6 +1717,12 @@ struct sctp_association {
	/* Highest TSN that is acknowledged by incoming SACKs. */
	/* Highest TSN that is acknowledged by incoming SACKs. */
	__u32 highest_sacked;
	__u32 highest_sacked;


	/* TSN marking the fast recovery exit point */
	__u32 fast_recovery_exit;

	/* Flag to track the current fast recovery state */
	__u8 fast_recovery;

	/* The number of unacknowledged data chunks.  Reported through
	/* The number of unacknowledged data chunks.  Reported through
	 * the SCTP_STATUS sockopt.
	 * the SCTP_STATUS sockopt.
	 */
	 */
+17 −15
Original line number Original line Diff line number Diff line
@@ -378,15 +378,16 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
void sctp_transport_raise_cwnd(struct sctp_transport *transport,
void sctp_transport_raise_cwnd(struct sctp_transport *transport,
			       __u32 sack_ctsn, __u32 bytes_acked)
			       __u32 sack_ctsn, __u32 bytes_acked)
{
{
	struct sctp_association *asoc = transport->asoc;
	__u32 cwnd, ssthresh, flight_size, pba, pmtu;
	__u32 cwnd, ssthresh, flight_size, pba, pmtu;


	cwnd = transport->cwnd;
	cwnd = transport->cwnd;
	flight_size = transport->flight_size;
	flight_size = transport->flight_size;


	/* See if we need to exit Fast Recovery first */
	/* See if we need to exit Fast Recovery first */
	if (transport->fast_recovery &&
	if (asoc->fast_recovery &&
	    TSN_lte(transport->fast_recovery_exit, sack_ctsn))
	    TSN_lte(asoc->fast_recovery_exit, sack_ctsn))
		transport->fast_recovery = 0;
		asoc->fast_recovery = 0;


	/* The appropriate cwnd increase algorithm is performed if, and only
	/* The appropriate cwnd increase algorithm is performed if, and only
	 * if the cumulative TSN whould advanced and the congestion window is
	 * if the cumulative TSN whould advanced and the congestion window is
@@ -415,7 +416,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport,
		 *    2) the destination's path MTU.  This upper bound protects
		 *    2) the destination's path MTU.  This upper bound protects
		 *    against the ACK-Splitting attack outlined in [SAVAGE99].
		 *    against the ACK-Splitting attack outlined in [SAVAGE99].
		 */
		 */
		if (transport->fast_recovery)
		if (asoc->fast_recovery)
			return;
			return;


		if (bytes_acked > pmtu)
		if (bytes_acked > pmtu)
@@ -466,6 +467,8 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport,
void sctp_transport_lower_cwnd(struct sctp_transport *transport,
void sctp_transport_lower_cwnd(struct sctp_transport *transport,
			       sctp_lower_cwnd_t reason)
			       sctp_lower_cwnd_t reason)
{
{
	struct sctp_association *asoc = transport->asoc;

	switch (reason) {
	switch (reason) {
	case SCTP_LOWER_CWND_T3_RTX:
	case SCTP_LOWER_CWND_T3_RTX:
		/* RFC 2960 Section 7.2.3, sctpimpguide
		/* RFC 2960 Section 7.2.3, sctpimpguide
@@ -476,11 +479,11 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
		 *      partial_bytes_acked = 0
		 *      partial_bytes_acked = 0
		 */
		 */
		transport->ssthresh = max(transport->cwnd/2,
		transport->ssthresh = max(transport->cwnd/2,
					  4*transport->asoc->pathmtu);
					  4*asoc->pathmtu);
		transport->cwnd = transport->asoc->pathmtu;
		transport->cwnd = asoc->pathmtu;


		/* T3-rtx also clears fast recovery on the transport */
		/* T3-rtx also clears fast recovery */
		transport->fast_recovery = 0;
		asoc->fast_recovery = 0;
		break;
		break;


	case SCTP_LOWER_CWND_FAST_RTX:
	case SCTP_LOWER_CWND_FAST_RTX:
@@ -496,15 +499,15 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
		 *      cwnd = ssthresh
		 *      cwnd = ssthresh
		 *      partial_bytes_acked = 0
		 *      partial_bytes_acked = 0
		 */
		 */
		if (transport->fast_recovery)
		if (asoc->fast_recovery)
			return;
			return;


		/* Mark Fast recovery */
		/* Mark Fast recovery */
		transport->fast_recovery = 1;
		asoc->fast_recovery = 1;
		transport->fast_recovery_exit = transport->asoc->next_tsn - 1;
		asoc->fast_recovery_exit = asoc->next_tsn - 1;


		transport->ssthresh = max(transport->cwnd/2,
		transport->ssthresh = max(transport->cwnd/2,
					  4*transport->asoc->pathmtu);
					  4*asoc->pathmtu);
		transport->cwnd = transport->ssthresh;
		transport->cwnd = transport->ssthresh;
		break;
		break;


@@ -524,7 +527,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
		if (time_after(jiffies, transport->last_time_ecne_reduced +
		if (time_after(jiffies, transport->last_time_ecne_reduced +
					transport->rtt)) {
					transport->rtt)) {
			transport->ssthresh = max(transport->cwnd/2,
			transport->ssthresh = max(transport->cwnd/2,
						  4*transport->asoc->pathmtu);
						  4*asoc->pathmtu);
			transport->cwnd = transport->ssthresh;
			transport->cwnd = transport->ssthresh;
			transport->last_time_ecne_reduced = jiffies;
			transport->last_time_ecne_reduced = jiffies;
		}
		}
@@ -540,7 +543,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
		 * interval.
		 * interval.
		 */
		 */
		transport->cwnd = max(transport->cwnd/2,
		transport->cwnd = max(transport->cwnd/2,
					 4*transport->asoc->pathmtu);
					 4*asoc->pathmtu);
		break;
		break;
	}
	}


@@ -625,7 +628,6 @@ void sctp_transport_reset(struct sctp_transport *t)
	t->error_count = 0;
	t->error_count = 0;
	t->rto_pending = 0;
	t->rto_pending = 0;
	t->hb_sent = 0;
	t->hb_sent = 0;
	t->fast_recovery = 0;


	/* Initialize the state information for SFR-CACC */
	/* Initialize the state information for SFR-CACC */
	t->cacc.changeover_active = 0;
	t->cacc.changeover_active = 0;