18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _SOCK_REUSEPORT_H
38c2ecf20Sopenharmony_ci#define _SOCK_REUSEPORT_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/filter.h>
68c2ecf20Sopenharmony_ci#include <linux/skbuff.h>
78c2ecf20Sopenharmony_ci#include <linux/types.h>
88c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
98c2ecf20Sopenharmony_ci#include <net/sock.h>
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ciextern spinlock_t reuseport_lock;
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cistruct sock_reuseport {
148c2ecf20Sopenharmony_ci	struct rcu_head		rcu;
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci	u16			max_socks;	/* length of socks */
178c2ecf20Sopenharmony_ci	u16			num_socks;	/* elements in socks */
188c2ecf20Sopenharmony_ci	/* The last synq overflow event timestamp of this
198c2ecf20Sopenharmony_ci	 * reuse->socks[] group.
208c2ecf20Sopenharmony_ci	 */
218c2ecf20Sopenharmony_ci	unsigned int		synq_overflow_ts;
228c2ecf20Sopenharmony_ci	/* ID stays the same even after the size of socks[] grows. */
238c2ecf20Sopenharmony_ci	unsigned int		reuseport_id;
248c2ecf20Sopenharmony_ci	unsigned int		bind_inany:1;
258c2ecf20Sopenharmony_ci	unsigned int		has_conns:1;
268c2ecf20Sopenharmony_ci	struct bpf_prog __rcu	*prog;		/* optional BPF sock selector */
278c2ecf20Sopenharmony_ci	struct sock		*socks[];	/* array of sock pointers */
288c2ecf20Sopenharmony_ci};
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ciextern int reuseport_alloc(struct sock *sk, bool bind_inany);
318c2ecf20Sopenharmony_ciextern int reuseport_add_sock(struct sock *sk, struct sock *sk2,
328c2ecf20Sopenharmony_ci			      bool bind_inany);
338c2ecf20Sopenharmony_ciextern void reuseport_detach_sock(struct sock *sk);
348c2ecf20Sopenharmony_ciextern struct sock *reuseport_select_sock(struct sock *sk,
358c2ecf20Sopenharmony_ci					  u32 hash,
368c2ecf20Sopenharmony_ci					  struct sk_buff *skb,
378c2ecf20Sopenharmony_ci					  int hdr_len);
388c2ecf20Sopenharmony_ciextern int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog);
398c2ecf20Sopenharmony_ciextern int reuseport_detach_prog(struct sock *sk);
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_cistatic inline bool reuseport_has_conns(struct sock *sk)
428c2ecf20Sopenharmony_ci{
438c2ecf20Sopenharmony_ci	struct sock_reuseport *reuse;
448c2ecf20Sopenharmony_ci	bool ret = false;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	rcu_read_lock();
478c2ecf20Sopenharmony_ci	reuse = rcu_dereference(sk->sk_reuseport_cb);
488c2ecf20Sopenharmony_ci	if (reuse && reuse->has_conns)
498c2ecf20Sopenharmony_ci		ret = true;
508c2ecf20Sopenharmony_ci	rcu_read_unlock();
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	return ret;
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_civoid reuseport_has_conns_set(struct sock *sk);
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci#endif  /* _SOCK_REUSEPORT_H */
58