// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * INET		An implementation of the TCP/IP protocol suite for the LINUX
 *		operating system.  INET is implemented using the BSD Socket
 *		interface as the means of communication with the user level.
 *
 *		Generic INET transport hashtables
 *
 * Authors:	Lotsa people, from code originally in tcp
 */

#include <linux/module.h>
#include <linux/random.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/vmalloc.h>
#include <linux/memblock.h>

#include <net/addrconf.h>
#include <net/inet_connection_sock.h>
#include <net/inet_hashtables.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/inet6_hashtables.h>
#endif
#include <net/hotdata.h>
#include <net/ip.h>
#include <net/rps.h>
#include <net/secure_seq.h>
#include <net/sock_reuseport.h>
#include <net/tcp.h>

u32 inet_ehashfn(const struct net *net, const __be32 laddr,
		 const __u16 lport, const __be32 faddr,
		 const __be16 fport)
{
	net_get_random_once(&inet_ehash_secret, sizeof(inet_ehash_secret));

	return lport + __inet_ehashfn(laddr, 0, faddr, fport,
				      inet_ehash_secret + net_hash_mix(net));
}
EXPORT_SYMBOL_GPL(inet_ehashfn);

/* This function handles inet_sock, but also timewait and request sockets
 * for IPv4/IPv6.
 */
static u32 sk_ehashfn(const struct sock *sk)
{
#if IS_ENABLED(CONFIG_IPV6)
	if (sk->sk_family == AF_INET6 &&
	    !ipv6_addr_v4mapped(&sk->sk_v6_daddr))
		return inet6_ehashfn(sock_net(sk),
				     &sk->sk_v6_rcv_saddr, sk->sk_num,
				     &sk->sk_v6_daddr, sk->sk_dport);
#endif
	return inet_ehashfn(sock_net(sk),
			    sk->sk_rcv_saddr, sk->sk_num,
			    sk->sk_daddr, sk->sk_dport);
}

static bool sk_is_connect_bind(const struct sock *sk)
{
	if (sk->sk_state == TCP_TIME_WAIT)
		return inet_twsk(sk)->tw_connect_bind;
	else
		return sk->sk_userlocks & SOCK_CONNECT_BIND;
}

/*
 * Allocate and initialize a new local port bind bucket.
 * The bindhash mutex for snum's hash chain must be held here.
 */
struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
						 struct net *net,
						 struct inet_bind_hashbucket *head,
						 const unsigned short snum,
						 int l3mdev)
{
	struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);

	if (tb) {
		write_pnet(&tb->ib_net, net);
		tb->l3mdev    = l3mdev;
		tb->port      = snum;
		tb->fastreuse = 0;
		tb->fastreuseport = 0;
		INIT_HLIST_HEAD(&tb->bhash2);
		hlist_add_head_rcu(&tb->node, &head->chain);
	}
	return tb;
}

/*
 * Caller must hold hashbucket lock for this tb with local BH disabled
 */
void inet_bind_bucket_destroy(struct inet_bind_bucket *tb)
{
	const struct inet_bind2_bucket *tb2;

	if (hlist_empty(&tb->bhash2)) {
		hlist_del_rcu(&tb->node);
		kfree_rcu(tb, rcu);
		return;
	}

	if (tb->fastreuse == -1 && tb->fastreuseport == -1)
		return;
	hlist_for_each_entry(tb2, &tb->bhash2, bhash_node) {
		if (tb2->fastreuse != -1 || tb2->fastreuseport != -1)
			return;
	}
	tb->fastreuse = -1;
	tb->fastreuseport = -1;
}

bool inet_bind_bucket_match(const struct inet_bind_bucket *tb, const struct net *net,
			    unsigned short port, int l3mdev)
{
	return net_eq(ib_net(tb), net) && tb->port == port &&
		tb->l3mdev == l3mdev;
}

static void inet_bind2_bucket_init(struct inet_bind2_bucket *tb2,
				   struct net *net,
				   struct inet_bind_hashbucket *head,
				   struct inet_bind_bucket *tb,
				   const struct sock *sk)
{
	write_pnet(&tb2->ib_net, net);
	tb2->l3mdev = tb->l3mdev;
	tb2->port = tb->port;
#if IS_ENABLED(CONFIG_IPV6)
	BUILD_BUG_ON(USHRT_MAX < (IPV6_ADDR_ANY | IPV6_ADDR_MAPPED));
	if (sk->sk_family == AF_INET6) {
		tb2->addr_type = ipv6_addr_type(&sk->sk_v6_rcv_saddr);
		tb2->v6_rcv_saddr = sk->sk_v6_rcv_saddr;
	} else {
		tb2->addr_type = IPV6_ADDR_MAPPED;
		ipv6_addr_set_v4mapped(sk->sk_rcv_saddr, &tb2->v6_rcv_saddr);
	}
#else
	tb2->rcv_saddr = sk->sk_rcv_saddr;
#endif
	tb2->fastreuse = 0;
	tb2->fastreuseport = 0;
	INIT_HLIST_HEAD(&tb2->owners);
	hlist_add_head(&tb2->node, &head->chain);
	hlist_add_head(&tb2->bhash_node, &tb->bhash2);
}

struct inet_bind2_bucket *inet_bind2_bucket_create(struct kmem_cache *cachep,
						   struct net *net,
						   struct inet_bind_hashbucket *head,
						   struct inet_bind_bucket *tb,
						   const struct sock *sk)
{
	struct inet_bind2_bucket *tb2 = kmem_cache_alloc(cachep, GFP_ATOMIC);

	if (tb2)
		inet_bind2_bucket_init(tb2, net, head, tb, sk);

	return tb2;
}

/* Caller must hold hashbucket lock for this tb with local BH disabled */
void inet_bind2_bucket_destroy(struct kmem_cache *cachep, struct inet_bind2_bucket *tb)
{
	const struct sock *sk;

	if (hlist_empty(&tb->owners)) {
		__hlist_del(&tb->node);
		__hlist_del(&tb->bhash_node);
		kmem_cache_free(cachep, tb);
		return;
	}

	if (tb->fastreuse == -1 && tb->fastreuseport == -1)
		return;
	sk_for_each_bound(sk, &tb->owners) {
		if (!sk_is_connect_bind(sk))
			return;
	}
	tb->fastreuse = -1;
	tb->fastreuseport = -1;
}

static bool inet_bind2_bucket_addr_match(const struct inet_bind2_bucket *tb2,
					 const struct sock *sk)
{
#if IS_ENABLED(CONFIG_IPV6)
	if (sk->sk_family == AF_INET6)
		return ipv6_addr_equal(&tb2->v6_rcv_saddr, &sk->sk_v6_rcv_saddr);

	if (tb2->addr_type != IPV6_ADDR_MAPPED)
		return false;
#endif
	return tb2->rcv_saddr == sk->sk_rcv_saddr;
}

void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
		    struct inet_bind2_bucket *tb2, unsigned short port)
{
	WRITE_ONCE(inet_sk(sk)->inet_num, port);
	inet_csk(sk)->icsk_bind_hash = tb;
	inet_csk(sk)->icsk_bind2_hash = tb2;
	sk_add_bind_node(sk, &tb2->owners);
}

/*
 * Get rid of any references to a local port held by the given sock.
 */
static void __inet_put_port(struct sock *sk)
{
	struct inet_hashinfo *hashinfo = tcp_get_hashinfo(sk);
	struct inet_bind_hashbucket *head, *head2;
	struct net *net = sock_net(sk);
	struct inet_bind_bucket *tb;
	int bhash;

	bhash = inet_bhashfn(net, inet_sk(sk)->inet_num, hashinfo->bhash_size);
	head = &hashinfo->bhash[bhash];
	head2 = inet_bhashfn_portaddr(hashinfo, sk, net, inet_sk(sk)->inet_num);

	spin_lock(&head->lock);
	tb = inet_csk(sk)->icsk_bind_hash;
	inet_csk(sk)->icsk_bind_hash = NULL;
	WRITE_ONCE(inet_sk(sk)->inet_num, 0);
	sk->sk_userlocks &= ~SOCK_CONNECT_BIND;

	spin_lock(&head2->lock);
	if (inet_csk(sk)->icsk_bind2_hash) {
		struct inet_bind2_bucket *tb2 = inet_csk(sk)->icsk_bind2_hash;

		__sk_del_bind_node(sk);
		inet_csk(sk)->icsk_bind2_hash = NULL;
		inet_bind2_bucket_destroy(hashinfo->bind2_bucket_cachep, tb2);
	}
	spin_unlock(&head2->lock);

	inet_bind_bucket_destroy(tb);
	spin_unlock(&head->lock);
}

void inet_put_port(struct sock *sk)
{
	local_bh_disable();
	__inet_put_port(sk);
	local_bh_enable();
}
EXPORT_SYMBOL(inet_put_port);

int __inet_inherit_port(const struct sock *sk, struct sock *child)
{
	struct inet_hashinfo *table = tcp_get_hashinfo(sk);
	unsigned short port = inet_sk(child)->inet_num;
	struct inet_bind_hashbucket *head, *head2;
	bool created_inet_bind_bucket = false;
	struct net *net = sock_net(sk);
	bool update_fastreuse = false;
	struct inet_bind2_bucket *tb2;
	struct inet_bind_bucket *tb;
	int bhash, l3mdev;

	bhash = inet_bhashfn(net, port, table->bhash_size);
	head = &table->bhash[bhash];
	head2 = inet_bhashfn_portaddr(table, child, net, port);

	spin_lock(&head->lock);
	spin_lock(&head2->lock);
	tb = inet_csk(sk)->icsk_bind_hash;
	tb2 = inet_csk(sk)->icsk_bind2_hash;
	if (unlikely(!tb || !tb2)) {
		spin_unlock(&head2->lock);
		spin_unlock(&head->lock);
		return -ENOENT;
	}
	if (tb->port != port) {
		l3mdev = inet_sk_bound_l3mdev(sk);

		/* NOTE: using tproxy and redirecting skbs to a proxy
		 * on a different listener port breaks the assumption
		 * that the listener socket's icsk_bind_hash is the same
		 * as that of the child socket. We have to look up or
		 * create a new bind bucket for the child here. */
		inet_bind_bucket_for_each(tb, &head->chain) {
			if (inet_bind_bucket_match(tb, net, port, l3mdev))
				break;
		}
		if (!tb) {
			tb = inet_bind_bucket_create(table->bind_bucket_cachep,
						     net, head, port, l3mdev);
			if (!tb) {
				spin_unlock(&head2->lock);
				spin_unlock(&head->lock);
				return -ENOMEM;
			}
			created_inet_bind_bucket = true;
		}
		update_fastreuse = true;

		goto bhash2_find;
	} else if (!inet_bind2_bucket_addr_match(tb2, child)) {
		l3mdev = inet_sk_bound_l3mdev(sk);

bhash2_find:
		tb2 = inet_bind2_bucket_find(head2, net, port, l3mdev, child);
		if (!tb2) {
			tb2 = inet_bind2_bucket_create(table->bind2_bucket_cachep,
						       net, head2, tb, child);
			if (!tb2)
				goto error;
		}
	}
	if (update_fastreuse)
		inet_csk_update_fastreuse(child, tb, tb2);
	inet_bind_hash(child, tb, tb2, port);
	spin_unlock(&head2->lock);
	spin_unlock(&head->lock);

	return 0;

error:
	if (created_inet_bind_bucket)
		inet_bind_bucket_destroy(tb);
	spin_unlock(&head2->lock);
	spin_unlock(&head->lock);
	return -ENOMEM;
}
EXPORT_SYMBOL_GPL(__inet_inherit_port);

static struct inet_listen_hashbucket *
inet_lhash2_bucket_sk(struct inet_hashinfo *h, struct sock *sk)
{
	u32 hash;

#if IS_ENABLED(CONFIG_IPV6)
	if (sk->sk_family == AF_INET6)
		hash = ipv6_portaddr_hash(sock_net(sk),
					  &sk->sk_v6_rcv_saddr,
					  inet_sk(sk)->inet_num);
	else
#endif
		hash = ipv4_portaddr_hash(sock_net(sk),
					  inet_sk(sk)->inet_rcv_saddr,
					  inet_sk(sk)->inet_num);
	return inet_lhash2_bucket(h, hash);
}

static inline int compute_score(struct sock *sk, const struct net *net,
				const unsigned short hnum, const __be32 daddr,
				const int dif, const int sdif)
{
	int score = -1;

	if (net_eq(sock_net(sk), net) && READ_ONCE(sk->sk_num) == hnum &&
			!ipv6_only_sock(sk)) {
		if (sk->sk_rcv_saddr != daddr)
			return -1;

		if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
			return -1;
		score =  sk->sk_bound_dev_if ? 2 : 1;

		if (sk->sk_family == PF_INET)
			score++;
		if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
			score++;
	}
	return score;
}

/**
 * inet_lookup_reuseport() - execute reuseport logic on AF_INET socket if necessary.
 * @net: network namespace.
 * @sk: AF_INET socket, must be in TCP_LISTEN state for TCP or TCP_CLOSE for UDP.
 * @skb: context for a potential SK_REUSEPORT program.
 * @doff: header offset.
 * @saddr: source address.
 * @sport: source port.
 * @daddr: destination address.
 * @hnum: destination port in host byte order.
 * @ehashfn: hash function used to generate the fallback hash.
 *
 * Return: NULL if sk doesn't have SO_REUSEPORT set, otherwise a pointer to
 *         the selected sock or an error.
 */
struct sock *inet_lookup_reuseport(const struct net *net, struct sock *sk,
				   struct sk_buff *skb, int doff,
				   __be32 saddr, __be16 sport,
				   __be32 daddr, unsigned short hnum,
				   inet_ehashfn_t *ehashfn)
{
	struct sock *reuse_sk = NULL;
	u32 phash;

	if (sk->sk_reuseport) {
		phash = INDIRECT_CALL_2(ehashfn, udp_ehashfn, inet_ehashfn,
					net, daddr, hnum, saddr, sport);
		reuse_sk = reuseport_select_sock(sk, phash, skb, doff);
	}
	return reuse_sk;
}
EXPORT_SYMBOL_GPL(inet_lookup_reuseport);

/*
 * Here are some nice properties to exploit here. The BSD API
 * does not allow a listening sock to specify the remote port nor the
 * remote address for the connection. So always assume those are both
 * wildcarded during the search since they can never be otherwise.
 */

/* called with rcu_read_lock() : No refcount taken on the socket */
static struct sock *inet_lhash2_lookup(const struct net *net,
				struct inet_listen_hashbucket *ilb2,
				struct sk_buff *skb, int doff,
				const __be32 saddr, __be16 sport,
				const __be32 daddr, const unsigned short hnum,
				const int dif, const int sdif)
{
	struct sock *sk, *result = NULL;
	struct hlist_nulls_node *node;
	int score, hiscore = 0;

	sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) {
		score = compute_score(sk, net, hnum, daddr, dif, sdif);
		if (score > hiscore) {
			result = inet_lookup_reuseport(net, sk, skb, doff,
						       saddr, sport, daddr, hnum, inet_ehashfn);
			if (result)
				return result;

			result = sk;
			hiscore = score;
		}
	}

	return result;
}

struct sock *inet_lookup_run_sk_lookup(const struct net *net,
				       int protocol,
				       struct sk_buff *skb, int doff,
				       __be32 saddr, __be16 sport,
				       __be32 daddr, u16 hnum, const int dif,
				       inet_ehashfn_t *ehashfn)
{
	struct sock *sk, *reuse_sk;
	bool no_reuseport;

	no_reuseport = bpf_sk_lookup_run_v4(net, protocol, saddr, sport,
					    daddr, hnum, dif, &sk);
	if (no_reuseport || IS_ERR_OR_NULL(sk))
		return sk;

	reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum,
					 ehashfn);
	if (reuse_sk)
		sk = reuse_sk;
	return sk;
}

struct sock *__inet_lookup_listener(const struct net *net,
				    struct sk_buff *skb, int doff,
				    const __be32 saddr, __be16 sport,
				    const __be32 daddr, const unsigned short hnum,
				    const int dif, const int sdif)
{
	struct inet_listen_hashbucket *ilb2;
	struct inet_hashinfo *hashinfo;
	struct sock *result = NULL;
	unsigned int hash2;

	/* Lookup redirect from BPF */
	if (static_branch_unlikely(&bpf_sk_lookup_enabled)) {
		result = inet_lookup_run_sk_lookup(net, IPPROTO_TCP, skb, doff,
						   saddr, sport, daddr, hnum, dif,
						   inet_ehashfn);
		if (result)
			goto done;
	}

	hashinfo = net->ipv4.tcp_death_row.hashinfo;
	hash2 = ipv4_portaddr_hash(net, daddr, hnum);
	ilb2 = inet_lhash2_bucket(hashinfo, hash2);

	result = inet_lhash2_lookup(net, ilb2, skb, doff,
				    saddr, sport, daddr, hnum,
				    dif, sdif);
	if (result)
		goto done;

	/* Lookup lhash2 with INADDR_ANY */
	hash2 = ipv4_portaddr_hash(net, htonl(INADDR_ANY), hnum);
	ilb2 = inet_lhash2_bucket(hashinfo, hash2);

	result = inet_lhash2_lookup(net, ilb2, skb, doff,
				    saddr, sport, htonl(INADDR_ANY), hnum,
				    dif, sdif);
done:
	if (IS_ERR(result))
		return NULL;
	return result;
}
EXPORT_SYMBOL_GPL(__inet_lookup_listener);

/* All sockets share common refcount, but have different destructors */
void sock_gen_put(struct sock *sk)
{
	if (!refcount_dec_and_test(&sk->sk_refcnt))
		return;

	if (sk->sk_state == TCP_TIME_WAIT)
		inet_twsk_free(inet_twsk(sk));
	else if (sk->sk_state == TCP_NEW_SYN_RECV)
		reqsk_free(inet_reqsk(sk));
	else
		sk_free(sk);
}
EXPORT_SYMBOL_GPL(sock_gen_put);

void sock_edemux(struct sk_buff *skb)
{
	sock_gen_put(skb->sk);
}
EXPORT_SYMBOL(sock_edemux);

struct sock *__inet_lookup_established(const struct net *net,
				       const __be32 saddr, const __be16 sport,
				       const __be32 daddr, const u16 hnum,
				       const int dif, const int sdif)
{
	const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
	INET_ADDR_COOKIE(acookie, saddr, daddr);
	const struct hlist_nulls_node *node;
	struct inet_ehash_bucket *head;
	struct inet_hashinfo *hashinfo;
	unsigned int hash, slot;
	struct sock *sk;

	hashinfo = net->ipv4.tcp_death_row.hashinfo;
	hash = inet_ehashfn(net, daddr, hnum, saddr, sport);
	slot = hash & hashinfo->ehash_mask;
	head = &hashinfo->ehash[slot];

begin:
	sk_nulls_for_each_rcu(sk, node, &head->chain) {
		if (sk->sk_hash != hash)
			continue;
		if (likely(inet_match(net, sk, acookie, ports, dif, sdif))) {
			if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
				goto out;
			if (unlikely(!inet_match(net, sk, acookie,
						 ports, dif, sdif))) {
				sock_gen_put(sk);
				goto begin;
			}
			goto found;
		}
	}
	/*
	 * if the nulls value we got at the end of this lookup is
	 * not the expected one, we must restart lookup.
	 * We probably met an item that was moved to another chain.
	 */
	if (get_nulls_value(node) != slot)
		goto begin;
out:
	sk = NULL;
found:
	return sk;
}
EXPORT_SYMBOL_GPL(__inet_lookup_established);

/* called with local bh disabled */
static int __inet_check_established(struct inet_timewait_death_row *death_row,
				    struct sock *sk, __u16 lport,
				    struct inet_timewait_sock **twp,
				    bool rcu_lookup,
				    u32 hash)
{
	struct inet_hashinfo *hinfo = death_row->hashinfo;
	struct inet_sock *inet = inet_sk(sk);
	__be32 daddr = inet->inet_rcv_saddr;
	__be32 saddr = inet->inet_daddr;
	int dif = sk->sk_bound_dev_if;
	struct net *net = sock_net(sk);
	int sdif = l3mdev_master_ifindex_by_index(net, dif);
	INET_ADDR_COOKIE(acookie, saddr, daddr);
	const __portpair ports = INET_COMBINED_PORTS(inet->inet_dport, lport);
	struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
	struct inet_timewait_sock *tw = NULL;
	const struct hlist_nulls_node *node;
	struct sock *sk2;
	spinlock_t *lock;

	if (rcu_lookup) {
		sk_nulls_for_each(sk2, node, &head->chain) {
			if (sk2->sk_hash != hash ||
			    !inet_match(net, sk2, acookie, ports, dif, sdif))
				continue;
			if (sk2->sk_state == TCP_TIME_WAIT)
				break;
			return -EADDRNOTAVAIL;
		}
		return 0;
	}

	lock = inet_ehash_lockp(hinfo, hash);
	spin_lock(lock);

	sk_nulls_for_each(sk2, node, &head->chain) {
		if (sk2->sk_hash != hash)
			continue;

		if (likely(inet_match(net, sk2, acookie, ports, dif, sdif))) {
			if (sk2->sk_state == TCP_TIME_WAIT) {
				tw = inet_twsk(sk2);
				if (tcp_twsk_unique(sk, sk2, twp))
					break;
			}
			goto not_unique;
		}
	}

	/* Must record num and sport now. Otherwise we will see
	 * in hash table socket with a funny identity.
	 */
	inet->inet_num = lport;
	inet->inet_sport = htons(lport);
	sk->sk_hash = hash;
	WARN_ON(!sk_unhashed(sk));
	__sk_nulls_add_node_rcu(sk, &head->chain);
	if (tw) {
		sk_nulls_del_node_init_rcu((struct sock *)tw);
		__NET_INC_STATS(net, LINUX_MIB_TIMEWAITRECYCLED);
	}
	spin_unlock(lock);
	sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);

	if (twp) {
		*twp = tw;
	} else if (tw) {
		/* Silly. Should hash-dance instead... */
		inet_twsk_deschedule_put(tw);
	}
	return 0;

not_unique:
	spin_unlock(lock);
	return -EADDRNOTAVAIL;
}

static u64 inet_sk_port_offset(const struct sock *sk)
{
	const struct inet_sock *inet = inet_sk(sk);

	return secure_ipv4_port_ephemeral(inet->inet_rcv_saddr,
					  inet->inet_daddr,
					  inet->inet_dport);
}

/* Searches for an exsiting socket in the ehash bucket list.
 * Returns true if found, false otherwise.
 */
static bool inet_ehash_lookup_by_sk(struct sock *sk,
				    struct hlist_nulls_head *list)
{
	const __portpair ports = INET_COMBINED_PORTS(sk->sk_dport, sk->sk_num);
	const int sdif = sk->sk_bound_dev_if;
	const int dif = sk->sk_bound_dev_if;
	const struct hlist_nulls_node *node;
	struct net *net = sock_net(sk);
	struct sock *esk;

	INET_ADDR_COOKIE(acookie, sk->sk_daddr, sk->sk_rcv_saddr);

	sk_nulls_for_each_rcu(esk, node, list) {
		if (esk->sk_hash != sk->sk_hash)
			continue;
		if (sk->sk_family == AF_INET) {
			if (unlikely(inet_match(net, esk, acookie,
						ports, dif, sdif))) {
				return true;
			}
		}
#if IS_ENABLED(CONFIG_IPV6)
		else if (sk->sk_family == AF_INET6) {
			if (unlikely(inet6_match(net, esk,
						 &sk->sk_v6_daddr,
						 &sk->sk_v6_rcv_saddr,
						 ports, dif, sdif))) {
				return true;
			}
		}
#endif
	}
	return false;
}

/* Insert a socket into ehash, and eventually remove another one
 * (The another one can be a SYN_RECV or TIMEWAIT)
 * If an existing socket already exists, socket sk is not inserted,
 * and sets found_dup_sk parameter to true.
 */
bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk)
{
	struct inet_hashinfo *hashinfo = tcp_get_hashinfo(sk);
	struct inet_ehash_bucket *head;
	struct hlist_nulls_head *list;
	spinlock_t *lock;
	bool ret = true;

	WARN_ON_ONCE(!sk_unhashed(sk));

	sk->sk_hash = sk_ehashfn(sk);
	head = inet_ehash_bucket(hashinfo, sk->sk_hash);
	list = &head->chain;
	lock = inet_ehash_lockp(hashinfo, sk->sk_hash);

	spin_lock(lock);
	if (osk) {
		WARN_ON_ONCE(sk->sk_hash != osk->sk_hash);
		ret = sk_nulls_replace_node_init_rcu(osk, sk);
		goto unlock;
	}

	if (found_dup_sk) {
		*found_dup_sk = inet_ehash_lookup_by_sk(sk, list);
		if (*found_dup_sk)
			ret = false;
	}

	if (ret)
		__sk_nulls_add_node_rcu(sk, list);

unlock:
	spin_unlock(lock);

	return ret;
}

bool inet_ehash_nolisten(struct sock *sk, struct sock *osk, bool *found_dup_sk)
{
	bool ok = inet_ehash_insert(sk, osk, found_dup_sk);

	if (ok) {
		sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
	} else {
		tcp_orphan_count_inc();
		inet_sk_set_state(sk, TCP_CLOSE);
		sock_set_flag(sk, SOCK_DEAD);
		inet_csk_destroy_sock(sk);
	}
	return ok;
}
EXPORT_IPV6_MOD(inet_ehash_nolisten);

static int inet_reuseport_add_sock(struct sock *sk,
				   struct inet_listen_hashbucket *ilb)
{
	struct inet_bind_bucket *tb = inet_csk(sk)->icsk_bind_hash;
	const struct hlist_nulls_node *node;
	kuid_t uid = sk_uid(sk);
	struct sock *sk2;

	sk_nulls_for_each_rcu(sk2, node, &ilb->nulls_head) {
		if (sk2 != sk &&
		    sk2->sk_family == sk->sk_family &&
		    ipv6_only_sock(sk2) == ipv6_only_sock(sk) &&
		    sk2->sk_bound_dev_if == sk->sk_bound_dev_if &&
		    inet_csk(sk2)->icsk_bind_hash == tb &&
		    sk2->sk_reuseport && uid_eq(uid, sk_uid(sk2)) &&
		    inet_rcv_saddr_equal(sk, sk2, false))
			return reuseport_add_sock(sk, sk2,
						  inet_rcv_saddr_any(sk));
	}

	return reuseport_alloc(sk, inet_rcv_saddr_any(sk));
}

int inet_hash(struct sock *sk)
{
	struct inet_hashinfo *hashinfo = tcp_get_hashinfo(sk);
	struct inet_listen_hashbucket *ilb2;
	int err = 0;

	if (sk->sk_state == TCP_CLOSE)
		return 0;

	if (sk->sk_state != TCP_LISTEN) {
		local_bh_disable();
		inet_ehash_nolisten(sk, NULL, NULL);
		local_bh_enable();
		return 0;
	}
	WARN_ON(!sk_unhashed(sk));
	ilb2 = inet_lhash2_bucket_sk(hashinfo, sk);

	spin_lock(&ilb2->lock);
	if (sk->sk_reuseport) {
		err = inet_reuseport_add_sock(sk, ilb2);
		if (err)
			goto unlock;
	}
	sock_set_flag(sk, SOCK_RCU_FREE);
	if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport &&
		sk->sk_family == AF_INET6)
		__sk_nulls_add_node_tail_rcu(sk, &ilb2->nulls_head);
	else
		__sk_nulls_add_node_rcu(sk, &ilb2->nulls_head);
	sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
unlock:
	spin_unlock(&ilb2->lock);

	return err;
}
EXPORT_IPV6_MOD(inet_hash);

void inet_unhash(struct sock *sk)
{
	struct inet_hashinfo *hashinfo = tcp_get_hashinfo(sk);

	if (sk_unhashed(sk))
		return;

	sock_rps_delete_flow(sk);
	if (sk->sk_state == TCP_LISTEN) {
		struct inet_listen_hashbucket *ilb2;

		ilb2 = inet_lhash2_bucket_sk(hashinfo, sk);
		/* Don't disable bottom halves while acquiring the lock to
		 * avoid circular locking dependency on PREEMPT_RT.
		 */
		spin_lock(&ilb2->lock);
		if (rcu_access_pointer(sk->sk_reuseport_cb))
			reuseport_stop_listen_sock(sk);

		__sk_nulls_del_node_init_rcu(sk);
		sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
		spin_unlock(&ilb2->lock);
	} else {
		spinlock_t *lock = inet_ehash_lockp(hashinfo, sk->sk_hash);

		spin_lock_bh(lock);
		__sk_nulls_del_node_init_rcu(sk);
		sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
		spin_unlock_bh(lock);
	}
}
EXPORT_IPV6_MOD(inet_unhash);

static bool inet_bind2_bucket_match(const struct inet_bind2_bucket *tb,
				    const struct net *net, unsigned short port,
				    int l3mdev, const struct sock *sk)
{
	if (!net_eq(ib2_net(tb), net) || tb->port != port ||
	    tb->l3mdev != l3mdev)
		return false;

	return inet_bind2_bucket_addr_match(tb, sk);
}

bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const struct net *net,
				      unsigned short port, int l3mdev, const struct sock *sk)
{
	if (!net_eq(ib2_net(tb), net) || tb->port != port ||
	    tb->l3mdev != l3mdev)
		return false;

#if IS_ENABLED(CONFIG_IPV6)
	if (tb->addr_type == IPV6_ADDR_ANY)
		return true;

	if (tb->addr_type != IPV6_ADDR_MAPPED)
		return false;

	if (sk->sk_family == AF_INET6 &&
	    !ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
		return false;
#endif
	return tb->rcv_saddr == 0;
}

/* The socket's bhash2 hashbucket spinlock must be held when this is called */
struct inet_bind2_bucket *
inet_bind2_bucket_find(const struct inet_bind_hashbucket *head, const struct net *net,
		       unsigned short port, int l3mdev, const struct sock *sk)
{
	struct inet_bind2_bucket *bhash2 = NULL;

	inet_bind_bucket_for_each(bhash2, &head->chain)
		if (inet_bind2_bucket_match(bhash2, net, port, l3mdev, sk))
			break;

	return bhash2;
}

struct inet_bind_hashbucket *
inet_bhash2_addr_any_hashbucket(const struct sock *sk, const struct net *net, int port)
{
	struct inet_hashinfo *hinfo = tcp_get_hashinfo(sk);
	u32 hash;

#if IS_ENABLED(CONFIG_IPV6)
	if (sk->sk_family == AF_INET6)
		hash = ipv6_portaddr_hash(net, &in6addr_any, port);
	else
#endif
		hash = ipv4_portaddr_hash(net, 0, port);

	return &hinfo->bhash2[hash & (hinfo->bhash_size - 1)];
}

static void inet_update_saddr(struct sock *sk, void *saddr, int family)
{
	if (family == AF_INET) {
		inet_sk(sk)->inet_saddr = *(__be32 *)saddr;
		sk_rcv_saddr_set(sk, inet_sk(sk)->inet_saddr);
	}
#if IS_ENABLED(CONFIG_IPV6)
	else {
		sk->sk_v6_rcv_saddr = *(struct in6_addr *)saddr;
	}
#endif
}

static int __inet_bhash2_update_saddr(struct sock *sk, void *saddr, int family, bool reset)
{
	struct inet_hashinfo *hinfo = tcp_get_hashinfo(sk);
	struct inet_bind_hashbucket *head, *head2;
	struct inet_bind2_bucket *tb2, *new_tb2;
	int l3mdev = inet_sk_bound_l3mdev(sk);
	int port = inet_sk(sk)->inet_num;
	struct net *net = sock_net(sk);
	int bhash;

	if (!inet_csk(sk)->icsk_bind2_hash) {
		/* Not bind()ed before. */
		if (reset)
			inet_reset_saddr(sk);
		else
			inet_update_saddr(sk, saddr, family);

		return 0;
	}

	/* Allocate a bind2 bucket ahead of time to avoid permanently putting
	 * the bhash2 table in an inconsistent state if a new tb2 bucket
	 * allocation fails.
	 */
	new_tb2 = kmem_cache_alloc(hinfo->bind2_bucket_cachep, GFP_ATOMIC);
	if (!new_tb2) {
		if (reset) {
			/* The (INADDR_ANY, port) bucket might have already
			 * been freed, then we cannot fixup icsk_bind2_hash,
			 * so we give up and unlink sk from bhash/bhash2 not
			 * to leave inconsistency in bhash2.
			 */
			inet_put_port(sk);
			inet_reset_saddr(sk);
		}

		return -ENOMEM;
	}

	bhash = inet_bhashfn(net, port, hinfo->bhash_size);
	head = &hinfo->bhash[bhash];
	head2 = inet_bhashfn_portaddr(hinfo, sk, net, port);

	/* If we change saddr locklessly, another thread
	 * iterating over bhash might see corrupted address.
	 */
	spin_lock_bh(&head->lock);

	spin_lock(&head2->lock);
	__sk_del_bind_node(sk);
	inet_bind2_bucket_destroy(hinfo->bind2_bucket_cachep, inet_csk(sk)->icsk_bind2_hash);
	spin_unlock(&head2->lock);

	if (reset)
		inet_reset_saddr(sk);
	else
		inet_update_saddr(sk, saddr, family);

	head2 = inet_bhashfn_portaddr(hinfo, sk, net, port);

	spin_lock(&head2->lock);
	tb2 = inet_bind2_bucket_find(head2, net, port, l3mdev, sk);
	if (!tb2) {
		tb2 = new_tb2;
		inet_bind2_bucket_init(tb2, net, head2, inet_csk(sk)->icsk_bind_hash, sk);
		if (sk_is_connect_bind(sk)) {
			tb2->fastreuse = -1;
			tb2->fastreuseport = -1;
		}
	}
	inet_csk(sk)->icsk_bind2_hash = tb2;
	sk_add_bind_node(sk, &tb2->owners);
	spin_unlock(&head2->lock);

	spin_unlock_bh(&head->lock);

	if (tb2 != new_tb2)
		kmem_cache_free(hinfo->bind2_bucket_cachep, new_tb2);

	return 0;
}

int inet_bhash2_update_saddr(struct sock *sk, void *saddr, int family)
{
	return __inet_bhash2_update_saddr(sk, saddr, family, false);
}
EXPORT_IPV6_MOD(inet_bhash2_update_saddr);

void inet_bhash2_reset_saddr(struct sock *sk)
{
	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
		__inet_bhash2_update_saddr(sk, NULL, 0, true);
}
EXPORT_IPV6_MOD(inet_bhash2_reset_saddr);

/* RFC 6056 3.3.4.  Algorithm 4: Double-Hash Port Selection Algorithm
 * Note that we use 32bit integers (vs RFC 'short integers')
 * because 2^16 is not a multiple of num_ephemeral and this
 * property might be used by clever attacker.
 *
 * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, though
 * attacks were since demonstrated, thus we use 65536 by default instead
 * to really give more isolation and privacy, at the expense of 256kB
 * of kernel memory.
 */
#define INET_TABLE_PERTURB_SIZE (1 << CONFIG_INET_TABLE_PERTURB_ORDER)
static u32 *table_perturb;

int __inet_hash_connect(struct inet_timewait_death_row *death_row,
		struct sock *sk, u64 port_offset,
		u32 hash_port0,
		int (*check_established)(struct inet_timewait_death_row *,
			struct sock *, __u16, struct inet_timewait_sock **,
			bool rcu_lookup, u32 hash))
{
	struct inet_hashinfo *hinfo = death_row->hashinfo;
	struct inet_bind_hashbucket *head, *head2;
	struct inet_timewait_sock *tw = NULL;
	int port = inet_sk(sk)->inet_num;
	struct net *net = sock_net(sk);
	struct inet_bind2_bucket *tb2;
	struct inet_bind_bucket *tb;
	bool tb_created = false;
	u32 remaining, offset;
	int ret, i, low, high;
	bool local_ports;
	int step, l3mdev;
	u32 index;

	if (port) {
		local_bh_disable();
		ret = check_established(death_row, sk, port, NULL, false,
					hash_port0 + port);
		local_bh_enable();
		return ret;
	}

	l3mdev = inet_sk_bound_l3mdev(sk);

	local_ports = inet_sk_get_local_port_range(sk, &low, &high);
	step = local_ports ? 1 : 2;

	high++; /* [32768, 60999] -> [32768, 61000[ */
	remaining = high - low;
	if (!local_ports && remaining > 1)
		remaining &= ~1U;

	get_random_sleepable_once(table_perturb,
				  INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb));
	index = port_offset & (INET_TABLE_PERTURB_SIZE - 1);

	offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32);
	offset %= remaining;

	/* In first pass we try ports of @low parity.
	 * inet_csk_get_port() does the opposite choice.
	 */
	if (!local_ports)
		offset &= ~1U;
other_parity_scan:
	port = low + offset;
	for (i = 0; i < remaining; i += step, port += step) {
		if (unlikely(port >= high))
			port -= remaining;
		if (inet_is_local_reserved_port(net, port))
			continue;
		head = &hinfo->bhash[inet_bhashfn(net, port,
						  hinfo->bhash_size)];
		rcu_read_lock();
		hlist_for_each_entry_rcu(tb, &head->chain, node) {
			if (!inet_bind_bucket_match(tb, net, port, l3mdev))
				continue;
			if (tb->fastreuse >= 0 || tb->fastreuseport >= 0) {
				rcu_read_unlock();
				goto next_port;
			}
			if (!check_established(death_row, sk, port, &tw, true,
					       hash_port0 + port))
				break;
			rcu_read_unlock();
			goto next_port;
		}
		rcu_read_unlock();

		spin_lock_bh(&head->lock);

		/* Does not bother with rcv_saddr checks, because
		 * the established check is already unique enough.
		 */
		inet_bind_bucket_for_each(tb, &head->chain) {
			if (inet_bind_bucket_match(tb, net, port, l3mdev)) {
				if (tb->fastreuse >= 0 ||
				    tb->fastreuseport >= 0)
					goto next_port_unlock;
				WARN_ON(hlist_empty(&tb->bhash2));
				if (!check_established(death_row, sk,
						       port, &tw, false,
						       hash_port0 + port))
					goto ok;
				goto next_port_unlock;
			}
		}

		tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
					     net, head, port, l3mdev);
		if (!tb) {
			spin_unlock_bh(&head->lock);
			return -ENOMEM;
		}
		tb_created = true;
		tb->fastreuse = -1;
		tb->fastreuseport = -1;
		goto ok;
next_port_unlock:
		spin_unlock_bh(&head->lock);
next_port:
		cond_resched();
	}

	if (!local_ports) {
		offset++;
		if ((offset & 1) && remaining > 1)
			goto other_parity_scan;
	}
	return -EADDRNOTAVAIL;

ok:
	/* Find the corresponding tb2 bucket since we need to
	 * add the socket to the bhash2 table as well
	 */
	head2 = inet_bhashfn_portaddr(hinfo, sk, net, port);
	spin_lock(&head2->lock);

	tb2 = inet_bind2_bucket_find(head2, net, port, l3mdev, sk);
	if (!tb2) {
		tb2 = inet_bind2_bucket_create(hinfo->bind2_bucket_cachep, net,
					       head2, tb, sk);
		if (!tb2)
			goto error;
		tb2->fastreuse = -1;
		tb2->fastreuseport = -1;
	}

	/* Here we want to add a little bit of randomness to the next source
	 * port that will be chosen. We use a max() with a random here so that
	 * on low contention the randomness is maximal and on high contention
	 * it may be inexistent.
	 */
	i = max_t(int, i, get_random_u32_below(8) * step);
	WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + step);

	/* Head lock still held and bh's disabled */
	inet_bind_hash(sk, tb, tb2, port);
	sk->sk_userlocks |= SOCK_CONNECT_BIND;

	if (sk_unhashed(sk)) {
		inet_sk(sk)->inet_sport = htons(port);
		inet_ehash_nolisten(sk, (struct sock *)tw, NULL);
	}
	if (tw)
		inet_twsk_bind_unhash(tw, hinfo);

	spin_unlock(&head2->lock);
	spin_unlock(&head->lock);

	if (tw)
		inet_twsk_deschedule_put(tw);
	local_bh_enable();
	return 0;

error:
	if (sk_hashed(sk)) {
		spinlock_t *lock = inet_ehash_lockp(hinfo, sk->sk_hash);

		sock_prot_inuse_add(net, sk->sk_prot, -1);

		spin_lock(lock);
		__sk_nulls_del_node_init_rcu(sk);
		spin_unlock(lock);

		sk->sk_hash = 0;
		inet_sk(sk)->inet_sport = 0;
		WRITE_ONCE(inet_sk(sk)->inet_num, 0);

		if (tw)
			inet_twsk_bind_unhash(tw, hinfo);
	}

	spin_unlock(&head2->lock);
	if (tb_created)
		inet_bind_bucket_destroy(tb);
	spin_unlock(&head->lock);

	if (tw)
		inet_twsk_deschedule_put(tw);

	local_bh_enable();

	return -ENOMEM;
}

/*
 * Bind a port for a connect operation and hash it.
 */
int inet_hash_connect(struct inet_timewait_death_row *death_row,
		      struct sock *sk)
{
	const struct inet_sock *inet = inet_sk(sk);
	const struct net *net = sock_net(sk);
	u64 port_offset = 0;
	u32 hash_port0;

	if (!inet_sk(sk)->inet_num)
		port_offset = inet_sk_port_offset(sk);

	hash_port0 = inet_ehashfn(net, inet->inet_rcv_saddr, 0,
				  inet->inet_daddr, inet->inet_dport);

	return __inet_hash_connect(death_row, sk, port_offset, hash_port0,
				   __inet_check_established);
}

static void init_hashinfo_lhash2(struct inet_hashinfo *h)
{
	int i;

	for (i = 0; i <= h->lhash2_mask; i++) {
		spin_lock_init(&h->lhash2[i].lock);
		INIT_HLIST_NULLS_HEAD(&h->lhash2[i].nulls_head,
				      i + LISTENING_NULLS_BASE);
	}
}

void __init inet_hashinfo2_init(struct inet_hashinfo *h, const char *name,
				unsigned long numentries, int scale,
				unsigned long low_limit,
				unsigned long high_limit)
{
	h->lhash2 = alloc_large_system_hash(name,
					    sizeof(*h->lhash2),
					    numentries,
					    scale,
					    0,
					    NULL,
					    &h->lhash2_mask,
					    low_limit,
					    high_limit);
	init_hashinfo_lhash2(h);

	/* this one is used for source ports of outgoing connections */
	table_perturb = alloc_large_system_hash("Table-perturb",
						sizeof(*table_perturb),
						INET_TABLE_PERTURB_SIZE,
						0, 0, NULL, NULL,
						INET_TABLE_PERTURB_SIZE,
						INET_TABLE_PERTURB_SIZE);
}

int inet_hashinfo2_init_mod(struct inet_hashinfo *h)
{
	h->lhash2 = kmalloc_objs(*h->lhash2, INET_LHTABLE_SIZE);
	if (!h->lhash2)
		return -ENOMEM;

	h->lhash2_mask = INET_LHTABLE_SIZE - 1;
	/* INET_LHTABLE_SIZE must be a power of 2 */
	BUG_ON(INET_LHTABLE_SIZE & h->lhash2_mask);

	init_hashinfo_lhash2(h);
	return 0;
}

int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo)
{
	unsigned int locksz = sizeof(spinlock_t);
	unsigned int i, nblocks = 1;
	spinlock_t *ptr = NULL;

	if (locksz == 0)
		goto set_mask;

	/* Allocate 2 cache lines or at least one spinlock per cpu. */
	nblocks = max(2U * L1_CACHE_BYTES / locksz, 1U) * num_possible_cpus();

	/* At least one page per NUMA node. */
	nblocks = max(nblocks, num_online_nodes() * PAGE_SIZE / locksz);

	nblocks = roundup_pow_of_two(nblocks);

	/* No more locks than number of hash buckets. */
	nblocks = min(nblocks, hashinfo->ehash_mask + 1);

	if (num_online_nodes() > 1) {
		/* Use vmalloc() to allow NUMA policy to spread pages
		 * on all available nodes if desired.
		 */
		ptr = vmalloc_array(nblocks, locksz);
	}
	if (!ptr) {
		ptr = kvmalloc_array(nblocks, locksz, GFP_KERNEL);
		if (!ptr)
			return -ENOMEM;
	}
	for (i = 0; i < nblocks; i++)
		spin_lock_init(&ptr[i]);
	hashinfo->ehash_locks = ptr;
set_mask:
	hashinfo->ehash_locks_mask = nblocks - 1;
	return 0;
}

struct inet_hashinfo *inet_pernet_hashinfo_alloc(struct inet_hashinfo *hashinfo,
						 unsigned int ehash_entries)
{
	struct inet_hashinfo *new_hashinfo;
	int i;

	new_hashinfo = kmemdup(hashinfo, sizeof(*hashinfo), GFP_KERNEL);
	if (!new_hashinfo)
		goto err;

	new_hashinfo->ehash = vmalloc_huge(ehash_entries * sizeof(struct inet_ehash_bucket),
					   GFP_KERNEL_ACCOUNT);
	if (!new_hashinfo->ehash)
		goto free_hashinfo;

	new_hashinfo->ehash_mask = ehash_entries - 1;

	if (inet_ehash_locks_alloc(new_hashinfo))
		goto free_ehash;

	for (i = 0; i < ehash_entries; i++)
		INIT_HLIST_NULLS_HEAD(&new_hashinfo->ehash[i].chain, i);

	new_hashinfo->pernet = true;

	return new_hashinfo;

free_ehash:
	vfree(new_hashinfo->ehash);
free_hashinfo:
	kfree(new_hashinfo);
err:
	return NULL;
}

void inet_pernet_hashinfo_free(struct inet_hashinfo *hashinfo)
{
	if (!hashinfo->pernet)
		return;

	inet_ehash_locks_free(hashinfo);
	vfree(hashinfo->ehash);
	kfree(hashinfo);
}
