diff options
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index cf74c416831a..7c05a50c8840 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1853,6 +1853,37 @@ void tcp_v4_destroy_sock(struct sock *sk) EXPORT_SYMBOL(tcp_v4_destroy_sock); +/* + * tcp_v4_nuke_addr - destroy all sockets on the given local address + */ +void tcp_v4_nuke_addr(__u32 saddr) +{ + unsigned int bucket; + + for (bucket = 0; bucket < tcp_hashinfo.ehash_size; bucket++) { + struct hlist_nulls_node *node; + struct sock *sk; + spinlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, bucket); + + spin_lock_bh(lock); + sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[bucket].chain) { + struct inet_sock *inet = inet_sk(sk); + + if (inet->rcv_saddr != saddr) + continue; + if (sysctl_ip_dynaddr && sk->sk_state == TCP_SYN_SENT) + continue; + if (sock_flag(sk, SOCK_DEAD)) + continue; + + sk->sk_err = ETIMEDOUT; + sk->sk_error_report(sk); + tcp_done(sk); + } + spin_unlock_bh(lock); + } +} + #ifdef CONFIG_PROC_FS /* Proc filesystem TCP sock list dumping. */ |