linux/include/net/ip_vs.h

/* SPDX-License-Identifier: GPL-2.0 */
/* IP Virtual Server
 * data structure and functionality definitions
 */

#ifndef _NET_IP_VS_H
#define _NET_IP_VS_H

#include <linux/ip_vs.h>                /* definitions shared with userland */

#include <asm/types.h>                  /* for __uXX types */

#include <linux/list.h>                 /* for struct list_head */
#include <linux/spinlock.h>             /* for struct rwlock_t */
#include <linux/atomic.h>               /* for struct atomic_t */
#include <linux/refcount.h>             /* for struct refcount_t */
#include <linux/workqueue.h>

#include <linux/compiler.h>
#include <linux/timer.h>
#include <linux/bug.h>

#include <net/checksum.h>
#include <linux/netfilter.h>		/* for union nf_inet_addr */
#include <linux/ip.h>
#include <linux/ipv6.h>			/* for struct ipv6hdr */
#include <net/ipv6.h>
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <net/netfilter/nf_conntrack.h>
#endif
#include <net/net_namespace.h>		/* Netw namespace */
#include <linux/sched/isolation.h>

#define IP_VS_HDR_INVERSE
#define IP_VS_HDR_ICMP

/* Generic access of ipvs struct */
static inline struct netns_ipvs *net_ipvs(struct net* net)
{}

/* Connections' size value needed by ip_vs_ctl.c */
extern int ip_vs_conn_tab_size;

extern struct mutex __ip_vs_mutex;

struct ip_vs_iphdr {};

static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
				      int len, void *buffer)
{}

/* This function handles filling *ip_vs_iphdr, both for IPv4 and IPv6.
 * IPv6 requires some extra work, as finding proper header position,
 * depend on the IPv6 extension headers.
 */
static inline int
ip_vs_fill_iph_skb_off(int af, const struct sk_buff *skb, int offset,
		       int hdr_flags, struct ip_vs_iphdr *iphdr)
{}

static inline int
ip_vs_fill_iph_skb_icmp(int af, const struct sk_buff *skb, int offset,
			bool inverse, struct ip_vs_iphdr *iphdr)
{}

static inline int
ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, bool inverse,
		   struct ip_vs_iphdr *iphdr)
{}

static inline bool
ip_vs_iph_inverse(const struct ip_vs_iphdr *iph)
{}

static inline bool
ip_vs_iph_icmp(const struct ip_vs_iphdr *iph)
{}

static inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst,
				   const union nf_inet_addr *src)
{}

static inline void ip_vs_addr_set(int af, union nf_inet_addr *dst,
				  const union nf_inet_addr *src)
{}

static inline int ip_vs_addr_equal(int af, const union nf_inet_addr *a,
				   const union nf_inet_addr *b)
{}

#ifdef CONFIG_IP_VS_DEBUG
#include <linux/net.h>

int ip_vs_get_debug_level(void);

static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
					 const union nf_inet_addr *addr,
					 int *idx)
{}

#define IP_VS_DBG_BUF(level, msg, ...)
#define IP_VS_ERR_BUF(msg...)

/* Only use from within IP_VS_DBG_BUF() or IP_VS_ERR_BUF macros */
#define IP_VS_DBG_ADDR(af, addr)

#define IP_VS_DBG(level, msg, ...)
#define IP_VS_DBG_RL(msg, ...)
#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg)
#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg)
#else	/* NO DEBUGGING at ALL */
#define IP_VS_DBG_BUF
#define IP_VS_ERR_BUF
#define IP_VS_DBG
#define IP_VS_DBG_RL
#define IP_VS_DBG_PKT
#define IP_VS_DBG_RL_PKT
#endif

#define IP_VS_BUG()
#define IP_VS_ERR_RL(msg, ...)

/* The port number of FTP service (in network order). */
#define FTPPORT
#define FTPDATA

/* TCP State Values */
enum {};

/* UDP State Values */
enum {};

/* ICMP State Values */
enum {};

/* SCTP State Values */
enum ip_vs_sctp_states {};

/* Connection templates use bits from state */
#define IP_VS_CTPL_S_NONE
#define IP_VS_CTPL_S_ASSURED
#define IP_VS_CTPL_S_LAST

/* Delta sequence info structure
 * Each ip_vs_conn has 2 (output AND input seq. changes).
 * Only used in the VS/NAT.
 */
struct ip_vs_seq {};

/* counters per cpu */
struct ip_vs_counters {};
/* Stats per cpu */
struct ip_vs_cpu_stats {};

/* Default nice for estimator kthreads */
#define IPVS_EST_NICE

/* IPVS statistics objects */
struct ip_vs_estimator {};

/*
 * IPVS statistics object, 64-bit kernel version of struct ip_vs_stats_user
 */
struct ip_vs_kstats {};

struct ip_vs_stats {};

struct ip_vs_stats_rcu {};

int ip_vs_stats_init_alloc(struct ip_vs_stats *s);
struct ip_vs_stats *ip_vs_stats_alloc(void);
void ip_vs_stats_release(struct ip_vs_stats *stats);
void ip_vs_stats_free(struct ip_vs_stats *stats);

/* Process estimators in multiple timer ticks (20/50/100, see ktrow) */
#define IPVS_EST_NTICKS
/* Estimation uses a 2-second period containing ticks (in jiffies) */
#define IPVS_EST_TICK

/* Limit of CPU load per kthread (8 for 12.5%), ratio of CPU capacity (1/C).
 * Value of 4 and above ensures kthreads will take work without exceeding
 * the CPU capacity under different circumstances.
 */
#define IPVS_EST_LOAD_DIVISOR

/* Kthreads should not have work that exceeds the CPU load above 50% */
#define IPVS_EST_CPU_KTHREADS

/* Desired number of chains per timer tick (chain load factor in 100us units),
 * 48=4.8ms of 40ms tick (12% CPU usage):
 * 2 sec * 1000 ms in sec * 10 (100us in ms) / 8 (12.5%) / 50
 */
#define IPVS_EST_CHAIN_FACTOR

/* Compiled number of chains per tick
 * The defines should match cond_resched_rcu
 */
#if defined(CONFIG_DEBUG_ATOMIC_SLEEP) || !defined(CONFIG_PREEMPT_RCU)
#define IPVS_EST_TICK_CHAINS
#else
#define IPVS_EST_TICK_CHAINS
#endif

#if IPVS_EST_NTICKS > 127
#error Too many timer ticks for ktrow
#endif

/* Multiple chains processed in same tick */
struct ip_vs_est_tick_data {};

/* Context for estimation kthread */
struct ip_vs_est_kt_data {};

struct dst_entry;
struct iphdr;
struct ip_vs_conn;
struct ip_vs_app;
struct sk_buff;
struct ip_vs_proto_data;

struct ip_vs_protocol {};

/* protocol data per netns */
struct ip_vs_proto_data {};

struct ip_vs_protocol   *ip_vs_proto_get(unsigned short proto);
struct ip_vs_proto_data *ip_vs_proto_data_get(struct netns_ipvs *ipvs,
					      unsigned short proto);

struct ip_vs_conn_param {};

/* IP_VS structure allocated for each dynamically scheduled connection */
struct ip_vs_conn {};

/* Extended internal versions of struct ip_vs_service_user and ip_vs_dest_user
 * for IPv6 support.
 *
 * We need these to conveniently pass around service and destination
 * options, but unfortunately, we also need to keep the old definitions to
 * maintain userspace backwards compatibility for the setsockopt interface.
 */
struct ip_vs_service_user_kern {};


struct ip_vs_dest_user_kern {};


/*
 * The information about the virtual service offered to the net and the
 * forwarding entries.
 */
struct ip_vs_service {};

/* Information for cached dst */
struct ip_vs_dest_dst {};

/* The real server destination forwarding entry with ip address, port number,
 * and so on.
 */
struct ip_vs_dest {};

/* The scheduler object */
struct ip_vs_scheduler {};

/* The persistence engine object */
struct ip_vs_pe {};

/* The application module object (a.k.a. app incarnation) */
struct ip_vs_app {};

struct ipvs_master_sync_state {};

struct ip_vs_sync_thread_data;

/* How much time to keep dests in trash */
#define IP_VS_DEST_TRASH_PERIOD

struct ipvs_sync_daemon_cfg {};

/* IPVS in network namespace */
struct netns_ipvs {};

#define DEFAULT_SYNC_THRESHOLD
#define DEFAULT_SYNC_PERIOD
#define DEFAULT_SYNC_VER
#define DEFAULT_SLOPPY_TCP
#define DEFAULT_SLOPPY_SCTP
#define DEFAULT_SYNC_REFRESH_PERIOD
#define DEFAULT_SYNC_RETRIES
#define IPVS_SYNC_WAKEUP_RATE
#define IPVS_SYNC_QLEN_MAX
#define IPVS_SYNC_SEND_DELAY
#define IPVS_SYNC_CHECK_PERIOD
#define IPVS_SYNC_FLUSH_TIME
#define IPVS_SYNC_PORTS_MAX

#ifdef CONFIG_SYSCTL

static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
{}

static inline int sysctl_sync_period(struct netns_ipvs *ipvs)
{}

static inline unsigned int sysctl_sync_refresh_period(struct netns_ipvs *ipvs)
{}

static inline int sysctl_sync_retries(struct netns_ipvs *ipvs)
{}

static inline int sysctl_sync_ver(struct netns_ipvs *ipvs)
{}

static inline int sysctl_sloppy_tcp(struct netns_ipvs *ipvs)
{}

static inline int sysctl_sloppy_sctp(struct netns_ipvs *ipvs)
{}

static inline int sysctl_sync_ports(struct netns_ipvs *ipvs)
{}

static inline int sysctl_sync_persist_mode(struct netns_ipvs *ipvs)
{}

static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
{}

static inline int sysctl_sync_sock_size(struct netns_ipvs *ipvs)
{}

static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs)
{}

static inline int sysctl_backup_only(struct netns_ipvs *ipvs)
{}

static inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs)
{}

static inline int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs)
{}

static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
{}

static inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs)
{}

static inline int sysctl_cache_bypass(struct netns_ipvs *ipvs)
{}

static inline int sysctl_run_estimation(struct netns_ipvs *ipvs)
{}

static inline const struct cpumask *sysctl_est_cpulist(struct netns_ipvs *ipvs)
{}

static inline int sysctl_est_nice(struct netns_ipvs *ipvs)
{}

#else

static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
{
	return DEFAULT_SYNC_THRESHOLD;
}

static inline int sysctl_sync_period(struct netns_ipvs *ipvs)
{
	return DEFAULT_SYNC_PERIOD;
}

static inline unsigned int sysctl_sync_refresh_period(struct netns_ipvs *ipvs)
{
	return DEFAULT_SYNC_REFRESH_PERIOD;
}

static inline int sysctl_sync_retries(struct netns_ipvs *ipvs)
{
	return DEFAULT_SYNC_RETRIES & 3;
}

static inline int sysctl_sync_ver(struct netns_ipvs *ipvs)
{
	return DEFAULT_SYNC_VER;
}

static inline int sysctl_sloppy_tcp(struct netns_ipvs *ipvs)
{
	return DEFAULT_SLOPPY_TCP;
}

static inline int sysctl_sloppy_sctp(struct netns_ipvs *ipvs)
{
	return DEFAULT_SLOPPY_SCTP;
}

static inline int sysctl_sync_ports(struct netns_ipvs *ipvs)
{
	return 1;
}

static inline int sysctl_sync_persist_mode(struct netns_ipvs *ipvs)
{
	return 0;
}

static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
{
	return IPVS_SYNC_QLEN_MAX;
}

static inline int sysctl_sync_sock_size(struct netns_ipvs *ipvs)
{
	return 0;
}

static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs)
{
	return 1;
}

static inline int sysctl_backup_only(struct netns_ipvs *ipvs)
{
	return 0;
}

static inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs)
{
	return 1;
}

static inline int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs)
{
	return 0;
}

static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
{
	return 0;
}

static inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs)
{
	return 0;
}

static inline int sysctl_cache_bypass(struct netns_ipvs *ipvs)
{
	return 0;
}

static inline int sysctl_run_estimation(struct netns_ipvs *ipvs)
{
	return 1;
}

static inline const struct cpumask *sysctl_est_cpulist(struct netns_ipvs *ipvs)
{
	return housekeeping_cpumask(HK_TYPE_KTHREAD);
}

static inline int sysctl_est_nice(struct netns_ipvs *ipvs)
{
	return IPVS_EST_NICE;
}

#endif

/* IPVS core functions
 * (from ip_vs_core.c)
 */
const char *ip_vs_proto_name(unsigned int proto);
void ip_vs_init_hash_table(struct list_head *table, int rows);
struct ip_vs_conn *ip_vs_new_conn_out(struct ip_vs_service *svc,
				      struct ip_vs_dest *dest,
				      struct sk_buff *skb,
				      const struct ip_vs_iphdr *iph,
				      __be16 dport,
				      __be16 cport);
#define IP_VS_INIT_HASH_TABLE(t)

#define IP_VS_APP_TYPE_FTP

/* ip_vs_conn handling functions
 * (from ip_vs_conn.c)
 */
enum {};

static inline void ip_vs_conn_fill_param(struct netns_ipvs *ipvs, int af, int protocol,
					 const union nf_inet_addr *caddr,
					 __be16 cport,
					 const union nf_inet_addr *vaddr,
					 __be16 vport,
					 struct ip_vs_conn_param *p)
{}

struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p);
struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p);

struct ip_vs_conn * ip_vs_conn_in_get_proto(struct netns_ipvs *ipvs, int af,
					    const struct sk_buff *skb,
					    const struct ip_vs_iphdr *iph);

struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p);

struct ip_vs_conn * ip_vs_conn_out_get_proto(struct netns_ipvs *ipvs, int af,
					     const struct sk_buff *skb,
					     const struct ip_vs_iphdr *iph);

/* Get reference to gain full access to conn.
 * By default, RCU read-side critical sections have access only to
 * conn fields and its PE data, see ip_vs_conn_rcu_free() for reference.
 */
static inline bool __ip_vs_conn_get(struct ip_vs_conn *cp)
{}

/* put back the conn without restarting its timer */
static inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
{}
void ip_vs_conn_put(struct ip_vs_conn *cp);
void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport);

struct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p, int dest_af,
				  const union nf_inet_addr *daddr,
				  __be16 dport, unsigned int flags,
				  struct ip_vs_dest *dest, __u32 fwmark);
void ip_vs_conn_expire_now(struct ip_vs_conn *cp);

const char *ip_vs_state_name(const struct ip_vs_conn *cp);

void ip_vs_tcp_conn_listen(struct ip_vs_conn *cp);
int ip_vs_check_template(struct ip_vs_conn *ct, struct ip_vs_dest *cdest);
void ip_vs_random_dropentry(struct netns_ipvs *ipvs);
int ip_vs_conn_init(void);
void ip_vs_conn_cleanup(void);

static inline void ip_vs_control_del(struct ip_vs_conn *cp)
{}

static inline void
ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp)
{}

/* Mark our template as assured */
static inline void
ip_vs_control_assure_ct(struct ip_vs_conn *cp)
{}

/* IPVS netns init & cleanup functions */
int ip_vs_estimator_net_init(struct netns_ipvs *ipvs);
int ip_vs_control_net_init(struct netns_ipvs *ipvs);
int ip_vs_protocol_net_init(struct netns_ipvs *ipvs);
int ip_vs_app_net_init(struct netns_ipvs *ipvs);
int ip_vs_conn_net_init(struct netns_ipvs *ipvs);
int ip_vs_sync_net_init(struct netns_ipvs *ipvs);
void ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_app_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_control_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_estimator_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_sync_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_service_nets_cleanup(struct list_head *net_list);

/* IPVS application functions
 * (from ip_vs_app.c)
 */
#define IP_VS_APP_MAX_PORTS
struct ip_vs_app *register_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *app);
void unregister_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *app);
int ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
void ip_vs_unbind_app(struct ip_vs_conn *cp);
int register_ip_vs_app_inc(struct netns_ipvs *ipvs, struct ip_vs_app *app, __u16 proto,
			   __u16 port);
int ip_vs_app_inc_get(struct ip_vs_app *inc);
void ip_vs_app_inc_put(struct ip_vs_app *inc);

int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff *skb,
		      struct ip_vs_iphdr *ipvsh);
int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb,
		     struct ip_vs_iphdr *ipvsh);

int register_ip_vs_pe(struct ip_vs_pe *pe);
int unregister_ip_vs_pe(struct ip_vs_pe *pe);
struct ip_vs_pe *ip_vs_pe_getbyname(const char *name);
struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name);

/* Use a #define to avoid all of module.h just for these trivial ops */
#define ip_vs_pe_get(pe)

#define ip_vs_pe_put(pe)

/* IPVS protocol functions (from ip_vs_proto.c) */
int ip_vs_protocol_init(void);
void ip_vs_protocol_cleanup(void);
void ip_vs_protocol_timeout_change(struct netns_ipvs *ipvs, int flags);
int *ip_vs_create_timeout_table(int *table, int size);
void ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
			       const struct sk_buff *skb, int offset,
			       const char *msg);

extern struct ip_vs_protocol ip_vs_protocol_tcp;
extern struct ip_vs_protocol ip_vs_protocol_udp;
extern struct ip_vs_protocol ip_vs_protocol_icmp;
extern struct ip_vs_protocol ip_vs_protocol_esp;
extern struct ip_vs_protocol ip_vs_protocol_ah;
extern struct ip_vs_protocol ip_vs_protocol_sctp;

/* Registering/unregistering scheduler functions
 * (from ip_vs_sched.c)
 */
int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler);
int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler);
int ip_vs_bind_scheduler(struct ip_vs_service *svc,
			 struct ip_vs_scheduler *scheduler);
void ip_vs_unbind_scheduler(struct ip_vs_service *svc,
			    struct ip_vs_scheduler *sched);
struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name);
void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler);
struct ip_vs_conn *
ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
	       struct ip_vs_proto_data *pd, int *ignored,
	       struct ip_vs_iphdr *iph);
int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
		struct ip_vs_proto_data *pd, struct ip_vs_iphdr *iph);

void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg);

/* IPVS control data and functions (from ip_vs_ctl.c) */
extern struct ip_vs_stats ip_vs_stats;
extern int sysctl_ip_vs_sync_ver;

struct ip_vs_service *
ip_vs_service_find(struct netns_ipvs *ipvs, int af, __u32 fwmark, __u16 protocol,
		  const union nf_inet_addr *vaddr, __be16 vport);

bool ip_vs_has_real_service(struct netns_ipvs *ipvs, int af, __u16 protocol,
			    const union nf_inet_addr *daddr, __be16 dport);

struct ip_vs_dest *
ip_vs_find_real_service(struct netns_ipvs *ipvs, int af, __u16 protocol,
			const union nf_inet_addr *daddr, __be16 dport);
struct ip_vs_dest *ip_vs_find_tunnel(struct netns_ipvs *ipvs, int af,
				     const union nf_inet_addr *daddr,
				     __be16 tun_port);

int ip_vs_use_count_inc(void);
void ip_vs_use_count_dec(void);
int ip_vs_register_nl_ioctl(void);
void ip_vs_unregister_nl_ioctl(void);
int ip_vs_control_init(void);
void ip_vs_control_cleanup(void);
struct ip_vs_dest *
ip_vs_find_dest(struct netns_ipvs *ipvs, int svc_af, int dest_af,
		const union nf_inet_addr *daddr, __be16 dport,
		const union nf_inet_addr *vaddr, __be16 vport,
		__u16 protocol, __u32 fwmark, __u32 flags);
void ip_vs_try_bind_dest(struct ip_vs_conn *cp);

static inline void ip_vs_dest_hold(struct ip_vs_dest *dest)
{}

static inline void ip_vs_dest_put(struct ip_vs_dest *dest)
{}

static inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest)
{}

/* IPVS sync daemon data and function prototypes
 * (from ip_vs_sync.c)
 */
int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *cfg,
		      int state);
int stop_sync_thread(struct netns_ipvs *ipvs, int state);
void ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts);

/* IPVS rate estimator prototypes (from ip_vs_est.c) */
int ip_vs_start_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats);
void ip_vs_stop_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats);
void ip_vs_zero_estimator(struct ip_vs_stats *stats);
void ip_vs_read_estimator(struct ip_vs_kstats *dst, struct ip_vs_stats *stats);
void ip_vs_est_reload_start(struct netns_ipvs *ipvs);
int ip_vs_est_kthread_start(struct netns_ipvs *ipvs,
			    struct ip_vs_est_kt_data *kd);
void ip_vs_est_kthread_stop(struct ip_vs_est_kt_data *kd);

static inline void ip_vs_est_stopped_recalc(struct netns_ipvs *ipvs)
{}

static inline bool ip_vs_est_stopped(struct netns_ipvs *ipvs)
{}

static inline int ip_vs_est_max_threads(struct netns_ipvs *ipvs)
{}

/* Various IPVS packet transmitters (from ip_vs_xmit.c) */
int ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
		    struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
int ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
		      struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
int ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
		   struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
int ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
		      struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
int ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
		  struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
int ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
		    struct ip_vs_protocol *pp, int offset,
		    unsigned int hooknum, struct ip_vs_iphdr *iph);
void ip_vs_dest_dst_rcu_free(struct rcu_head *head);

#ifdef CONFIG_IP_VS_IPV6
int ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
			 struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
int ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
		      struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
int ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
			 struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
int ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
		     struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
int ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
		       struct ip_vs_protocol *pp, int offset,
		       unsigned int hooknum, struct ip_vs_iphdr *iph);
#endif

#ifdef CONFIG_SYSCTL
/* This is a simple mechanism to ignore packets when
 * we are loaded. Just set ip_vs_drop_rate to 'n' and
 * we start to drop 1/rate of the packets
 */
static inline int ip_vs_todrop(struct netns_ipvs *ipvs)
{}
#else
static inline int ip_vs_todrop(struct netns_ipvs *ipvs) { return 0; }
#endif

#ifdef CONFIG_SYSCTL
/* Enqueue delayed work for expiring no dest connections
 * Only run when sysctl_expire_nodest=1
 */
static inline void ip_vs_enqueue_expire_nodest_conns(struct netns_ipvs *ipvs)
{}

void ip_vs_expire_nodest_conn_flush(struct netns_ipvs *ipvs);
#else
static inline void ip_vs_enqueue_expire_nodest_conns(struct netns_ipvs *ipvs) {}
#endif

#define IP_VS_DFWD_METHOD(dest)

/* ip_vs_fwd_tag returns the forwarding tag of the connection */
#define IP_VS_FWD_METHOD(cp)

static inline char ip_vs_fwd_tag(struct ip_vs_conn *cp)
{}

void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
		    struct ip_vs_conn *cp, int dir);

#ifdef CONFIG_IP_VS_IPV6
void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
		       struct ip_vs_conn *cp, int dir);
#endif

__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset);

static inline __wsum ip_vs_check_diff4(__be32 old, __be32 new, __wsum oldsum)
{}

#ifdef CONFIG_IP_VS_IPV6
static inline __wsum ip_vs_check_diff16(const __be32 *old, const __be32 *new,
					__wsum oldsum)
{}
#endif

static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
{}

/* Forget current conntrack (unconfirmed) and attach notrack entry */
static inline void ip_vs_notrack(struct sk_buff *skb)
{}

#ifdef CONFIG_IP_VS_NFCT
/* Netfilter connection tracking
 * (from ip_vs_nfct.c)
 */
static inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs)
{}

void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,
			    int outin);
int ip_vs_confirm_conntrack(struct sk_buff *skb);
void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
			       struct ip_vs_conn *cp, u_int8_t proto,
			       const __be16 port, int from_rs);
void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp);

#else

static inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs)
{
	return 0;
}

static inline void ip_vs_update_conntrack(struct sk_buff *skb,
					  struct ip_vs_conn *cp, int outin)
{
}

static inline int ip_vs_confirm_conntrack(struct sk_buff *skb)
{
	return NF_ACCEPT;
}

static inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp)
{
}
#endif /* CONFIG_IP_VS_NFCT */

/* Using old conntrack that can not be redirected to another real server? */
static inline bool ip_vs_conn_uses_old_conntrack(struct ip_vs_conn *cp,
						 struct sk_buff *skb)
{}

static inline int ip_vs_register_conntrack(struct ip_vs_service *svc)
{}

static inline void ip_vs_unregister_conntrack(struct ip_vs_service *svc)
{}

int ip_vs_register_hooks(struct netns_ipvs *ipvs, unsigned int af);
void ip_vs_unregister_hooks(struct netns_ipvs *ipvs, unsigned int af);

static inline int
ip_vs_dest_conn_overhead(struct ip_vs_dest *dest)
{}

#ifdef CONFIG_IP_VS_PROTO_TCP
INDIRECT_CALLABLE_DECLARE();
#endif

#ifdef CONFIG_IP_VS_PROTO_UDP
INDIRECT_CALLABLE_DECLARE();
#endif
#endif	/* _NET_IP_VS_H */