diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/tcp_cong.c | 12 |
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) | |||
113 | spin_lock(&tcp_cong_list_lock); | 113 | spin_lock(&tcp_cong_list_lock); |
114 | ca = tcp_ca_find(name); | 114 | ca = tcp_ca_find(name); |
115 | #ifdef CONFIG_KMOD | 115 | #ifdef CONFIG_KMOD |
116 | if (!ca) { | 116 | if (!ca && capable(CAP_SYS_MODULE)) { |
117 | spin_unlock(&tcp_cong_list_lock); | 117 | spin_unlock(&tcp_cong_list_lock); |
118 | 118 | ||
119 | request_module("tcp_%s", name); | 119 | request_module("tcp_%s", name); |
@@ -236,9 +236,19 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
236 | 236 | ||
237 | rcu_read_lock(); | 237 | rcu_read_lock(); |
238 | ca = tcp_ca_find(name); | 238 | ca = tcp_ca_find(name); |
239 | /* no change asking for existing value */ | ||
239 | if (ca == icsk->icsk_ca_ops) | 240 | if (ca == icsk->icsk_ca_ops) |
240 | goto out; | 241 | goto out; |
241 | 242 | ||
243 | #ifdef CONFIG_KMOD | ||
244 | /* not found attempt to autoload module */ | ||
245 | if (!ca && capable(CAP_SYS_MODULE)) { | ||
246 | rcu_read_unlock(); | ||
247 | request_module("tcp_%s", name); | ||
248 | rcu_read_lock(); | ||
249 | ca = tcp_ca_find(name); | ||
250 | } | ||
251 | #endif | ||
242 | if (!ca) | 252 | if (!ca) |
243 | err = -ENOENT; | 253 | err = -ENOENT; |
244 | 254 | ||