// 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 <linux/gcd.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>

static void inet_init_ehash_secret(void)
{
	net_get_random_sleepable_once(&inet_ehash_secret,
				      sizeof(inet_ehash_secret));
}

u32 inet_ehashfn(const struct net *net, const __be32 laddr,
		 const __u16 lport, const __be32 faddr,
		 const __be16 fport)
{
	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();
}

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;
}

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;
}

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;
	}

#if IS_ENABLED(CONFIG_IPV6)
	if (sk->sk_family == AF_INET6)
		inet6_init_ehash_secret();
#endif
	inet_init_ehash_secret();

	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;
}

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);
	}
}

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);
}

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

/* 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;
	int step, scan_step, l3mdev;
	u32 index, max_rand_step;
	bool tb_created = false;
	u32 remaining, offset;
	int ret, i, low, high;
	bool local_ports;

	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;
	scan_step = step;
	max_rand_step = READ_ONCE(net->ipv4.sysctl_ip_local_port_step_width);

	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;

	if (max_rand_step && remaining > 1) {
		u32 range = remaining / step;
		u32 upper_bound;

		upper_bound = min(range, max_rand_step);
		scan_step = get_random_u32_inclusive(1, upper_bound);
		while (gcd(scan_step, range) != 1) {
			scan_step++;
			/* if both scan_step and range are even gcd won't be 1 */
			if (!(scan_step & 1) && !(range & 1))
				scan_step++;
			if (unlikely(scan_step > upper_bound)) {
				scan_step = 1;
				break;
			}
		}
		scan_step *= step;
	}
other_parity_scan:
	port = low + offset;
	for (i = 0; i < remaining; i += step, port += scan_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);

	inet_init_ehash_secret();

	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);
}

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)
{
	unsigned int i;

	h->lhash2 = alloc_large_system_hash(name,
					    sizeof(*h->lhash2),
					    numentries,
					    scale,
					    0,
					    NULL,
					    &h->lhash2_mask,
					    low_limit,
					    high_limit);

	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);
	}

	/* 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_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);
}
