Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Dec 2010 17:59:38 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r216669 - in head/sys: netinet netinet6
Message-ID:  <201012221759.oBMHxcqY030477@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Wed Dec 22 17:59:38 2010
New Revision: 216669
URL: http://svn.freebsd.org/changeset/base/216669

Log:
  Improve plausibility check in sctp_handle_sack().
  Allow cmt_on_off to support values 0 (no CMT), 1 (CMT), and 2 (CMT/RP).
  
  MFC after: 3 months.

Modified:
  head/sys/netinet/sctp_cc_functions.c
  head/sys/netinet/sctp_indata.c
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_sysctl.h
  head/sys/netinet/sctp_timer.c
  head/sys/netinet/sctp_usrreq.c
  head/sys/netinet6/sctp6_usrreq.c

Modified: head/sys/netinet/sctp_cc_functions.c
==============================================================================
--- head/sys/netinet/sctp_cc_functions.c	Wed Dec 22 17:12:58 2010	(r216668)
+++ head/sys/netinet/sctp_cc_functions.c	Wed Dec 22 17:59:38 2010	(r216669)
@@ -80,12 +80,12 @@ sctp_cwnd_update_after_fr(struct sctp_tc
 	struct sctp_nets *net;
 
 	/*-
-	 * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off == 1) &&
+	 * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off > 0) &&
 	 * (net->fast_retran_loss_recovery == 0)))
 	 */
 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
 		if ((asoc->fast_retran_loss_recovery == 0) ||
-		    (asoc->sctp_cmt_on_off == 1)) {
+		    (asoc->sctp_cmt_on_off > 0)) {
 			/* out of a RFC2582 Fast recovery window? */
 			if (net->net_ack > 0) {
 				/*
@@ -250,7 +250,7 @@ sctp_cwnd_update_after_sack(struct sctp_
 			 * 
 			 * Should we stop any running T3 timer here?
 			 */
-			if ((asoc->sctp_cmt_on_off == 1) &&
+			if ((asoc->sctp_cmt_on_off > 0) &&
 			    (asoc->sctp_cmt_pf > 0) &&
 			    ((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
 				net->dest_state &= ~SCTP_ADDR_PF;
@@ -274,10 +274,9 @@ sctp_cwnd_update_after_sack(struct sctp_
 		 * CMT fast recovery code
 		 */
 		/*
-		 * if (sctp_cmt_on_off == 1 &&
-		 * net->fast_retran_loss_recovery &&
-		 * net->will_exit_fast_recovery == 0) { @@@ Do something }
-		 * else if (sctp_cmt_on_off == 0 &&
+		 * if (sctp_cmt_on_off > 0 && net->fast_retran_loss_recovery
+		 * && net->will_exit_fast_recovery == 0) { @@@ Do something
+		 * } else if (sctp_cmt_on_off == 0 &&
 		 * asoc->fast_retran_loss_recovery && will_exit == 0) {
 		 */
 #endif
@@ -296,7 +295,7 @@ sctp_cwnd_update_after_sack(struct sctp_
 		 * moved.
 		 */
 		if (accum_moved ||
-		    ((asoc->sctp_cmt_on_off == 1) && net->new_pseudo_cumack)) {
+		    ((asoc->sctp_cmt_on_off > 0) && net->new_pseudo_cumack)) {
 			/* If the cumulative ack moved we can proceed */
 			if (net->cwnd <= net->ssthresh) {
 				/* We are in slow start */
@@ -759,12 +758,12 @@ sctp_hs_cwnd_update_after_fr(struct sctp
 	struct sctp_nets *net;
 
 	/*
-	 * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off == 1) &&
+	 * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off > 0) &&
 	 * (net->fast_retran_loss_recovery == 0)))
 	 */
 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
 		if ((asoc->fast_retran_loss_recovery == 0) ||
-		    (asoc->sctp_cmt_on_off == 1)) {
+		    (asoc->sctp_cmt_on_off > 0)) {
 			/* out of a RFC2582 Fast recovery window? */
 			if (net->net_ack > 0) {
 				/*
@@ -917,7 +916,7 @@ sctp_hs_cwnd_update_after_sack(struct sc
 			 * 
 			 * Should we stop any running T3 timer here?
 			 */
-			if ((asoc->sctp_cmt_on_off == 1) &&
+			if ((asoc->sctp_cmt_on_off > 0) &&
 			    (asoc->sctp_cmt_pf > 0) &&
 			    ((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
 				net->dest_state &= ~SCTP_ADDR_PF;
@@ -937,10 +936,9 @@ sctp_hs_cwnd_update_after_sack(struct sc
 		 * CMT fast recovery code
 		 */
 		/*
-		 * if (sctp_cmt_on_off == 1 &&
-		 * net->fast_retran_loss_recovery &&
-		 * net->will_exit_fast_recovery == 0) { @@@ Do something }
-		 * else if (sctp_cmt_on_off == 0 &&
+		 * if (sctp_cmt_on_off > 0 && net->fast_retran_loss_recovery
+		 * && net->will_exit_fast_recovery == 0) { @@@ Do something
+		 * } else if (sctp_cmt_on_off == 0 &&
 		 * asoc->fast_retran_loss_recovery && will_exit == 0) {
 		 */
 #endif
@@ -959,7 +957,7 @@ sctp_hs_cwnd_update_after_sack(struct sc
 		 * moved.
 		 */
 		if (accum_moved ||
-		    ((asoc->sctp_cmt_on_off == 1) && net->new_pseudo_cumack)) {
+		    ((asoc->sctp_cmt_on_off > 0) && net->new_pseudo_cumack)) {
 			/* If the cumulative ack moved we can proceed */
 			if (net->cwnd <= net->ssthresh) {
 				/* We are in slow start */
@@ -1403,7 +1401,7 @@ sctp_htcp_cwnd_update_after_sack(struct 
 			 * 
 			 * Should we stop any running T3 timer here?
 			 */
-			if ((asoc->sctp_cmt_on_off == 1) &&
+			if ((asoc->sctp_cmt_on_off > 0) &&
 			    (asoc->sctp_cmt_pf > 0) &&
 			    ((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
 				net->dest_state &= ~SCTP_ADDR_PF;
@@ -1423,10 +1421,9 @@ sctp_htcp_cwnd_update_after_sack(struct 
 		 * CMT fast recovery code
 		 */
 		/*
-		 * if (sctp_cmt_on_off == 1 &&
-		 * net->fast_retran_loss_recovery &&
-		 * net->will_exit_fast_recovery == 0) { @@@ Do something }
-		 * else if (sctp_cmt_on_off == 0 &&
+		 * if (sctp_cmt_on_off > 0 && net->fast_retran_loss_recovery
+		 * && net->will_exit_fast_recovery == 0) { @@@ Do something
+		 * } else if (sctp_cmt_on_off == 0 &&
 		 * asoc->fast_retran_loss_recovery && will_exit == 0) {
 		 */
 #endif
@@ -1445,7 +1442,7 @@ sctp_htcp_cwnd_update_after_sack(struct 
 		 * moved.
 		 */
 		if (accum_moved ||
-		    ((asoc->sctp_cmt_on_off == 1) && net->new_pseudo_cumack)) {
+		    ((asoc->sctp_cmt_on_off > 0) && net->new_pseudo_cumack)) {
 			htcp_cong_avoid(stcb, net);
 			measure_achieved_throughput(stcb, net);
 		} else {
@@ -1481,12 +1478,12 @@ sctp_htcp_cwnd_update_after_fr(struct sc
 	struct sctp_nets *net;
 
 	/*
-	 * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off == 1) &&
+	 * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off > 0) &&
 	 * (net->fast_retran_loss_recovery == 0)))
 	 */
 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
 		if ((asoc->fast_retran_loss_recovery == 0) ||
-		    (asoc->sctp_cmt_on_off == 1)) {
+		    (asoc->sctp_cmt_on_off > 0)) {
 			/* out of a RFC2582 Fast recovery window? */
 			if (net->net_ack > 0) {
 				/*

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c	Wed Dec 22 17:12:58 2010	(r216668)
+++ head/sys/netinet/sctp_indata.c	Wed Dec 22 17:59:38 2010	(r216669)
@@ -2476,7 +2476,7 @@ sctp_sack_check(struct sctp_tcb *stcb, i
 		    (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq)	/* hit limit of pkts */
 		    ) {
 
-			if ((stcb->asoc.sctp_cmt_on_off == 1) &&
+			if ((stcb->asoc.sctp_cmt_on_off > 0) &&
 			    (SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) &&
 			    (stcb->asoc.send_sack == 0) &&
 			    (stcb->asoc.numduptsns == 0) &&
@@ -3242,7 +3242,7 @@ sctp_strike_gap_ack_chunks(struct sctp_t
 	}
 
 	/* CMT DAC algo: finding out if SACK is a mixed SACK */
-	if ((asoc->sctp_cmt_on_off == 1) &&
+	if ((asoc->sctp_cmt_on_off > 0) &&
 	    SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
 		TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
 			if (net->saw_newack)
@@ -3353,7 +3353,7 @@ sctp_strike_gap_ack_chunks(struct sctp_t
 			if (tp1->sent < SCTP_DATAGRAM_RESEND) {
 				tp1->sent++;
 			}
-			if ((asoc->sctp_cmt_on_off == 1) &&
+			if ((asoc->sctp_cmt_on_off > 0) &&
 			    SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
 				/*
 				 * CMT DAC algorithm: If SACK flag is set to
@@ -3419,7 +3419,7 @@ sctp_strike_gap_ack_chunks(struct sctp_t
 						tp1->sent++;
 					}
 					strike_flag = 1;
-					if ((asoc->sctp_cmt_on_off == 1) &&
+					if ((asoc->sctp_cmt_on_off > 0) &&
 					    SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
 						/*
 						 * CMT DAC algorithm: If
@@ -3480,7 +3480,7 @@ sctp_strike_gap_ack_chunks(struct sctp_t
 			if (tp1->sent < SCTP_DATAGRAM_RESEND) {
 				tp1->sent++;
 			}
-			if ((asoc->sctp_cmt_on_off == 1) &&
+			if ((asoc->sctp_cmt_on_off > 0) &&
 			    SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
 				/*
 				 * CMT DAC algorithm: If SACK flag is set to
@@ -3560,7 +3560,7 @@ sctp_strike_gap_ack_chunks(struct sctp_t
 				SCTP_STAT_INCR(sctps_sendmultfastretrans);
 			}
 			sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
-			if (asoc->sctp_cmt_on_off == 1) {
+			if (asoc->sctp_cmt_on_off > 0) {
 				/*
 				 * CMT: Using RTX_SSTHRESH policy for CMT.
 				 * If CMT is being used, then pick dest with
@@ -4776,7 +4776,7 @@ sctp_handle_sack(struct mbuf *m, int off
 	/*******************************************/
 	/* cancel ALL T3-send timer if accum moved */
 	/*******************************************/
-	if (asoc->sctp_cmt_on_off == 1) {
+	if (asoc->sctp_cmt_on_off > 0) {
 		TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
 			if (net->new_pseudo_cumack)
 				sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
@@ -4797,10 +4797,7 @@ sctp_handle_sack(struct mbuf *m, int off
 	/********************************************/
 	asoc->last_acked_seq = cum_ack;
 
-	tp1 = TAILQ_FIRST(&asoc->sent_queue);
-	if (tp1 == NULL)
-		goto done_with_it;
-	do {
+	TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) {
 		if (compare_with_wrap(tp1->rec.data.TSN_seq, cum_ack,
 		    MAX_TSN)) {
 			break;
@@ -4810,26 +4807,17 @@ sctp_handle_sack(struct mbuf *m, int off
 			printf("Warning, tp1->sent == %d and its now acked?\n",
 			    tp1->sent);
 		}
-		tp2 = TAILQ_NEXT(tp1, sctp_next);
 		TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
 		if (tp1->pr_sctp_on) {
 			if (asoc->pr_sctp_cnt != 0)
 				asoc->pr_sctp_cnt--;
 		}
-		if (TAILQ_EMPTY(&asoc->sent_queue) &&
-		    (asoc->total_flight > 0)) {
-#ifdef INVARIANTS
-			panic("Warning flight size is postive and should be 0");
-#else
-			SCTP_PRINTF("Warning flight size incorrect should be 0 is %d\n",
-			    asoc->total_flight);
-#endif
-			asoc->total_flight = 0;
-		}
+		asoc->sent_queue_cnt--;
 		if (tp1->data) {
 			/* sa_ignore NO_NULL_CHK */
 			sctp_free_bufspace(stcb, asoc, tp1, 1);
 			sctp_m_freem(tp1->data);
+			tp1->data = NULL;
 			if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(tp1->flags)) {
 				asoc->sent_queue_cnt_removeable--;
 			}
@@ -4842,14 +4830,18 @@ sctp_handle_sack(struct mbuf *m, int off
 			    0,
 			    SCTP_LOG_FREE_SENT);
 		}
-		tp1->data = NULL;
-		asoc->sent_queue_cnt--;
 		sctp_free_a_chunk(stcb, tp1);
 		wake_him++;
-		tp1 = tp2;
-	} while (tp1 != NULL);
-
-done_with_it:
+	}
+	if (TAILQ_EMPTY(&asoc->sent_queue) && (asoc->total_flight > 0)) {
+#ifdef INVARIANTS
+		panic("Warning flight size is postive and should be 0");
+#else
+		SCTP_PRINTF("Warning flight size incorrect should be 0 is %d\n",
+		    asoc->total_flight);
+#endif
+		asoc->total_flight = 0;
+	}
 	/* sa_ignore NO_NULL_CHK */
 	if ((wake_him) && (stcb->sctp_socket)) {
 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -5077,7 +5069,7 @@ done_with_it:
 	 * to be done. Setting this_sack_lowest_newack to the cum_ack will
 	 * automatically ensure that.
 	 */
-	if ((asoc->sctp_cmt_on_off == 1) &&
+	if ((asoc->sctp_cmt_on_off > 0) &&
 	    SCTP_BASE_SYSCTL(sctp_cmt_use_dac) &&
 	    (cmt_dac_flag == 0)) {
 		this_sack_lowest_newack = cum_ack;

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c	Wed Dec 22 17:12:58 2010	(r216668)
+++ head/sys/netinet/sctp_input.c	Wed Dec 22 17:59:38 2010	(r216669)
@@ -623,7 +623,7 @@ sctp_handle_heartbeat_ack(struct sctp_he
 	 * timer is running, for the destination, stop the timer because a
 	 * PF-heartbeat was received.
 	 */
-	if ((stcb->asoc.sctp_cmt_on_off == 1) &&
+	if ((stcb->asoc.sctp_cmt_on_off > 0) &&
 	    (stcb->asoc.sctp_cmt_pf > 0) &&
 	    ((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
 		if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c	Wed Dec 22 17:12:58 2010	(r216668)
+++ head/sys/netinet/sctp_output.c	Wed Dec 22 17:59:38 2010	(r216669)
@@ -3686,7 +3686,7 @@ sctp_lowlevel_chunk_output(struct sctp_i
 						 * Stop any running T3
 						 * timers here?
 						 */
-						if ((stcb->asoc.sctp_cmt_on_off == 1) &&
+						if ((stcb->asoc.sctp_cmt_on_off > 0) &&
 						    (stcb->asoc.sctp_cmt_pf > 0)) {
 							net->dest_state &= ~SCTP_ADDR_PF;
 							SCTPDBG(SCTP_DEBUG_OUTPUT1, "Destination %p moved from PF to unreachable.\n",
@@ -7325,7 +7325,7 @@ sctp_fill_outqueue(struct sctp_tcb *stcb
 		    (net == stcb->asoc.primary_destination)) {
 			/* ran dry for primary network net */
 			SCTP_STAT_INCR(sctps_primary_randry);
-		} else if (stcb->asoc.sctp_cmt_on_off == 1) {
+		} else if (stcb->asoc.sctp_cmt_on_off > 0) {
 			/* ran dry with CMT on */
 			SCTP_STAT_INCR(sctps_cmt_randry);
 		}
@@ -7526,7 +7526,7 @@ sctp_med_chunk_output(struct sctp_inpcb 
 		*reason_code = 8;
 		return (0);
 	}
-	if (asoc->sctp_cmt_on_off == 1) {
+	if (asoc->sctp_cmt_on_off > 0) {
 		/* get the last start point */
 		start_at = asoc->last_net_cmt_send_started;
 		if (start_at == NULL) {
@@ -8028,7 +8028,7 @@ again_one_more_time:
 			}
 		}
 		/* JRI: if dest is in PF state, do not send data to it */
-		if ((asoc->sctp_cmt_on_off == 1) &&
+		if ((asoc->sctp_cmt_on_off > 0) &&
 		    (asoc->sctp_cmt_pf > 0) &&
 		    (net->dest_state & SCTP_ADDR_PF)) {
 			goto no_data_fill;
@@ -8036,7 +8036,7 @@ again_one_more_time:
 		if (net->flight_size >= net->cwnd) {
 			goto no_data_fill;
 		}
-		if ((asoc->sctp_cmt_on_off == 1) &&
+		if ((asoc->sctp_cmt_on_off > 0) &&
 		    (SCTP_BASE_SYSCTL(sctp_buffer_splitting) & SCTP_RECV_BUFFER_SPLITTING) &&
 		    (net->flight_size > max_rwnd_per_dest)) {
 			goto no_data_fill;
@@ -8047,7 +8047,7 @@ again_one_more_time:
 		 * net. For now, this is better than nothing and it disabled
 		 * by default...
 		 */
-		if ((asoc->sctp_cmt_on_off == 1) &&
+		if ((asoc->sctp_cmt_on_off > 0) &&
 		    (SCTP_BASE_SYSCTL(sctp_buffer_splitting) & SCTP_SEND_BUFFER_SPLITTING) &&
 		    (max_send_per_dest > 0) &&
 		    (net->flight_size > max_send_per_dest)) {
@@ -8268,7 +8268,7 @@ no_data_fill:
 				 * restart it.
 				 */
 				sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
-			} else if ((asoc->sctp_cmt_on_off == 1) &&
+			} else if ((asoc->sctp_cmt_on_off > 0) &&
 				    (asoc->sctp_cmt_pf > 0) &&
 				    pf_hbflag &&
 				    ((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF) &&
@@ -9576,7 +9576,7 @@ sctp_chunk_output(struct sctp_inpcb *inp
 			 */
 			if (net->ref_count > 1)
 				sctp_move_chunks_from_net(stcb, net);
-		} else if ((asoc->sctp_cmt_on_off == 1) &&
+		} else if ((asoc->sctp_cmt_on_off > 0) &&
 			    (asoc->sctp_cmt_pf > 0) &&
 		    ((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
 			/*
@@ -10073,7 +10073,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
 	else
 		flags = 0;
 
-	if ((asoc->sctp_cmt_on_off == 1) &&
+	if ((asoc->sctp_cmt_on_off > 0) &&
 	    SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
 		/*-
 		 * CMT DAC algorithm: If 2 (i.e., 0x10) packets have been

Modified: head/sys/netinet/sctp_sysctl.h
==============================================================================
--- head/sys/netinet/sctp_sysctl.h	Wed Dec 22 17:12:58 2010	(r216668)
+++ head/sys/netinet/sctp_sysctl.h	Wed Dec 22 17:59:38 2010	(r216669)
@@ -325,9 +325,9 @@ struct sctp_sysctl {
 #define SCTPCTL_OUTGOING_STREAMS_DEFAULT SCTP_OSTREAM_INITIAL
 
 /* cmt_on_off: CMT on/off flag */
-#define SCTPCTL_CMT_ON_OFF_DESC		"CMT on/off flag"
+#define SCTPCTL_CMT_ON_OFF_DESC		"CMT settings"
 #define SCTPCTL_CMT_ON_OFF_MIN		0
-#define SCTPCTL_CMT_ON_OFF_MAX		1
+#define SCTPCTL_CMT_ON_OFF_MAX		2
 #define SCTPCTL_CMT_ON_OFF_DEFAULT	0
 
 /* EY - nr_sack_on_off: NR_SACK on/off flag */

Modified: head/sys/netinet/sctp_timer.c
==============================================================================
--- head/sys/netinet/sctp_timer.c	Wed Dec 22 17:12:58 2010	(r216668)
+++ head/sys/netinet/sctp_timer.c	Wed Dec 22 17:59:38 2010	(r216669)
@@ -215,7 +215,7 @@ sctp_threshold_management(struct sctp_in
 				 * not in PF state.
 				 */
 				/* Stop any running T3 timers here? */
-				if ((stcb->asoc.sctp_cmt_on_off == 1) &&
+				if ((stcb->asoc.sctp_cmt_on_off > 0) &&
 				    (stcb->asoc.sctp_cmt_pf > 0)) {
 					net->dest_state &= ~SCTP_ADDR_PF;
 					SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n",
@@ -850,7 +850,7 @@ start_again:
 			/*
 			 * CMT: Do not allow FRs on retransmitted TSNs.
 			 */
-			if (stcb->asoc.sctp_cmt_on_off == 1) {
+			if (stcb->asoc.sctp_cmt_on_off > 0) {
 				chk->no_fr_allowed = 1;
 			}
 #ifdef THIS_SHOULD_NOT_BE_DONE
@@ -1005,7 +1005,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
 	 * addition, find an alternate destination with PF-based
 	 * find_alt_net().
 	 */
-	if ((stcb->asoc.sctp_cmt_on_off == 1) &&
+	if ((stcb->asoc.sctp_cmt_on_off > 0) &&
 	    (stcb->asoc.sctp_cmt_pf > 0)) {
 		if ((net->dest_state & SCTP_ADDR_PF) != SCTP_ADDR_PF) {
 			net->dest_state |= SCTP_ADDR_PF;
@@ -1014,7 +1014,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
 			    net);
 		}
 		alt = sctp_find_alternate_net(stcb, net, 2);
-	} else if (stcb->asoc.sctp_cmt_on_off == 1) {
+	} else if (stcb->asoc.sctp_cmt_on_off > 0) {
 		/*
 		 * CMT: Using RTX_SSTHRESH policy for CMT. If CMT is being
 		 * used, then pick dest with largest ssthresh for any
@@ -1129,7 +1129,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
 				net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
 			}
 		}
-	} else if ((stcb->asoc.sctp_cmt_on_off == 1) &&
+	} else if ((stcb->asoc.sctp_cmt_on_off > 0) &&
 		    (stcb->asoc.sctp_cmt_pf > 0) &&
 	    ((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
 		/*

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c	Wed Dec 22 17:12:58 2010	(r216668)
+++ head/sys/netinet/sctp_usrreq.c	Wed Dec 22 17:59:38 2010	(r216669)
@@ -292,7 +292,7 @@ sctp_notify(struct sctp_inpcb *inp,
 			 * PF state.
 			 */
 			/* Stop any running T3 timers here? */
-			if ((stcb->asoc.sctp_cmt_on_off == 1) &&
+			if ((stcb->asoc.sctp_cmt_on_off > 0) &&
 			    (stcb->asoc.sctp_cmt_pf > 0)) {
 				net->dest_state &= ~SCTP_ADDR_PF;
 				SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n",
@@ -2840,17 +2840,17 @@ sctp_setopt(struct socket *so, int optna
 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
 			if (stcb) {
-				if (av->assoc_value != 0)
-					stcb->asoc.sctp_cmt_on_off = 1;
-				else
-					stcb->asoc.sctp_cmt_on_off = 0;
+				stcb->asoc.sctp_cmt_on_off = av->assoc_value;
+				if (stcb->asoc.sctp_cmt_on_off > 2) {
+					stcb->asoc.sctp_cmt_on_off = 2;
+				}
 				SCTP_TCB_UNLOCK(stcb);
 			} else {
 				SCTP_INP_WLOCK(inp);
-				if (av->assoc_value != 0)
-					inp->sctp_cmt_on_off = 1;
-				else
-					inp->sctp_cmt_on_off = 0;
+				inp->sctp_cmt_on_off = av->assoc_value;
+				if (inp->sctp_cmt_on_off > 2) {
+					inp->sctp_cmt_on_off = 2;
+				}
 				SCTP_INP_WUNLOCK(inp);
 			}
 		} else {

Modified: head/sys/netinet6/sctp6_usrreq.c
==============================================================================
--- head/sys/netinet6/sctp6_usrreq.c	Wed Dec 22 17:12:58 2010	(r216668)
+++ head/sys/netinet6/sctp6_usrreq.c	Wed Dec 22 17:59:38 2010	(r216669)
@@ -426,7 +426,7 @@ sctp6_notify(struct sctp_inpcb *inp,
 			 * PF state.
 			 */
 			/* Stop any running T3 timers here? */
-			if ((stcb->asoc.sctp_cmt_on_off == 1) &&
+			if ((stcb->asoc.sctp_cmt_on_off > 0) &&
 			    (stcb->asoc.sctp_cmt_pf > 0)) {
 				net->dest_state &= ~SCTP_ADDR_PF;
 				SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n",



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