Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Feb 2012 19:02:07 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r231400 - stable/8/sys/netinet
Message-ID:  <201202101902.q1AJ27cG088675@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Fri Feb 10 19:02:07 2012
New Revision: 231400
URL: http://svn.freebsd.org/changeset/base/231400

Log:
  MFC r218072:
  Fixes to ECN in SCTP.
  1) ECN was on an association basis, this is incorrect and
     will not work with CMT or for that matter if the user
     is sending to multiple addresses. This commit makes
     ECN on a per path basis.
  2) Adopt the new format for the ECN internet draft. This also
     maintains compatability with old format chunks as well.
  3) Keep track of the real time of a RTT down to micro seconds.
     For some future conditional features (for like a data center
     this is good information to have).
  From rrs@.

Modified:
  stable/8/sys/netinet/sctp.h
  stable/8/sys/netinet/sctp_header.h
  stable/8/sys/netinet/sctp_indata.c
  stable/8/sys/netinet/sctp_input.c
  stable/8/sys/netinet/sctp_output.c
  stable/8/sys/netinet/sctp_output.h
  stable/8/sys/netinet/sctp_pcb.c
  stable/8/sys/netinet/sctp_structs.h
  stable/8/sys/netinet/sctputil.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)

Modified: stable/8/sys/netinet/sctp.h
==============================================================================
--- stable/8/sys/netinet/sctp.h	Fri Feb 10 18:58:36 2012	(r231399)
+++ stable/8/sys/netinet/sctp.h	Fri Feb 10 19:02:07 2012	(r231400)
@@ -417,6 +417,10 @@ struct sctp_error_unrecognized_chunk {
 #define SCTP_BADCRC		0x02
 #define SCTP_PACKET_TRUNCATED	0x04
 
+/* Flag for ECN -CWR */
+#define SCTP_CWR_REDUCE_OVERRIDE 0x01
+#define SCTP_CWR_IN_SAME_WINDOW  0x02
+
 #define SCTP_SAT_NETWORK_MIN	400	/* min ms for RTT to set satellite
 					 * time */
 #define SCTP_SAT_NETWORK_BURST_INCR  2	/* how many times to multiply maxburst

Modified: stable/8/sys/netinet/sctp_header.h
==============================================================================
--- stable/8/sys/netinet/sctp_header.h	Fri Feb 10 18:58:36 2012	(r231399)
+++ stable/8/sys/netinet/sctp_header.h	Fri Feb 10 19:02:07 2012	(r231400)
@@ -360,9 +360,15 @@ struct sctp_cookie_ack_chunk {
 }                     SCTP_PACKED;
 
 /* Explicit Congestion Notification Echo (ECNE) */
+struct old_sctp_ecne_chunk {
+	struct sctp_chunkhdr ch;
+	uint32_t tsn;
+}                   SCTP_PACKED;
+
 struct sctp_ecne_chunk {
 	struct sctp_chunkhdr ch;
 	uint32_t tsn;
+	uint32_t num_pkts_since_cwr;
 }               SCTP_PACKED;
 
 /* Congestion Window Reduced (CWR) */

Modified: stable/8/sys/netinet/sctp_indata.c
==============================================================================
--- stable/8/sys/netinet/sctp_indata.c	Fri Feb 10 18:58:36 2012	(r231399)
+++ stable/8/sys/netinet/sctp_indata.c	Fri Feb 10 19:02:07 2012	(r231400)
@@ -3829,6 +3829,10 @@ sctp_express_handle_sack(struct sctp_tcb
 	}
 	/* First setup for CC stuff */
 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
+		if (SCTP_TSN_GT(cumack, net->cwr_window_tsn)) {
+			/* Drag along the window_tsn for cwr's */
+			net->cwr_window_tsn = cumack;
+		}
 		net->prev_cwnd = net->cwnd;
 		net->net_ack = 0;
 		net->net_ack2 = 0;
@@ -4522,6 +4526,10 @@ sctp_handle_sack(struct mbuf *m, int off
 	 * destination address basis.
 	 */
 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
+		if (SCTP_TSN_GT(cum_ack, net->cwr_window_tsn)) {
+			/* Drag along the window_tsn for cwr's */
+			net->cwr_window_tsn = cum_ack;
+		}
 		net->prev_cwnd = net->cwnd;
 		net->net_ack = 0;
 		net->net_ack2 = 0;

Modified: stable/8/sys/netinet/sctp_input.c
==============================================================================
--- stable/8/sys/netinet/sctp_input.c	Fri Feb 10 18:58:36 2012	(r231399)
+++ stable/8/sys/netinet/sctp_input.c	Fri Feb 10 19:02:07 2012	(r231400)
@@ -1678,8 +1678,6 @@ sctp_process_cookie_existing(struct mbuf
 		asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
 		asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
 
-		/* Note last_cwr_tsn? where is this used? */
-		asoc->last_cwr_tsn = asoc->init_seq_number - 1;
 		if (ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) {
 			/*
 			 * Ok the peer probably discarded our data (if we
@@ -1835,7 +1833,6 @@ sctp_process_cookie_existing(struct mbuf
 		asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
 		asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
 
-		asoc->last_cwr_tsn = asoc->init_seq_number - 1;
 		asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
 
 		asoc->str_reset_seq_in = asoc->init_seq_number;
@@ -2073,7 +2070,6 @@ sctp_process_cookie_new(struct mbuf *m, 
 	asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
 	asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
 	asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
-	asoc->last_cwr_tsn = asoc->init_seq_number - 1;
 	asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
 	asoc->str_reset_seq_in = asoc->init_seq_number;
 
@@ -2917,25 +2913,38 @@ sctp_handle_ecn_echo(struct sctp_ecne_ch
 {
 	struct sctp_nets *net;
 	struct sctp_tmit_chunk *lchk;
-	uint32_t tsn;
-
-	if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_ecne_chunk)) {
+	struct sctp_ecne_chunk bkup;
+	uint8_t override_bit = 0;
+	uint32_t tsn, window_data_tsn;
+	int len;
+	int pkt_cnt;
+
+	len = ntohs(cp->ch.chunk_length);
+	if ((len != sizeof(struct sctp_ecne_chunk)) &&
+	    (len != sizeof(struct old_sctp_ecne_chunk))) {
 		return;
 	}
+	if (len == sizeof(struct old_sctp_ecne_chunk)) {
+		/* Its the old format */
+		memcpy(&bkup, cp, sizeof(struct old_sctp_ecne_chunk));
+		bkup.num_pkts_since_cwr = htonl(1);
+		cp = &bkup;
+	}
 	SCTP_STAT_INCR(sctps_recvecne);
 	tsn = ntohl(cp->tsn);
+	pkt_cnt = ntohl(cp->num_pkts_since_cwr);
 	/* ECN Nonce stuff: need a resync and disable the nonce sum check */
 	/* Also we make sure we disable the nonce_wait */
-	lchk = TAILQ_FIRST(&stcb->asoc.send_queue);
+	lchk = TAILQ_LAST(&stcb->asoc.send_queue, sctpchunk_listhead);
 	if (lchk == NULL) {
-		stcb->asoc.nonce_resync_tsn = stcb->asoc.sending_seq;
+		window_data_tsn = stcb->asoc.nonce_resync_tsn = stcb->asoc.sending_seq - 1;
 	} else {
-		stcb->asoc.nonce_resync_tsn = lchk->rec.data.TSN_seq;
+		window_data_tsn = stcb->asoc.nonce_resync_tsn = lchk->rec.data.TSN_seq;
 	}
 	stcb->asoc.nonce_wait_for_ecne = 0;
 	stcb->asoc.nonce_sum_check = 0;
 
-	/* Find where it was sent, if possible */
+	/* Find where it was sent to if possible. */
 	net = NULL;
 	TAILQ_FOREACH(lchk, &stcb->asoc.sent_queue, sctp_next) {
 		if (lchk->rec.data.TSN_seq == tsn) {
@@ -2946,32 +2955,71 @@ sctp_handle_ecn_echo(struct sctp_ecne_ch
 			break;
 		}
 	}
-	if (net == NULL)
-		/* default is we use the primary */
-		net = stcb->asoc.primary_destination;
-
-	if (SCTP_TSN_GT(tsn, stcb->asoc.last_cwr_tsn)) {
+	if (net == NULL) {
+		/*
+		 * What to do. A previous send of a CWR was possibly lost.
+		 * See how old it is, we may have it marked on the actual
+		 * net.
+		 */
+		TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
+			if (tsn == net->last_cwr_tsn) {
+				/* Found him, send it off */
+				goto out;
+			}
+		}
+		/*
+		 * If we reach here, we need to send a special CWR that says
+		 * hey, we did this a long time ago and you lost the
+		 * response.
+		 */
+		net = TAILQ_FIRST(&stcb->asoc.nets);
+		override_bit = SCTP_CWR_REDUCE_OVERRIDE;
+	}
+out:
+	if (SCTP_TSN_GT(tsn, net->cwr_window_tsn)) {
 		/*
 		 * JRS - Use the congestion control given in the pluggable
 		 * CC module
 		 */
+		int ocwnd;
+
+		ocwnd = net->cwnd;
 		stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net);
 		/*
-		 * we reduce once every RTT. So we will only lower cwnd at
-		 * the next sending seq i.e. the resync_tsn.
+		 * We reduce once every RTT. So we will only lower cwnd at
+		 * the next sending seq i.e. the window_data_tsn
 		 */
-		stcb->asoc.last_cwr_tsn = stcb->asoc.nonce_resync_tsn;
+		net->cwr_window_tsn = window_data_tsn;
+		net->ecn_ce_pkt_cnt += pkt_cnt;
+		net->lost_cnt = pkt_cnt;
+		net->last_cwr_tsn = tsn;
+	} else {
+		override_bit |= SCTP_CWR_IN_SAME_WINDOW;
+		if (SCTP_TSN_GT(tsn, net->last_cwr_tsn)) {
+			/*
+			 * Another loss in the same window update how man
+			 * marks we have had
+			 */
+
+			if (pkt_cnt > net->lost_cnt) {
+				/* Should be the case */
+				net->ecn_ce_pkt_cnt += (pkt_cnt - net->lost_cnt);
+				net->lost_cnt = pkt_cnt;
+			}
+			net->last_cwr_tsn = tsn;
+		}
 	}
 	/*
 	 * We always send a CWR this way if our previous one was lost our
 	 * peer will get an update, or if it is not time again to reduce we
-	 * still get the cwr to the peer.
+	 * still get the cwr to the peer. Note we set the override when we
+	 * could not find the TSN on the chunk or the destination network.
 	 */
-	sctp_send_cwr(stcb, net, tsn);
+	sctp_send_cwr(stcb, net, net->last_cwr_tsn, override_bit);
 }
 
 static void
-sctp_handle_ecn_cwr(struct sctp_cwr_chunk *cp, struct sctp_tcb *stcb)
+sctp_handle_ecn_cwr(struct sctp_cwr_chunk *cp, struct sctp_tcb *stcb, struct sctp_nets *net)
 {
 	/*
 	 * Here we get a CWR from the peer. We must look in the outqueue and
@@ -2980,18 +3028,22 @@ sctp_handle_ecn_cwr(struct sctp_cwr_chun
 	 */
 	struct sctp_tmit_chunk *chk;
 	struct sctp_ecne_chunk *ecne;
+	int override;
+	uint32_t cwr_tsn;
+
+	cwr_tsn = ntohl(cp->tsn);
 
+	override = cp->ch.chunk_flags & SCTP_CWR_REDUCE_OVERRIDE;
 	TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
 		if (chk->rec.chunk_id.id != SCTP_ECN_ECHO) {
 			continue;
 		}
-		/*
-		 * Look for and remove if it is the right TSN. Since there
-		 * is only ONE ECNE on the control queue at any one time we
-		 * don't need to worry about more than one!
-		 */
+		if ((override == 0) && (chk->whoTo != net)) {
+			/* Must be from the right src unless override is set */
+			continue;
+		}
 		ecne = mtod(chk->data, struct sctp_ecne_chunk *);
-		if (SCTP_TSN_GE(ntohl(cp->tsn), ntohl(ecne->tsn))) {
+		if (SCTP_TSN_GE(cwr_tsn, ntohl(ecne->tsn))) {
 			/* this covers this ECNE, we can remove it */
 			stcb->asoc.ecn_echo_cnt_onq--;
 			TAILQ_REMOVE(&stcb->asoc.control_send_queue, chk,
@@ -3002,7 +3054,9 @@ sctp_handle_ecn_cwr(struct sctp_cwr_chun
 			}
 			stcb->asoc.ctrl_queue_cnt--;
 			sctp_free_a_chunk(stcb, chk);
-			break;
+			if (override == 0) {
+				break;
+			}
 		}
 	}
 }
@@ -5043,7 +5097,7 @@ process_control_chunks:
 					    __LINE__);
 				}
 				stcb->asoc.overall_error_count = 0;
-				sctp_handle_ecn_cwr((struct sctp_cwr_chunk *)ch, stcb);
+				sctp_handle_ecn_cwr((struct sctp_cwr_chunk *)ch, stcb, *netp);
 			}
 			break;
 		case SCTP_SHUTDOWN_COMPLETE:

Modified: stable/8/sys/netinet/sctp_output.c
==============================================================================
--- stable/8/sys/netinet/sctp_output.c	Fri Feb 10 18:58:36 2012	(r231399)
+++ stable/8/sys/netinet/sctp_output.c	Fri Feb 10 19:02:07 2012	(r231400)
@@ -7274,7 +7274,7 @@ sctp_med_chunk_output(struct sctp_inpcb 
 	 * fomulate and send the low level chunks. Making sure to combine
 	 * any control in the control chunk queue also.
 	 */
-	struct sctp_nets *net, *start_at, *old_start_at = NULL;
+	struct sctp_nets *net, *start_at, *sack_goes_to = NULL, *old_start_at = NULL;
 	struct mbuf *outchain, *endoutchain;
 	struct sctp_tmit_chunk *chk, *nchk;
 
@@ -7327,10 +7327,12 @@ sctp_med_chunk_output(struct sctp_inpcb 
 		no_data_chunks = 0;
 
 	/* Nothing to possible to send? */
-	if (TAILQ_EMPTY(&asoc->control_send_queue) &&
+	if ((TAILQ_EMPTY(&asoc->control_send_queue) ||
+	    (asoc->ctrl_queue_cnt == stcb->asoc.ecn_echo_cnt_onq)) &&
 	    TAILQ_EMPTY(&asoc->asconf_send_queue) &&
 	    TAILQ_EMPTY(&asoc->send_queue) &&
 	    stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
+nothing_to_send:
 		*reason_code = 9;
 		return (0);
 	}
@@ -7342,6 +7344,21 @@ sctp_med_chunk_output(struct sctp_inpcb 
 			no_data_chunks = 1;
 		}
 	}
+	if (stcb->asoc.ecn_echo_cnt_onq) {
+		/* Record where a sack goes, if any */
+		if (no_data_chunks &&
+		    (asoc->ctrl_queue_cnt == stcb->asoc.ecn_echo_cnt_onq)) {
+			/* Nothing but ECNe to send - we don't do that */
+			goto nothing_to_send;
+		}
+		TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
+			if ((chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) ||
+			    (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK)) {
+				sack_goes_to = chk->whoTo;
+				break;
+			}
+		}
+	}
 	max_rwnd_per_dest = ((asoc->peers_rwnd + asoc->total_flight) / asoc->numnets);
 	if (stcb->sctp_socket)
 		max_send_per_dest = SCTP_SB_LIMIT_SND(stcb->sctp_socket) / asoc->numnets;
@@ -7685,6 +7702,28 @@ again_one_more_time:
 		/************************/
 		/* Now first lets go through the control queue */
 		TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
+			if ((sack_goes_to) &&
+			    (chk->rec.chunk_id.id == SCTP_ECN_ECHO) &&
+			    (chk->whoTo != sack_goes_to)) {
+				/*
+				 * if we have a sack in queue, and we are
+				 * looking at an ecn echo that is NOT queued
+				 * to where the sack is going..
+				 */
+				if (chk->whoTo == net) {
+					/*
+					 * Don't transmit it to where its
+					 * going (current net)
+					 */
+					continue;
+				} else if (sack_goes_to == net) {
+					/*
+					 * But do transmit it to this
+					 * address
+					 */
+					goto skip_net_check;
+				}
+			}
 			if (chk->whoTo != net) {
 				/*
 				 * No, not sent to the network we are
@@ -7692,6 +7731,7 @@ again_one_more_time:
 				 */
 				continue;
 			}
+	skip_net_check:
 			if (chk->data == NULL) {
 				continue;
 			}
@@ -10761,11 +10801,19 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb
 	asoc = &stcb->asoc;
 	SCTP_TCB_LOCK_ASSERT(stcb);
 	TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
-		if (chk->rec.chunk_id.id == SCTP_ECN_ECHO) {
+		if ((chk->rec.chunk_id.id == SCTP_ECN_ECHO) && (net == chk->whoTo)) {
 			/* found a previous ECN_ECHO update it if needed */
+			uint32_t cnt, ctsn;
+
 			ecne = mtod(chk->data, struct sctp_ecne_chunk *);
-			ecne->tsn = htonl(high_tsn);
-			SCTP_STAT_INCR(sctps_queue_upd_ecne);
+			ctsn = ntohl(ecne->tsn);
+			if (SCTP_TSN_GT(high_tsn, ctsn)) {
+				ecne->tsn = htonl(high_tsn);
+				cnt = ntohl(ecne->num_pkts_since_cwr);
+				cnt++;
+				ecne->num_pkts_since_cwr = htonl(cnt);
+				SCTP_STAT_INCR(sctps_queue_upd_ecne);
+			}
 			return;
 		}
 	}
@@ -10797,7 +10845,8 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb
 	ecne->ch.chunk_flags = 0;
 	ecne->ch.chunk_length = htons(sizeof(struct sctp_ecne_chunk));
 	ecne->tsn = htonl(high_tsn);
-	TAILQ_INSERT_TAIL(&stcb->asoc.control_send_queue, chk, sctp_next);
+	ecne->num_pkts_since_cwr = htonl(1);
+	TAILQ_INSERT_HEAD(&stcb->asoc.control_send_queue, chk, sctp_next);
 	asoc->ctrl_queue_cnt++;
 }
 
@@ -10975,7 +11024,7 @@ jump_out:
 }
 
 void
-sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn)
+sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, uint8_t override)
 {
 	struct sctp_association *asoc;
 	struct sctp_cwr_chunk *cwr;
@@ -10983,17 +11032,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, str
 
 	asoc = &stcb->asoc;
 	SCTP_TCB_LOCK_ASSERT(stcb);
-	TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
-		if (chk->rec.chunk_id.id == SCTP_ECN_CWR) {
-			/* found a previous ECN_CWR update it if needed */
-			cwr = mtod(chk->data, struct sctp_cwr_chunk *);
-			if (SCTP_TSN_GT(high_tsn, ntohl(cwr->tsn))) {
-				cwr->tsn = htonl(high_tsn);
-			}
-			return;
-		}
-	}
-	/* nope could not find one to update so we must build one */
+
 	sctp_alloc_a_chunk(stcb, chk);
 	if (chk == NULL) {
 		return;
@@ -11016,7 +11055,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, str
 	atomic_add_int(&chk->whoTo->ref_count, 1);
 	cwr = mtod(chk->data, struct sctp_cwr_chunk *);
 	cwr->ch.chunk_type = SCTP_ECN_CWR;
-	cwr->ch.chunk_flags = 0;
+	cwr->ch.chunk_flags = override;
 	cwr->ch.chunk_length = htons(sizeof(struct sctp_cwr_chunk));
 	cwr->tsn = htonl(high_tsn);
 	TAILQ_INSERT_TAIL(&stcb->asoc.control_send_queue, chk, sctp_next);

Modified: stable/8/sys/netinet/sctp_output.h
==============================================================================
--- stable/8/sys/netinet/sctp_output.h	Fri Feb 10 18:58:36 2012	(r231399)
+++ stable/8/sys/netinet/sctp_output.h	Fri Feb 10 19:02:07 2012	(r231400)
@@ -163,7 +163,7 @@ sctp_send_packet_dropped(struct sctp_tcb
 
 
 
-void sctp_send_cwr(struct sctp_tcb *, struct sctp_nets *, uint32_t);
+void sctp_send_cwr(struct sctp_tcb *, struct sctp_nets *, uint32_t, uint8_t);
 
 
 void

Modified: stable/8/sys/netinet/sctp_pcb.c
==============================================================================
--- stable/8/sys/netinet/sctp_pcb.c	Fri Feb 10 18:58:36 2012	(r231399)
+++ stable/8/sys/netinet/sctp_pcb.c	Fri Feb 10 19:02:07 2012	(r231400)
@@ -3854,6 +3854,7 @@ sctp_add_remote_addr(struct sctp_tcb *st
 	net->RTO_measured = 0;
 	stcb->asoc.numnets++;
 	*(&net->ref_count) = 1;
+	net->cwr_window_tsn = net->last_cwr_tsn = stcb->asoc.sending_seq - 1;
 	net->tos_flowlabel = 0;
 	if (SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable)) {
 		net->port = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));

Modified: stable/8/sys/netinet/sctp_structs.h
==============================================================================
--- stable/8/sys/netinet/sctp_structs.h	Fri Feb 10 18:58:36 2012	(r231399)
+++ stable/8/sys/netinet/sctp_structs.h	Fri Feb 10 19:02:07 2012	(r231400)
@@ -211,7 +211,10 @@ struct sctp_nets {
 	/* mtu discovered so far */
 	uint32_t mtu;
 	uint32_t ssthresh;	/* not sure about this one for split */
-
+	uint32_t last_cwr_tsn;
+	uint32_t cwr_window_tsn;
+	uint32_t ecn_ce_pkt_cnt;
+	uint32_t lost_cnt;
 	/* smoothed average things for RTT and RTO itself */
 	int lastsa;
 	int lastsv;
@@ -864,7 +867,6 @@ struct sctp_association {
 	uint32_t highest_tsn_inside_nr_map;
 
 	uint32_t last_echo_tsn;
-	uint32_t last_cwr_tsn;
 	uint32_t fast_recovery_tsn;
 	uint32_t sat_t3_recovery_tsn;
 	uint32_t tsn_last_delivered;
@@ -1048,7 +1050,6 @@ struct sctp_association {
 	uint16_t ecn_echo_cnt_onq;
 
 	uint16_t free_chunk_cnt;
-
 	uint8_t stream_locked;
 	uint8_t authenticated;	/* packet authenticated ok */
 	/*

Modified: stable/8/sys/netinet/sctputil.c
==============================================================================
--- stable/8/sys/netinet/sctputil.c	Fri Feb 10 18:58:36 2012	(r231399)
+++ stable/8/sys/netinet/sctputil.c	Fri Feb 10 19:02:07 2012	(r231400)
@@ -971,7 +971,6 @@ sctp_init_asoc(struct sctp_inpcb *m, str
 	asoc->last_net_cmt_send_started = NULL;
 
 	/* This will need to be adjusted */
-	asoc->last_cwr_tsn = asoc->init_seq_number - 1;
 	asoc->last_acked_seq = asoc->init_seq_number - 1;
 	asoc->advanced_peer_ack_point = asoc->last_acked_seq;
 	asoc->asconf_seq_in = asoc->last_acked_seq;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202101902.q1AJ27cG088675>