1317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/*
2317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * Plugable TCP congestion control support and newReno
3317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * congestion control.
402582e9bcc36ed503ffede46e104a885dea222fbMasanari Iida * Based on ideas from I/O scheduler support and Web100.
5317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger *
6317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org>
7317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger */
8317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
9afd465030acb4098abcb6b965a5aebc7ea2209e0Joe Perches#define pr_fmt(fmt) "TCP: " fmt
10afd465030acb4098abcb6b965a5aebc7ea2209e0Joe Perches
11317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger#include <linux/module.h>
12317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger#include <linux/mm.h>
13317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger#include <linux/types.h>
14317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger#include <linux/list.h>
155a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h>
16317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger#include <net/tcp.h>
17317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
18317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemmingerstatic DEFINE_SPINLOCK(tcp_cong_list_lock);
19317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemmingerstatic LIST_HEAD(tcp_cong_list);
20317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
21317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/* Simple linear search, don't expect many entries! */
22317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemmingerstatic struct tcp_congestion_ops *tcp_ca_find(const char *name)
23317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger{
24317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	struct tcp_congestion_ops *e;
25317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
265f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	list_for_each_entry_rcu(e, &tcp_cong_list, list) {
27317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		if (strcmp(e->name, name) == 0)
28317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger			return e;
29317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	}
30317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
31317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	return NULL;
32317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger}
33317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
34317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/*
35d08df601a30df9e36c29f3214315f4f0c8784c68Robert P. J. Day * Attach new congestion control algorithm to the list
36317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * of available options.
37317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger */
38317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemmingerint tcp_register_congestion_control(struct tcp_congestion_ops *ca)
39317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger{
40317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	int ret = 0;
41317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
42317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	/* all algorithms must implement ssthresh and cong_avoid ops */
4372dc5b9225c53310c010b68a70ea97c8c8e24bdfStephen Hemminger	if (!ca->ssthresh || !ca->cong_avoid) {
44afd465030acb4098abcb6b965a5aebc7ea2209e0Joe Perches		pr_err("%s does not implement required ops\n", ca->name);
45317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		return -EINVAL;
46317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	}
47317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
48317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	spin_lock(&tcp_cong_list_lock);
49317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	if (tcp_ca_find(ca->name)) {
50afd465030acb4098abcb6b965a5aebc7ea2209e0Joe Perches		pr_notice("%s already registered\n", ca->name);
51317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		ret = -EEXIST;
52317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	} else {
533d2573f7ebe507e372a23cdd3c8b03305d6e90aaStephen Hemminger		list_add_tail_rcu(&ca->list, &tcp_cong_list);
54afd465030acb4098abcb6b965a5aebc7ea2209e0Joe Perches		pr_info("%s registered\n", ca->name);
55317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	}
56317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	spin_unlock(&tcp_cong_list_lock);
57317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
58317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	return ret;
59317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger}
60317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen HemmingerEXPORT_SYMBOL_GPL(tcp_register_congestion_control);
61317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
62317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/*
63317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * Remove congestion control algorithm, called from
64317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * the module's remove function.  Module ref counts are used
65317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * to ensure that this can't be done till all sockets using
66317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * that method are closed.
67317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger */
68317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemmingervoid tcp_unregister_congestion_control(struct tcp_congestion_ops *ca)
69317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger{
70317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	spin_lock(&tcp_cong_list_lock);
71317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	list_del_rcu(&ca->list);
72317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	spin_unlock(&tcp_cong_list_lock);
73317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger}
74317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen HemmingerEXPORT_SYMBOL_GPL(tcp_unregister_congestion_control);
75317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
76317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/* Assign choice of congestion control. */
7755d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphalvoid tcp_assign_congestion_control(struct sock *sk)
78317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger{
796687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo	struct inet_connection_sock *icsk = inet_csk(sk);
80317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	struct tcp_congestion_ops *ca;
81317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
8255d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal	rcu_read_lock();
8355d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal	list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
8455d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal		if (likely(try_module_get(ca->owner))) {
8555d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal			icsk->icsk_ca_ops = ca;
8655d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal			goto out;
87317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		}
8855d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal		/* Fallback to next available. The last really
8955d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal		 * guaranteed fallback is Reno from this list.
9055d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal		 */
91317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	}
9255d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphalout:
9355d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal	rcu_read_unlock();
9455d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal
9555d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal	/* Clear out private data before diag gets it and
9655d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal	 * the ca has not been initialized.
9755d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal	 */
9855d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal	if (ca->get_info)
9955d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal		memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
10055d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal}
10155d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal
10255d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphalvoid tcp_init_congestion_control(struct sock *sk)
10355d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal{
10455d8694fa82c9b5858ae5a78a210353961f908f9Florian Westphal	const struct inet_connection_sock *icsk = inet_csk(sk);
105317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
1066687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo	if (icsk->icsk_ca_ops->init)
1076687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo		icsk->icsk_ca_ops->init(sk);
108317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger}
109317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
110317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/* Manage refcounts on socket close. */
1116687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melovoid tcp_cleanup_congestion_control(struct sock *sk)
112317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger{
1136687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo	struct inet_connection_sock *icsk = inet_csk(sk);
1146687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo
1156687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo	if (icsk->icsk_ca_ops->release)
1166687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo		icsk->icsk_ca_ops->release(sk);
1176687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo	module_put(icsk->icsk_ca_ops->owner);
118317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger}
119317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
120317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/* Used by sysctl to change default congestion control */
121317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemmingerint tcp_set_default_congestion_control(const char *name)
122317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger{
123317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	struct tcp_congestion_ops *ca;
124317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	int ret = -ENOENT;
125317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
126317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	spin_lock(&tcp_cong_list_lock);
127317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	ca = tcp_ca_find(name);
12895a5afca4a8d2e1cb77e1d4bc6ff9f718dc32f7aJohannes Berg#ifdef CONFIG_MODULES
129a8f80e8ff94ecba629542d9b4b5f5a8ee3eb565cEric Paris	if (!ca && capable(CAP_NET_ADMIN)) {
130317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		spin_unlock(&tcp_cong_list_lock);
131317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
132317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		request_module("tcp_%s", name);
133317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		spin_lock(&tcp_cong_list_lock);
134317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		ca = tcp_ca_find(name);
135317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	}
136317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger#endif
137317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
138317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	if (ca) {
139164891aadf1721fca4dce473bb0e0998181537c6Stephen Hemminger		ca->flags |= TCP_CONG_NON_RESTRICTED;	/* default is always allowed */
140317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		list_move(&ca->list, &tcp_cong_list);
141317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		ret = 0;
142317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	}
143317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	spin_unlock(&tcp_cong_list_lock);
144317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
145317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	return ret;
146317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger}
147317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
148b1736a71404b3961f061c795a81210aa7f945fc0Stephen Hemminger/* Set default value from kernel configuration at bootup */
149b1736a71404b3961f061c795a81210aa7f945fc0Stephen Hemmingerstatic int __init tcp_congestion_default(void)
150b1736a71404b3961f061c795a81210aa7f945fc0Stephen Hemminger{
151b1736a71404b3961f061c795a81210aa7f945fc0Stephen Hemminger	return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG);
152b1736a71404b3961f061c795a81210aa7f945fc0Stephen Hemminger}
153b1736a71404b3961f061c795a81210aa7f945fc0Stephen Hemmingerlate_initcall(tcp_congestion_default);
154b1736a71404b3961f061c795a81210aa7f945fc0Stephen Hemminger
1553ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger/* Build string with list of available congestion control values */
1563ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemmingervoid tcp_get_available_congestion_control(char *buf, size_t maxlen)
1573ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger{
1583ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger	struct tcp_congestion_ops *ca;
1593ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger	size_t offs = 0;
1603ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger
1613ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger	rcu_read_lock();
1623ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger	list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
1633ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger		offs += snprintf(buf + offs, maxlen - offs,
1643ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger				 "%s%s",
1653ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger				 offs == 0 ? "" : " ", ca->name);
1663ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger	}
1673ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger	rcu_read_unlock();
1683ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger}
1693ff825b28d3345ef381eceae22bf9d92231f23dcStephen Hemminger
170317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/* Get current default congestion control */
171317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemmingervoid tcp_get_default_congestion_control(char *name)
172317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger{
173317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	struct tcp_congestion_ops *ca;
174317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	/* We will always have reno... */
175317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	BUG_ON(list_empty(&tcp_cong_list));
176317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
177317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	rcu_read_lock();
178317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	ca = list_entry(tcp_cong_list.next, struct tcp_congestion_ops, list);
179317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	strncpy(name, ca->name, TCP_CA_NAME_MAX);
180317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	rcu_read_unlock();
181317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger}
182317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
183ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger/* Built list of non-restricted congestion control values */
184ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemmingervoid tcp_get_allowed_congestion_control(char *buf, size_t maxlen)
185ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger{
186ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	struct tcp_congestion_ops *ca;
187ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	size_t offs = 0;
188ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger
189ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	*buf = '\0';
190ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	rcu_read_lock();
191ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
192164891aadf1721fca4dce473bb0e0998181537c6Stephen Hemminger		if (!(ca->flags & TCP_CONG_NON_RESTRICTED))
193ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger			continue;
194ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger		offs += snprintf(buf + offs, maxlen - offs,
195ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger				 "%s%s",
196ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger				 offs == 0 ? "" : " ", ca->name);
197ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	}
198ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	rcu_read_unlock();
199ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger}
200ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger
201ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger/* Change list of non-restricted congestion control */
202ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemmingerint tcp_set_allowed_congestion_control(char *val)
203ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger{
204ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	struct tcp_congestion_ops *ca;
205c34186ed008229e7f7e3f1de8e6acf6374995358Julia Lawall	char *saved_clone, *clone, *name;
206ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	int ret = 0;
207ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger
208c34186ed008229e7f7e3f1de8e6acf6374995358Julia Lawall	saved_clone = clone = kstrdup(val, GFP_USER);
209ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	if (!clone)
210ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger		return -ENOMEM;
211ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger
212ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	spin_lock(&tcp_cong_list_lock);
213ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	/* pass 1 check for bad entries */
214ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	while ((name = strsep(&clone, " ")) && *name) {
215ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger		ca = tcp_ca_find(name);
216ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger		if (!ca) {
217ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger			ret = -ENOENT;
218ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger			goto out;
219ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger		}
220ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	}
221ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger
222164891aadf1721fca4dce473bb0e0998181537c6Stephen Hemminger	/* pass 2 clear old values */
223ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	list_for_each_entry_rcu(ca, &tcp_cong_list, list)
224164891aadf1721fca4dce473bb0e0998181537c6Stephen Hemminger		ca->flags &= ~TCP_CONG_NON_RESTRICTED;
225ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger
226ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	/* pass 3 mark as allowed */
227ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	while ((name = strsep(&val, " ")) && *name) {
228ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger		ca = tcp_ca_find(name);
229ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger		WARN_ON(!ca);
230ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger		if (ca)
231164891aadf1721fca4dce473bb0e0998181537c6Stephen Hemminger			ca->flags |= TCP_CONG_NON_RESTRICTED;
232ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	}
233ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemmingerout:
234ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	spin_unlock(&tcp_cong_list_lock);
235c34186ed008229e7f7e3f1de8e6acf6374995358Julia Lawall	kfree(saved_clone);
236ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger
237ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger	return ret;
238ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger}
239ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger
2405f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger/* Change congestion control for socket */
2416687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Meloint tcp_set_congestion_control(struct sock *sk, const char *name)
2425f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger{
2436687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo	struct inet_connection_sock *icsk = inet_csk(sk);
2445f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	struct tcp_congestion_ops *ca;
2455f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	int err = 0;
2465f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger
2475f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	rcu_read_lock();
2485f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	ca = tcp_ca_find(name);
2494d4d3d1e8807d6aa9822eeedf7fe8500e1b7e38dStephen Hemminger
25035bfbc94070e480f350c868abc4ff9f77e7f2051Stephen Hemminger	/* no change asking for existing value */
2516687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo	if (ca == icsk->icsk_ca_ops)
2525f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger		goto out;
2535f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger
25495a5afca4a8d2e1cb77e1d4bc6ff9f718dc32f7aJohannes Berg#ifdef CONFIG_MODULES
25535bfbc94070e480f350c868abc4ff9f77e7f2051Stephen Hemminger	/* not found attempt to autoload module */
256a8f80e8ff94ecba629542d9b4b5f5a8ee3eb565cEric Paris	if (!ca && capable(CAP_NET_ADMIN)) {
25735bfbc94070e480f350c868abc4ff9f77e7f2051Stephen Hemminger		rcu_read_unlock();
25835bfbc94070e480f350c868abc4ff9f77e7f2051Stephen Hemminger		request_module("tcp_%s", name);
25935bfbc94070e480f350c868abc4ff9f77e7f2051Stephen Hemminger		rcu_read_lock();
26035bfbc94070e480f350c868abc4ff9f77e7f2051Stephen Hemminger		ca = tcp_ca_find(name);
26135bfbc94070e480f350c868abc4ff9f77e7f2051Stephen Hemminger	}
26235bfbc94070e480f350c868abc4ff9f77e7f2051Stephen Hemminger#endif
2635f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	if (!ca)
2645f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger		err = -ENOENT;
2655f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger
26652e804c6dfaa5df1e4b0e290357b82ad4e4cda2cEric W. Biederman	else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) ||
26752e804c6dfaa5df1e4b0e290357b82ad4e4cda2cEric W. Biederman		   ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)))
268ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger		err = -EPERM;
269ce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336Stephen Hemminger
2705f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	else if (!try_module_get(ca->owner))
2715f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger		err = -EBUSY;
2725f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger
2735f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	else {
2746687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo		tcp_cleanup_congestion_control(sk);
2756687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo		icsk->icsk_ca_ops = ca;
2764d4d3d1e8807d6aa9822eeedf7fe8500e1b7e38dStephen Hemminger
2774d4d3d1e8807d6aa9822eeedf7fe8500e1b7e38dStephen Hemminger		if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init)
2786687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo			icsk->icsk_ca_ops->init(sk);
2795f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	}
2805f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger out:
2815f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	rcu_read_unlock();
2825f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger	return err;
2835f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger}
2845f8ef48d240963093451bcf83df89f1a1364f51dStephen Hemminger
2859f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng/* Slow start is used when congestion window is no greater than the slow start
2869f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng * threshold. We base on RFC2581 and also handle stretch ACKs properly.
2879f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng * We do not implement RFC3465 Appropriate Byte Counting (ABC) per se but
2889f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng * something better;) a packet is only considered (s)acked in its entirety to
2899f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng * defend the ACK attacks described in the RFC. Slow start processes a stretch
2909f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng * ACK of degree N as if N acks of degree 1 are received back to back except
2919f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng * ABC caps N to 2. Slow start exits when cwnd grows over ssthresh and
2929f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng * returns the leftover acks to adjust cwnd in congestion avoidance mode.
29340efc6fa179f440a008333ea98f701bc35a1f97fStephen Hemminger */
294a12a601ed163578084a48708ae376805f79a1ccfLi RongQingvoid tcp_slow_start(struct tcp_sock *tp, u32 acked)
29540efc6fa179f440a008333ea98f701bc35a1f97fStephen Hemminger{
2969f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng	u32 cwnd = tp->snd_cwnd + acked;
297a02ba041664171563e6418ccdf3b363d32d6a43bStephen Hemminger
2989f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng	if (cwnd > tp->snd_ssthresh)
2999f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng		cwnd = tp->snd_ssthresh + 1;
3009f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng	tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp);
30140efc6fa179f440a008333ea98f701bc35a1f97fStephen Hemminger}
30240efc6fa179f440a008333ea98f701bc35a1f97fStephen HemmingerEXPORT_SYMBOL_GPL(tcp_slow_start);
30340efc6fa179f440a008333ea98f701bc35a1f97fStephen Hemminger
304758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen/* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd (or alternative w) */
305758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinenvoid tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w)
306758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen{
307758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen	if (tp->snd_cwnd_cnt >= w) {
308758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen		if (tp->snd_cwnd < tp->snd_cwnd_clamp)
309758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen			tp->snd_cwnd++;
310758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen		tp->snd_cwnd_cnt = 0;
311758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen	} else {
312758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen		tp->snd_cwnd_cnt++;
313758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen	}
314758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen}
315758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo JärvinenEXPORT_SYMBOL_GPL(tcp_cong_avoid_ai);
316758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen
317317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/*
318317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * TCP Reno congestion control
319317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * This is special case used for fallback as well.
320317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger */
321317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/* This is Jacobson's slow start and congestion avoidance.
322317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger * SIGCOMM '88, p. 328.
323317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger */
324249015515fe3fc9818d86cb5c83bbc92505ad7dcEric Dumazetvoid tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 acked)
325317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger{
3266687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo	struct tcp_sock *tp = tcp_sk(sk);
3276687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo
328249015515fe3fc9818d86cb5c83bbc92505ad7dcEric Dumazet	if (!tcp_is_cwnd_limited(sk))
329317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger		return;
330317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
3317faffa1c7fb9b8e8917e3225d4e2638270c0a48bStephen Hemminger	/* In "safe" area, increase. */
332e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	if (tp->snd_cwnd <= tp->snd_ssthresh)
3339f9843a751d0a2057f9f3d313886e7e5e6ebaac9Yuchung Cheng		tcp_slow_start(tp, acked);
334e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	/* In dangerous area, increase slowly. */
335ca2eb5679f8ddffff60156af42595df44a315ef0Stephen Hemminger	else
336758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eacIlpo Järvinen		tcp_cong_avoid_ai(tp, tp->snd_cwnd);
337317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger}
338317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen HemmingerEXPORT_SYMBOL_GPL(tcp_reno_cong_avoid);
339317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
340317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger/* Slow start threshold is half the congestion window (min 2) */
3416687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melou32 tcp_reno_ssthresh(struct sock *sk)
342317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger{
3436687e988d9aeaccad6774e6a8304f681f3ec0a03Arnaldo Carvalho de Melo	const struct tcp_sock *tp = tcp_sk(sk);
344688d1945bc89bd585ec67b5b83121f499e6290bbstephen hemminger
345317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	return max(tp->snd_cwnd >> 1U, 2U);
346317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger}
347317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen HemmingerEXPORT_SYMBOL_GPL(tcp_reno_ssthresh);
348317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger
349317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemmingerstruct tcp_congestion_ops tcp_reno = {
350164891aadf1721fca4dce473bb0e0998181537c6Stephen Hemminger	.flags		= TCP_CONG_NON_RESTRICTED,
351317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	.name		= "reno",
352317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	.owner		= THIS_MODULE,
353317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	.ssthresh	= tcp_reno_ssthresh,
354317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger	.cong_avoid	= tcp_reno_cong_avoid,
355317a76f9a44b437d6301718f4e5d08bd93f98da7Stephen Hemminger};
356