162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/* IP Virtual Server
362306a36Sopenharmony_ci * data structure and functionality definitions
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef _NET_IP_VS_H
762306a36Sopenharmony_ci#define _NET_IP_VS_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/ip_vs.h>                /* definitions shared with userland */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <asm/types.h>                  /* for __uXX types */
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/list.h>                 /* for struct list_head */
1462306a36Sopenharmony_ci#include <linux/spinlock.h>             /* for struct rwlock_t */
1562306a36Sopenharmony_ci#include <linux/atomic.h>               /* for struct atomic_t */
1662306a36Sopenharmony_ci#include <linux/refcount.h>             /* for struct refcount_t */
1762306a36Sopenharmony_ci#include <linux/workqueue.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include <linux/compiler.h>
2062306a36Sopenharmony_ci#include <linux/timer.h>
2162306a36Sopenharmony_ci#include <linux/bug.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#include <net/checksum.h>
2462306a36Sopenharmony_ci#include <linux/netfilter.h>		/* for union nf_inet_addr */
2562306a36Sopenharmony_ci#include <linux/ip.h>
2662306a36Sopenharmony_ci#include <linux/ipv6.h>			/* for struct ipv6hdr */
2762306a36Sopenharmony_ci#include <net/ipv6.h>
2862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NF_CONNTRACK)
2962306a36Sopenharmony_ci#include <net/netfilter/nf_conntrack.h>
3062306a36Sopenharmony_ci#endif
3162306a36Sopenharmony_ci#include <net/net_namespace.h>		/* Netw namespace */
3262306a36Sopenharmony_ci#include <linux/sched/isolation.h>
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define IP_VS_HDR_INVERSE	1
3562306a36Sopenharmony_ci#define IP_VS_HDR_ICMP		2
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/* Generic access of ipvs struct */
3862306a36Sopenharmony_cistatic inline struct netns_ipvs *net_ipvs(struct net* net)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	return net->ipvs;
4162306a36Sopenharmony_ci}
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci/* Connections' size value needed by ip_vs_ctl.c */
4462306a36Sopenharmony_ciextern int ip_vs_conn_tab_size;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ciextern struct mutex __ip_vs_mutex;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cistruct ip_vs_iphdr {
4962306a36Sopenharmony_ci	int hdr_flags;	/* ipvs flags */
5062306a36Sopenharmony_ci	__u32 off;	/* Where IP or IPv4 header starts */
5162306a36Sopenharmony_ci	__u32 len;	/* IPv4 simply where L4 starts
5262306a36Sopenharmony_ci			 * IPv6 where L4 Transport Header starts */
5362306a36Sopenharmony_ci	__u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/
5462306a36Sopenharmony_ci	__s16 protocol;
5562306a36Sopenharmony_ci	__s32 flags;
5662306a36Sopenharmony_ci	union nf_inet_addr saddr;
5762306a36Sopenharmony_ci	union nf_inet_addr daddr;
5862306a36Sopenharmony_ci};
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
6162306a36Sopenharmony_ci				      int len, void *buffer)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	return skb_header_pointer(skb, offset, len, buffer);
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/* This function handles filling *ip_vs_iphdr, both for IPv4 and IPv6.
6762306a36Sopenharmony_ci * IPv6 requires some extra work, as finding proper header position,
6862306a36Sopenharmony_ci * depend on the IPv6 extension headers.
6962306a36Sopenharmony_ci */
7062306a36Sopenharmony_cistatic inline int
7162306a36Sopenharmony_ciip_vs_fill_iph_skb_off(int af, const struct sk_buff *skb, int offset,
7262306a36Sopenharmony_ci		       int hdr_flags, struct ip_vs_iphdr *iphdr)
7362306a36Sopenharmony_ci{
7462306a36Sopenharmony_ci	iphdr->hdr_flags = hdr_flags;
7562306a36Sopenharmony_ci	iphdr->off = offset;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6
7862306a36Sopenharmony_ci	if (af == AF_INET6) {
7962306a36Sopenharmony_ci		struct ipv6hdr _iph;
8062306a36Sopenharmony_ci		const struct ipv6hdr *iph = skb_header_pointer(
8162306a36Sopenharmony_ci			skb, offset, sizeof(_iph), &_iph);
8262306a36Sopenharmony_ci		if (!iph)
8362306a36Sopenharmony_ci			return 0;
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci		iphdr->saddr.in6 = iph->saddr;
8662306a36Sopenharmony_ci		iphdr->daddr.in6 = iph->daddr;
8762306a36Sopenharmony_ci		/* ipv6_find_hdr() updates len, flags */
8862306a36Sopenharmony_ci		iphdr->len	 = offset;
8962306a36Sopenharmony_ci		iphdr->flags	 = 0;
9062306a36Sopenharmony_ci		iphdr->protocol  = ipv6_find_hdr(skb, &iphdr->len, -1,
9162306a36Sopenharmony_ci						 &iphdr->fragoffs,
9262306a36Sopenharmony_ci						 &iphdr->flags);
9362306a36Sopenharmony_ci		if (iphdr->protocol < 0)
9462306a36Sopenharmony_ci			return 0;
9562306a36Sopenharmony_ci	} else
9662306a36Sopenharmony_ci#endif
9762306a36Sopenharmony_ci	{
9862306a36Sopenharmony_ci		struct iphdr _iph;
9962306a36Sopenharmony_ci		const struct iphdr *iph = skb_header_pointer(
10062306a36Sopenharmony_ci			skb, offset, sizeof(_iph), &_iph);
10162306a36Sopenharmony_ci		if (!iph)
10262306a36Sopenharmony_ci			return 0;
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci		iphdr->len	= offset + iph->ihl * 4;
10562306a36Sopenharmony_ci		iphdr->fragoffs	= 0;
10662306a36Sopenharmony_ci		iphdr->protocol	= iph->protocol;
10762306a36Sopenharmony_ci		iphdr->saddr.ip	= iph->saddr;
10862306a36Sopenharmony_ci		iphdr->daddr.ip	= iph->daddr;
10962306a36Sopenharmony_ci	}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	return 1;
11262306a36Sopenharmony_ci}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistatic inline int
11562306a36Sopenharmony_ciip_vs_fill_iph_skb_icmp(int af, const struct sk_buff *skb, int offset,
11662306a36Sopenharmony_ci			bool inverse, struct ip_vs_iphdr *iphdr)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	int hdr_flags = IP_VS_HDR_ICMP;
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	if (inverse)
12162306a36Sopenharmony_ci		hdr_flags |= IP_VS_HDR_INVERSE;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	return ip_vs_fill_iph_skb_off(af, skb, offset, hdr_flags, iphdr);
12462306a36Sopenharmony_ci}
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_cistatic inline int
12762306a36Sopenharmony_ciip_vs_fill_iph_skb(int af, const struct sk_buff *skb, bool inverse,
12862306a36Sopenharmony_ci		   struct ip_vs_iphdr *iphdr)
12962306a36Sopenharmony_ci{
13062306a36Sopenharmony_ci	int hdr_flags = 0;
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	if (inverse)
13362306a36Sopenharmony_ci		hdr_flags |= IP_VS_HDR_INVERSE;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	return ip_vs_fill_iph_skb_off(af, skb, skb_network_offset(skb),
13662306a36Sopenharmony_ci				      hdr_flags, iphdr);
13762306a36Sopenharmony_ci}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_cistatic inline bool
14062306a36Sopenharmony_ciip_vs_iph_inverse(const struct ip_vs_iphdr *iph)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	return !!(iph->hdr_flags & IP_VS_HDR_INVERSE);
14362306a36Sopenharmony_ci}
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_cistatic inline bool
14662306a36Sopenharmony_ciip_vs_iph_icmp(const struct ip_vs_iphdr *iph)
14762306a36Sopenharmony_ci{
14862306a36Sopenharmony_ci	return !!(iph->hdr_flags & IP_VS_HDR_ICMP);
14962306a36Sopenharmony_ci}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cistatic inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst,
15262306a36Sopenharmony_ci				   const union nf_inet_addr *src)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6
15562306a36Sopenharmony_ci	if (af == AF_INET6)
15662306a36Sopenharmony_ci		dst->in6 = src->in6;
15762306a36Sopenharmony_ci	else
15862306a36Sopenharmony_ci#endif
15962306a36Sopenharmony_ci	dst->ip = src->ip;
16062306a36Sopenharmony_ci}
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cistatic inline void ip_vs_addr_set(int af, union nf_inet_addr *dst,
16362306a36Sopenharmony_ci				  const union nf_inet_addr *src)
16462306a36Sopenharmony_ci{
16562306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6
16662306a36Sopenharmony_ci	if (af == AF_INET6) {
16762306a36Sopenharmony_ci		dst->in6 = src->in6;
16862306a36Sopenharmony_ci		return;
16962306a36Sopenharmony_ci	}
17062306a36Sopenharmony_ci#endif
17162306a36Sopenharmony_ci	dst->ip = src->ip;
17262306a36Sopenharmony_ci	dst->all[1] = 0;
17362306a36Sopenharmony_ci	dst->all[2] = 0;
17462306a36Sopenharmony_ci	dst->all[3] = 0;
17562306a36Sopenharmony_ci}
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_cistatic inline int ip_vs_addr_equal(int af, const union nf_inet_addr *a,
17862306a36Sopenharmony_ci				   const union nf_inet_addr *b)
17962306a36Sopenharmony_ci{
18062306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6
18162306a36Sopenharmony_ci	if (af == AF_INET6)
18262306a36Sopenharmony_ci		return ipv6_addr_equal(&a->in6, &b->in6);
18362306a36Sopenharmony_ci#endif
18462306a36Sopenharmony_ci	return a->ip == b->ip;
18562306a36Sopenharmony_ci}
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_DEBUG
18862306a36Sopenharmony_ci#include <linux/net.h>
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ciint ip_vs_get_debug_level(void);
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_cistatic inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
19362306a36Sopenharmony_ci					 const union nf_inet_addr *addr,
19462306a36Sopenharmony_ci					 int *idx)
19562306a36Sopenharmony_ci{
19662306a36Sopenharmony_ci	int len;
19762306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6
19862306a36Sopenharmony_ci	if (af == AF_INET6)
19962306a36Sopenharmony_ci		len = snprintf(&buf[*idx], buf_len - *idx, "[%pI6c]",
20062306a36Sopenharmony_ci			       &addr->in6) + 1;
20162306a36Sopenharmony_ci	else
20262306a36Sopenharmony_ci#endif
20362306a36Sopenharmony_ci		len = snprintf(&buf[*idx], buf_len - *idx, "%pI4",
20462306a36Sopenharmony_ci			       &addr->ip) + 1;
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	*idx += len;
20762306a36Sopenharmony_ci	BUG_ON(*idx > buf_len + 1);
20862306a36Sopenharmony_ci	return &buf[*idx - len];
20962306a36Sopenharmony_ci}
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci#define IP_VS_DBG_BUF(level, msg, ...)					\
21262306a36Sopenharmony_ci	do {								\
21362306a36Sopenharmony_ci		char ip_vs_dbg_buf[160];				\
21462306a36Sopenharmony_ci		int ip_vs_dbg_idx = 0;					\
21562306a36Sopenharmony_ci		if (level <= ip_vs_get_debug_level())			\
21662306a36Sopenharmony_ci			printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);	\
21762306a36Sopenharmony_ci	} while (0)
21862306a36Sopenharmony_ci#define IP_VS_ERR_BUF(msg...)						\
21962306a36Sopenharmony_ci	do {								\
22062306a36Sopenharmony_ci		char ip_vs_dbg_buf[160];				\
22162306a36Sopenharmony_ci		int ip_vs_dbg_idx = 0;					\
22262306a36Sopenharmony_ci		pr_err(msg);						\
22362306a36Sopenharmony_ci	} while (0)
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci/* Only use from within IP_VS_DBG_BUF() or IP_VS_ERR_BUF macros */
22662306a36Sopenharmony_ci#define IP_VS_DBG_ADDR(af, addr)					\
22762306a36Sopenharmony_ci	ip_vs_dbg_addr(af, ip_vs_dbg_buf,				\
22862306a36Sopenharmony_ci		       sizeof(ip_vs_dbg_buf), addr,			\
22962306a36Sopenharmony_ci		       &ip_vs_dbg_idx)
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci#define IP_VS_DBG(level, msg, ...)					\
23262306a36Sopenharmony_ci	do {								\
23362306a36Sopenharmony_ci		if (level <= ip_vs_get_debug_level())			\
23462306a36Sopenharmony_ci			printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);	\
23562306a36Sopenharmony_ci	} while (0)
23662306a36Sopenharmony_ci#define IP_VS_DBG_RL(msg, ...)						\
23762306a36Sopenharmony_ci	do {								\
23862306a36Sopenharmony_ci		if (net_ratelimit())					\
23962306a36Sopenharmony_ci			printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);	\
24062306a36Sopenharmony_ci	} while (0)
24162306a36Sopenharmony_ci#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg)			\
24262306a36Sopenharmony_ci	do {								\
24362306a36Sopenharmony_ci		if (level <= ip_vs_get_debug_level())			\
24462306a36Sopenharmony_ci			pp->debug_packet(af, pp, skb, ofs, msg);	\
24562306a36Sopenharmony_ci	} while (0)
24662306a36Sopenharmony_ci#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg)			\
24762306a36Sopenharmony_ci	do {								\
24862306a36Sopenharmony_ci		if (level <= ip_vs_get_debug_level() &&			\
24962306a36Sopenharmony_ci		    net_ratelimit())					\
25062306a36Sopenharmony_ci			pp->debug_packet(af, pp, skb, ofs, msg);	\
25162306a36Sopenharmony_ci	} while (0)
25262306a36Sopenharmony_ci#else	/* NO DEBUGGING at ALL */
25362306a36Sopenharmony_ci#define IP_VS_DBG_BUF(level, msg...)  do {} while (0)
25462306a36Sopenharmony_ci#define IP_VS_ERR_BUF(msg...)  do {} while (0)
25562306a36Sopenharmony_ci#define IP_VS_DBG(level, msg...)  do {} while (0)
25662306a36Sopenharmony_ci#define IP_VS_DBG_RL(msg...)  do {} while (0)
25762306a36Sopenharmony_ci#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg)	do {} while (0)
25862306a36Sopenharmony_ci#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg)	do {} while (0)
25962306a36Sopenharmony_ci#endif
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci#define IP_VS_BUG() BUG()
26262306a36Sopenharmony_ci#define IP_VS_ERR_RL(msg, ...)						\
26362306a36Sopenharmony_ci	do {								\
26462306a36Sopenharmony_ci		if (net_ratelimit())					\
26562306a36Sopenharmony_ci			pr_err(msg, ##__VA_ARGS__);			\
26662306a36Sopenharmony_ci	} while (0)
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci/* The port number of FTP service (in network order). */
26962306a36Sopenharmony_ci#define FTPPORT  cpu_to_be16(21)
27062306a36Sopenharmony_ci#define FTPDATA  cpu_to_be16(20)
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci/* TCP State Values */
27362306a36Sopenharmony_cienum {
27462306a36Sopenharmony_ci	IP_VS_TCP_S_NONE = 0,
27562306a36Sopenharmony_ci	IP_VS_TCP_S_ESTABLISHED,
27662306a36Sopenharmony_ci	IP_VS_TCP_S_SYN_SENT,
27762306a36Sopenharmony_ci	IP_VS_TCP_S_SYN_RECV,
27862306a36Sopenharmony_ci	IP_VS_TCP_S_FIN_WAIT,
27962306a36Sopenharmony_ci	IP_VS_TCP_S_TIME_WAIT,
28062306a36Sopenharmony_ci	IP_VS_TCP_S_CLOSE,
28162306a36Sopenharmony_ci	IP_VS_TCP_S_CLOSE_WAIT,
28262306a36Sopenharmony_ci	IP_VS_TCP_S_LAST_ACK,
28362306a36Sopenharmony_ci	IP_VS_TCP_S_LISTEN,
28462306a36Sopenharmony_ci	IP_VS_TCP_S_SYNACK,
28562306a36Sopenharmony_ci	IP_VS_TCP_S_LAST
28662306a36Sopenharmony_ci};
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci/* UDP State Values */
28962306a36Sopenharmony_cienum {
29062306a36Sopenharmony_ci	IP_VS_UDP_S_NORMAL,
29162306a36Sopenharmony_ci	IP_VS_UDP_S_LAST,
29262306a36Sopenharmony_ci};
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci/* ICMP State Values */
29562306a36Sopenharmony_cienum {
29662306a36Sopenharmony_ci	IP_VS_ICMP_S_NORMAL,
29762306a36Sopenharmony_ci	IP_VS_ICMP_S_LAST,
29862306a36Sopenharmony_ci};
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci/* SCTP State Values */
30162306a36Sopenharmony_cienum ip_vs_sctp_states {
30262306a36Sopenharmony_ci	IP_VS_SCTP_S_NONE,
30362306a36Sopenharmony_ci	IP_VS_SCTP_S_INIT1,
30462306a36Sopenharmony_ci	IP_VS_SCTP_S_INIT,
30562306a36Sopenharmony_ci	IP_VS_SCTP_S_COOKIE_SENT,
30662306a36Sopenharmony_ci	IP_VS_SCTP_S_COOKIE_REPLIED,
30762306a36Sopenharmony_ci	IP_VS_SCTP_S_COOKIE_WAIT,
30862306a36Sopenharmony_ci	IP_VS_SCTP_S_COOKIE,
30962306a36Sopenharmony_ci	IP_VS_SCTP_S_COOKIE_ECHOED,
31062306a36Sopenharmony_ci	IP_VS_SCTP_S_ESTABLISHED,
31162306a36Sopenharmony_ci	IP_VS_SCTP_S_SHUTDOWN_SENT,
31262306a36Sopenharmony_ci	IP_VS_SCTP_S_SHUTDOWN_RECEIVED,
31362306a36Sopenharmony_ci	IP_VS_SCTP_S_SHUTDOWN_ACK_SENT,
31462306a36Sopenharmony_ci	IP_VS_SCTP_S_REJECTED,
31562306a36Sopenharmony_ci	IP_VS_SCTP_S_CLOSED,
31662306a36Sopenharmony_ci	IP_VS_SCTP_S_LAST
31762306a36Sopenharmony_ci};
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci/* Connection templates use bits from state */
32062306a36Sopenharmony_ci#define IP_VS_CTPL_S_NONE		0x0000
32162306a36Sopenharmony_ci#define IP_VS_CTPL_S_ASSURED		0x0001
32262306a36Sopenharmony_ci#define IP_VS_CTPL_S_LAST		0x0002
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci/* Delta sequence info structure
32562306a36Sopenharmony_ci * Each ip_vs_conn has 2 (output AND input seq. changes).
32662306a36Sopenharmony_ci * Only used in the VS/NAT.
32762306a36Sopenharmony_ci */
32862306a36Sopenharmony_cistruct ip_vs_seq {
32962306a36Sopenharmony_ci	__u32			init_seq;	/* Add delta from this seq */
33062306a36Sopenharmony_ci	__u32			delta;		/* Delta in sequence numbers */
33162306a36Sopenharmony_ci	__u32			previous_delta;	/* Delta in sequence numbers
33262306a36Sopenharmony_ci						 * before last resized pkt */
33362306a36Sopenharmony_ci};
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci/* counters per cpu */
33662306a36Sopenharmony_cistruct ip_vs_counters {
33762306a36Sopenharmony_ci	u64_stats_t	conns;		/* connections scheduled */
33862306a36Sopenharmony_ci	u64_stats_t	inpkts;		/* incoming packets */
33962306a36Sopenharmony_ci	u64_stats_t	outpkts;	/* outgoing packets */
34062306a36Sopenharmony_ci	u64_stats_t	inbytes;	/* incoming bytes */
34162306a36Sopenharmony_ci	u64_stats_t	outbytes;	/* outgoing bytes */
34262306a36Sopenharmony_ci};
34362306a36Sopenharmony_ci/* Stats per cpu */
34462306a36Sopenharmony_cistruct ip_vs_cpu_stats {
34562306a36Sopenharmony_ci	struct ip_vs_counters   cnt;
34662306a36Sopenharmony_ci	struct u64_stats_sync   syncp;
34762306a36Sopenharmony_ci};
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci/* Default nice for estimator kthreads */
35062306a36Sopenharmony_ci#define IPVS_EST_NICE		0
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci/* IPVS statistics objects */
35362306a36Sopenharmony_cistruct ip_vs_estimator {
35462306a36Sopenharmony_ci	struct hlist_node	list;
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	u64			last_inbytes;
35762306a36Sopenharmony_ci	u64			last_outbytes;
35862306a36Sopenharmony_ci	u64			last_conns;
35962306a36Sopenharmony_ci	u64			last_inpkts;
36062306a36Sopenharmony_ci	u64			last_outpkts;
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci	u64			cps;
36362306a36Sopenharmony_ci	u64			inpps;
36462306a36Sopenharmony_ci	u64			outpps;
36562306a36Sopenharmony_ci	u64			inbps;
36662306a36Sopenharmony_ci	u64			outbps;
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	s32			ktid:16,	/* kthread ID, -1=temp list */
36962306a36Sopenharmony_ci				ktrow:8,	/* row/tick ID for kthread */
37062306a36Sopenharmony_ci				ktcid:8;	/* chain ID for kthread tick */
37162306a36Sopenharmony_ci};
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci/*
37462306a36Sopenharmony_ci * IPVS statistics object, 64-bit kernel version of struct ip_vs_stats_user
37562306a36Sopenharmony_ci */
37662306a36Sopenharmony_cistruct ip_vs_kstats {
37762306a36Sopenharmony_ci	u64			conns;		/* connections scheduled */
37862306a36Sopenharmony_ci	u64			inpkts;		/* incoming packets */
37962306a36Sopenharmony_ci	u64			outpkts;	/* outgoing packets */
38062306a36Sopenharmony_ci	u64			inbytes;	/* incoming bytes */
38162306a36Sopenharmony_ci	u64			outbytes;	/* outgoing bytes */
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci	u64			cps;		/* current connection rate */
38462306a36Sopenharmony_ci	u64			inpps;		/* current in packet rate */
38562306a36Sopenharmony_ci	u64			outpps;		/* current out packet rate */
38662306a36Sopenharmony_ci	u64			inbps;		/* current in byte rate */
38762306a36Sopenharmony_ci	u64			outbps;		/* current out byte rate */
38862306a36Sopenharmony_ci};
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_cistruct ip_vs_stats {
39162306a36Sopenharmony_ci	struct ip_vs_kstats	kstats;		/* kernel statistics */
39262306a36Sopenharmony_ci	struct ip_vs_estimator	est;		/* estimator */
39362306a36Sopenharmony_ci	struct ip_vs_cpu_stats __percpu	*cpustats;	/* per cpu counters */
39462306a36Sopenharmony_ci	spinlock_t		lock;		/* spin lock */
39562306a36Sopenharmony_ci	struct ip_vs_kstats	kstats0;	/* reset values */
39662306a36Sopenharmony_ci};
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_cistruct ip_vs_stats_rcu {
39962306a36Sopenharmony_ci	struct ip_vs_stats	s;
40062306a36Sopenharmony_ci	struct rcu_head		rcu_head;
40162306a36Sopenharmony_ci};
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ciint ip_vs_stats_init_alloc(struct ip_vs_stats *s);
40462306a36Sopenharmony_cistruct ip_vs_stats *ip_vs_stats_alloc(void);
40562306a36Sopenharmony_civoid ip_vs_stats_release(struct ip_vs_stats *stats);
40662306a36Sopenharmony_civoid ip_vs_stats_free(struct ip_vs_stats *stats);
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci/* Process estimators in multiple timer ticks (20/50/100, see ktrow) */
40962306a36Sopenharmony_ci#define IPVS_EST_NTICKS		50
41062306a36Sopenharmony_ci/* Estimation uses a 2-second period containing ticks (in jiffies) */
41162306a36Sopenharmony_ci#define IPVS_EST_TICK		((2 * HZ) / IPVS_EST_NTICKS)
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci/* Limit of CPU load per kthread (8 for 12.5%), ratio of CPU capacity (1/C).
41462306a36Sopenharmony_ci * Value of 4 and above ensures kthreads will take work without exceeding
41562306a36Sopenharmony_ci * the CPU capacity under different circumstances.
41662306a36Sopenharmony_ci */
41762306a36Sopenharmony_ci#define IPVS_EST_LOAD_DIVISOR	8
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci/* Kthreads should not have work that exceeds the CPU load above 50% */
42062306a36Sopenharmony_ci#define IPVS_EST_CPU_KTHREADS	(IPVS_EST_LOAD_DIVISOR / 2)
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci/* Desired number of chains per timer tick (chain load factor in 100us units),
42362306a36Sopenharmony_ci * 48=4.8ms of 40ms tick (12% CPU usage):
42462306a36Sopenharmony_ci * 2 sec * 1000 ms in sec * 10 (100us in ms) / 8 (12.5%) / 50
42562306a36Sopenharmony_ci */
42662306a36Sopenharmony_ci#define IPVS_EST_CHAIN_FACTOR	\
42762306a36Sopenharmony_ci	ALIGN_DOWN(2 * 1000 * 10 / IPVS_EST_LOAD_DIVISOR / IPVS_EST_NTICKS, 8)
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ci/* Compiled number of chains per tick
43062306a36Sopenharmony_ci * The defines should match cond_resched_rcu
43162306a36Sopenharmony_ci */
43262306a36Sopenharmony_ci#if defined(CONFIG_DEBUG_ATOMIC_SLEEP) || !defined(CONFIG_PREEMPT_RCU)
43362306a36Sopenharmony_ci#define IPVS_EST_TICK_CHAINS	IPVS_EST_CHAIN_FACTOR
43462306a36Sopenharmony_ci#else
43562306a36Sopenharmony_ci#define IPVS_EST_TICK_CHAINS	1
43662306a36Sopenharmony_ci#endif
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci#if IPVS_EST_NTICKS > 127
43962306a36Sopenharmony_ci#error Too many timer ticks for ktrow
44062306a36Sopenharmony_ci#endif
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci/* Multiple chains processed in same tick */
44362306a36Sopenharmony_cistruct ip_vs_est_tick_data {
44462306a36Sopenharmony_ci	struct rcu_head		rcu_head;
44562306a36Sopenharmony_ci	struct hlist_head	chains[IPVS_EST_TICK_CHAINS];
44662306a36Sopenharmony_ci	DECLARE_BITMAP(present, IPVS_EST_TICK_CHAINS);
44762306a36Sopenharmony_ci	DECLARE_BITMAP(full, IPVS_EST_TICK_CHAINS);
44862306a36Sopenharmony_ci	int			chain_len[IPVS_EST_TICK_CHAINS];
44962306a36Sopenharmony_ci};
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci/* Context for estimation kthread */
45262306a36Sopenharmony_cistruct ip_vs_est_kt_data {
45362306a36Sopenharmony_ci	struct netns_ipvs	*ipvs;
45462306a36Sopenharmony_ci	struct task_struct	*task;		/* task if running */
45562306a36Sopenharmony_ci	struct ip_vs_est_tick_data __rcu *ticks[IPVS_EST_NTICKS];
45662306a36Sopenharmony_ci	DECLARE_BITMAP(avail, IPVS_EST_NTICKS);	/* tick has space for ests */
45762306a36Sopenharmony_ci	unsigned long		est_timer;	/* estimation timer (jiffies) */
45862306a36Sopenharmony_ci	struct ip_vs_stats	*calc_stats;	/* Used for calculation */
45962306a36Sopenharmony_ci	int			tick_len[IPVS_EST_NTICKS];	/* est count */
46062306a36Sopenharmony_ci	int			id;		/* ktid per netns */
46162306a36Sopenharmony_ci	int			chain_max;	/* max ests per tick chain */
46262306a36Sopenharmony_ci	int			tick_max;	/* max ests per tick */
46362306a36Sopenharmony_ci	int			est_count;	/* attached ests to kthread */
46462306a36Sopenharmony_ci	int			est_max_count;	/* max ests per kthread */
46562306a36Sopenharmony_ci	int			add_row;	/* row for new ests */
46662306a36Sopenharmony_ci	int			est_row;	/* estimated row */
46762306a36Sopenharmony_ci};
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_cistruct dst_entry;
47062306a36Sopenharmony_cistruct iphdr;
47162306a36Sopenharmony_cistruct ip_vs_conn;
47262306a36Sopenharmony_cistruct ip_vs_app;
47362306a36Sopenharmony_cistruct sk_buff;
47462306a36Sopenharmony_cistruct ip_vs_proto_data;
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_cistruct ip_vs_protocol {
47762306a36Sopenharmony_ci	struct ip_vs_protocol	*next;
47862306a36Sopenharmony_ci	char			*name;
47962306a36Sopenharmony_ci	u16			protocol;
48062306a36Sopenharmony_ci	u16			num_states;
48162306a36Sopenharmony_ci	int			dont_defrag;
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci	void (*init)(struct ip_vs_protocol *pp);
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	void (*exit)(struct ip_vs_protocol *pp);
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	int (*init_netns)(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd);
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	void (*exit_netns)(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd);
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	int (*conn_schedule)(struct netns_ipvs *ipvs,
49262306a36Sopenharmony_ci			     int af, struct sk_buff *skb,
49362306a36Sopenharmony_ci			     struct ip_vs_proto_data *pd,
49462306a36Sopenharmony_ci			     int *verdict, struct ip_vs_conn **cpp,
49562306a36Sopenharmony_ci			     struct ip_vs_iphdr *iph);
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	struct ip_vs_conn *
49862306a36Sopenharmony_ci	(*conn_in_get)(struct netns_ipvs *ipvs,
49962306a36Sopenharmony_ci		       int af,
50062306a36Sopenharmony_ci		       const struct sk_buff *skb,
50162306a36Sopenharmony_ci		       const struct ip_vs_iphdr *iph);
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	struct ip_vs_conn *
50462306a36Sopenharmony_ci	(*conn_out_get)(struct netns_ipvs *ipvs,
50562306a36Sopenharmony_ci			int af,
50662306a36Sopenharmony_ci			const struct sk_buff *skb,
50762306a36Sopenharmony_ci			const struct ip_vs_iphdr *iph);
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	int (*snat_handler)(struct sk_buff *skb, struct ip_vs_protocol *pp,
51062306a36Sopenharmony_ci			    struct ip_vs_conn *cp, struct ip_vs_iphdr *iph);
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci	int (*dnat_handler)(struct sk_buff *skb, struct ip_vs_protocol *pp,
51362306a36Sopenharmony_ci			    struct ip_vs_conn *cp, struct ip_vs_iphdr *iph);
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci	const char *(*state_name)(int state);
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	void (*state_transition)(struct ip_vs_conn *cp, int direction,
51862306a36Sopenharmony_ci				 const struct sk_buff *skb,
51962306a36Sopenharmony_ci				 struct ip_vs_proto_data *pd);
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci	int (*register_app)(struct netns_ipvs *ipvs, struct ip_vs_app *inc);
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci	void (*unregister_app)(struct netns_ipvs *ipvs, struct ip_vs_app *inc);
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci	int (*app_conn_bind)(struct ip_vs_conn *cp);
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci	void (*debug_packet)(int af, struct ip_vs_protocol *pp,
52862306a36Sopenharmony_ci			     const struct sk_buff *skb,
52962306a36Sopenharmony_ci			     int offset,
53062306a36Sopenharmony_ci			     const char *msg);
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	void (*timeout_change)(struct ip_vs_proto_data *pd, int flags);
53362306a36Sopenharmony_ci};
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci/* protocol data per netns */
53662306a36Sopenharmony_cistruct ip_vs_proto_data {
53762306a36Sopenharmony_ci	struct ip_vs_proto_data	*next;
53862306a36Sopenharmony_ci	struct ip_vs_protocol	*pp;
53962306a36Sopenharmony_ci	int			*timeout_table;	/* protocol timeout table */
54062306a36Sopenharmony_ci	atomic_t		appcnt;		/* counter of proto app incs. */
54162306a36Sopenharmony_ci	struct tcp_states_t	*tcp_state_table;
54262306a36Sopenharmony_ci};
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_cistruct ip_vs_protocol   *ip_vs_proto_get(unsigned short proto);
54562306a36Sopenharmony_cistruct ip_vs_proto_data *ip_vs_proto_data_get(struct netns_ipvs *ipvs,
54662306a36Sopenharmony_ci					      unsigned short proto);
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_cistruct ip_vs_conn_param {
54962306a36Sopenharmony_ci	struct netns_ipvs		*ipvs;
55062306a36Sopenharmony_ci	const union nf_inet_addr	*caddr;
55162306a36Sopenharmony_ci	const union nf_inet_addr	*vaddr;
55262306a36Sopenharmony_ci	__be16				cport;
55362306a36Sopenharmony_ci	__be16				vport;
55462306a36Sopenharmony_ci	__u16				protocol;
55562306a36Sopenharmony_ci	u16				af;
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	const struct ip_vs_pe		*pe;
55862306a36Sopenharmony_ci	char				*pe_data;
55962306a36Sopenharmony_ci	__u8				pe_data_len;
56062306a36Sopenharmony_ci};
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci/* IP_VS structure allocated for each dynamically scheduled connection */
56362306a36Sopenharmony_cistruct ip_vs_conn {
56462306a36Sopenharmony_ci	struct hlist_node	c_list;         /* hashed list heads */
56562306a36Sopenharmony_ci	/* Protocol, addresses and port numbers */
56662306a36Sopenharmony_ci	__be16                  cport;
56762306a36Sopenharmony_ci	__be16                  dport;
56862306a36Sopenharmony_ci	__be16                  vport;
56962306a36Sopenharmony_ci	u16			af;		/* address family */
57062306a36Sopenharmony_ci	union nf_inet_addr      caddr;          /* client address */
57162306a36Sopenharmony_ci	union nf_inet_addr      vaddr;          /* virtual address */
57262306a36Sopenharmony_ci	union nf_inet_addr      daddr;          /* destination address */
57362306a36Sopenharmony_ci	volatile __u32          flags;          /* status flags */
57462306a36Sopenharmony_ci	__u16                   protocol;       /* Which protocol (TCP/UDP) */
57562306a36Sopenharmony_ci	__u16			daf;		/* Address family of the dest */
57662306a36Sopenharmony_ci	struct netns_ipvs	*ipvs;
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci	/* counter and timer */
57962306a36Sopenharmony_ci	refcount_t		refcnt;		/* reference count */
58062306a36Sopenharmony_ci	struct timer_list	timer;		/* Expiration timer */
58162306a36Sopenharmony_ci	volatile unsigned long	timeout;	/* timeout */
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	/* Flags and state transition */
58462306a36Sopenharmony_ci	spinlock_t              lock;           /* lock for state transition */
58562306a36Sopenharmony_ci	volatile __u16          state;          /* state info */
58662306a36Sopenharmony_ci	volatile __u16          old_state;      /* old state, to be used for
58762306a36Sopenharmony_ci						 * state transition triggered
58862306a36Sopenharmony_ci						 * synchronization
58962306a36Sopenharmony_ci						 */
59062306a36Sopenharmony_ci	__u32			fwmark;		/* Fire wall mark from skb */
59162306a36Sopenharmony_ci	unsigned long		sync_endtime;	/* jiffies + sent_retries */
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci	/* Control members */
59462306a36Sopenharmony_ci	struct ip_vs_conn       *control;       /* Master control connection */
59562306a36Sopenharmony_ci	atomic_t                n_control;      /* Number of controlled ones */
59662306a36Sopenharmony_ci	struct ip_vs_dest       *dest;          /* real server */
59762306a36Sopenharmony_ci	atomic_t                in_pkts;        /* incoming packet counter */
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci	/* Packet transmitter for different forwarding methods.  If it
60062306a36Sopenharmony_ci	 * mangles the packet, it must return NF_DROP or better NF_STOLEN,
60162306a36Sopenharmony_ci	 * otherwise this must be changed to a sk_buff **.
60262306a36Sopenharmony_ci	 * NF_ACCEPT can be returned when destination is local.
60362306a36Sopenharmony_ci	 */
60462306a36Sopenharmony_ci	int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp,
60562306a36Sopenharmony_ci			   struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	/* Note: we can group the following members into a structure,
60862306a36Sopenharmony_ci	 * in order to save more space, and the following members are
60962306a36Sopenharmony_ci	 * only used in VS/NAT anyway
61062306a36Sopenharmony_ci	 */
61162306a36Sopenharmony_ci	struct ip_vs_app        *app;           /* bound ip_vs_app object */
61262306a36Sopenharmony_ci	void                    *app_data;      /* Application private data */
61362306a36Sopenharmony_ci	struct_group(sync_conn_opt,
61462306a36Sopenharmony_ci		struct ip_vs_seq  in_seq;       /* incoming seq. struct */
61562306a36Sopenharmony_ci		struct ip_vs_seq  out_seq;      /* outgoing seq. struct */
61662306a36Sopenharmony_ci	);
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci	const struct ip_vs_pe	*pe;
61962306a36Sopenharmony_ci	char			*pe_data;
62062306a36Sopenharmony_ci	__u8			pe_data_len;
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	struct rcu_head		rcu_head;
62362306a36Sopenharmony_ci};
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci/* Extended internal versions of struct ip_vs_service_user and ip_vs_dest_user
62662306a36Sopenharmony_ci * for IPv6 support.
62762306a36Sopenharmony_ci *
62862306a36Sopenharmony_ci * We need these to conveniently pass around service and destination
62962306a36Sopenharmony_ci * options, but unfortunately, we also need to keep the old definitions to
63062306a36Sopenharmony_ci * maintain userspace backwards compatibility for the setsockopt interface.
63162306a36Sopenharmony_ci */
63262306a36Sopenharmony_cistruct ip_vs_service_user_kern {
63362306a36Sopenharmony_ci	/* virtual service addresses */
63462306a36Sopenharmony_ci	u16			af;
63562306a36Sopenharmony_ci	u16			protocol;
63662306a36Sopenharmony_ci	union nf_inet_addr	addr;		/* virtual ip address */
63762306a36Sopenharmony_ci	__be16			port;
63862306a36Sopenharmony_ci	u32			fwmark;		/* firewall mark of service */
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	/* virtual service options */
64162306a36Sopenharmony_ci	char			*sched_name;
64262306a36Sopenharmony_ci	char			*pe_name;
64362306a36Sopenharmony_ci	unsigned int		flags;		/* virtual service flags */
64462306a36Sopenharmony_ci	unsigned int		timeout;	/* persistent timeout in sec */
64562306a36Sopenharmony_ci	__be32			netmask;	/* persistent netmask or plen */
64662306a36Sopenharmony_ci};
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_cistruct ip_vs_dest_user_kern {
65062306a36Sopenharmony_ci	/* destination server address */
65162306a36Sopenharmony_ci	union nf_inet_addr	addr;
65262306a36Sopenharmony_ci	__be16			port;
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci	/* real server options */
65562306a36Sopenharmony_ci	unsigned int		conn_flags;	/* connection flags */
65662306a36Sopenharmony_ci	int			weight;		/* destination weight */
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci	/* thresholds for active connections */
65962306a36Sopenharmony_ci	u32			u_threshold;	/* upper threshold */
66062306a36Sopenharmony_ci	u32			l_threshold;	/* lower threshold */
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ci	/* Address family of addr */
66362306a36Sopenharmony_ci	u16			af;
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	u16			tun_type;	/* tunnel type */
66662306a36Sopenharmony_ci	__be16			tun_port;	/* tunnel port */
66762306a36Sopenharmony_ci	u16			tun_flags;	/* tunnel flags */
66862306a36Sopenharmony_ci};
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci/*
67262306a36Sopenharmony_ci * The information about the virtual service offered to the net and the
67362306a36Sopenharmony_ci * forwarding entries.
67462306a36Sopenharmony_ci */
67562306a36Sopenharmony_cistruct ip_vs_service {
67662306a36Sopenharmony_ci	struct hlist_node	s_list;   /* for normal service table */
67762306a36Sopenharmony_ci	struct hlist_node	f_list;   /* for fwmark-based service table */
67862306a36Sopenharmony_ci	atomic_t		refcnt;   /* reference counter */
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	u16			af;       /* address family */
68162306a36Sopenharmony_ci	__u16			protocol; /* which protocol (TCP/UDP) */
68262306a36Sopenharmony_ci	union nf_inet_addr	addr;	  /* IP address for virtual service */
68362306a36Sopenharmony_ci	__be16			port;	  /* port number for the service */
68462306a36Sopenharmony_ci	__u32                   fwmark;   /* firewall mark of the service */
68562306a36Sopenharmony_ci	unsigned int		flags;	  /* service status flags */
68662306a36Sopenharmony_ci	unsigned int		timeout;  /* persistent timeout in ticks */
68762306a36Sopenharmony_ci	__be32			netmask;  /* grouping granularity, mask/plen */
68862306a36Sopenharmony_ci	struct netns_ipvs	*ipvs;
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ci	struct list_head	destinations;  /* real server d-linked list */
69162306a36Sopenharmony_ci	__u32			num_dests;     /* number of servers */
69262306a36Sopenharmony_ci	struct ip_vs_stats      stats;         /* statistics for the service */
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	/* for scheduling */
69562306a36Sopenharmony_ci	struct ip_vs_scheduler __rcu *scheduler; /* bound scheduler object */
69662306a36Sopenharmony_ci	spinlock_t		sched_lock;    /* lock sched_data */
69762306a36Sopenharmony_ci	void			*sched_data;   /* scheduler application data */
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci	/* alternate persistence engine */
70062306a36Sopenharmony_ci	struct ip_vs_pe __rcu	*pe;
70162306a36Sopenharmony_ci	int			conntrack_afmask;
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci	struct rcu_head		rcu_head;
70462306a36Sopenharmony_ci};
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ci/* Information for cached dst */
70762306a36Sopenharmony_cistruct ip_vs_dest_dst {
70862306a36Sopenharmony_ci	struct dst_entry	*dst_cache;	/* destination cache entry */
70962306a36Sopenharmony_ci	u32			dst_cookie;
71062306a36Sopenharmony_ci	union nf_inet_addr	dst_saddr;
71162306a36Sopenharmony_ci	struct rcu_head		rcu_head;
71262306a36Sopenharmony_ci};
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci/* The real server destination forwarding entry with ip address, port number,
71562306a36Sopenharmony_ci * and so on.
71662306a36Sopenharmony_ci */
71762306a36Sopenharmony_cistruct ip_vs_dest {
71862306a36Sopenharmony_ci	struct list_head	n_list;   /* for the dests in the service */
71962306a36Sopenharmony_ci	struct hlist_node	d_list;   /* for table with all the dests */
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci	u16			af;		/* address family */
72262306a36Sopenharmony_ci	__be16			port;		/* port number of the server */
72362306a36Sopenharmony_ci	union nf_inet_addr	addr;		/* IP address of the server */
72462306a36Sopenharmony_ci	volatile unsigned int	flags;		/* dest status flags */
72562306a36Sopenharmony_ci	atomic_t		conn_flags;	/* flags to copy to conn */
72662306a36Sopenharmony_ci	atomic_t		weight;		/* server weight */
72762306a36Sopenharmony_ci	atomic_t		last_weight;	/* server latest weight */
72862306a36Sopenharmony_ci	__u16			tun_type;	/* tunnel type */
72962306a36Sopenharmony_ci	__be16			tun_port;	/* tunnel port */
73062306a36Sopenharmony_ci	__u16			tun_flags;	/* tunnel flags */
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_ci	refcount_t		refcnt;		/* reference counter */
73362306a36Sopenharmony_ci	struct ip_vs_stats      stats;          /* statistics */
73462306a36Sopenharmony_ci	unsigned long		idle_start;	/* start time, jiffies */
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci	/* connection counters and thresholds */
73762306a36Sopenharmony_ci	atomic_t		activeconns;	/* active connections */
73862306a36Sopenharmony_ci	atomic_t		inactconns;	/* inactive connections */
73962306a36Sopenharmony_ci	atomic_t		persistconns;	/* persistent connections */
74062306a36Sopenharmony_ci	__u32			u_threshold;	/* upper threshold */
74162306a36Sopenharmony_ci	__u32			l_threshold;	/* lower threshold */
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci	/* for destination cache */
74462306a36Sopenharmony_ci	spinlock_t		dst_lock;	/* lock of dst_cache */
74562306a36Sopenharmony_ci	struct ip_vs_dest_dst __rcu *dest_dst;	/* cached dst info */
74662306a36Sopenharmony_ci
74762306a36Sopenharmony_ci	/* for virtual service */
74862306a36Sopenharmony_ci	struct ip_vs_service __rcu *svc;	/* service it belongs to */
74962306a36Sopenharmony_ci	__u16			protocol;	/* which protocol (TCP/UDP) */
75062306a36Sopenharmony_ci	__be16			vport;		/* virtual port number */
75162306a36Sopenharmony_ci	union nf_inet_addr	vaddr;		/* virtual IP address */
75262306a36Sopenharmony_ci	__u32			vfwmark;	/* firewall mark of service */
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci	struct rcu_head		rcu_head;
75562306a36Sopenharmony_ci	struct list_head	t_list;		/* in dest_trash */
75662306a36Sopenharmony_ci	unsigned int		in_rs_table:1;	/* we are in rs_table */
75762306a36Sopenharmony_ci};
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci/* The scheduler object */
76062306a36Sopenharmony_cistruct ip_vs_scheduler {
76162306a36Sopenharmony_ci	struct list_head	n_list;		/* d-linked list head */
76262306a36Sopenharmony_ci	char			*name;		/* scheduler name */
76362306a36Sopenharmony_ci	atomic_t		refcnt;		/* reference counter */
76462306a36Sopenharmony_ci	struct module		*module;	/* THIS_MODULE/NULL */
76562306a36Sopenharmony_ci
76662306a36Sopenharmony_ci	/* scheduler initializing service */
76762306a36Sopenharmony_ci	int (*init_service)(struct ip_vs_service *svc);
76862306a36Sopenharmony_ci	/* scheduling service finish */
76962306a36Sopenharmony_ci	void (*done_service)(struct ip_vs_service *svc);
77062306a36Sopenharmony_ci	/* dest is linked */
77162306a36Sopenharmony_ci	int (*add_dest)(struct ip_vs_service *svc, struct ip_vs_dest *dest);
77262306a36Sopenharmony_ci	/* dest is unlinked */
77362306a36Sopenharmony_ci	int (*del_dest)(struct ip_vs_service *svc, struct ip_vs_dest *dest);
77462306a36Sopenharmony_ci	/* dest is updated */
77562306a36Sopenharmony_ci	int (*upd_dest)(struct ip_vs_service *svc, struct ip_vs_dest *dest);
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci	/* selecting a server from the given service */
77862306a36Sopenharmony_ci	struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc,
77962306a36Sopenharmony_ci				       const struct sk_buff *skb,
78062306a36Sopenharmony_ci				       struct ip_vs_iphdr *iph);
78162306a36Sopenharmony_ci};
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ci/* The persistence engine object */
78462306a36Sopenharmony_cistruct ip_vs_pe {
78562306a36Sopenharmony_ci	struct list_head	n_list;		/* d-linked list head */
78662306a36Sopenharmony_ci	char			*name;		/* scheduler name */
78762306a36Sopenharmony_ci	atomic_t		refcnt;		/* reference counter */
78862306a36Sopenharmony_ci	struct module		*module;	/* THIS_MODULE/NULL */
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci	/* get the connection template, if any */
79162306a36Sopenharmony_ci	int (*fill_param)(struct ip_vs_conn_param *p, struct sk_buff *skb);
79262306a36Sopenharmony_ci	bool (*ct_match)(const struct ip_vs_conn_param *p,
79362306a36Sopenharmony_ci			 struct ip_vs_conn *ct);
79462306a36Sopenharmony_ci	u32 (*hashkey_raw)(const struct ip_vs_conn_param *p, u32 initval,
79562306a36Sopenharmony_ci			   bool inverse);
79662306a36Sopenharmony_ci	int (*show_pe_data)(const struct ip_vs_conn *cp, char *buf);
79762306a36Sopenharmony_ci	/* create connections for real-server outgoing packets */
79862306a36Sopenharmony_ci	struct ip_vs_conn* (*conn_out)(struct ip_vs_service *svc,
79962306a36Sopenharmony_ci				       struct ip_vs_dest *dest,
80062306a36Sopenharmony_ci				       struct sk_buff *skb,
80162306a36Sopenharmony_ci				       const struct ip_vs_iphdr *iph,
80262306a36Sopenharmony_ci				       __be16 dport, __be16 cport);
80362306a36Sopenharmony_ci};
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ci/* The application module object (a.k.a. app incarnation) */
80662306a36Sopenharmony_cistruct ip_vs_app {
80762306a36Sopenharmony_ci	struct list_head	a_list;		/* member in app list */
80862306a36Sopenharmony_ci	int			type;		/* IP_VS_APP_TYPE_xxx */
80962306a36Sopenharmony_ci	char			*name;		/* application module name */
81062306a36Sopenharmony_ci	__u16			protocol;
81162306a36Sopenharmony_ci	struct module		*module;	/* THIS_MODULE/NULL */
81262306a36Sopenharmony_ci	struct list_head	incs_list;	/* list of incarnations */
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci	/* members for application incarnations */
81562306a36Sopenharmony_ci	struct list_head	p_list;		/* member in proto app list */
81662306a36Sopenharmony_ci	struct ip_vs_app	*app;		/* its real application */
81762306a36Sopenharmony_ci	__be16			port;		/* port number in net order */
81862306a36Sopenharmony_ci	atomic_t		usecnt;		/* usage counter */
81962306a36Sopenharmony_ci	struct rcu_head		rcu_head;
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci	/* output hook: Process packet in inout direction, diff set for TCP.
82262306a36Sopenharmony_ci	 * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok,
82362306a36Sopenharmony_ci	 *	   2=Mangled but checksum was not updated
82462306a36Sopenharmony_ci	 */
82562306a36Sopenharmony_ci	int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *,
82662306a36Sopenharmony_ci		       struct sk_buff *, int *diff, struct ip_vs_iphdr *ipvsh);
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci	/* input hook: Process packet in outin direction, diff set for TCP.
82962306a36Sopenharmony_ci	 * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok,
83062306a36Sopenharmony_ci	 *	   2=Mangled but checksum was not updated
83162306a36Sopenharmony_ci	 */
83262306a36Sopenharmony_ci	int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *,
83362306a36Sopenharmony_ci		      struct sk_buff *, int *diff, struct ip_vs_iphdr *ipvsh);
83462306a36Sopenharmony_ci
83562306a36Sopenharmony_ci	/* ip_vs_app initializer */
83662306a36Sopenharmony_ci	int (*init_conn)(struct ip_vs_app *, struct ip_vs_conn *);
83762306a36Sopenharmony_ci
83862306a36Sopenharmony_ci	/* ip_vs_app finish */
83962306a36Sopenharmony_ci	int (*done_conn)(struct ip_vs_app *, struct ip_vs_conn *);
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci	/* not used now */
84362306a36Sopenharmony_ci	int (*bind_conn)(struct ip_vs_app *, struct ip_vs_conn *,
84462306a36Sopenharmony_ci			 struct ip_vs_protocol *);
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_ci	void (*unbind_conn)(struct ip_vs_app *, struct ip_vs_conn *);
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ci	int *			timeout_table;
84962306a36Sopenharmony_ci	int *			timeouts;
85062306a36Sopenharmony_ci	int			timeouts_size;
85162306a36Sopenharmony_ci
85262306a36Sopenharmony_ci	int (*conn_schedule)(struct sk_buff *skb, struct ip_vs_app *app,
85362306a36Sopenharmony_ci			     int *verdict, struct ip_vs_conn **cpp);
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_ci	struct ip_vs_conn *
85662306a36Sopenharmony_ci	(*conn_in_get)(const struct sk_buff *skb, struct ip_vs_app *app,
85762306a36Sopenharmony_ci		       const struct iphdr *iph, int inverse);
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_ci	struct ip_vs_conn *
86062306a36Sopenharmony_ci	(*conn_out_get)(const struct sk_buff *skb, struct ip_vs_app *app,
86162306a36Sopenharmony_ci			const struct iphdr *iph, int inverse);
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci	int (*state_transition)(struct ip_vs_conn *cp, int direction,
86462306a36Sopenharmony_ci				const struct sk_buff *skb,
86562306a36Sopenharmony_ci				struct ip_vs_app *app);
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_ci	void (*timeout_change)(struct ip_vs_app *app, int flags);
86862306a36Sopenharmony_ci};
86962306a36Sopenharmony_ci
87062306a36Sopenharmony_cistruct ipvs_master_sync_state {
87162306a36Sopenharmony_ci	struct list_head	sync_queue;
87262306a36Sopenharmony_ci	struct ip_vs_sync_buff	*sync_buff;
87362306a36Sopenharmony_ci	unsigned long		sync_queue_len;
87462306a36Sopenharmony_ci	unsigned int		sync_queue_delay;
87562306a36Sopenharmony_ci	struct delayed_work	master_wakeup_work;
87662306a36Sopenharmony_ci	struct netns_ipvs	*ipvs;
87762306a36Sopenharmony_ci};
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_cistruct ip_vs_sync_thread_data;
88062306a36Sopenharmony_ci
88162306a36Sopenharmony_ci/* How much time to keep dests in trash */
88262306a36Sopenharmony_ci#define IP_VS_DEST_TRASH_PERIOD		(120 * HZ)
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_cistruct ipvs_sync_daemon_cfg {
88562306a36Sopenharmony_ci	union nf_inet_addr	mcast_group;
88662306a36Sopenharmony_ci	int			syncid;
88762306a36Sopenharmony_ci	u16			sync_maxlen;
88862306a36Sopenharmony_ci	u16			mcast_port;
88962306a36Sopenharmony_ci	u8			mcast_af;
89062306a36Sopenharmony_ci	u8			mcast_ttl;
89162306a36Sopenharmony_ci	/* multicast interface name */
89262306a36Sopenharmony_ci	char			mcast_ifn[IP_VS_IFNAME_MAXLEN];
89362306a36Sopenharmony_ci};
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci/* IPVS in network namespace */
89662306a36Sopenharmony_cistruct netns_ipvs {
89762306a36Sopenharmony_ci	int			gen;		/* Generation */
89862306a36Sopenharmony_ci	int			enable;		/* enable like nf_hooks do */
89962306a36Sopenharmony_ci	/* Hash table: for real service lookups */
90062306a36Sopenharmony_ci	#define IP_VS_RTAB_BITS 4
90162306a36Sopenharmony_ci	#define IP_VS_RTAB_SIZE (1 << IP_VS_RTAB_BITS)
90262306a36Sopenharmony_ci	#define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1)
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci	struct hlist_head	rs_table[IP_VS_RTAB_SIZE];
90562306a36Sopenharmony_ci	/* ip_vs_app */
90662306a36Sopenharmony_ci	struct list_head	app_list;
90762306a36Sopenharmony_ci	/* ip_vs_proto */
90862306a36Sopenharmony_ci	#define IP_VS_PROTO_TAB_SIZE	32	/* must be power of 2 */
90962306a36Sopenharmony_ci	struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE];
91062306a36Sopenharmony_ci	/* ip_vs_proto_tcp */
91162306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_PROTO_TCP
91262306a36Sopenharmony_ci	#define	TCP_APP_TAB_BITS	4
91362306a36Sopenharmony_ci	#define	TCP_APP_TAB_SIZE	(1 << TCP_APP_TAB_BITS)
91462306a36Sopenharmony_ci	#define	TCP_APP_TAB_MASK	(TCP_APP_TAB_SIZE - 1)
91562306a36Sopenharmony_ci	struct list_head	tcp_apps[TCP_APP_TAB_SIZE];
91662306a36Sopenharmony_ci#endif
91762306a36Sopenharmony_ci	/* ip_vs_proto_udp */
91862306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_PROTO_UDP
91962306a36Sopenharmony_ci	#define	UDP_APP_TAB_BITS	4
92062306a36Sopenharmony_ci	#define	UDP_APP_TAB_SIZE	(1 << UDP_APP_TAB_BITS)
92162306a36Sopenharmony_ci	#define	UDP_APP_TAB_MASK	(UDP_APP_TAB_SIZE - 1)
92262306a36Sopenharmony_ci	struct list_head	udp_apps[UDP_APP_TAB_SIZE];
92362306a36Sopenharmony_ci#endif
92462306a36Sopenharmony_ci	/* ip_vs_proto_sctp */
92562306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_PROTO_SCTP
92662306a36Sopenharmony_ci	#define SCTP_APP_TAB_BITS	4
92762306a36Sopenharmony_ci	#define SCTP_APP_TAB_SIZE	(1 << SCTP_APP_TAB_BITS)
92862306a36Sopenharmony_ci	#define SCTP_APP_TAB_MASK	(SCTP_APP_TAB_SIZE - 1)
92962306a36Sopenharmony_ci	/* Hash table for SCTP application incarnations	 */
93062306a36Sopenharmony_ci	struct list_head	sctp_apps[SCTP_APP_TAB_SIZE];
93162306a36Sopenharmony_ci#endif
93262306a36Sopenharmony_ci	/* ip_vs_conn */
93362306a36Sopenharmony_ci	atomic_t		conn_count;      /* connection counter */
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_ci	/* ip_vs_ctl */
93662306a36Sopenharmony_ci	struct ip_vs_stats_rcu	*tot_stats;      /* Statistics & est. */
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_ci	int			num_services;    /* no of virtual services */
93962306a36Sopenharmony_ci	int			num_services6;   /* IPv6 virtual services */
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci	/* Trash for destinations */
94262306a36Sopenharmony_ci	struct list_head	dest_trash;
94362306a36Sopenharmony_ci	spinlock_t		dest_trash_lock;
94462306a36Sopenharmony_ci	struct timer_list	dest_trash_timer; /* expiration timer */
94562306a36Sopenharmony_ci	/* Service counters */
94662306a36Sopenharmony_ci	atomic_t		ftpsvc_counter;
94762306a36Sopenharmony_ci	atomic_t		nullsvc_counter;
94862306a36Sopenharmony_ci	atomic_t		conn_out_counter;
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
95162306a36Sopenharmony_ci	/* delayed work for expiring no dest connections */
95262306a36Sopenharmony_ci	struct delayed_work	expire_nodest_conn_work;
95362306a36Sopenharmony_ci	/* 1/rate drop and drop-entry variables */
95462306a36Sopenharmony_ci	struct delayed_work	defense_work;   /* Work handler */
95562306a36Sopenharmony_ci	int			drop_rate;
95662306a36Sopenharmony_ci	int			drop_counter;
95762306a36Sopenharmony_ci	int			old_secure_tcp;
95862306a36Sopenharmony_ci	atomic_t		dropentry;
95962306a36Sopenharmony_ci	/* locks in ctl.c */
96062306a36Sopenharmony_ci	spinlock_t		dropentry_lock;  /* drop entry handling */
96162306a36Sopenharmony_ci	spinlock_t		droppacket_lock; /* drop packet handling */
96262306a36Sopenharmony_ci	spinlock_t		securetcp_lock;  /* state and timeout tables */
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci	/* sys-ctl struct */
96562306a36Sopenharmony_ci	struct ctl_table_header	*sysctl_hdr;
96662306a36Sopenharmony_ci	struct ctl_table	*sysctl_tbl;
96762306a36Sopenharmony_ci#endif
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci	/* sysctl variables */
97062306a36Sopenharmony_ci	int			sysctl_amemthresh;
97162306a36Sopenharmony_ci	int			sysctl_am_droprate;
97262306a36Sopenharmony_ci	int			sysctl_drop_entry;
97362306a36Sopenharmony_ci	int			sysctl_drop_packet;
97462306a36Sopenharmony_ci	int			sysctl_secure_tcp;
97562306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_NFCT
97662306a36Sopenharmony_ci	int			sysctl_conntrack;
97762306a36Sopenharmony_ci#endif
97862306a36Sopenharmony_ci	int			sysctl_snat_reroute;
97962306a36Sopenharmony_ci	int			sysctl_sync_ver;
98062306a36Sopenharmony_ci	int			sysctl_sync_ports;
98162306a36Sopenharmony_ci	int			sysctl_sync_persist_mode;
98262306a36Sopenharmony_ci	unsigned long		sysctl_sync_qlen_max;
98362306a36Sopenharmony_ci	int			sysctl_sync_sock_size;
98462306a36Sopenharmony_ci	int			sysctl_cache_bypass;
98562306a36Sopenharmony_ci	int			sysctl_expire_nodest_conn;
98662306a36Sopenharmony_ci	int			sysctl_sloppy_tcp;
98762306a36Sopenharmony_ci	int			sysctl_sloppy_sctp;
98862306a36Sopenharmony_ci	int			sysctl_expire_quiescent_template;
98962306a36Sopenharmony_ci	int			sysctl_sync_threshold[2];
99062306a36Sopenharmony_ci	unsigned int		sysctl_sync_refresh_period;
99162306a36Sopenharmony_ci	int			sysctl_sync_retries;
99262306a36Sopenharmony_ci	int			sysctl_nat_icmp_send;
99362306a36Sopenharmony_ci	int			sysctl_pmtu_disc;
99462306a36Sopenharmony_ci	int			sysctl_backup_only;
99562306a36Sopenharmony_ci	int			sysctl_conn_reuse_mode;
99662306a36Sopenharmony_ci	int			sysctl_schedule_icmp;
99762306a36Sopenharmony_ci	int			sysctl_ignore_tunneled;
99862306a36Sopenharmony_ci	int			sysctl_run_estimation;
99962306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
100062306a36Sopenharmony_ci	cpumask_var_t		sysctl_est_cpulist;	/* kthread cpumask */
100162306a36Sopenharmony_ci	int			est_cpulist_valid;	/* cpulist set */
100262306a36Sopenharmony_ci	int			sysctl_est_nice;	/* kthread nice */
100362306a36Sopenharmony_ci	int			est_stopped;		/* stop tasks */
100462306a36Sopenharmony_ci#endif
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_ci	/* ip_vs_lblc */
100762306a36Sopenharmony_ci	int			sysctl_lblc_expiration;
100862306a36Sopenharmony_ci	struct ctl_table_header	*lblc_ctl_header;
100962306a36Sopenharmony_ci	struct ctl_table	*lblc_ctl_table;
101062306a36Sopenharmony_ci	/* ip_vs_lblcr */
101162306a36Sopenharmony_ci	int			sysctl_lblcr_expiration;
101262306a36Sopenharmony_ci	struct ctl_table_header	*lblcr_ctl_header;
101362306a36Sopenharmony_ci	struct ctl_table	*lblcr_ctl_table;
101462306a36Sopenharmony_ci	/* ip_vs_est */
101562306a36Sopenharmony_ci	struct delayed_work	est_reload_work;/* Reload kthread tasks */
101662306a36Sopenharmony_ci	struct mutex		est_mutex;	/* protect kthread tasks */
101762306a36Sopenharmony_ci	struct hlist_head	est_temp_list;	/* Ests during calc phase */
101862306a36Sopenharmony_ci	struct ip_vs_est_kt_data **est_kt_arr;	/* Array of kthread data ptrs */
101962306a36Sopenharmony_ci	unsigned long		est_max_threads;/* Hard limit of kthreads */
102062306a36Sopenharmony_ci	int			est_calc_phase;	/* Calculation phase */
102162306a36Sopenharmony_ci	int			est_chain_max;	/* Calculated chain_max */
102262306a36Sopenharmony_ci	int			est_kt_count;	/* Allocated ptrs */
102362306a36Sopenharmony_ci	int			est_add_ktid;	/* ktid where to add ests */
102462306a36Sopenharmony_ci	atomic_t		est_genid;	/* kthreads reload genid */
102562306a36Sopenharmony_ci	atomic_t		est_genid_done;	/* applied genid */
102662306a36Sopenharmony_ci	/* ip_vs_sync */
102762306a36Sopenharmony_ci	spinlock_t		sync_lock;
102862306a36Sopenharmony_ci	struct ipvs_master_sync_state *ms;
102962306a36Sopenharmony_ci	spinlock_t		sync_buff_lock;
103062306a36Sopenharmony_ci	struct ip_vs_sync_thread_data *master_tinfo;
103162306a36Sopenharmony_ci	struct ip_vs_sync_thread_data *backup_tinfo;
103262306a36Sopenharmony_ci	int			threads_mask;
103362306a36Sopenharmony_ci	volatile int		sync_state;
103462306a36Sopenharmony_ci	struct mutex		sync_mutex;
103562306a36Sopenharmony_ci	struct ipvs_sync_daemon_cfg	mcfg;	/* Master Configuration */
103662306a36Sopenharmony_ci	struct ipvs_sync_daemon_cfg	bcfg;	/* Backup Configuration */
103762306a36Sopenharmony_ci	/* net name space ptr */
103862306a36Sopenharmony_ci	struct net		*net;            /* Needed by timer routines */
103962306a36Sopenharmony_ci	/* Number of heterogeneous destinations, needed because heterogeneous
104062306a36Sopenharmony_ci	 * are not supported when synchronization is enabled.
104162306a36Sopenharmony_ci	 */
104262306a36Sopenharmony_ci	unsigned int		mixed_address_family_dests;
104362306a36Sopenharmony_ci	unsigned int		hooks_afmask;	/* &1=AF_INET, &2=AF_INET6 */
104462306a36Sopenharmony_ci};
104562306a36Sopenharmony_ci
104662306a36Sopenharmony_ci#define DEFAULT_SYNC_THRESHOLD	3
104762306a36Sopenharmony_ci#define DEFAULT_SYNC_PERIOD	50
104862306a36Sopenharmony_ci#define DEFAULT_SYNC_VER	1
104962306a36Sopenharmony_ci#define DEFAULT_SLOPPY_TCP	0
105062306a36Sopenharmony_ci#define DEFAULT_SLOPPY_SCTP	0
105162306a36Sopenharmony_ci#define DEFAULT_SYNC_REFRESH_PERIOD	(0U * HZ)
105262306a36Sopenharmony_ci#define DEFAULT_SYNC_RETRIES		0
105362306a36Sopenharmony_ci#define IPVS_SYNC_WAKEUP_RATE	8
105462306a36Sopenharmony_ci#define IPVS_SYNC_QLEN_MAX	(IPVS_SYNC_WAKEUP_RATE * 4)
105562306a36Sopenharmony_ci#define IPVS_SYNC_SEND_DELAY	(HZ / 50)
105662306a36Sopenharmony_ci#define IPVS_SYNC_CHECK_PERIOD	HZ
105762306a36Sopenharmony_ci#define IPVS_SYNC_FLUSH_TIME	(HZ * 2)
105862306a36Sopenharmony_ci#define IPVS_SYNC_PORTS_MAX	(1 << 6)
105962306a36Sopenharmony_ci
106062306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
106162306a36Sopenharmony_ci
106262306a36Sopenharmony_cistatic inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
106362306a36Sopenharmony_ci{
106462306a36Sopenharmony_ci	return ipvs->sysctl_sync_threshold[0];
106562306a36Sopenharmony_ci}
106662306a36Sopenharmony_ci
106762306a36Sopenharmony_cistatic inline int sysctl_sync_period(struct netns_ipvs *ipvs)
106862306a36Sopenharmony_ci{
106962306a36Sopenharmony_ci	return READ_ONCE(ipvs->sysctl_sync_threshold[1]);
107062306a36Sopenharmony_ci}
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_cistatic inline unsigned int sysctl_sync_refresh_period(struct netns_ipvs *ipvs)
107362306a36Sopenharmony_ci{
107462306a36Sopenharmony_ci	return READ_ONCE(ipvs->sysctl_sync_refresh_period);
107562306a36Sopenharmony_ci}
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_cistatic inline int sysctl_sync_retries(struct netns_ipvs *ipvs)
107862306a36Sopenharmony_ci{
107962306a36Sopenharmony_ci	return ipvs->sysctl_sync_retries;
108062306a36Sopenharmony_ci}
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_cistatic inline int sysctl_sync_ver(struct netns_ipvs *ipvs)
108362306a36Sopenharmony_ci{
108462306a36Sopenharmony_ci	return ipvs->sysctl_sync_ver;
108562306a36Sopenharmony_ci}
108662306a36Sopenharmony_ci
108762306a36Sopenharmony_cistatic inline int sysctl_sloppy_tcp(struct netns_ipvs *ipvs)
108862306a36Sopenharmony_ci{
108962306a36Sopenharmony_ci	return ipvs->sysctl_sloppy_tcp;
109062306a36Sopenharmony_ci}
109162306a36Sopenharmony_ci
109262306a36Sopenharmony_cistatic inline int sysctl_sloppy_sctp(struct netns_ipvs *ipvs)
109362306a36Sopenharmony_ci{
109462306a36Sopenharmony_ci	return ipvs->sysctl_sloppy_sctp;
109562306a36Sopenharmony_ci}
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_cistatic inline int sysctl_sync_ports(struct netns_ipvs *ipvs)
109862306a36Sopenharmony_ci{
109962306a36Sopenharmony_ci	return READ_ONCE(ipvs->sysctl_sync_ports);
110062306a36Sopenharmony_ci}
110162306a36Sopenharmony_ci
110262306a36Sopenharmony_cistatic inline int sysctl_sync_persist_mode(struct netns_ipvs *ipvs)
110362306a36Sopenharmony_ci{
110462306a36Sopenharmony_ci	return ipvs->sysctl_sync_persist_mode;
110562306a36Sopenharmony_ci}
110662306a36Sopenharmony_ci
110762306a36Sopenharmony_cistatic inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
110862306a36Sopenharmony_ci{
110962306a36Sopenharmony_ci	return ipvs->sysctl_sync_qlen_max;
111062306a36Sopenharmony_ci}
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_cistatic inline int sysctl_sync_sock_size(struct netns_ipvs *ipvs)
111362306a36Sopenharmony_ci{
111462306a36Sopenharmony_ci	return ipvs->sysctl_sync_sock_size;
111562306a36Sopenharmony_ci}
111662306a36Sopenharmony_ci
111762306a36Sopenharmony_cistatic inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs)
111862306a36Sopenharmony_ci{
111962306a36Sopenharmony_ci	return ipvs->sysctl_pmtu_disc;
112062306a36Sopenharmony_ci}
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_cistatic inline int sysctl_backup_only(struct netns_ipvs *ipvs)
112362306a36Sopenharmony_ci{
112462306a36Sopenharmony_ci	return ipvs->sync_state & IP_VS_STATE_BACKUP &&
112562306a36Sopenharmony_ci	       ipvs->sysctl_backup_only;
112662306a36Sopenharmony_ci}
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_cistatic inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs)
112962306a36Sopenharmony_ci{
113062306a36Sopenharmony_ci	return ipvs->sysctl_conn_reuse_mode;
113162306a36Sopenharmony_ci}
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_cistatic inline int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs)
113462306a36Sopenharmony_ci{
113562306a36Sopenharmony_ci	return ipvs->sysctl_expire_nodest_conn;
113662306a36Sopenharmony_ci}
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_cistatic inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
113962306a36Sopenharmony_ci{
114062306a36Sopenharmony_ci	return ipvs->sysctl_schedule_icmp;
114162306a36Sopenharmony_ci}
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_cistatic inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs)
114462306a36Sopenharmony_ci{
114562306a36Sopenharmony_ci	return ipvs->sysctl_ignore_tunneled;
114662306a36Sopenharmony_ci}
114762306a36Sopenharmony_ci
114862306a36Sopenharmony_cistatic inline int sysctl_cache_bypass(struct netns_ipvs *ipvs)
114962306a36Sopenharmony_ci{
115062306a36Sopenharmony_ci	return ipvs->sysctl_cache_bypass;
115162306a36Sopenharmony_ci}
115262306a36Sopenharmony_ci
115362306a36Sopenharmony_cistatic inline int sysctl_run_estimation(struct netns_ipvs *ipvs)
115462306a36Sopenharmony_ci{
115562306a36Sopenharmony_ci	return ipvs->sysctl_run_estimation;
115662306a36Sopenharmony_ci}
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_cistatic inline const struct cpumask *sysctl_est_cpulist(struct netns_ipvs *ipvs)
115962306a36Sopenharmony_ci{
116062306a36Sopenharmony_ci	if (ipvs->est_cpulist_valid)
116162306a36Sopenharmony_ci		return ipvs->sysctl_est_cpulist;
116262306a36Sopenharmony_ci	else
116362306a36Sopenharmony_ci		return housekeeping_cpumask(HK_TYPE_KTHREAD);
116462306a36Sopenharmony_ci}
116562306a36Sopenharmony_ci
116662306a36Sopenharmony_cistatic inline int sysctl_est_nice(struct netns_ipvs *ipvs)
116762306a36Sopenharmony_ci{
116862306a36Sopenharmony_ci	return ipvs->sysctl_est_nice;
116962306a36Sopenharmony_ci}
117062306a36Sopenharmony_ci
117162306a36Sopenharmony_ci#else
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_cistatic inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
117462306a36Sopenharmony_ci{
117562306a36Sopenharmony_ci	return DEFAULT_SYNC_THRESHOLD;
117662306a36Sopenharmony_ci}
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_cistatic inline int sysctl_sync_period(struct netns_ipvs *ipvs)
117962306a36Sopenharmony_ci{
118062306a36Sopenharmony_ci	return DEFAULT_SYNC_PERIOD;
118162306a36Sopenharmony_ci}
118262306a36Sopenharmony_ci
118362306a36Sopenharmony_cistatic inline unsigned int sysctl_sync_refresh_period(struct netns_ipvs *ipvs)
118462306a36Sopenharmony_ci{
118562306a36Sopenharmony_ci	return DEFAULT_SYNC_REFRESH_PERIOD;
118662306a36Sopenharmony_ci}
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_cistatic inline int sysctl_sync_retries(struct netns_ipvs *ipvs)
118962306a36Sopenharmony_ci{
119062306a36Sopenharmony_ci	return DEFAULT_SYNC_RETRIES & 3;
119162306a36Sopenharmony_ci}
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_cistatic inline int sysctl_sync_ver(struct netns_ipvs *ipvs)
119462306a36Sopenharmony_ci{
119562306a36Sopenharmony_ci	return DEFAULT_SYNC_VER;
119662306a36Sopenharmony_ci}
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_cistatic inline int sysctl_sloppy_tcp(struct netns_ipvs *ipvs)
119962306a36Sopenharmony_ci{
120062306a36Sopenharmony_ci	return DEFAULT_SLOPPY_TCP;
120162306a36Sopenharmony_ci}
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_cistatic inline int sysctl_sloppy_sctp(struct netns_ipvs *ipvs)
120462306a36Sopenharmony_ci{
120562306a36Sopenharmony_ci	return DEFAULT_SLOPPY_SCTP;
120662306a36Sopenharmony_ci}
120762306a36Sopenharmony_ci
120862306a36Sopenharmony_cistatic inline int sysctl_sync_ports(struct netns_ipvs *ipvs)
120962306a36Sopenharmony_ci{
121062306a36Sopenharmony_ci	return 1;
121162306a36Sopenharmony_ci}
121262306a36Sopenharmony_ci
121362306a36Sopenharmony_cistatic inline int sysctl_sync_persist_mode(struct netns_ipvs *ipvs)
121462306a36Sopenharmony_ci{
121562306a36Sopenharmony_ci	return 0;
121662306a36Sopenharmony_ci}
121762306a36Sopenharmony_ci
121862306a36Sopenharmony_cistatic inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
121962306a36Sopenharmony_ci{
122062306a36Sopenharmony_ci	return IPVS_SYNC_QLEN_MAX;
122162306a36Sopenharmony_ci}
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_cistatic inline int sysctl_sync_sock_size(struct netns_ipvs *ipvs)
122462306a36Sopenharmony_ci{
122562306a36Sopenharmony_ci	return 0;
122662306a36Sopenharmony_ci}
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_cistatic inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs)
122962306a36Sopenharmony_ci{
123062306a36Sopenharmony_ci	return 1;
123162306a36Sopenharmony_ci}
123262306a36Sopenharmony_ci
123362306a36Sopenharmony_cistatic inline int sysctl_backup_only(struct netns_ipvs *ipvs)
123462306a36Sopenharmony_ci{
123562306a36Sopenharmony_ci	return 0;
123662306a36Sopenharmony_ci}
123762306a36Sopenharmony_ci
123862306a36Sopenharmony_cistatic inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs)
123962306a36Sopenharmony_ci{
124062306a36Sopenharmony_ci	return 1;
124162306a36Sopenharmony_ci}
124262306a36Sopenharmony_ci
124362306a36Sopenharmony_cistatic inline int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs)
124462306a36Sopenharmony_ci{
124562306a36Sopenharmony_ci	return 0;
124662306a36Sopenharmony_ci}
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_cistatic inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
124962306a36Sopenharmony_ci{
125062306a36Sopenharmony_ci	return 0;
125162306a36Sopenharmony_ci}
125262306a36Sopenharmony_ci
125362306a36Sopenharmony_cistatic inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs)
125462306a36Sopenharmony_ci{
125562306a36Sopenharmony_ci	return 0;
125662306a36Sopenharmony_ci}
125762306a36Sopenharmony_ci
125862306a36Sopenharmony_cistatic inline int sysctl_cache_bypass(struct netns_ipvs *ipvs)
125962306a36Sopenharmony_ci{
126062306a36Sopenharmony_ci	return 0;
126162306a36Sopenharmony_ci}
126262306a36Sopenharmony_ci
126362306a36Sopenharmony_cistatic inline int sysctl_run_estimation(struct netns_ipvs *ipvs)
126462306a36Sopenharmony_ci{
126562306a36Sopenharmony_ci	return 1;
126662306a36Sopenharmony_ci}
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_cistatic inline const struct cpumask *sysctl_est_cpulist(struct netns_ipvs *ipvs)
126962306a36Sopenharmony_ci{
127062306a36Sopenharmony_ci	return housekeeping_cpumask(HK_TYPE_KTHREAD);
127162306a36Sopenharmony_ci}
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_cistatic inline int sysctl_est_nice(struct netns_ipvs *ipvs)
127462306a36Sopenharmony_ci{
127562306a36Sopenharmony_ci	return IPVS_EST_NICE;
127662306a36Sopenharmony_ci}
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_ci#endif
127962306a36Sopenharmony_ci
128062306a36Sopenharmony_ci/* IPVS core functions
128162306a36Sopenharmony_ci * (from ip_vs_core.c)
128262306a36Sopenharmony_ci */
128362306a36Sopenharmony_ciconst char *ip_vs_proto_name(unsigned int proto);
128462306a36Sopenharmony_civoid ip_vs_init_hash_table(struct list_head *table, int rows);
128562306a36Sopenharmony_cistruct ip_vs_conn *ip_vs_new_conn_out(struct ip_vs_service *svc,
128662306a36Sopenharmony_ci				      struct ip_vs_dest *dest,
128762306a36Sopenharmony_ci				      struct sk_buff *skb,
128862306a36Sopenharmony_ci				      const struct ip_vs_iphdr *iph,
128962306a36Sopenharmony_ci				      __be16 dport,
129062306a36Sopenharmony_ci				      __be16 cport);
129162306a36Sopenharmony_ci#define IP_VS_INIT_HASH_TABLE(t) ip_vs_init_hash_table((t), ARRAY_SIZE((t)))
129262306a36Sopenharmony_ci
129362306a36Sopenharmony_ci#define IP_VS_APP_TYPE_FTP	1
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci/* ip_vs_conn handling functions
129662306a36Sopenharmony_ci * (from ip_vs_conn.c)
129762306a36Sopenharmony_ci */
129862306a36Sopenharmony_cienum {
129962306a36Sopenharmony_ci	IP_VS_DIR_INPUT = 0,
130062306a36Sopenharmony_ci	IP_VS_DIR_OUTPUT,
130162306a36Sopenharmony_ci	IP_VS_DIR_INPUT_ONLY,
130262306a36Sopenharmony_ci	IP_VS_DIR_LAST,
130362306a36Sopenharmony_ci};
130462306a36Sopenharmony_ci
130562306a36Sopenharmony_cistatic inline void ip_vs_conn_fill_param(struct netns_ipvs *ipvs, int af, int protocol,
130662306a36Sopenharmony_ci					 const union nf_inet_addr *caddr,
130762306a36Sopenharmony_ci					 __be16 cport,
130862306a36Sopenharmony_ci					 const union nf_inet_addr *vaddr,
130962306a36Sopenharmony_ci					 __be16 vport,
131062306a36Sopenharmony_ci					 struct ip_vs_conn_param *p)
131162306a36Sopenharmony_ci{
131262306a36Sopenharmony_ci	p->ipvs = ipvs;
131362306a36Sopenharmony_ci	p->af = af;
131462306a36Sopenharmony_ci	p->protocol = protocol;
131562306a36Sopenharmony_ci	p->caddr = caddr;
131662306a36Sopenharmony_ci	p->cport = cport;
131762306a36Sopenharmony_ci	p->vaddr = vaddr;
131862306a36Sopenharmony_ci	p->vport = vport;
131962306a36Sopenharmony_ci	p->pe = NULL;
132062306a36Sopenharmony_ci	p->pe_data = NULL;
132162306a36Sopenharmony_ci}
132262306a36Sopenharmony_ci
132362306a36Sopenharmony_cistruct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p);
132462306a36Sopenharmony_cistruct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p);
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_cistruct ip_vs_conn * ip_vs_conn_in_get_proto(struct netns_ipvs *ipvs, int af,
132762306a36Sopenharmony_ci					    const struct sk_buff *skb,
132862306a36Sopenharmony_ci					    const struct ip_vs_iphdr *iph);
132962306a36Sopenharmony_ci
133062306a36Sopenharmony_cistruct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p);
133162306a36Sopenharmony_ci
133262306a36Sopenharmony_cistruct ip_vs_conn * ip_vs_conn_out_get_proto(struct netns_ipvs *ipvs, int af,
133362306a36Sopenharmony_ci					     const struct sk_buff *skb,
133462306a36Sopenharmony_ci					     const struct ip_vs_iphdr *iph);
133562306a36Sopenharmony_ci
133662306a36Sopenharmony_ci/* Get reference to gain full access to conn.
133762306a36Sopenharmony_ci * By default, RCU read-side critical sections have access only to
133862306a36Sopenharmony_ci * conn fields and its PE data, see ip_vs_conn_rcu_free() for reference.
133962306a36Sopenharmony_ci */
134062306a36Sopenharmony_cistatic inline bool __ip_vs_conn_get(struct ip_vs_conn *cp)
134162306a36Sopenharmony_ci{
134262306a36Sopenharmony_ci	return refcount_inc_not_zero(&cp->refcnt);
134362306a36Sopenharmony_ci}
134462306a36Sopenharmony_ci
134562306a36Sopenharmony_ci/* put back the conn without restarting its timer */
134662306a36Sopenharmony_cistatic inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
134762306a36Sopenharmony_ci{
134862306a36Sopenharmony_ci	smp_mb__before_atomic();
134962306a36Sopenharmony_ci	refcount_dec(&cp->refcnt);
135062306a36Sopenharmony_ci}
135162306a36Sopenharmony_civoid ip_vs_conn_put(struct ip_vs_conn *cp);
135262306a36Sopenharmony_civoid ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport);
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_cistruct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p, int dest_af,
135562306a36Sopenharmony_ci				  const union nf_inet_addr *daddr,
135662306a36Sopenharmony_ci				  __be16 dport, unsigned int flags,
135762306a36Sopenharmony_ci				  struct ip_vs_dest *dest, __u32 fwmark);
135862306a36Sopenharmony_civoid ip_vs_conn_expire_now(struct ip_vs_conn *cp);
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ciconst char *ip_vs_state_name(const struct ip_vs_conn *cp);
136162306a36Sopenharmony_ci
136262306a36Sopenharmony_civoid ip_vs_tcp_conn_listen(struct ip_vs_conn *cp);
136362306a36Sopenharmony_ciint ip_vs_check_template(struct ip_vs_conn *ct, struct ip_vs_dest *cdest);
136462306a36Sopenharmony_civoid ip_vs_random_dropentry(struct netns_ipvs *ipvs);
136562306a36Sopenharmony_ciint ip_vs_conn_init(void);
136662306a36Sopenharmony_civoid ip_vs_conn_cleanup(void);
136762306a36Sopenharmony_ci
136862306a36Sopenharmony_cistatic inline void ip_vs_control_del(struct ip_vs_conn *cp)
136962306a36Sopenharmony_ci{
137062306a36Sopenharmony_ci	struct ip_vs_conn *ctl_cp = cp->control;
137162306a36Sopenharmony_ci	if (!ctl_cp) {
137262306a36Sopenharmony_ci		IP_VS_ERR_BUF("request control DEL for uncontrolled: "
137362306a36Sopenharmony_ci			      "%s:%d to %s:%d\n",
137462306a36Sopenharmony_ci			      IP_VS_DBG_ADDR(cp->af, &cp->caddr),
137562306a36Sopenharmony_ci			      ntohs(cp->cport),
137662306a36Sopenharmony_ci			      IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
137762306a36Sopenharmony_ci			      ntohs(cp->vport));
137862306a36Sopenharmony_ci
137962306a36Sopenharmony_ci		return;
138062306a36Sopenharmony_ci	}
138162306a36Sopenharmony_ci
138262306a36Sopenharmony_ci	IP_VS_DBG_BUF(7, "DELeting control for: "
138362306a36Sopenharmony_ci		      "cp.dst=%s:%d ctl_cp.dst=%s:%d\n",
138462306a36Sopenharmony_ci		      IP_VS_DBG_ADDR(cp->af, &cp->caddr),
138562306a36Sopenharmony_ci		      ntohs(cp->cport),
138662306a36Sopenharmony_ci		      IP_VS_DBG_ADDR(cp->af, &ctl_cp->caddr),
138762306a36Sopenharmony_ci		      ntohs(ctl_cp->cport));
138862306a36Sopenharmony_ci
138962306a36Sopenharmony_ci	cp->control = NULL;
139062306a36Sopenharmony_ci	if (atomic_read(&ctl_cp->n_control) == 0) {
139162306a36Sopenharmony_ci		IP_VS_ERR_BUF("BUG control DEL with n=0 : "
139262306a36Sopenharmony_ci			      "%s:%d to %s:%d\n",
139362306a36Sopenharmony_ci			      IP_VS_DBG_ADDR(cp->af, &cp->caddr),
139462306a36Sopenharmony_ci			      ntohs(cp->cport),
139562306a36Sopenharmony_ci			      IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
139662306a36Sopenharmony_ci			      ntohs(cp->vport));
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci		return;
139962306a36Sopenharmony_ci	}
140062306a36Sopenharmony_ci	atomic_dec(&ctl_cp->n_control);
140162306a36Sopenharmony_ci}
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_cistatic inline void
140462306a36Sopenharmony_ciip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp)
140562306a36Sopenharmony_ci{
140662306a36Sopenharmony_ci	if (cp->control) {
140762306a36Sopenharmony_ci		IP_VS_ERR_BUF("request control ADD for already controlled: "
140862306a36Sopenharmony_ci			      "%s:%d to %s:%d\n",
140962306a36Sopenharmony_ci			      IP_VS_DBG_ADDR(cp->af, &cp->caddr),
141062306a36Sopenharmony_ci			      ntohs(cp->cport),
141162306a36Sopenharmony_ci			      IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
141262306a36Sopenharmony_ci			      ntohs(cp->vport));
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_ci		ip_vs_control_del(cp);
141562306a36Sopenharmony_ci	}
141662306a36Sopenharmony_ci
141762306a36Sopenharmony_ci	IP_VS_DBG_BUF(7, "ADDing control for: "
141862306a36Sopenharmony_ci		      "cp.dst=%s:%d ctl_cp.dst=%s:%d\n",
141962306a36Sopenharmony_ci		      IP_VS_DBG_ADDR(cp->af, &cp->caddr),
142062306a36Sopenharmony_ci		      ntohs(cp->cport),
142162306a36Sopenharmony_ci		      IP_VS_DBG_ADDR(cp->af, &ctl_cp->caddr),
142262306a36Sopenharmony_ci		      ntohs(ctl_cp->cport));
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_ci	cp->control = ctl_cp;
142562306a36Sopenharmony_ci	atomic_inc(&ctl_cp->n_control);
142662306a36Sopenharmony_ci}
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci/* Mark our template as assured */
142962306a36Sopenharmony_cistatic inline void
143062306a36Sopenharmony_ciip_vs_control_assure_ct(struct ip_vs_conn *cp)
143162306a36Sopenharmony_ci{
143262306a36Sopenharmony_ci	struct ip_vs_conn *ct = cp->control;
143362306a36Sopenharmony_ci
143462306a36Sopenharmony_ci	if (ct && !(ct->state & IP_VS_CTPL_S_ASSURED) &&
143562306a36Sopenharmony_ci	    (ct->flags & IP_VS_CONN_F_TEMPLATE))
143662306a36Sopenharmony_ci		ct->state |= IP_VS_CTPL_S_ASSURED;
143762306a36Sopenharmony_ci}
143862306a36Sopenharmony_ci
143962306a36Sopenharmony_ci/* IPVS netns init & cleanup functions */
144062306a36Sopenharmony_ciint ip_vs_estimator_net_init(struct netns_ipvs *ipvs);
144162306a36Sopenharmony_ciint ip_vs_control_net_init(struct netns_ipvs *ipvs);
144262306a36Sopenharmony_ciint ip_vs_protocol_net_init(struct netns_ipvs *ipvs);
144362306a36Sopenharmony_ciint ip_vs_app_net_init(struct netns_ipvs *ipvs);
144462306a36Sopenharmony_ciint ip_vs_conn_net_init(struct netns_ipvs *ipvs);
144562306a36Sopenharmony_ciint ip_vs_sync_net_init(struct netns_ipvs *ipvs);
144662306a36Sopenharmony_civoid ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs);
144762306a36Sopenharmony_civoid ip_vs_app_net_cleanup(struct netns_ipvs *ipvs);
144862306a36Sopenharmony_civoid ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs);
144962306a36Sopenharmony_civoid ip_vs_control_net_cleanup(struct netns_ipvs *ipvs);
145062306a36Sopenharmony_civoid ip_vs_estimator_net_cleanup(struct netns_ipvs *ipvs);
145162306a36Sopenharmony_civoid ip_vs_sync_net_cleanup(struct netns_ipvs *ipvs);
145262306a36Sopenharmony_civoid ip_vs_service_nets_cleanup(struct list_head *net_list);
145362306a36Sopenharmony_ci
145462306a36Sopenharmony_ci/* IPVS application functions
145562306a36Sopenharmony_ci * (from ip_vs_app.c)
145662306a36Sopenharmony_ci */
145762306a36Sopenharmony_ci#define IP_VS_APP_MAX_PORTS  8
145862306a36Sopenharmony_cistruct ip_vs_app *register_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *app);
145962306a36Sopenharmony_civoid unregister_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *app);
146062306a36Sopenharmony_ciint ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
146162306a36Sopenharmony_civoid ip_vs_unbind_app(struct ip_vs_conn *cp);
146262306a36Sopenharmony_ciint register_ip_vs_app_inc(struct netns_ipvs *ipvs, struct ip_vs_app *app, __u16 proto,
146362306a36Sopenharmony_ci			   __u16 port);
146462306a36Sopenharmony_ciint ip_vs_app_inc_get(struct ip_vs_app *inc);
146562306a36Sopenharmony_civoid ip_vs_app_inc_put(struct ip_vs_app *inc);
146662306a36Sopenharmony_ci
146762306a36Sopenharmony_ciint ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff *skb,
146862306a36Sopenharmony_ci		      struct ip_vs_iphdr *ipvsh);
146962306a36Sopenharmony_ciint ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb,
147062306a36Sopenharmony_ci		     struct ip_vs_iphdr *ipvsh);
147162306a36Sopenharmony_ci
147262306a36Sopenharmony_ciint register_ip_vs_pe(struct ip_vs_pe *pe);
147362306a36Sopenharmony_ciint unregister_ip_vs_pe(struct ip_vs_pe *pe);
147462306a36Sopenharmony_cistruct ip_vs_pe *ip_vs_pe_getbyname(const char *name);
147562306a36Sopenharmony_cistruct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name);
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci/* Use a #define to avoid all of module.h just for these trivial ops */
147862306a36Sopenharmony_ci#define ip_vs_pe_get(pe)			\
147962306a36Sopenharmony_ci	if (pe && pe->module)			\
148062306a36Sopenharmony_ci		__module_get(pe->module);
148162306a36Sopenharmony_ci
148262306a36Sopenharmony_ci#define ip_vs_pe_put(pe)			\
148362306a36Sopenharmony_ci	if (pe && pe->module)			\
148462306a36Sopenharmony_ci		module_put(pe->module);
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_ci/* IPVS protocol functions (from ip_vs_proto.c) */
148762306a36Sopenharmony_ciint ip_vs_protocol_init(void);
148862306a36Sopenharmony_civoid ip_vs_protocol_cleanup(void);
148962306a36Sopenharmony_civoid ip_vs_protocol_timeout_change(struct netns_ipvs *ipvs, int flags);
149062306a36Sopenharmony_ciint *ip_vs_create_timeout_table(int *table, int size);
149162306a36Sopenharmony_civoid ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
149262306a36Sopenharmony_ci			       const struct sk_buff *skb, int offset,
149362306a36Sopenharmony_ci			       const char *msg);
149462306a36Sopenharmony_ci
149562306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_tcp;
149662306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_udp;
149762306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_icmp;
149862306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_esp;
149962306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_ah;
150062306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_sctp;
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci/* Registering/unregistering scheduler functions
150362306a36Sopenharmony_ci * (from ip_vs_sched.c)
150462306a36Sopenharmony_ci */
150562306a36Sopenharmony_ciint register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler);
150662306a36Sopenharmony_ciint unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler);
150762306a36Sopenharmony_ciint ip_vs_bind_scheduler(struct ip_vs_service *svc,
150862306a36Sopenharmony_ci			 struct ip_vs_scheduler *scheduler);
150962306a36Sopenharmony_civoid ip_vs_unbind_scheduler(struct ip_vs_service *svc,
151062306a36Sopenharmony_ci			    struct ip_vs_scheduler *sched);
151162306a36Sopenharmony_cistruct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name);
151262306a36Sopenharmony_civoid ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler);
151362306a36Sopenharmony_cistruct ip_vs_conn *
151462306a36Sopenharmony_ciip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
151562306a36Sopenharmony_ci	       struct ip_vs_proto_data *pd, int *ignored,
151662306a36Sopenharmony_ci	       struct ip_vs_iphdr *iph);
151762306a36Sopenharmony_ciint ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
151862306a36Sopenharmony_ci		struct ip_vs_proto_data *pd, struct ip_vs_iphdr *iph);
151962306a36Sopenharmony_ci
152062306a36Sopenharmony_civoid ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg);
152162306a36Sopenharmony_ci
152262306a36Sopenharmony_ci/* IPVS control data and functions (from ip_vs_ctl.c) */
152362306a36Sopenharmony_ciextern struct ip_vs_stats ip_vs_stats;
152462306a36Sopenharmony_ciextern int sysctl_ip_vs_sync_ver;
152562306a36Sopenharmony_ci
152662306a36Sopenharmony_cistruct ip_vs_service *
152762306a36Sopenharmony_ciip_vs_service_find(struct netns_ipvs *ipvs, int af, __u32 fwmark, __u16 protocol,
152862306a36Sopenharmony_ci		  const union nf_inet_addr *vaddr, __be16 vport);
152962306a36Sopenharmony_ci
153062306a36Sopenharmony_cibool ip_vs_has_real_service(struct netns_ipvs *ipvs, int af, __u16 protocol,
153162306a36Sopenharmony_ci			    const union nf_inet_addr *daddr, __be16 dport);
153262306a36Sopenharmony_ci
153362306a36Sopenharmony_cistruct ip_vs_dest *
153462306a36Sopenharmony_ciip_vs_find_real_service(struct netns_ipvs *ipvs, int af, __u16 protocol,
153562306a36Sopenharmony_ci			const union nf_inet_addr *daddr, __be16 dport);
153662306a36Sopenharmony_cistruct ip_vs_dest *ip_vs_find_tunnel(struct netns_ipvs *ipvs, int af,
153762306a36Sopenharmony_ci				     const union nf_inet_addr *daddr,
153862306a36Sopenharmony_ci				     __be16 tun_port);
153962306a36Sopenharmony_ci
154062306a36Sopenharmony_ciint ip_vs_use_count_inc(void);
154162306a36Sopenharmony_civoid ip_vs_use_count_dec(void);
154262306a36Sopenharmony_ciint ip_vs_register_nl_ioctl(void);
154362306a36Sopenharmony_civoid ip_vs_unregister_nl_ioctl(void);
154462306a36Sopenharmony_ciint ip_vs_control_init(void);
154562306a36Sopenharmony_civoid ip_vs_control_cleanup(void);
154662306a36Sopenharmony_cistruct ip_vs_dest *
154762306a36Sopenharmony_ciip_vs_find_dest(struct netns_ipvs *ipvs, int svc_af, int dest_af,
154862306a36Sopenharmony_ci		const union nf_inet_addr *daddr, __be16 dport,
154962306a36Sopenharmony_ci		const union nf_inet_addr *vaddr, __be16 vport,
155062306a36Sopenharmony_ci		__u16 protocol, __u32 fwmark, __u32 flags);
155162306a36Sopenharmony_civoid ip_vs_try_bind_dest(struct ip_vs_conn *cp);
155262306a36Sopenharmony_ci
155362306a36Sopenharmony_cistatic inline void ip_vs_dest_hold(struct ip_vs_dest *dest)
155462306a36Sopenharmony_ci{
155562306a36Sopenharmony_ci	refcount_inc(&dest->refcnt);
155662306a36Sopenharmony_ci}
155762306a36Sopenharmony_ci
155862306a36Sopenharmony_cistatic inline void ip_vs_dest_put(struct ip_vs_dest *dest)
155962306a36Sopenharmony_ci{
156062306a36Sopenharmony_ci	smp_mb__before_atomic();
156162306a36Sopenharmony_ci	refcount_dec(&dest->refcnt);
156262306a36Sopenharmony_ci}
156362306a36Sopenharmony_ci
156462306a36Sopenharmony_cistatic inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest)
156562306a36Sopenharmony_ci{
156662306a36Sopenharmony_ci	if (refcount_dec_and_test(&dest->refcnt))
156762306a36Sopenharmony_ci		kfree(dest);
156862306a36Sopenharmony_ci}
156962306a36Sopenharmony_ci
157062306a36Sopenharmony_ci/* IPVS sync daemon data and function prototypes
157162306a36Sopenharmony_ci * (from ip_vs_sync.c)
157262306a36Sopenharmony_ci */
157362306a36Sopenharmony_ciint start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *cfg,
157462306a36Sopenharmony_ci		      int state);
157562306a36Sopenharmony_ciint stop_sync_thread(struct netns_ipvs *ipvs, int state);
157662306a36Sopenharmony_civoid ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts);
157762306a36Sopenharmony_ci
157862306a36Sopenharmony_ci/* IPVS rate estimator prototypes (from ip_vs_est.c) */
157962306a36Sopenharmony_ciint ip_vs_start_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats);
158062306a36Sopenharmony_civoid ip_vs_stop_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats);
158162306a36Sopenharmony_civoid ip_vs_zero_estimator(struct ip_vs_stats *stats);
158262306a36Sopenharmony_civoid ip_vs_read_estimator(struct ip_vs_kstats *dst, struct ip_vs_stats *stats);
158362306a36Sopenharmony_civoid ip_vs_est_reload_start(struct netns_ipvs *ipvs);
158462306a36Sopenharmony_ciint ip_vs_est_kthread_start(struct netns_ipvs *ipvs,
158562306a36Sopenharmony_ci			    struct ip_vs_est_kt_data *kd);
158662306a36Sopenharmony_civoid ip_vs_est_kthread_stop(struct ip_vs_est_kt_data *kd);
158762306a36Sopenharmony_ci
158862306a36Sopenharmony_cistatic inline void ip_vs_est_stopped_recalc(struct netns_ipvs *ipvs)
158962306a36Sopenharmony_ci{
159062306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
159162306a36Sopenharmony_ci	/* Stop tasks while cpulist is empty or if disabled with flag */
159262306a36Sopenharmony_ci	ipvs->est_stopped = !sysctl_run_estimation(ipvs) ||
159362306a36Sopenharmony_ci			    (ipvs->est_cpulist_valid &&
159462306a36Sopenharmony_ci			     cpumask_empty(sysctl_est_cpulist(ipvs)));
159562306a36Sopenharmony_ci#endif
159662306a36Sopenharmony_ci}
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_cistatic inline bool ip_vs_est_stopped(struct netns_ipvs *ipvs)
159962306a36Sopenharmony_ci{
160062306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
160162306a36Sopenharmony_ci	return ipvs->est_stopped;
160262306a36Sopenharmony_ci#else
160362306a36Sopenharmony_ci	return false;
160462306a36Sopenharmony_ci#endif
160562306a36Sopenharmony_ci}
160662306a36Sopenharmony_ci
160762306a36Sopenharmony_cistatic inline int ip_vs_est_max_threads(struct netns_ipvs *ipvs)
160862306a36Sopenharmony_ci{
160962306a36Sopenharmony_ci	unsigned int limit = IPVS_EST_CPU_KTHREADS *
161062306a36Sopenharmony_ci			     cpumask_weight(sysctl_est_cpulist(ipvs));
161162306a36Sopenharmony_ci
161262306a36Sopenharmony_ci	return max(1U, limit);
161362306a36Sopenharmony_ci}
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_ci/* Various IPVS packet transmitters (from ip_vs_xmit.c) */
161662306a36Sopenharmony_ciint ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
161762306a36Sopenharmony_ci		    struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
161862306a36Sopenharmony_ciint ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
161962306a36Sopenharmony_ci		      struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
162062306a36Sopenharmony_ciint ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
162162306a36Sopenharmony_ci		   struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
162262306a36Sopenharmony_ciint ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
162362306a36Sopenharmony_ci		      struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
162462306a36Sopenharmony_ciint ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
162562306a36Sopenharmony_ci		  struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
162662306a36Sopenharmony_ciint ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
162762306a36Sopenharmony_ci		    struct ip_vs_protocol *pp, int offset,
162862306a36Sopenharmony_ci		    unsigned int hooknum, struct ip_vs_iphdr *iph);
162962306a36Sopenharmony_civoid ip_vs_dest_dst_rcu_free(struct rcu_head *head);
163062306a36Sopenharmony_ci
163162306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6
163262306a36Sopenharmony_ciint ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
163362306a36Sopenharmony_ci			 struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
163462306a36Sopenharmony_ciint ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
163562306a36Sopenharmony_ci		      struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
163662306a36Sopenharmony_ciint ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
163762306a36Sopenharmony_ci			 struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
163862306a36Sopenharmony_ciint ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
163962306a36Sopenharmony_ci		     struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
164062306a36Sopenharmony_ciint ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
164162306a36Sopenharmony_ci		       struct ip_vs_protocol *pp, int offset,
164262306a36Sopenharmony_ci		       unsigned int hooknum, struct ip_vs_iphdr *iph);
164362306a36Sopenharmony_ci#endif
164462306a36Sopenharmony_ci
164562306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
164662306a36Sopenharmony_ci/* This is a simple mechanism to ignore packets when
164762306a36Sopenharmony_ci * we are loaded. Just set ip_vs_drop_rate to 'n' and
164862306a36Sopenharmony_ci * we start to drop 1/rate of the packets
164962306a36Sopenharmony_ci */
165062306a36Sopenharmony_cistatic inline int ip_vs_todrop(struct netns_ipvs *ipvs)
165162306a36Sopenharmony_ci{
165262306a36Sopenharmony_ci	if (!ipvs->drop_rate)
165362306a36Sopenharmony_ci		return 0;
165462306a36Sopenharmony_ci	if (--ipvs->drop_counter > 0)
165562306a36Sopenharmony_ci		return 0;
165662306a36Sopenharmony_ci	ipvs->drop_counter = ipvs->drop_rate;
165762306a36Sopenharmony_ci	return 1;
165862306a36Sopenharmony_ci}
165962306a36Sopenharmony_ci#else
166062306a36Sopenharmony_cistatic inline int ip_vs_todrop(struct netns_ipvs *ipvs) { return 0; }
166162306a36Sopenharmony_ci#endif
166262306a36Sopenharmony_ci
166362306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
166462306a36Sopenharmony_ci/* Enqueue delayed work for expiring no dest connections
166562306a36Sopenharmony_ci * Only run when sysctl_expire_nodest=1
166662306a36Sopenharmony_ci */
166762306a36Sopenharmony_cistatic inline void ip_vs_enqueue_expire_nodest_conns(struct netns_ipvs *ipvs)
166862306a36Sopenharmony_ci{
166962306a36Sopenharmony_ci	if (sysctl_expire_nodest_conn(ipvs))
167062306a36Sopenharmony_ci		queue_delayed_work(system_long_wq,
167162306a36Sopenharmony_ci				   &ipvs->expire_nodest_conn_work, 1);
167262306a36Sopenharmony_ci}
167362306a36Sopenharmony_ci
167462306a36Sopenharmony_civoid ip_vs_expire_nodest_conn_flush(struct netns_ipvs *ipvs);
167562306a36Sopenharmony_ci#else
167662306a36Sopenharmony_cistatic inline void ip_vs_enqueue_expire_nodest_conns(struct netns_ipvs *ipvs) {}
167762306a36Sopenharmony_ci#endif
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_ci#define IP_VS_DFWD_METHOD(dest) (atomic_read(&(dest)->conn_flags) & \
168062306a36Sopenharmony_ci				 IP_VS_CONN_F_FWD_MASK)
168162306a36Sopenharmony_ci
168262306a36Sopenharmony_ci/* ip_vs_fwd_tag returns the forwarding tag of the connection */
168362306a36Sopenharmony_ci#define IP_VS_FWD_METHOD(cp)  (cp->flags & IP_VS_CONN_F_FWD_MASK)
168462306a36Sopenharmony_ci
168562306a36Sopenharmony_cistatic inline char ip_vs_fwd_tag(struct ip_vs_conn *cp)
168662306a36Sopenharmony_ci{
168762306a36Sopenharmony_ci	char fwd;
168862306a36Sopenharmony_ci
168962306a36Sopenharmony_ci	switch (IP_VS_FWD_METHOD(cp)) {
169062306a36Sopenharmony_ci	case IP_VS_CONN_F_MASQ:
169162306a36Sopenharmony_ci		fwd = 'M'; break;
169262306a36Sopenharmony_ci	case IP_VS_CONN_F_LOCALNODE:
169362306a36Sopenharmony_ci		fwd = 'L'; break;
169462306a36Sopenharmony_ci	case IP_VS_CONN_F_TUNNEL:
169562306a36Sopenharmony_ci		fwd = 'T'; break;
169662306a36Sopenharmony_ci	case IP_VS_CONN_F_DROUTE:
169762306a36Sopenharmony_ci		fwd = 'R'; break;
169862306a36Sopenharmony_ci	case IP_VS_CONN_F_BYPASS:
169962306a36Sopenharmony_ci		fwd = 'B'; break;
170062306a36Sopenharmony_ci	default:
170162306a36Sopenharmony_ci		fwd = '?'; break;
170262306a36Sopenharmony_ci	}
170362306a36Sopenharmony_ci	return fwd;
170462306a36Sopenharmony_ci}
170562306a36Sopenharmony_ci
170662306a36Sopenharmony_civoid ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
170762306a36Sopenharmony_ci		    struct ip_vs_conn *cp, int dir);
170862306a36Sopenharmony_ci
170962306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6
171062306a36Sopenharmony_civoid ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
171162306a36Sopenharmony_ci		       struct ip_vs_conn *cp, int dir);
171262306a36Sopenharmony_ci#endif
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ci__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset);
171562306a36Sopenharmony_ci
171662306a36Sopenharmony_cistatic inline __wsum ip_vs_check_diff4(__be32 old, __be32 new, __wsum oldsum)
171762306a36Sopenharmony_ci{
171862306a36Sopenharmony_ci	__be32 diff[2] = { ~old, new };
171962306a36Sopenharmony_ci
172062306a36Sopenharmony_ci	return csum_partial(diff, sizeof(diff), oldsum);
172162306a36Sopenharmony_ci}
172262306a36Sopenharmony_ci
172362306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6
172462306a36Sopenharmony_cistatic inline __wsum ip_vs_check_diff16(const __be32 *old, const __be32 *new,
172562306a36Sopenharmony_ci					__wsum oldsum)
172662306a36Sopenharmony_ci{
172762306a36Sopenharmony_ci	__be32 diff[8] = { ~old[3], ~old[2], ~old[1], ~old[0],
172862306a36Sopenharmony_ci			    new[3],  new[2],  new[1],  new[0] };
172962306a36Sopenharmony_ci
173062306a36Sopenharmony_ci	return csum_partial(diff, sizeof(diff), oldsum);
173162306a36Sopenharmony_ci}
173262306a36Sopenharmony_ci#endif
173362306a36Sopenharmony_ci
173462306a36Sopenharmony_cistatic inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
173562306a36Sopenharmony_ci{
173662306a36Sopenharmony_ci	__be16 diff[2] = { ~old, new };
173762306a36Sopenharmony_ci
173862306a36Sopenharmony_ci	return csum_partial(diff, sizeof(diff), oldsum);
173962306a36Sopenharmony_ci}
174062306a36Sopenharmony_ci
174162306a36Sopenharmony_ci/* Forget current conntrack (unconfirmed) and attach notrack entry */
174262306a36Sopenharmony_cistatic inline void ip_vs_notrack(struct sk_buff *skb)
174362306a36Sopenharmony_ci{
174462306a36Sopenharmony_ci#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
174562306a36Sopenharmony_ci	enum ip_conntrack_info ctinfo;
174662306a36Sopenharmony_ci	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
174762306a36Sopenharmony_ci
174862306a36Sopenharmony_ci	if (ct) {
174962306a36Sopenharmony_ci		nf_conntrack_put(&ct->ct_general);
175062306a36Sopenharmony_ci		nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
175162306a36Sopenharmony_ci	}
175262306a36Sopenharmony_ci#endif
175362306a36Sopenharmony_ci}
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_NFCT
175662306a36Sopenharmony_ci/* Netfilter connection tracking
175762306a36Sopenharmony_ci * (from ip_vs_nfct.c)
175862306a36Sopenharmony_ci */
175962306a36Sopenharmony_cistatic inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs)
176062306a36Sopenharmony_ci{
176162306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
176262306a36Sopenharmony_ci	return ipvs->sysctl_conntrack;
176362306a36Sopenharmony_ci#else
176462306a36Sopenharmony_ci	return 0;
176562306a36Sopenharmony_ci#endif
176662306a36Sopenharmony_ci}
176762306a36Sopenharmony_ci
176862306a36Sopenharmony_civoid ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,
176962306a36Sopenharmony_ci			    int outin);
177062306a36Sopenharmony_ciint ip_vs_confirm_conntrack(struct sk_buff *skb);
177162306a36Sopenharmony_civoid ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
177262306a36Sopenharmony_ci			       struct ip_vs_conn *cp, u_int8_t proto,
177362306a36Sopenharmony_ci			       const __be16 port, int from_rs);
177462306a36Sopenharmony_civoid ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp);
177562306a36Sopenharmony_ci
177662306a36Sopenharmony_ci#else
177762306a36Sopenharmony_ci
177862306a36Sopenharmony_cistatic inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs)
177962306a36Sopenharmony_ci{
178062306a36Sopenharmony_ci	return 0;
178162306a36Sopenharmony_ci}
178262306a36Sopenharmony_ci
178362306a36Sopenharmony_cistatic inline void ip_vs_update_conntrack(struct sk_buff *skb,
178462306a36Sopenharmony_ci					  struct ip_vs_conn *cp, int outin)
178562306a36Sopenharmony_ci{
178662306a36Sopenharmony_ci}
178762306a36Sopenharmony_ci
178862306a36Sopenharmony_cistatic inline int ip_vs_confirm_conntrack(struct sk_buff *skb)
178962306a36Sopenharmony_ci{
179062306a36Sopenharmony_ci	return NF_ACCEPT;
179162306a36Sopenharmony_ci}
179262306a36Sopenharmony_ci
179362306a36Sopenharmony_cistatic inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp)
179462306a36Sopenharmony_ci{
179562306a36Sopenharmony_ci}
179662306a36Sopenharmony_ci#endif /* CONFIG_IP_VS_NFCT */
179762306a36Sopenharmony_ci
179862306a36Sopenharmony_ci/* Using old conntrack that can not be redirected to another real server? */
179962306a36Sopenharmony_cistatic inline bool ip_vs_conn_uses_old_conntrack(struct ip_vs_conn *cp,
180062306a36Sopenharmony_ci						 struct sk_buff *skb)
180162306a36Sopenharmony_ci{
180262306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_NFCT
180362306a36Sopenharmony_ci	enum ip_conntrack_info ctinfo;
180462306a36Sopenharmony_ci	struct nf_conn *ct;
180562306a36Sopenharmony_ci
180662306a36Sopenharmony_ci	ct = nf_ct_get(skb, &ctinfo);
180762306a36Sopenharmony_ci	if (ct && nf_ct_is_confirmed(ct))
180862306a36Sopenharmony_ci		return true;
180962306a36Sopenharmony_ci#endif
181062306a36Sopenharmony_ci	return false;
181162306a36Sopenharmony_ci}
181262306a36Sopenharmony_ci
181362306a36Sopenharmony_cistatic inline int ip_vs_register_conntrack(struct ip_vs_service *svc)
181462306a36Sopenharmony_ci{
181562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NF_CONNTRACK)
181662306a36Sopenharmony_ci	int afmask = (svc->af == AF_INET6) ? 2 : 1;
181762306a36Sopenharmony_ci	int ret = 0;
181862306a36Sopenharmony_ci
181962306a36Sopenharmony_ci	if (!(svc->conntrack_afmask & afmask)) {
182062306a36Sopenharmony_ci		ret = nf_ct_netns_get(svc->ipvs->net, svc->af);
182162306a36Sopenharmony_ci		if (ret >= 0)
182262306a36Sopenharmony_ci			svc->conntrack_afmask |= afmask;
182362306a36Sopenharmony_ci	}
182462306a36Sopenharmony_ci	return ret;
182562306a36Sopenharmony_ci#else
182662306a36Sopenharmony_ci	return 0;
182762306a36Sopenharmony_ci#endif
182862306a36Sopenharmony_ci}
182962306a36Sopenharmony_ci
183062306a36Sopenharmony_cistatic inline void ip_vs_unregister_conntrack(struct ip_vs_service *svc)
183162306a36Sopenharmony_ci{
183262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NF_CONNTRACK)
183362306a36Sopenharmony_ci	int afmask = (svc->af == AF_INET6) ? 2 : 1;
183462306a36Sopenharmony_ci
183562306a36Sopenharmony_ci	if (svc->conntrack_afmask & afmask) {
183662306a36Sopenharmony_ci		nf_ct_netns_put(svc->ipvs->net, svc->af);
183762306a36Sopenharmony_ci		svc->conntrack_afmask &= ~afmask;
183862306a36Sopenharmony_ci	}
183962306a36Sopenharmony_ci#endif
184062306a36Sopenharmony_ci}
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ciint ip_vs_register_hooks(struct netns_ipvs *ipvs, unsigned int af);
184362306a36Sopenharmony_civoid ip_vs_unregister_hooks(struct netns_ipvs *ipvs, unsigned int af);
184462306a36Sopenharmony_ci
184562306a36Sopenharmony_cistatic inline int
184662306a36Sopenharmony_ciip_vs_dest_conn_overhead(struct ip_vs_dest *dest)
184762306a36Sopenharmony_ci{
184862306a36Sopenharmony_ci	/* We think the overhead of processing active connections is 256
184962306a36Sopenharmony_ci	 * times higher than that of inactive connections in average. (This
185062306a36Sopenharmony_ci	 * 256 times might not be accurate, we will change it later) We
185162306a36Sopenharmony_ci	 * use the following formula to estimate the overhead now:
185262306a36Sopenharmony_ci	 *		  dest->activeconns*256 + dest->inactconns
185362306a36Sopenharmony_ci	 */
185462306a36Sopenharmony_ci	return (atomic_read(&dest->activeconns) << 8) +
185562306a36Sopenharmony_ci		atomic_read(&dest->inactconns);
185662306a36Sopenharmony_ci}
185762306a36Sopenharmony_ci
185862306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_PROTO_TCP
185962306a36Sopenharmony_ciINDIRECT_CALLABLE_DECLARE(int
186062306a36Sopenharmony_ci	tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
186162306a36Sopenharmony_ci			 struct ip_vs_conn *cp, struct ip_vs_iphdr *iph));
186262306a36Sopenharmony_ci#endif
186362306a36Sopenharmony_ci
186462306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_PROTO_UDP
186562306a36Sopenharmony_ciINDIRECT_CALLABLE_DECLARE(int
186662306a36Sopenharmony_ci	udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
186762306a36Sopenharmony_ci			 struct ip_vs_conn *cp, struct ip_vs_iphdr *iph));
186862306a36Sopenharmony_ci#endif
186962306a36Sopenharmony_ci#endif	/* _NET_IP_VS_H */
1870