Index: head/share/man/man4/cc_newreno.4
===================================================================
--- head/share/man/man4/cc_newreno.4	(revision 331213)
+++ head/share/man/man4/cc_newreno.4	(revision 331214)
@@ -1,82 +1,155 @@
 .\"
 .\" Copyright (c) 2009 Lawrence Stewart <lstewart@FreeBSD.org>
 .\" Copyright (c) 2011 The FreeBSD Foundation
 .\" All rights reserved.
 .\"
 .\" Portions of this documentation were written at the Centre for Advanced
 .\" Internet Architectures, Swinburne University of Technology, Melbourne,
 .\" Australia by Lawrence Stewart under sponsorship from the FreeBSD Foundation.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
 .\" are met:
 .\" 1. Redistributions of source code must retain the above copyright
 .\"    notice, this list of conditions and the following disclaimer.
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
 .\"
 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 .\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 15, 2011
+.Dd March 19, 2018
 .Dt CC_NEWRENO 4
 .Os
 .Sh NAME
 .Nm cc_newreno
 .Nd NewReno Congestion Control Algorithm
+.Sh SYNOPSIS
+.In netinet/cc/cc_newreno.h
 .Sh DESCRIPTION
 The NewReno congestion control algorithm is the default for TCP.
 Details about the algorithm can be found in RFC5681.
+.Sh Socket Options
+The
+.Nm
+module supports a number of socket options under TCP_CCALGOOPT (refer to
+.Xr tcp 4
+and
+.Xr moc_cc 9 for details)
+which can
+be set with
+.Xr setsockopt 2
+and tested with
+.Xr getsockopt 2 .
+The 
+.Nm
+socket options use this structure defined in
+<sys/netinet/cc/cc_newreno.h>:
+.Bd -literal
+struct cc_newreno_opts {
+	int name;
+	uint32_t val;
+}
+.Ed
+.Bl -tag -width ".Va CC_NEWRENO_BETA_ECN"
+.It Va CC_NEWRENO_BETA
+Multiplicative window decrease factor, specified as a percentage, applied to
+the congestion window in response to a congestion signal per: cwnd = (cwnd *
+CC_NEWRENO_BETA) / 100.
+Default is 50.
+.It Va CC_NEWRENO_BETA_ECN
+Multiplicative window decrease factor, specified as a percentage, applied to
+the congestion window in response to an ECN congestion signal when
+.Va net.inet.tcp.cc.abe=1
+per: cwnd = (cwnd * CC_NEWRENO_BETA_ECN) / 100.
+Default is 80.
 .Sh MIB Variables
-There are currently no tunable MIB variables.
+The algorithm exposes these variables in the
+.Va net.inet.tcp.cc.newreno
+branch of the
+.Xr sysctl 3
+MIB:
+.Bl -tag -width ".Va beta_ecn"
+.It Va beta
+Multiplicative window decrease factor, specified as a percentage, applied to
+the congestion window in response to a congestion signal per: cwnd = (cwnd *
+beta) / 100.
+Default is 50.
+.It Va beta_ecn
+Multiplicative window decrease factor, specified as a percentage, applied to
+the congestion window in response to an ECN congestion signal when
+.Va net.inet.tcp.cc.abe=1
+per: cwnd = (cwnd * beta_ecn) / 100.
+Default is 80.
 .Sh SEE ALSO
 .Xr cc_chd 4 ,
 .Xr cc_cubic 4 ,
 .Xr cc_hd 4 ,
 .Xr cc_htcp 4 ,
 .Xr cc_vegas 4 ,
 .Xr mod_cc 4 ,
 .Xr tcp 4 ,
 .Xr mod_cc 9
+.Rs
+.%A "Mark Allman"
+.%A "Vern Paxson"
+.%A "Ethan Blanton"
+.%T "TCP Congestion Control"
+.%O "RFC 5681"
+.Re
+.Rs
+.%A "Naeem Khademi"
+.%A "Michael Welzl"
+.%A "Grenville Armitage"
+.%A "Gorry Fairhurst"
+.%T "TCP Alternative Backoff with ECN (ABE)"
+.%R "internet draft"
+.%D "February 2018"
+.%N "draft-ietf-tcpm-alternativebackoff-ecn"
+.%O "work in progress"
+.Re
 .Sh ACKNOWLEDGEMENTS
 Development and testing of this software were made possible in part by grants
 from the FreeBSD Foundation and Cisco University Research Program Fund at
 Community Foundation Silicon Valley.
 .Sh HISTORY
 The
 .Nm
 congestion control algorithm first appeared in its modular form in
 .Fx 9.0 .
 .Pp
 The module was first released in 2007 by James Healy and Lawrence Stewart whilst
 working on the NewTCP research project at Swinburne University of Technology's
 Centre for Advanced Internet Architectures, Melbourne, Australia, which was made
 possible in part by a grant from the Cisco University Research Program Fund at
 Community Foundation Silicon Valley.
 More details are available at:
 .Pp
 http://caia.swin.edu.au/urp/newtcp/
 .Sh AUTHORS
 .An -nosplit
 The
 .Nm
 congestion control module was written by
 .An James Healy Aq Mt jimmy@deefa.com ,
 .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org
 and
 .An David Hayes Aq Mt david.hayes@ieee.org .
+.Pp
+Support for TCP ABE was added by
+.An Tom Jones Aq Mt tj@enoti.me .
 .Pp
 This manual page was written by
 .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org .
Index: head/share/man/man4/mod_cc.4
===================================================================
--- head/share/man/man4/mod_cc.4	(revision 331213)
+++ head/share/man/man4/mod_cc.4	(revision 331214)
@@ -1,129 +1,138 @@
 .\"
 .\" Copyright (c) 2010-2011 The FreeBSD Foundation
 .\" All rights reserved.
 .\"
 .\" This documentation was written at the Centre for Advanced Internet
 .\" Architectures, Swinburne University of Technology, Melbourne, Australia by
 .\" David Hayes and Lawrence Stewart under sponsorship from the FreeBSD
 .\" Foundation.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
 .\" are met:
 .\" 1. Redistributions of source code must retain the above copyright
 .\"    notice, this list of conditions and the following disclaimer.
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
 .\"
 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 .\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 21, 2016
+.Dd March 19, 2018
 .Dt MOD_CC 4
 .Os
 .Sh NAME
 .Nm mod_cc
 .Nd Modular congestion control
 .Sh DESCRIPTION
 The modular congestion control framework allows the TCP implementation to
 dynamically change the congestion control algorithm used by new and existing
 connections.
 Algorithms are identified by a unique
 .Xr ascii 7
 name.
 Algorithm modules can be compiled into the kernel or loaded as kernel modules
 using the
 .Xr kld 4
 facility.
 .Pp
 The default algorithm is NewReno, and all connections use the default unless
 explicitly overridden using the
 .Dv TCP_CONGESTION
 socket option (see
 .Xr tcp 4
 for details).
 The default can be changed using a
 .Xr sysctl 3
 MIB variable detailed in the
 .Sx MIB Variables
 section below.
 .Pp
 Algorithm specific parameters can be set or queried using the
 .Dv TCP_CCALGOOPT
 socket option (see
 .Xr tcp 4
 for details).
 Callers must pass a pointer to an algorithm specific data, and specify
 its size.
 .Sh MIB Variables
 The framework exposes the following variables in the
 .Va net.inet.tcp.cc
 branch of the
 .Xr sysctl 3
 MIB:
-.Bl -tag -width ".Va available"
+.Bl -tag -width ".Va abe_frlossreduce"
 .It Va available
 Read-only list of currently available congestion control algorithms by name.
 .It Va algorithm
 Returns the current default congestion control algorithm when read, and changes
 the default when set.
 When attempting to change the default algorithm, this variable should be set to
 one of the names listed by the
 .Va net.inet.tcp.cc.available
 MIB variable.
+.It Va abe
+Enable support for draft-ietf-tcpm-alternativebackoff-ecn,
+which alters the window decrease factor applied to the congestion window in
+response to an ECN congestion signal.
+Refer to individual congestion control man pages to determine if they implement
+support for ABE and for configuration details.
+.It Va abe_frlossreduce
+If non-zero, apply standard beta instead of ABE-beta during ECN-signalled
+congestion recovery episodes if loss also needs to be repaired.
 .El
 .Sh SEE ALSO
 .Xr cc_cdg 4 ,
 .Xr cc_chd 4 ,
 .Xr cc_cubic 4 ,
 .Xr cc_dctcp 4 ,
 .Xr cc_hd 4 ,
 .Xr cc_htcp 4 ,
 .Xr cc_newreno 4 ,
 .Xr cc_vegas 4 ,
 .Xr tcp 4 ,
 .Xr mod_cc 9
 .Sh ACKNOWLEDGEMENTS
 Development and testing of this software were made possible in part by grants
 from the FreeBSD Foundation and Cisco University Research Program Fund at
 Community Foundation Silicon Valley.
 .Sh HISTORY
 The
 .Nm
 modular congestion control framework first appeared in
 .Fx 9.0 .
 .Pp
 The framework was first released in 2007 by James Healy and Lawrence Stewart
 whilst working on the NewTCP research project at Swinburne University of
 Technology's Centre for Advanced Internet Architectures, Melbourne, Australia,
 which was made possible in part by a grant from the Cisco University Research
 Program Fund at Community Foundation Silicon Valley.
 More details are available at:
 .Pp
 http://caia.swin.edu.au/urp/newtcp/
 .Sh AUTHORS
 .An -nosplit
 The
 .Nm
 facility was written by
 .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org ,
 .An James Healy Aq Mt jimmy@deefa.com
 and
 .An David Hayes Aq Mt david.hayes@ieee.org .
 .Pp
 This manual page was written by
 .An David Hayes Aq Mt david.hayes@ieee.org
 and
 .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org .
Index: head/sys/netinet/cc/cc.c
===================================================================
--- head/sys/netinet/cc/cc.c	(revision 331213)
+++ head/sys/netinet/cc/cc.c	(revision 331214)
@@ -1,329 +1,340 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
  *
  * Copyright (c) 2007-2008
  *	Swinburne University of Technology, Melbourne, Australia.
  * Copyright (c) 2009-2010 Lawrence Stewart <lstewart@freebsd.org>
  * Copyright (c) 2010 The FreeBSD Foundation
  * All rights reserved.
  *
  * This software was developed at the Centre for Advanced Internet
  * Architectures, Swinburne University of Technology, by Lawrence Stewart and
  * James Healy, made possible in part by a grant from the Cisco University
  * Research Program Fund at Community Foundation Silicon Valley.
  *
  * Portions of this software were developed at the Centre for Advanced
  * Internet Architectures, Swinburne University of Technology, Melbourne,
  * Australia by David Hayes under sponsorship from the FreeBSD Foundation.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
 
 /*
  * This software was first released in 2007 by James Healy and Lawrence Stewart
  * whilst working on the NewTCP research project at Swinburne University of
  * Technology's Centre for Advanced Internet Architectures, Melbourne,
  * Australia, which was made possible in part by a grant from the Cisco
  * University Research Program Fund at Community Foundation Silicon Valley.
  * More details are available at:
  *   http://caia.swin.edu.au/urp/newtcp/
  */
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/libkern.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/mutex.h>
 #include <sys/queue.h>
 #include <sys/rwlock.h>
 #include <sys/sbuf.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
 
 #include <net/vnet.h>
 
 #include <netinet/in.h>
 #include <netinet/in_pcb.h>
 #include <netinet/tcp.h>
 #include <netinet/tcp_var.h>
 #include <netinet/cc/cc.h>
 
 #include <netinet/cc/cc_module.h>
 
 /*
  * List of available cc algorithms on the current system. First element
  * is used as the system default CC algorithm.
  */
 struct cc_head cc_list = STAILQ_HEAD_INITIALIZER(cc_list);
 
 /* Protects the cc_list TAILQ. */
 struct rwlock cc_list_lock;
 
 VNET_DEFINE(struct cc_algo *, default_cc_ptr) = &newreno_cc_algo;
 
 /*
  * Sysctl handler to show and change the default CC algorithm.
  */
 static int
 cc_default_algo(SYSCTL_HANDLER_ARGS)
 {
 	char default_cc[TCP_CA_NAME_MAX];
 	struct cc_algo *funcs;
 	int error;
 
 	/* Get the current default: */
 	CC_LIST_RLOCK();
 	strlcpy(default_cc, CC_DEFAULT()->name, sizeof(default_cc));
 	CC_LIST_RUNLOCK();
 
 	error = sysctl_handle_string(oidp, default_cc, sizeof(default_cc), req);
 
 	/* Check for error or no change */
 	if (error != 0 || req->newptr == NULL)
 		goto done;
 
 	error = ESRCH;
 
 	/* Find algo with specified name and set it to default. */
 	CC_LIST_RLOCK();
 	STAILQ_FOREACH(funcs, &cc_list, entries) {
 		if (strncmp(default_cc, funcs->name, sizeof(default_cc)))
 			continue;
 		V_default_cc_ptr = funcs;
 		error = 0;
 		break;
 	}
 	CC_LIST_RUNLOCK();
 done:
 	return (error);
 }
 
 /*
  * Sysctl handler to display the list of available CC algorithms.
  */
 static int
 cc_list_available(SYSCTL_HANDLER_ARGS)
 {
 	struct cc_algo *algo;
 	struct sbuf *s;
 	int err, first, nalgos;
 
 	err = nalgos = 0;
 	first = 1;
 
 	CC_LIST_RLOCK();
 	STAILQ_FOREACH(algo, &cc_list, entries) {
 		nalgos++;
 	}
 	CC_LIST_RUNLOCK();
 
 	s = sbuf_new(NULL, NULL, nalgos * TCP_CA_NAME_MAX, SBUF_FIXEDLEN);
 
 	if (s == NULL)
 		return (ENOMEM);
 
 	/*
 	 * It is theoretically possible for the CC list to have grown in size
 	 * since the call to sbuf_new() and therefore for the sbuf to be too
 	 * small. If this were to happen (incredibly unlikely), the sbuf will
 	 * reach an overflow condition, sbuf_printf() will return an error and
 	 * the sysctl will fail gracefully.
 	 */
 	CC_LIST_RLOCK();
 	STAILQ_FOREACH(algo, &cc_list, entries) {
 		err = sbuf_printf(s, first ? "%s" : ", %s", algo->name);
 		if (err) {
 			/* Sbuf overflow condition. */
 			err = EOVERFLOW;
 			break;
 		}
 		first = 0;
 	}
 	CC_LIST_RUNLOCK();
 
 	if (!err) {
 		sbuf_finish(s);
 		err = sysctl_handle_string(oidp, sbuf_data(s), 0, req);
 	}
 
 	sbuf_delete(s);
 	return (err);
 }
 
 /*
  * Reset the default CC algo to NewReno for any netstack which is using the algo
  * that is about to go away as its default.
  */
 static void
 cc_checkreset_default(struct cc_algo *remove_cc)
 {
 	VNET_ITERATOR_DECL(vnet_iter);
 
 	CC_LIST_LOCK_ASSERT();
 
 	VNET_LIST_RLOCK_NOSLEEP();
 	VNET_FOREACH(vnet_iter) {
 		CURVNET_SET(vnet_iter);
 		if (strncmp(CC_DEFAULT()->name, remove_cc->name,
 		    TCP_CA_NAME_MAX) == 0)
 			V_default_cc_ptr = &newreno_cc_algo;
 		CURVNET_RESTORE();
 	}
 	VNET_LIST_RUNLOCK_NOSLEEP();
 }
 
 /*
  * Initialise CC subsystem on system boot.
  */
 static void
 cc_init(void)
 {
 	CC_LIST_LOCK_INIT();
 	STAILQ_INIT(&cc_list);
 }
 
 /*
  * Returns non-zero on success, 0 on failure.
  */
 int
 cc_deregister_algo(struct cc_algo *remove_cc)
 {
 	struct cc_algo *funcs, *tmpfuncs;
 	int err;
 
 	err = ENOENT;
 
 	/* Never allow newreno to be deregistered. */
 	if (&newreno_cc_algo == remove_cc)
 		return (EPERM);
 
 	/* Remove algo from cc_list so that new connections can't use it. */
 	CC_LIST_WLOCK();
 	STAILQ_FOREACH_SAFE(funcs, &cc_list, entries, tmpfuncs) {
 		if (funcs == remove_cc) {
 			cc_checkreset_default(remove_cc);
 			STAILQ_REMOVE(&cc_list, funcs, cc_algo, entries);
 			err = 0;
 			break;
 		}
 	}
 	CC_LIST_WUNLOCK();
 
 	if (!err)
 		/*
 		 * XXXLAS:
 		 * - We may need to handle non-zero return values in future.
 		 * - If we add CC framework support for protocols other than
 		 *   TCP, we may want a more generic way to handle this step.
 		 */
 		tcp_ccalgounload(remove_cc);
 
 	return (err);
 }
 
 /*
  * Returns 0 on success, non-zero on failure.
  */
 int
 cc_register_algo(struct cc_algo *add_cc)
 {
 	struct cc_algo *funcs;
 	int err;
 
 	err = 0;
 
 	/*
 	 * Iterate over list of registered CC algorithms and make sure
 	 * we're not trying to add a duplicate.
 	 */
 	CC_LIST_WLOCK();
 	STAILQ_FOREACH(funcs, &cc_list, entries) {
 		if (funcs == add_cc || strncmp(funcs->name, add_cc->name,
 		    TCP_CA_NAME_MAX) == 0)
 			err = EEXIST;
 	}
 
 	if (!err)
 		STAILQ_INSERT_TAIL(&cc_list, add_cc, entries);
 
 	CC_LIST_WUNLOCK();
 
 	return (err);
 }
 
 /*
  * Handles kld related events. Returns 0 on success, non-zero on failure.
  */
 int
 cc_modevent(module_t mod, int event_type, void *data)
 {
 	struct cc_algo *algo;
 	int err;
 
 	err = 0;
 	algo = (struct cc_algo *)data;
 
 	switch(event_type) {
 	case MOD_LOAD:
 		if (algo->mod_init != NULL)
 			err = algo->mod_init();
 		if (!err)
 			err = cc_register_algo(algo);
 		break;
 
 	case MOD_QUIESCE:
 	case MOD_SHUTDOWN:
 	case MOD_UNLOAD:
 		err = cc_deregister_algo(algo);
 		if (!err && algo->mod_destroy != NULL)
 			algo->mod_destroy();
 		if (err == ENOENT)
 			err = 0;
 		break;
 
 	default:
 		err = EINVAL;
 		break;
 	}
 
 	return (err);
 }
 
 SYSINIT(cc, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST, cc_init, NULL);
 
 /* Declare sysctl tree and populate it. */
 SYSCTL_NODE(_net_inet_tcp, OID_AUTO, cc, CTLFLAG_RW, NULL,
     "Congestion control related settings");
 
 SYSCTL_PROC(_net_inet_tcp_cc, OID_AUTO, algorithm,
     CTLFLAG_VNET | CTLTYPE_STRING | CTLFLAG_RW,
     NULL, 0, cc_default_algo, "A", "Default congestion control algorithm");
 
 SYSCTL_PROC(_net_inet_tcp_cc, OID_AUTO, available, CTLTYPE_STRING|CTLFLAG_RD,
     NULL, 0, cc_list_available, "A",
     "List available congestion control algorithms");
+
+VNET_DEFINE(int, cc_do_abe) = 0;
+SYSCTL_INT(_net_inet_tcp_cc, OID_AUTO, abe, CTLFLAG_VNET | CTLFLAG_RW,
+    &VNET_NAME(cc_do_abe), 0,
+    "Enable draft-ietf-tcpm-alternativebackoff-ecn (TCP Alternative Backoff with ECN)");
+
+VNET_DEFINE(int, cc_abe_frlossreduce) = 0;
+SYSCTL_INT(_net_inet_tcp_cc, OID_AUTO, abe_frlossreduce, CTLFLAG_VNET | CTLFLAG_RW,
+    &VNET_NAME(cc_abe_frlossreduce), 0,
+    "Apply standard beta instead of ABE-beta during ECN-signalled congestion "
+    "recovery episodes if loss also needs to be repaired");
Index: head/sys/netinet/cc/cc.h
===================================================================
--- head/sys/netinet/cc/cc.h	(revision 331213)
+++ head/sys/netinet/cc/cc.h	(revision 331214)
@@ -1,179 +1,185 @@
 /*-
  * Copyright (c) 2007-2008
  * 	Swinburne University of Technology, Melbourne, Australia.
  * Copyright (c) 2009-2010 Lawrence Stewart <lstewart@freebsd.org>
  * Copyright (c) 2010 The FreeBSD Foundation
  * All rights reserved.
  *
  * This software was developed at the Centre for Advanced Internet
  * Architectures, Swinburne University of Technology, by Lawrence Stewart and
  * James Healy, made possible in part by a grant from the Cisco University
  * Research Program Fund at Community Foundation Silicon Valley.
  *
  * Portions of this software were developed at the Centre for Advanced
  * Internet Architectures, Swinburne University of Technology, Melbourne,
  * Australia by David Hayes under sponsorship from the FreeBSD Foundation.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * $FreeBSD$
  */
 
 /*
  * This software was first released in 2007 by James Healy and Lawrence Stewart
  * whilst working on the NewTCP research project at Swinburne University of
  * Technology's Centre for Advanced Internet Architectures, Melbourne,
  * Australia, which was made possible in part by a grant from the Cisco
  * University Research Program Fund at Community Foundation Silicon Valley.
  * More details are available at:
  *   http://caia.swin.edu.au/urp/newtcp/
  */
 
 #ifndef _NETINET_CC_CC_H_
 #define _NETINET_CC_CC_H_
 
 #if !defined(_KERNEL)
 #error "no user-serviceable parts inside"
 #endif
 
 /* Global CC vars. */
 extern STAILQ_HEAD(cc_head, cc_algo) cc_list;
 extern const int tcprexmtthresh;
 extern struct cc_algo newreno_cc_algo;
 
 /* Per-netstack bits. */
 VNET_DECLARE(struct cc_algo *, default_cc_ptr);
 #define	V_default_cc_ptr VNET(default_cc_ptr)
 
+VNET_DECLARE(int, cc_do_abe);
+#define	V_cc_do_abe			VNET(cc_do_abe)
+
+VNET_DECLARE(int, cc_abe_frlossreduce);
+#define	V_cc_abe_frlossreduce		VNET(cc_abe_frlossreduce)
+
 /* Define the new net.inet.tcp.cc sysctl tree. */
 SYSCTL_DECL(_net_inet_tcp_cc);
 
 /* CC housekeeping functions. */
 int	cc_register_algo(struct cc_algo *add_cc);
 int	cc_deregister_algo(struct cc_algo *remove_cc);
 
 /*
  * Wrapper around transport structs that contain same-named congestion
  * control variables. Allows algos to be shared amongst multiple CC aware
  * transprots.
  */
 struct cc_var {
 	void		*cc_data; /* Per-connection private CC algorithm data. */
 	int		bytes_this_ack; /* # bytes acked by the current ACK. */
 	tcp_seq		curack; /* Most recent ACK. */
 	uint32_t	flags; /* Flags for cc_var (see below) */
 	int		type; /* Indicates which ptr is valid in ccvc. */
 	union ccv_container {
 		struct tcpcb		*tcp;
 		struct sctp_nets	*sctp;
 	} ccvc;
 	uint16_t	nsegs; /* # segments coalesced into current chain. */
 };
 
 /* cc_var flags. */
 #define	CCF_ABC_SENTAWND	0x0001	/* ABC counted cwnd worth of bytes? */
 #define	CCF_CWND_LIMITED	0x0002	/* Are we currently cwnd limited? */
 #define	CCF_DELACK		0x0004	/* Is this ack delayed? */
 #define	CCF_ACKNOW		0x0008	/* Will this ack be sent now? */
 #define	CCF_IPHDR_CE		0x0010	/* Does this packet set CE bit? */
 #define	CCF_TCPHDR_CWR		0x0020	/* Does this packet set CWR bit? */
 
 /* ACK types passed to the ack_received() hook. */
 #define	CC_ACK		0x0001	/* Regular in sequence ACK. */
 #define	CC_DUPACK	0x0002	/* Duplicate ACK. */
 #define	CC_PARTIALACK	0x0004	/* Not yet. */
 #define	CC_SACK		0x0008	/* Not yet. */
 
 /*
  * Congestion signal types passed to the cong_signal() hook. The highest order 8
  * bits (0x01000000 - 0x80000000) are reserved for CC algos to declare their own
  * congestion signal types.
  */
 #define	CC_ECN		0x00000001	/* ECN marked packet received. */
 #define	CC_RTO		0x00000002	/* RTO fired. */
 #define	CC_RTO_ERR	0x00000004	/* RTO fired in error. */
 #define	CC_NDUPACK	0x00000008	/* Threshold of dupack's reached. */
 
 #define	CC_SIGPRIVMASK	0xFF000000	/* Mask to check if sig is private. */
 
 /*
  * Structure to hold data and function pointers that together represent a
  * congestion control algorithm.
  */
 struct cc_algo {
 	char	name[TCP_CA_NAME_MAX];
 
 	/* Init global module state on kldload. */
 	int	(*mod_init)(void);
 
 	/* Cleanup global module state on kldunload. */
 	int	(*mod_destroy)(void);
 
 	/* Init CC state for a new control block. */
 	int	(*cb_init)(struct cc_var *ccv);
 
 	/* Cleanup CC state for a terminating control block. */
 	void	(*cb_destroy)(struct cc_var *ccv);
 
 	/* Init variables for a newly established connection. */
 	void	(*conn_init)(struct cc_var *ccv);
 
 	/* Called on receipt of an ack. */
 	void	(*ack_received)(struct cc_var *ccv, uint16_t type);
 
 	/* Called on detection of a congestion signal. */
 	void	(*cong_signal)(struct cc_var *ccv, uint32_t type);
 
 	/* Called after exiting congestion recovery. */
 	void	(*post_recovery)(struct cc_var *ccv);
 
 	/* Called when data transfer resumes after an idle period. */
 	void	(*after_idle)(struct cc_var *ccv);
 
 	/* Called for an additional ECN processing apart from RFC3168. */
 	void	(*ecnpkt_handler)(struct cc_var *ccv);
 
 	/* Called for {get|set}sockopt() on a TCP socket with TCP_CCALGOOPT. */
 	int     (*ctl_output)(struct cc_var *, struct sockopt *, void *);
 
 	STAILQ_ENTRY (cc_algo) entries;
 };
 
 /* Macro to obtain the CC algo's struct ptr. */
 #define	CC_ALGO(tp)	((tp)->cc_algo)
 
 /* Macro to obtain the CC algo's data ptr. */
 #define	CC_DATA(tp)	((tp)->ccv->cc_data)
 
 /* Macro to obtain the system default CC algo's struct ptr. */
 #define	CC_DEFAULT()	V_default_cc_ptr
 
 extern struct rwlock cc_list_lock;
 #define	CC_LIST_LOCK_INIT()	rw_init(&cc_list_lock, "cc_list")
 #define	CC_LIST_LOCK_DESTROY()	rw_destroy(&cc_list_lock)
 #define	CC_LIST_RLOCK()		rw_rlock(&cc_list_lock)
 #define	CC_LIST_RUNLOCK()	rw_runlock(&cc_list_lock)
 #define	CC_LIST_WLOCK()		rw_wlock(&cc_list_lock)
 #define	CC_LIST_WUNLOCK()	rw_wunlock(&cc_list_lock)
 #define	CC_LIST_LOCK_ASSERT()	rw_assert(&cc_list_lock, RA_LOCKED)
 
 #endif /* _NETINET_CC_CC_H_ */
Index: head/sys/netinet/cc/cc_newreno.c
===================================================================
--- head/sys/netinet/cc/cc_newreno.c	(revision 331213)
+++ head/sys/netinet/cc/cc_newreno.c	(revision 331214)
@@ -1,246 +1,376 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
  *
  * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
  *	The Regents of the University of California.
- * Copyright (c) 2007-2008,2010
+ * Copyright (c) 2007-2008,2010,2014
  *	Swinburne University of Technology, Melbourne, Australia.
  * Copyright (c) 2009-2010 Lawrence Stewart <lstewart@freebsd.org>
  * Copyright (c) 2010 The FreeBSD Foundation
  * All rights reserved.
  *
  * This software was developed at the Centre for Advanced Internet
  * Architectures, Swinburne University of Technology, by Lawrence Stewart, James
  * Healy and David Hayes, made possible in part by a grant from the Cisco
  * University Research Program Fund at Community Foundation Silicon Valley.
  *
  * Portions of this software were developed at the Centre for Advanced
  * Internet Architectures, Swinburne University of Technology, Melbourne,
  * Australia by David Hayes under sponsorship from the FreeBSD Foundation.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
 
 /*
  * This software was first released in 2007 by James Healy and Lawrence Stewart
  * whilst working on the NewTCP research project at Swinburne University of
  * Technology's Centre for Advanced Internet Architectures, Melbourne,
  * Australia, which was made possible in part by a grant from the Cisco
  * University Research Program Fund at Community Foundation Silicon Valley.
  * More details are available at:
  *   http://caia.swin.edu.au/urp/newtcp/
+ *
+ * Dec 2014 garmitage@swin.edu.au
+ * Borrowed code fragments from cc_cdg.c to add modifiable beta
+ * via sysctls.
+ *
  */
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
 
 #include <net/vnet.h>
 
 #include <netinet/tcp.h>
 #include <netinet/tcp_seq.h>
 #include <netinet/tcp_var.h>
 #include <netinet/cc/cc.h>
 #include <netinet/cc/cc_module.h>
+#include <netinet/cc/cc_newreno.h>
 
+static MALLOC_DEFINE(M_NEWRENO, "newreno data",
+	"newreno beta values");
+
+#define	CAST_PTR_INT(X) (*((int*)(X)))
+
+static int newreno_cb_init(struct cc_var *ccv);
 static void	newreno_ack_received(struct cc_var *ccv, uint16_t type);
 static void	newreno_after_idle(struct cc_var *ccv);
 static void	newreno_cong_signal(struct cc_var *ccv, uint32_t type);
 static void	newreno_post_recovery(struct cc_var *ccv);
+static int newreno_ctl_output(struct cc_var *ccv, struct sockopt *sopt, void *buf);
 
+static VNET_DEFINE(uint32_t, newreno_beta) = 50;
+static VNET_DEFINE(uint32_t, newreno_beta_ecn) = 80;
+#define V_newreno_beta VNET(newreno_beta)
+#define V_newreno_beta_ecn VNET(newreno_beta_ecn)
+
 struct cc_algo newreno_cc_algo = {
 	.name = "newreno",
+	.cb_init = newreno_cb_init,
 	.ack_received = newreno_ack_received,
 	.after_idle = newreno_after_idle,
 	.cong_signal = newreno_cong_signal,
 	.post_recovery = newreno_post_recovery,
+	.ctl_output = newreno_ctl_output,
 };
 
+struct newreno {
+	uint32_t beta;
+	uint32_t beta_ecn;
+};
+
+int
+newreno_cb_init(struct cc_var *ccv)
+{
+	struct newreno *nreno;		
+
+	nreno = malloc(sizeof(struct newreno), M_NEWRENO, M_NOWAIT|M_ZERO);
+	if (nreno != NULL) {
+		nreno->beta = V_newreno_beta;
+		nreno->beta_ecn = V_newreno_beta_ecn;
+	}
+
+	return (0);
+}
+
 static void
 newreno_ack_received(struct cc_var *ccv, uint16_t type)
 {
 	if (type == CC_ACK && !IN_RECOVERY(CCV(ccv, t_flags)) &&
 	    (ccv->flags & CCF_CWND_LIMITED)) {
 		u_int cw = CCV(ccv, snd_cwnd);
 		u_int incr = CCV(ccv, t_maxseg);
 
 		/*
 		 * Regular in-order ACK, open the congestion window.
 		 * Method depends on which congestion control state we're
 		 * in (slow start or cong avoid) and if ABC (RFC 3465) is
 		 * enabled.
 		 *
 		 * slow start: cwnd <= ssthresh
 		 * cong avoid: cwnd > ssthresh
 		 *
 		 * slow start and ABC (RFC 3465):
 		 *   Grow cwnd exponentially by the amount of data
 		 *   ACKed capping the max increment per ACK to
 		 *   (abc_l_var * maxseg) bytes.
 		 *
 		 * slow start without ABC (RFC 5681):
 		 *   Grow cwnd exponentially by maxseg per ACK.
 		 *
 		 * cong avoid and ABC (RFC 3465):
 		 *   Grow cwnd linearly by maxseg per RTT for each
 		 *   cwnd worth of ACKed data.
 		 *
 		 * cong avoid without ABC (RFC 5681):
 		 *   Grow cwnd linearly by approximately maxseg per RTT using
 		 *   maxseg^2 / cwnd per ACK as the increment.
 		 *   If cwnd > maxseg^2, fix the cwnd increment at 1 byte to
 		 *   avoid capping cwnd.
 		 */
 		if (cw > CCV(ccv, snd_ssthresh)) {
 			if (V_tcp_do_rfc3465) {
 				if (ccv->flags & CCF_ABC_SENTAWND)
 					ccv->flags &= ~CCF_ABC_SENTAWND;
 				else
 					incr = 0;
 			} else
 				incr = max((incr * incr / cw), 1);
 		} else if (V_tcp_do_rfc3465) {
 			/*
 			 * In slow-start with ABC enabled and no RTO in sight?
 			 * (Must not use abc_l_var > 1 if slow starting after
 			 * an RTO. On RTO, snd_nxt = snd_una, so the
 			 * snd_nxt == snd_max check is sufficient to
 			 * handle this).
 			 *
 			 * XXXLAS: Find a way to signal SS after RTO that
 			 * doesn't rely on tcpcb vars.
 			 */
 			if (CCV(ccv, snd_nxt) == CCV(ccv, snd_max))
 				incr = min(ccv->bytes_this_ack,
 				    ccv->nsegs * V_tcp_abc_l_var *
 				    CCV(ccv, t_maxseg));
 			else
 				incr = min(ccv->bytes_this_ack, CCV(ccv, t_maxseg));
 		}
 		/* ABC is on by default, so incr equals 0 frequently. */
 		if (incr > 0)
 			CCV(ccv, snd_cwnd) = min(cw + incr,
 			    TCP_MAXWIN << CCV(ccv, snd_scale));
 	}
 }
 
 static void
 newreno_after_idle(struct cc_var *ccv)
 {
 	int rw;
 
 	/*
 	 * If we've been idle for more than one retransmit timeout the old
 	 * congestion window is no longer current and we have to reduce it to
 	 * the restart window before we can transmit again.
 	 *
 	 * The restart window is the initial window or the last CWND, whichever
 	 * is smaller.
 	 *
 	 * This is done to prevent us from flooding the path with a full CWND at
 	 * wirespeed, overloading router and switch buffers along the way.
 	 *
 	 * See RFC5681 Section 4.1. "Restarting Idle Connections".
 	 */
 	if (V_tcp_do_rfc3390)
 		rw = min(4 * CCV(ccv, t_maxseg),
 		    max(2 * CCV(ccv, t_maxseg), 4380));
 	else
 		rw = CCV(ccv, t_maxseg) * 2;
 
 	CCV(ccv, snd_cwnd) = min(rw, CCV(ccv, snd_cwnd));
 }
 
 /*
  * Perform any necessary tasks before we enter congestion recovery.
  */
 static void
 newreno_cong_signal(struct cc_var *ccv, uint32_t type)
 {
-	u_int win;
+	struct newreno *nreno;
+	uint32_t cwin, factor;
+	u_int mss;
 
+	factor = V_newreno_beta;
+	nreno = ccv->cc_data;
+	if (nreno != NULL) {
+	    if (V_cc_do_abe)
+		factor = (type == CC_ECN ? nreno->beta_ecn: nreno->beta);
+	    else
+		factor = nreno->beta;
+	}
+
+	cwin = CCV(ccv, snd_cwnd);
+	mss = CCV(ccv, t_maxseg);
+
 	/* Catch algos which mistakenly leak private signal types. */
 	KASSERT((type & CC_SIGPRIVMASK) == 0,
 	    ("%s: congestion signal type 0x%08x is private\n", __func__, type));
 
-	win = max(CCV(ccv, snd_cwnd) / 2 / CCV(ccv, t_maxseg), 2) *
-	    CCV(ccv, t_maxseg);
+	cwin = max(((uint64_t)cwin * (uint64_t)factor) / (100ULL * (uint64_t)mss),
+	    2) * mss;
 
 	switch (type) {
 	case CC_NDUPACK:
 		if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
+			if (IN_CONGRECOVERY(CCV(ccv, t_flags) &&
+			    V_cc_do_abe && V_cc_abe_frlossreduce)) {
+				CCV(ccv, snd_ssthresh) =
+				    ((uint64_t)CCV(ccv, snd_ssthresh) *
+				    (uint64_t)nreno->beta) /
+				    (100ULL * (uint64_t)nreno->beta_ecn);
+			}
 			if (!IN_CONGRECOVERY(CCV(ccv, t_flags)))
-				CCV(ccv, snd_ssthresh) = win;
+				CCV(ccv, snd_ssthresh) = cwin;
 			ENTER_RECOVERY(CCV(ccv, t_flags));
 		}
 		break;
 	case CC_ECN:
 		if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
-			CCV(ccv, snd_ssthresh) = win;
-			CCV(ccv, snd_cwnd) = win;
+			CCV(ccv, snd_ssthresh) = cwin;
+			CCV(ccv, snd_cwnd) = cwin;
 			ENTER_CONGRECOVERY(CCV(ccv, t_flags));
 		}
 		break;
 	}
 }
 
 /*
  * Perform any necessary tasks before we exit congestion recovery.
  */
 static void
 newreno_post_recovery(struct cc_var *ccv)
 {
 	int pipe;
 	pipe = 0;
 
 	if (IN_FASTRECOVERY(CCV(ccv, t_flags))) {
 		/*
 		 * Fast recovery will conclude after returning from this
 		 * function. Window inflation should have left us with
 		 * approximately snd_ssthresh outstanding data. But in case we
 		 * would be inclined to send a burst, better to do it via the
 		 * slow start mechanism.
 		 *
 		 * XXXLAS: Find a way to do this without needing curack
 		 */
 		if (V_tcp_do_rfc6675_pipe)
 			pipe = tcp_compute_pipe(ccv->ccvc.tcp);
 		else
 			pipe = CCV(ccv, snd_max) - ccv->curack;
 
 		if (pipe < CCV(ccv, snd_ssthresh))
 			CCV(ccv, snd_cwnd) = pipe + CCV(ccv, t_maxseg);
 		else
 			CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
 	}
 }
 
+int
+newreno_ctl_output(struct cc_var *ccv, struct sockopt *sopt, void *buf)
+{
+	struct newreno *nreno;
+	struct cc_newreno_opts *opt;
+
+	if (sopt->sopt_valsize != sizeof(struct cc_newreno_opts))
+		return (EMSGSIZE);
+
+	nreno = ccv->cc_data;
+	opt = buf;
+	
+	switch (sopt->sopt_dir) {
+	case SOPT_SET:
+		switch (opt->name) {
+		case CC_NEWRENO_BETA:
+			nreno->beta = opt->val;
+			break;
+		case CC_NEWRENO_BETA_ECN:
+			if (!V_cc_do_abe)
+				return (EACCES);
+			nreno->beta_ecn = opt->val;
+			break;
+		default:
+			return (ENOPROTOOPT);
+		}
+	case SOPT_GET:
+		switch (opt->name) {
+		case CC_NEWRENO_BETA:
+			opt->val = nreno->beta;
+			break;
+		case CC_NEWRENO_BETA_ECN:
+			opt->val = nreno->beta_ecn;
+			break;
+		default:
+			return (ENOPROTOOPT);
+		}
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+static int
+newreno_beta_handler(SYSCTL_HANDLER_ARGS)
+{
+	if (req->newptr != NULL ) {
+		if (arg1 == &VNET_NAME(newreno_beta_ecn) && !V_cc_do_abe)
+			return (EACCES);
+		if (CAST_PTR_INT(req->newptr) <= 0 || CAST_PTR_INT(req->newptr) > 100)
+			return (EINVAL);
+	}
+
+	return (sysctl_handle_int(oidp, arg1, arg2, req));
+}
+
+SYSCTL_DECL(_net_inet_tcp_cc_newreno);
+SYSCTL_NODE(_net_inet_tcp_cc, OID_AUTO, newreno, CTLFLAG_RW, NULL,
+    "New Reno related settings");
+
+SYSCTL_PROC(_net_inet_tcp_cc_newreno, OID_AUTO, beta,
+	CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW,
+	&VNET_NAME(newreno_beta), 3, &newreno_beta_handler, "IU",
+	"New Reno beta, specified as number between 1 and 100");
+
+SYSCTL_PROC(_net_inet_tcp_cc_newreno, OID_AUTO, beta_ecn,
+	CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW,
+	&VNET_NAME(newreno_beta_ecn), 3, &newreno_beta_handler, "IU",
+	"New Reno beta ecn, specified as number between 1 and 100");
 
 DECLARE_CC_MODULE(newreno, &newreno_cc_algo);
Index: head/sys/netinet/cc/cc_newreno.h
===================================================================
--- head/sys/netinet/cc/cc_newreno.h	(nonexistent)
+++ head/sys/netinet/cc/cc_newreno.h	(revision 331214)
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2017 Tom Jones <tj@enoti.me>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _CC_NEWRENO_H
+#define _CC_NEWRENO_H
+
+#define CCALGONAME_NEWRENO "newreno"
+
+struct cc_newreno_opts {
+	int			name;
+	uint32_t	val;
+};
+
+#define CC_NEWRENO_BETA		1
+#define CC_NEWRENO_BETA_ECN	2
+
+#endif /* _CC_NEWRENO_H */

Property changes on: head/sys/netinet/cc/cc_newreno.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property