Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Feb 2012 20:17:28 +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: r231423 - stable/8/sys/netinet
Message-ID:  <201202102017.q1AKHSch092225@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Fri Feb 10 20:17:28 2012
New Revision: 231423
URL: http://svn.freebsd.org/changeset/base/231423

Log:
  MFC r219057:
  Improvements to CC modules:
  1) Add four new points that allow you to get more information
     to cc algo's
  2) Fix the case where user changes module on a existing TCB, in
     such a case, the initialization module needs to be called on all nets.
  3) Move htcp_cc structure to a union that other modules can use.
  4) Add 5th point for get/set socket options for cc_module specific options
  From rrs@.

Modified:
  stable/8/sys/netinet/sctp.h
  stable/8/sys/netinet/sctp_cc_functions.c
  stable/8/sys/netinet/sctp_dtrace_declare.h
  stable/8/sys/netinet/sctp_dtrace_define.h
  stable/8/sys/netinet/sctp_indata.c
  stable/8/sys/netinet/sctp_output.c
  stable/8/sys/netinet/sctp_pcb.c
  stable/8/sys/netinet/sctp_structs.h
  stable/8/sys/netinet/sctp_sysctl.c
  stable/8/sys/netinet/sctp_sysctl.h
  stable/8/sys/netinet/sctp_timer.c
  stable/8/sys/netinet/sctp_uio.h
  stable/8/sys/netinet/sctp_usrreq.c
  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 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp.h	Fri Feb 10 20:17:28 2012	(r231423)
@@ -161,9 +161,10 @@ struct sctp_paramhdr {
 /* JRS - Pluggable Congestion Control Socket option */
 #define SCTP_PLUGGABLE_CC               0x00001202
 /* RS - Pluggable Stream Scheduling Socket option */
-#define SCTP_PLUGGABLE_SS				0x00001203
-#define SCTP_SS_VALUE					0x00001204
-
+#define SCTP_PLUGGABLE_SS		0x00001203
+#define SCTP_SS_VALUE			0x00001204
+#define SCTP_CC_OPTION			0x00001205	/* Options for CC
+							 * modules */
 /* read only */
 #define SCTP_GET_SNDBUF_USE		0x00001101
 #define SCTP_GET_STAT_LOG		0x00001103

Modified: stable/8/sys/netinet/sctp_cc_functions.c
==============================================================================
--- stable/8/sys/netinet/sctp_cc_functions.c	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_cc_functions.c	Fri Feb 10 20:17:28 2012	(r231423)
@@ -1135,10 +1135,10 @@ htcp_reset(struct htcp *ca)
 static uint32_t
 htcp_cwnd_undo(struct sctp_tcb *stcb, struct sctp_nets *net)
 {
-	net->htcp_ca.last_cong = net->htcp_ca.undo_last_cong;
-	net->htcp_ca.maxRTT = net->htcp_ca.undo_maxRTT;
-	net->htcp_ca.old_maxB = net->htcp_ca.undo_old_maxB;
-	return max(net->cwnd, ((net->ssthresh / net->mtu << 7) / net->htcp_ca.beta) * net->mtu);
+	net->cc_mod.htcp_ca.last_cong = net->cc_mod.htcp_ca.undo_last_cong;
+	net->cc_mod.htcp_ca.maxRTT = net->cc_mod.htcp_ca.undo_maxRTT;
+	net->cc_mod.htcp_ca.old_maxB = net->cc_mod.htcp_ca.undo_old_maxB;
+	return max(net->cwnd, ((net->ssthresh / net->mtu << 7) / net->cc_mod.htcp_ca.beta) * net->mtu);
 }
 
 #endif
@@ -1149,15 +1149,15 @@ measure_rtt(struct sctp_tcb *stcb, struc
 	uint32_t srtt = net->lastsa >> SCTP_RTT_SHIFT;
 
 	/* keep track of minimum RTT seen so far, minRTT is zero at first */
-	if (net->htcp_ca.minRTT > srtt || !net->htcp_ca.minRTT)
-		net->htcp_ca.minRTT = srtt;
+	if (net->cc_mod.htcp_ca.minRTT > srtt || !net->cc_mod.htcp_ca.minRTT)
+		net->cc_mod.htcp_ca.minRTT = srtt;
 
 	/* max RTT */
-	if (net->fast_retran_ip == 0 && net->ssthresh < 0xFFFF && htcp_ccount(&net->htcp_ca) > 3) {
-		if (net->htcp_ca.maxRTT < net->htcp_ca.minRTT)
-			net->htcp_ca.maxRTT = net->htcp_ca.minRTT;
-		if (net->htcp_ca.maxRTT < srtt && srtt <= net->htcp_ca.maxRTT + MSEC_TO_TICKS(20))
-			net->htcp_ca.maxRTT = srtt;
+	if (net->fast_retran_ip == 0 && net->ssthresh < 0xFFFF && htcp_ccount(&net->cc_mod.htcp_ca) > 3) {
+		if (net->cc_mod.htcp_ca.maxRTT < net->cc_mod.htcp_ca.minRTT)
+			net->cc_mod.htcp_ca.maxRTT = net->cc_mod.htcp_ca.minRTT;
+		if (net->cc_mod.htcp_ca.maxRTT < srtt && srtt <= net->cc_mod.htcp_ca.maxRTT + MSEC_TO_TICKS(20))
+			net->cc_mod.htcp_ca.maxRTT = srtt;
 	}
 }
 
@@ -1167,7 +1167,7 @@ measure_achieved_throughput(struct sctp_
 	uint32_t now = sctp_get_tick_count();
 
 	if (net->fast_retran_ip == 0)
-		net->htcp_ca.bytes_acked = net->net_ack;
+		net->cc_mod.htcp_ca.bytes_acked = net->net_ack;
 
 	if (!use_bandwidth_switch)
 		return;
@@ -1175,29 +1175,29 @@ measure_achieved_throughput(struct sctp_
 	/* achieved throughput calculations */
 	/* JRS - not 100% sure of this statement */
 	if (net->fast_retran_ip == 1) {
-		net->htcp_ca.bytecount = 0;
-		net->htcp_ca.lasttime = now;
+		net->cc_mod.htcp_ca.bytecount = 0;
+		net->cc_mod.htcp_ca.lasttime = now;
 		return;
 	}
-	net->htcp_ca.bytecount += net->net_ack;
+	net->cc_mod.htcp_ca.bytecount += net->net_ack;
 
-	if (net->htcp_ca.bytecount >= net->cwnd - ((net->htcp_ca.alpha >> 7 ? : 1) * net->mtu)
-	    && now - net->htcp_ca.lasttime >= net->htcp_ca.minRTT
-	    && net->htcp_ca.minRTT > 0) {
-		uint32_t cur_Bi = net->htcp_ca.bytecount / net->mtu * hz / (now - net->htcp_ca.lasttime);
+	if (net->cc_mod.htcp_ca.bytecount >= net->cwnd - ((net->cc_mod.htcp_ca.alpha >> 7 ? : 1) * net->mtu)
+	    && now - net->cc_mod.htcp_ca.lasttime >= net->cc_mod.htcp_ca.minRTT
+	    && net->cc_mod.htcp_ca.minRTT > 0) {
+		uint32_t cur_Bi = net->cc_mod.htcp_ca.bytecount / net->mtu * hz / (now - net->cc_mod.htcp_ca.lasttime);
 
-		if (htcp_ccount(&net->htcp_ca) <= 3) {
+		if (htcp_ccount(&net->cc_mod.htcp_ca) <= 3) {
 			/* just after backoff */
-			net->htcp_ca.minB = net->htcp_ca.maxB = net->htcp_ca.Bi = cur_Bi;
+			net->cc_mod.htcp_ca.minB = net->cc_mod.htcp_ca.maxB = net->cc_mod.htcp_ca.Bi = cur_Bi;
 		} else {
-			net->htcp_ca.Bi = (3 * net->htcp_ca.Bi + cur_Bi) / 4;
-			if (net->htcp_ca.Bi > net->htcp_ca.maxB)
-				net->htcp_ca.maxB = net->htcp_ca.Bi;
-			if (net->htcp_ca.minB > net->htcp_ca.maxB)
-				net->htcp_ca.minB = net->htcp_ca.maxB;
+			net->cc_mod.htcp_ca.Bi = (3 * net->cc_mod.htcp_ca.Bi + cur_Bi) / 4;
+			if (net->cc_mod.htcp_ca.Bi > net->cc_mod.htcp_ca.maxB)
+				net->cc_mod.htcp_ca.maxB = net->cc_mod.htcp_ca.Bi;
+			if (net->cc_mod.htcp_ca.minB > net->cc_mod.htcp_ca.maxB)
+				net->cc_mod.htcp_ca.minB = net->cc_mod.htcp_ca.maxB;
 		}
-		net->htcp_ca.bytecount = 0;
-		net->htcp_ca.lasttime = now;
+		net->cc_mod.htcp_ca.bytecount = 0;
+		net->cc_mod.htcp_ca.lasttime = now;
 	}
 }
 
@@ -1264,25 +1264,25 @@ htcp_alpha_update(struct htcp *ca)
 static void
 htcp_param_update(struct sctp_tcb *stcb, struct sctp_nets *net)
 {
-	uint32_t minRTT = net->htcp_ca.minRTT;
-	uint32_t maxRTT = net->htcp_ca.maxRTT;
+	uint32_t minRTT = net->cc_mod.htcp_ca.minRTT;
+	uint32_t maxRTT = net->cc_mod.htcp_ca.maxRTT;
 
-	htcp_beta_update(&net->htcp_ca, minRTT, maxRTT);
-	htcp_alpha_update(&net->htcp_ca);
+	htcp_beta_update(&net->cc_mod.htcp_ca, minRTT, maxRTT);
+	htcp_alpha_update(&net->cc_mod.htcp_ca);
 
 	/*
 	 * add slowly fading memory for maxRTT to accommodate routing
 	 * changes etc
 	 */
 	if (minRTT > 0 && maxRTT > minRTT)
-		net->htcp_ca.maxRTT = minRTT + ((maxRTT - minRTT) * 95) / 100;
+		net->cc_mod.htcp_ca.maxRTT = minRTT + ((maxRTT - minRTT) * 95) / 100;
 }
 
 static uint32_t
 htcp_recalc_ssthresh(struct sctp_tcb *stcb, struct sctp_nets *net)
 {
 	htcp_param_update(stcb, net);
-	return max(((net->cwnd / net->mtu * net->htcp_ca.beta) >> 7) * net->mtu, 2U * net->mtu);
+	return max(((net->cwnd / net->mtu * net->cc_mod.htcp_ca.beta) >> 7) * net->mtu, 2U * net->mtu);
 }
 
 static void
@@ -1323,14 +1323,14 @@ htcp_cong_avoid(struct sctp_tcb *stcb, s
 		 * net->cwnd += alpha / net->cwnd
 		 */
 		/* What is snd_cwnd_cnt?? */
-		if (((net->partial_bytes_acked / net->mtu * net->htcp_ca.alpha) >> 7) * net->mtu >= net->cwnd) {
+		if (((net->partial_bytes_acked / net->mtu * net->cc_mod.htcp_ca.alpha) >> 7) * net->mtu >= net->cwnd) {
 			/*-
 			 * Does SCTP have a cwnd clamp?
 			 * if (net->snd_cwnd < net->snd_cwnd_clamp) - Nope (RRS).
 			 */
 			net->cwnd += net->mtu;
 			net->partial_bytes_acked = 0;
-			htcp_alpha_update(&net->htcp_ca);
+			htcp_alpha_update(&net->cc_mod.htcp_ca);
 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
 				sctp_log_cwnd(stcb, net, net->mtu,
 				    SCTP_CWND_LOG_FROM_CA);
@@ -1343,7 +1343,7 @@ htcp_cong_avoid(struct sctp_tcb *stcb, s
 			}
 		}
 
-		net->htcp_ca.bytes_acked = net->mtu;
+		net->cc_mod.htcp_ca.bytes_acked = net->mtu;
 	}
 }
 
@@ -1360,11 +1360,11 @@ htcp_min_cwnd(struct sctp_tcb *stcb, str
 static void
 htcp_init(struct sctp_tcb *stcb, struct sctp_nets *net)
 {
-	memset(&net->htcp_ca, 0, sizeof(struct htcp));
-	net->htcp_ca.alpha = ALPHA_BASE;
-	net->htcp_ca.beta = BETA_MIN;
-	net->htcp_ca.bytes_acked = net->mtu;
-	net->htcp_ca.last_cong = sctp_get_tick_count();
+	memset(&net->cc_mod.htcp_ca, 0, sizeof(struct htcp));
+	net->cc_mod.htcp_ca.alpha = ALPHA_BASE;
+	net->cc_mod.htcp_ca.beta = BETA_MIN;
+	net->cc_mod.htcp_ca.bytes_acked = net->mtu;
+	net->cc_mod.htcp_ca.last_cong = sctp_get_tick_count();
 }
 
 static void
@@ -1568,7 +1568,7 @@ sctp_htcp_cwnd_update_after_fr(struct sc
 				int old_cwnd = net->cwnd;
 
 				/* JRS - reset as if state were changed */
-				htcp_reset(&net->htcp_ca);
+				htcp_reset(&net->cc_mod.htcp_ca);
 				net->ssthresh = htcp_recalc_ssthresh(stcb, net);
 				net->cwnd = net->ssthresh;
 				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
@@ -1622,7 +1622,7 @@ sctp_htcp_cwnd_update_after_timeout(stru
 	int old_cwnd = net->cwnd;
 
 	/* JRS - reset as if the state were being changed to timeout */
-	htcp_reset(&net->htcp_ca);
+	htcp_reset(&net->cc_mod.htcp_ca);
 	net->ssthresh = htcp_recalc_ssthresh(stcb, net);
 	net->cwnd = net->mtu;
 	net->partial_bytes_acked = 0;
@@ -1640,7 +1640,7 @@ sctp_htcp_cwnd_update_after_fr_timer(str
 	old_cwnd = net->cwnd;
 
 	sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_EARLY_FR_TMR, SCTP_SO_NOT_LOCKED);
-	net->htcp_ca.last_cong = sctp_get_tick_count();
+	net->cc_mod.htcp_ca.last_cong = sctp_get_tick_count();
 	/*
 	 * make a small adjustment to cwnd and force to CA.
 	 */
@@ -1665,7 +1665,7 @@ sctp_htcp_cwnd_update_after_ecn_echo(str
 
 	/* JRS - reset hctp as if state changed */
 	if (in_window == 0) {
-		htcp_reset(&net->htcp_ca);
+		htcp_reset(&net->cc_mod.htcp_ca);
 		SCTP_STAT_INCR(sctps_ecnereducedcwnd);
 		net->ssthresh = htcp_recalc_ssthresh(stcb, net);
 		if (net->ssthresh < net->mtu) {

Modified: stable/8/sys/netinet/sctp_dtrace_declare.h
==============================================================================
--- stable/8/sys/netinet/sctp_dtrace_declare.h	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_dtrace_declare.h	Fri Feb 10 20:17:28 2012	(r231423)
@@ -55,6 +55,8 @@ SDT_PROBE_DECLARE(sctp, cwnd, net, bl);
 SDT_PROBE_DECLARE(sctp, cwnd, net, ecn);
 /* update at a Packet-Drop -- decrease */
 SDT_PROBE_DECLARE(sctp, cwnd, net, pd);
+/* Rttvar probe declaration */
+SDT_PROBE_DECLARE(sctp, cwnd, net, rttvar);
 
 /* One to track an associations rwnd */
 SDT_PROBE_DECLARE(sctp, rwnd, assoc, val);

Modified: stable/8/sys/netinet/sctp_dtrace_define.h
==============================================================================
--- stable/8/sys/netinet/sctp_dtrace_define.h	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_dtrace_define.h	Fri Feb 10 20:17:28 2012	(r231423)
@@ -71,6 +71,21 @@ SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 
 /* The new value of the cwnd */
 SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 4, "int");
 
+
+/* ACK-INCREASE */
+SDT_PROBE_DEFINE(sctp, cwnd, net, rttvar, rttvar);
+/* The Vtag << 32 | localport << 16 | remoteport */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 0, "uint64_t");
+/* obw | nbw */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 1, "uint64_t");
+/* newrtt */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 2, "uint64_t");
+/* bwrtt  */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 3, "uint64_t");
+/* (cwnd << 32) | point << 16 | retval(0/1) */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 4, "uint64_t");
+
+
 /* FastRetransmit-DECREASE */
 SDT_PROBE_DEFINE(sctp, cwnd, net, fr, fr);
 /* The Vtag for this end */

Modified: stable/8/sys/netinet/sctp_indata.c
==============================================================================
--- stable/8/sys/netinet/sctp_indata.c	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_indata.c	Fri Feb 10 20:17:28 2012	(r231423)
@@ -2939,6 +2939,10 @@ sctp_process_segment_range(struct sctp_t
 							    tp1->rec.data.TSN_seq);
 						}
 						sctp_flight_size_decrease(tp1);
+						if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) {
+							(*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) (tp1->whoTo,
+							    tp1);
+						}
 						sctp_total_flight_decrease(stcb, tp1);
 
 						tp1->whoTo->net_ack += tp1->send_size;
@@ -3442,6 +3446,10 @@ sctp_strike_gap_ack_chunks(struct sctp_t
 			if (tp1->whoTo) {
 				tp1->whoTo->net_ack++;
 				sctp_flight_size_decrease(tp1);
+				if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) {
+					(*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) (tp1->whoTo,
+					    tp1);
+				}
 			}
 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_RWND_ENABLE) {
 				sctp_log_rwnd(SCTP_INCREASE_PEER_RWND,
@@ -3737,6 +3745,10 @@ sctp_window_probe_recovery(struct sctp_t
 		return;
 	}
 	/* First setup this by shrinking flight */
+	if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) {
+		(*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) (tp1->whoTo,
+		    tp1);
+	}
 	sctp_flight_size_decrease(tp1);
 	sctp_total_flight_decrease(stcb, tp1);
 	/* Now mark for resend */
@@ -3810,6 +3822,9 @@ sctp_express_handle_sack(struct sctp_tcb
 		 */
 		net->new_pseudo_cumack = 0;
 		net->will_exit_fast_recovery = 0;
+		if (stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) {
+			(*stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) (stcb, net);
+		}
 	}
 	if (SCTP_BASE_SYSCTL(sctp_strict_sacks)) {
 		uint32_t send_s;
@@ -3883,6 +3898,10 @@ sctp_express_handle_sack(struct sctp_tcb
 							    tp1->rec.data.TSN_seq);
 						}
 						sctp_flight_size_decrease(tp1);
+						if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) {
+							(*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) (tp1->whoTo,
+							    tp1);
+						}
 						/* sa_ignore NO_NULL_CHK */
 						sctp_total_flight_decrease(stcb, tp1);
 					}
@@ -4447,6 +4466,9 @@ sctp_handle_sack(struct mbuf *m, int off
 		 */
 		net->new_pseudo_cumack = 0;
 		net->will_exit_fast_recovery = 0;
+		if (stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) {
+			(*stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) (stcb, net);
+		}
 	}
 	/* process the new consecutive TSN first */
 	TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
@@ -4483,6 +4505,10 @@ sctp_handle_sack(struct mbuf *m, int off
 						}
 						sctp_flight_size_decrease(tp1);
 						sctp_total_flight_decrease(stcb, tp1);
+						if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) {
+							(*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) (tp1->whoTo,
+							    tp1);
+						}
 					}
 					tp1->whoTo->net_ack += tp1->send_size;
 

Modified: stable/8/sys/netinet/sctp_output.c
==============================================================================
--- stable/8/sys/netinet/sctp_output.c	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_output.c	Fri Feb 10 20:17:28 2012	(r231423)
@@ -6476,6 +6476,9 @@ all_done:
 			asoc->peers_rwnd = 0;
 		}
 	}
+	if (asoc->cc_functions.sctp_cwnd_update_packet_transmitted) {
+		(*asoc->cc_functions.sctp_cwnd_update_packet_transmitted) (stcb, net);
+	}
 }
 
 static void
@@ -7341,6 +7344,10 @@ nothing_to_send:
 				}
 				continue;
 			}
+			if ((stcb->asoc.cc_functions.sctp_cwnd_new_transmission_begins) &&
+			    (net->flight_size == 0)) {
+				(*stcb->asoc.cc_functions.sctp_cwnd_new_transmission_begins) (stcb, net);
+			}
 			if ((asoc->sctp_cmt_on_off == 0) &&
 			    (asoc->primary_destination != net) &&
 			    (net->ref_count < 2)) {

Modified: stable/8/sys/netinet/sctp_pcb.c
==============================================================================
--- stable/8/sys/netinet/sctp_pcb.c	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_pcb.c	Fri Feb 10 20:17:28 2012	(r231423)
@@ -3953,7 +3953,8 @@ sctp_add_remote_addr(struct sctp_tcb *st
 		stcb->asoc.smallest_mtu = net->mtu;
 	}
 	/* JRS - Use the congestion control given in the CC module */
-	stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
+	if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL)
+		(*stcb->asoc.cc_functions.sctp_set_initial_cc_param) (stcb, net);
 
 	/*
 	 * CMT: CUC algo - set find_pseudo_cumack to TRUE (1) at beginning

Modified: stable/8/sys/netinet/sctp_structs.h
==============================================================================
--- stable/8/sys/netinet/sctp_structs.h	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_structs.h	Fri Feb 10 20:17:28 2012	(r231423)
@@ -219,7 +219,6 @@ struct htcp {
 	uint32_t lasttime;
 };
 
-
 struct sctp_nets {
 	TAILQ_ENTRY(sctp_nets) sctp_next;	/* next link */
 
@@ -254,10 +253,9 @@ struct sctp_nets {
 
 	/* last time in seconds I sent to it */
 	struct timeval last_sent_time;
-
-	/* JRS - struct used in HTCP algorithm */
-	struct htcp htcp_ca;
-
+	union cc_control_data {
+		struct htcp htcp_ca;	/* JRS - struct used in HTCP algorithm */
+	}               cc_mod;
 	int ref_count;
 
 	/* Congestion stats per destination */
@@ -648,6 +646,15 @@ struct sctp_cc_functions {
 	         struct sctp_nets *net, int burst_limit);
 	void (*sctp_cwnd_update_after_fr_timer) (struct sctp_inpcb *inp,
 	         struct sctp_tcb *stcb, struct sctp_nets *net);
+	void (*sctp_cwnd_update_packet_transmitted) (struct sctp_tcb *stcb,
+	         struct sctp_nets *net);
+	void (*sctp_cwnd_update_tsn_acknowledged) (struct sctp_nets *net,
+	         struct sctp_tmit_chunk *);
+	void (*sctp_cwnd_new_transmission_begins) (struct sctp_tcb *stcb,
+	         struct sctp_nets *net);
+	void (*sctp_cwnd_prepare_net_for_sack) (struct sctp_tcb *stcb,
+	         struct sctp_nets *net);
+	int (*sctp_cwnd_socket_option) (struct sctp_tcb *stcb, int set, struct sctp_cc_option *);
 };
 
 /*
@@ -1166,6 +1173,7 @@ struct sctp_association {
 	uint8_t sctp_nr_sack_on_off;
 	/* JRS 5/21/07 - CMT PF variable */
 	uint8_t sctp_cmt_pf;
+	uint8_t use_precise_time;
 	/*
 	 * The mapping array is used to track out of order sequences above
 	 * last_acked_seq. 0 indicates packet missing 1 indicates packet

Modified: stable/8/sys/netinet/sctp_sysctl.c
==============================================================================
--- stable/8/sys/netinet/sctp_sysctl.c	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_sysctl.c	Fri Feb 10 20:17:28 2012	(r231423)
@@ -115,6 +115,9 @@ sctp_init_sysctls()
 	SCTP_BASE_SYSCTL(sctp_vtag_time_wait) = SCTPCTL_TIME_WAIT_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_buffer_splitting) = SCTPCTL_BUFFER_SPLITTING_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_initial_cwnd) = SCTPCTL_INITIAL_CWND_DEFAULT;
+	SCTP_BASE_SYSCTL(sctp_rttvar_bw) = SCTPCTL_RTTVAR_BW_DEFAULT;
+	SCTP_BASE_SYSCTL(sctp_rttvar_rtt) = SCTPCTL_RTTVAR_RTT_DEFAULT;
+	SCTP_BASE_SYSCTL(sctp_rttvar_eqret) = SCTPCTL_RTTVAR_EQRET_DEFAULT;
 #if defined(SCTP_LOCAL_TRACE_BUF)
 	memset(&SCTP_BASE_SYSCTL(sctp_log), 0, sizeof(struct sctp_log));
 #endif
@@ -633,6 +636,9 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_vtag_time_wait), SCTPCTL_TIME_WAIT_MIN, SCTPCTL_TIME_WAIT_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_buffer_splitting), SCTPCTL_BUFFER_SPLITTING_MIN, SCTPCTL_BUFFER_SPLITTING_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_initial_cwnd), SCTPCTL_INITIAL_CWND_MIN, SCTPCTL_INITIAL_CWND_MAX);
+		RANGECHK(SCTP_BASE_SYSCTL(sctp_rttvar_bw), SCTPCTL_RTTVAR_BW_MIN, SCTPCTL_RTTVAR_BW_MAX);
+		RANGECHK(SCTP_BASE_SYSCTL(sctp_rttvar_rtt), SCTPCTL_RTTVAR_RTT_MIN, SCTPCTL_RTTVAR_RTT_MAX);
+		RANGECHK(SCTP_BASE_SYSCTL(sctp_rttvar_eqret), SCTPCTL_RTTVAR_EQRET_MIN, SCTPCTL_RTTVAR_EQRET_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_base), SCTPCTL_MOBILITY_BASE_MIN, SCTPCTL_MOBILITY_BASE_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), SCTPCTL_MOBILITY_FASTHANDOFF_MIN, SCTPCTL_MOBILITY_FASTHANDOFF_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable), SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MIN, SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MAX);
@@ -1100,6 +1106,18 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUT
     &SCTP_BASE_SYSCTL(sctp_initial_cwnd), 0, sysctl_sctp_check, "IU",
     SCTPCTL_INITIAL_CWND_DESC);
 
+SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, rttvar_bw, CTLTYPE_UINT | CTLFLAG_RW,
+    &SCTP_BASE_SYSCTL(sctp_rttvar_bw), 0, sysctl_sctp_check, "IU",
+    SCTPCTL_RTTVAR_BW_DESC);
+
+SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, rttvar_rtt, CTLTYPE_UINT | CTLFLAG_RW,
+    &SCTP_BASE_SYSCTL(sctp_rttvar_rtt), 0, sysctl_sctp_check, "IU",
+    SCTPCTL_RTTVAR_RTT_DESC);
+
+SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, rttvar_eqret, CTLTYPE_UINT | CTLFLAG_RW,
+    &SCTP_BASE_SYSCTL(sctp_rttvar_eqret), 0, sysctl_sctp_check, "IU",
+    SCTPCTL_RTTVAR_EQRET_DESC);
+
 #ifdef SCTP_DEBUG
 SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, debug, CTLTYPE_UINT | CTLFLAG_RW,
     &SCTP_BASE_SYSCTL(sctp_debug_on), 0, sysctl_sctp_check, "IU",

Modified: stable/8/sys/netinet/sctp_sysctl.h
==============================================================================
--- stable/8/sys/netinet/sctp_sysctl.h	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_sysctl.h	Fri Feb 10 20:17:28 2012	(r231423)
@@ -104,6 +104,11 @@ struct sctp_sysctl {
 	uint32_t sctp_mobility_base;
 	uint32_t sctp_mobility_fasthandoff;
 	uint32_t sctp_inits_include_nat_friendly;
+#ifdef SCTP_HAS_RTTCC
+	uint32_t sctp_rttvar_bw;
+	uint32_t sctp_rttvar_rtt;
+	uint32_t sctp_rttvar_eqret;
+#endif
 #if defined(SCTP_LOCAL_TRACE_BUF)
 	struct sctp_log sctp_log;
 #endif
@@ -514,6 +519,25 @@ struct sctp_sysctl {
 #define SCTPCTL_INITIAL_CWND_MIN	0
 #define SCTPCTL_INITIAL_CWND_MAX	0xffffffff
 #define SCTPCTL_INITIAL_CWND_DEFAULT	3
+#ifdef SCTP_HAS_RTTCC
+
+/* rttvar smooth avg for bw calc  */
+#define SCTPCTL_RTTVAR_BW_DESC	"Shift amount for bw smothing on rtt calc"
+#define SCTPCTL_RTTVAR_BW_MIN	0
+#define SCTPCTL_RTTVAR_BW_MAX	32
+#define SCTPCTL_RTTVAR_BW_DEFAULT	4
+
+/* rttvar smooth avg for bw calc  */
+#define SCTPCTL_RTTVAR_RTT_DESC	"Shift amount for rtt smothing on rtt calc"
+#define SCTPCTL_RTTVAR_RTT_MIN	0
+#define SCTPCTL_RTTVAR_RTT_MAX	32
+#define SCTPCTL_RTTVAR_RTT_DEFAULT	5
+
+#define SCTPCTL_RTTVAR_EQRET_DESC	"When rtt and bw are unchanged return what"
+#define SCTPCTL_RTTVAR_EQRET_MIN	0
+#define SCTPCTL_RTTVAR_EQRET_MAX	1
+#define SCTPCTL_RTTVAR_EQRET_DEFAULT	0
+#endif
 
 #if defined(SCTP_DEBUG)
 /* debug: Configure debug output */

Modified: stable/8/sys/netinet/sctp_timer.c
==============================================================================
--- stable/8/sys/netinet/sctp_timer.c	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_timer.c	Fri Feb 10 20:17:28 2012	(r231423)
@@ -1015,7 +1015,10 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
 
 	/* CMT FR loss recovery ended with the T3 */
 	net->fast_retran_loss_recovery = 0;
-
+	if ((stcb->asoc.cc_functions.sctp_cwnd_new_transmission_begins) &&
+	    (net->flight_size == 0)) {
+		(*stcb->asoc.cc_functions.sctp_cwnd_new_transmission_begins) (stcb, net);
+	}
 	/*
 	 * setup the sat loss recovery that prevents satellite cwnd advance.
 	 */

Modified: stable/8/sys/netinet/sctp_uio.h
==============================================================================
--- stable/8/sys/netinet/sctp_uio.h	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_uio.h	Fri Feb 10 20:17:28 2012	(r231423)
@@ -533,6 +533,11 @@ struct sctp_assoc_value {
 	uint32_t assoc_value;
 };
 
+struct sctp_cc_option {
+	int option;
+	struct sctp_assoc_value aid_value;
+};
+
 struct sctp_stream_value {
 	sctp_assoc_t assoc_id;
 	uint16_t stream_id;

Modified: stable/8/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/8/sys/netinet/sctp_usrreq.c	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctp_usrreq.c	Fri Feb 10 20:17:28 2012	(r231423)
@@ -1758,6 +1758,25 @@ flags_out:
 			*optsize = sizeof(*av);
 		}
 		break;
+	case SCTP_CC_OPTION:
+		{
+			struct sctp_cc_option *cc_opt;
+
+			SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, *optsize);
+			SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id);
+			if (stcb == NULL) {
+				error = EINVAL;
+			} else {
+				if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) {
+					error = ENOTSUP;
+				} else {
+					error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option) (stcb, 0,
+					    cc_opt);
+					*optsize = sizeof(*cc_opt);
+				}
+				SCTP_TCB_UNLOCK(stcb);
+			}
+		}
 		/* RS - Get socket option for pluggable stream scheduling */
 	case SCTP_PLUGGABLE_SS:
 		{
@@ -2926,6 +2945,7 @@ sctp_setopt(struct socket *so, int optna
 	case SCTP_PLUGGABLE_CC:
 		{
 			struct sctp_assoc_value *av;
+			struct sctp_nets *net;
 
 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
@@ -2936,6 +2956,11 @@ sctp_setopt(struct socket *so, int optna
 				case SCTP_CC_HTCP:
 					stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value];
 					stcb->asoc.congestion_control_module = av->assoc_value;
+					if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) {
+						TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
+							stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
+						}
+					}
 					break;
 				default:
 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
@@ -2959,6 +2984,24 @@ sctp_setopt(struct socket *so, int optna
 				}
 			}
 		}
+	case SCTP_CC_OPTION:
+		{
+			struct sctp_cc_option *cc_opt;
+
+			SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, optsize);
+			SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id);
+			if (stcb == NULL) {
+				error = EINVAL;
+			} else {
+				if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) {
+					error = ENOTSUP;
+				} else {
+					error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option) (stcb, 1,
+					    cc_opt);
+				}
+				SCTP_TCB_UNLOCK(stcb);
+			}
+		}
 		break;
 		/* RS - Set socket option for pluggable stream scheduling */
 	case SCTP_PLUGGABLE_SS:

Modified: stable/8/sys/netinet/sctputil.c
==============================================================================
--- stable/8/sys/netinet/sctputil.c	Fri Feb 10 20:09:23 2012	(r231422)
+++ stable/8/sys/netinet/sctputil.c	Fri Feb 10 20:17:28 2012	(r231423)
@@ -2495,7 +2495,11 @@ sctp_calculate_rto(struct sctp_tcb *stcb
 	/* 1. calculate new RTT */
 	/************************/
 	/* get the current time */
-	(void)SCTP_GETTIME_TIMEVAL(&now);
+	if (stcb->asoc.use_precise_time) {
+		(void)SCTP_GETPTIME_TIMEVAL(&now);
+	} else {
+		(void)SCTP_GETTIME_TIMEVAL(&now);
+	}
 	timevalsub(&now, old);
 	/* store the current RTT in us */
 	net->rtt = (uint64_t) 10000000 *(uint64_t) now.tv_sec +



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