diff options
author | David S. Miller <davem@davemloft.net> | 2018-01-29 18:14:59 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-29 18:15:51 +0300 |
commit | 3e3ab9ccca5b50b11bd4d16c2048b667343354bd (patch) | |
tree | 7279f7401e7cc2b93fb7cb2bff894b5385429a68 /net/ipv4/tcp_timer.c | |
parent | 868c36dcc949c26bc74fa4661b670d9acc6489e4 (diff) | |
parent | ba804bb4b72e57374b5f567b783aa0298fba0ce6 (diff) | |
download | linux-3e3ab9ccca5b50b11bd4d16c2048b667343354bd.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_timer.c')
-rw-r--r-- | net/ipv4/tcp_timer.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 257abdde23b0..71fc60f1b326 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -48,11 +48,19 @@ static void tcp_write_err(struct sock *sk) * to prevent DoS attacks. It is called when a retransmission timeout * or zero probe timeout occurs on orphaned socket. * + * Also close if our net namespace is exiting; in that case there is no + * hope of ever communicating again since all netns interfaces are already + * down (or about to be down), and we need to release our dst references, + * which have been moved to the netns loopback interface, so the namespace + * can finish exiting. This condition is only possible if we are a kernel + * socket, as those do not hold references to the namespace. + * * Criteria is still not confirmed experimentally and may change. * We kill the socket, if: * 1. If number of orphaned sockets exceeds an administratively configured * limit. * 2. If we have strong memory pressure. + * 3. If our net namespace is exiting. */ static int tcp_out_of_resources(struct sock *sk, bool do_reset) { @@ -81,6 +89,13 @@ static int tcp_out_of_resources(struct sock *sk, bool do_reset) __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); return 1; } + + if (!check_net(sock_net(sk))) { + /* Not possible to send reset; just close */ + tcp_done(sk); + return 1; + } + return 0; } |