summaryrefslogtreecommitdiff
path: root/net/ipv4/tcp_cong.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-11-09 16:36:36 -0800
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-02 21:21:50 -0800
commit35bfbc94070e480f350c868abc4ff9f77e7f2051 (patch)
tree4d6f9405aae719308ab5ff36818c048e0062996c /net/ipv4/tcp_cong.c
parentce7bc3bf15cbf5dc5a5587ccb6b04c5b4dde4336 (diff)
[TCP]: Allow autoloading of congestion control via setsockopt.
If user has permision to load modules, then autoload then attempt autoload of TCP congestion module. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_cong.c')
-rw-r--r--net/ipv4/tcp_cong.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 343d6197c92e..5ca7723d0798 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -113,7 +113,7 @@ int tcp_set_default_congestion_control(const char *name)
spin_lock(&tcp_cong_list_lock);
ca = tcp_ca_find(name);
#ifdef CONFIG_KMOD
- if (!ca) {
+ if (!ca && capable(CAP_SYS_MODULE)) {
spin_unlock(&tcp_cong_list_lock);
request_module("tcp_%s", name);
@@ -236,9 +236,19 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
rcu_read_lock();
ca = tcp_ca_find(name);
+ /* no change asking for existing value */
if (ca == icsk->icsk_ca_ops)
goto out;
+#ifdef CONFIG_KMOD
+ /* not found attempt to autoload module */
+ if (!ca && capable(CAP_SYS_MODULE)) {
+ rcu_read_unlock();
+ request_module("tcp_%s", name);
+ rcu_read_lock();
+ ca = tcp_ca_find(name);
+ }
+#endif
if (!ca)
err = -ENOENT;