diff options
-rw-r--r-- | net/ipv4/tcp_cong.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 27ead0dd16bc..38f2f8aa4ceb 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -107,6 +107,18 @@ void tcp_init_congestion_control(struct sock *sk) | |||
107 | icsk->icsk_ca_ops->init(sk); | 107 | icsk->icsk_ca_ops->init(sk); |
108 | } | 108 | } |
109 | 109 | ||
110 | static void tcp_reinit_congestion_control(struct sock *sk, | ||
111 | const struct tcp_congestion_ops *ca) | ||
112 | { | ||
113 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
114 | |||
115 | tcp_cleanup_congestion_control(sk); | ||
116 | icsk->icsk_ca_ops = ca; | ||
117 | |||
118 | if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) | ||
119 | icsk->icsk_ca_ops->init(sk); | ||
120 | } | ||
121 | |||
110 | /* Manage refcounts on socket close. */ | 122 | /* Manage refcounts on socket close. */ |
111 | void tcp_cleanup_congestion_control(struct sock *sk) | 123 | void tcp_cleanup_congestion_control(struct sock *sk) |
112 | { | 124 | { |
@@ -262,21 +274,13 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
262 | #endif | 274 | #endif |
263 | if (!ca) | 275 | if (!ca) |
264 | err = -ENOENT; | 276 | err = -ENOENT; |
265 | |||
266 | else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || | 277 | else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || |
267 | ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))) | 278 | ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))) |
268 | err = -EPERM; | 279 | err = -EPERM; |
269 | |||
270 | else if (!try_module_get(ca->owner)) | 280 | else if (!try_module_get(ca->owner)) |
271 | err = -EBUSY; | 281 | err = -EBUSY; |
272 | 282 | else | |
273 | else { | 283 | tcp_reinit_congestion_control(sk, ca); |
274 | tcp_cleanup_congestion_control(sk); | ||
275 | icsk->icsk_ca_ops = ca; | ||
276 | |||
277 | if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) | ||
278 | icsk->icsk_ca_ops->init(sk); | ||
279 | } | ||
280 | out: | 284 | out: |
281 | rcu_read_unlock(); | 285 | rcu_read_unlock(); |
282 | return err; | 286 | return err; |