771 lines · 23.2 KB · C
RawDownload
/* *      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 */ /* old ipvsadm versions still include this file directly */#ifdef __KERNEL__ #include <asm/types.h>                  /* for __uXX types */ #include <linux/sysctl.h>               /* for ctl_path */#include <linux/list.h>                 /* for struct list_head */#include <linux/spinlock.h>             /* for struct rwlock_t */#include <asm/atomic.h>                 /* for struct atomic_t */#include <linux/compiler.h>#include <linux/timer.h> #include <net/checksum.h> #ifdef CONFIG_IP_VS_DEBUG#include <linux/net.h> extern int ip_vs_get_debug_level(void);#define IP_VS_DBG(level, msg...)			\    do {						\	    if (level <= ip_vs_get_debug_level())	\		    printk(KERN_DEBUG "IPVS: " msg);	\    } while (0)#define IP_VS_DBG_RL(msg...)				\    do {						\	    if (net_ratelimit())			\		    printk(KERN_DEBUG "IPVS: " msg);	\    } while (0)#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg)		\    do {						\	    if (level <= ip_vs_get_debug_level())	\		pp->debug_packet(pp, skb, ofs, msg);	\    } while (0)#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg)	\    do {						\	    if (level <= ip_vs_get_debug_level() &&	\		net_ratelimit())			\		pp->debug_packet(pp, skb, ofs, msg);	\    } while (0)#else	/* NO DEBUGGING at ALL */#define IP_VS_DBG(level, msg...)  do {} while (0)#define IP_VS_DBG_RL(msg...)  do {} while (0)#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg)		do {} while (0)#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg)	do {} while (0)#endif #define IP_VS_BUG() BUG()#define IP_VS_ERR(msg...) printk(KERN_ERR "IPVS: " msg)#define IP_VS_INFO(msg...) printk(KERN_INFO "IPVS: " msg)#define IP_VS_WARNING(msg...) \	printk(KERN_WARNING "IPVS: " msg)#define IP_VS_ERR_RL(msg...)				\    do {						\	    if (net_ratelimit())			\		    printk(KERN_ERR "IPVS: " msg);	\    } while (0) #ifdef CONFIG_IP_VS_DEBUG#define EnterFunction(level)						\    do {								\	    if (level <= ip_vs_get_debug_level())			\		    printk(KERN_DEBUG "Enter: %s, %s line %i\n",	\			   __FUNCTION__, __FILE__, __LINE__);		\    } while (0)#define LeaveFunction(level)                                            \    do {                                                                \	    if (level <= ip_vs_get_debug_level())                       \			printk(KERN_DEBUG "Leave: %s, %s line %i\n",    \			       __FUNCTION__, __FILE__, __LINE__);       \    } while (0)#else#define EnterFunction(level)   do {} while (0)#define LeaveFunction(level)   do {} while (0)#endif #define	IP_VS_WAIT_WHILE(expr)	while (expr) { cpu_relax(); }  /* *      The port number of FTP service (in network order). */#define FTPPORT  __constant_htons(21)#define FTPDATA  __constant_htons(20) /* *      TCP State Values */enum {	IP_VS_TCP_S_NONE = 0,	IP_VS_TCP_S_ESTABLISHED,	IP_VS_TCP_S_SYN_SENT,	IP_VS_TCP_S_SYN_RECV,	IP_VS_TCP_S_FIN_WAIT,	IP_VS_TCP_S_TIME_WAIT,	IP_VS_TCP_S_CLOSE,	IP_VS_TCP_S_CLOSE_WAIT,	IP_VS_TCP_S_LAST_ACK,	IP_VS_TCP_S_LISTEN,	IP_VS_TCP_S_SYNACK,	IP_VS_TCP_S_LAST}; /* *	UDP State Values */enum {	IP_VS_UDP_S_NORMAL,	IP_VS_UDP_S_LAST,}; /* *	ICMP State Values */enum {	IP_VS_ICMP_S_NORMAL,	IP_VS_ICMP_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 {	__u32			init_seq;	/* Add delta from this seq */	__u32			delta;		/* Delta in sequence numbers */	__u32			previous_delta;	/* Delta in sequence numbers						   before last resized pkt */};  /* *	IPVS statistics objects */struct ip_vs_estimator {	struct list_head	list; 	u64			last_inbytes;	u64			last_outbytes;	u32			last_conns;	u32			last_inpkts;	u32			last_outpkts; 	u32			cps;	u32			inpps;	u32			outpps;	u32			inbps;	u32			outbps;}; struct ip_vs_stats{	__u32                   conns;          /* connections scheduled */	__u32                   inpkts;         /* incoming packets */	__u32                   outpkts;        /* outgoing packets */	__u64                   inbytes;        /* incoming bytes */	__u64                   outbytes;       /* outgoing bytes */ 	__u32			cps;		/* current connection rate */	__u32			inpps;		/* current in packet rate */	__u32			outpps;		/* current out packet rate */	__u32			inbps;		/* current in byte rate */	__u32			outbps;		/* current out byte rate */ 	/*	 * Don't add anything before the lock, because we use memcpy() to copy	 * the members before the lock to struct ip_vs_stats_user in	 * ip_vs_ctl.c.	 */ 	spinlock_t              lock;           /* spin lock */ 	struct ip_vs_estimator	est;		/* estimator */}; struct dst_entry;struct iphdr;struct ip_vs_conn;struct ip_vs_app;struct sk_buff; struct ip_vs_protocol {	struct ip_vs_protocol	*next;	char			*name;	u16			protocol;	u16			num_states;	int			dont_defrag;	atomic_t		appcnt;		/* counter of proto app incs */	int			*timeout_table;	/* protocol timeout table */ 	void (*init)(struct ip_vs_protocol *pp); 	void (*exit)(struct ip_vs_protocol *pp); 	int (*conn_schedule)(struct sk_buff *skb,			     struct ip_vs_protocol *pp,			     int *verdict, struct ip_vs_conn **cpp); 	struct ip_vs_conn *	(*conn_in_get)(const struct sk_buff *skb,		       struct ip_vs_protocol *pp,		       const struct iphdr *iph,		       unsigned int proto_off,		       int inverse); 	struct ip_vs_conn *	(*conn_out_get)(const struct sk_buff *skb,			struct ip_vs_protocol *pp,			const struct iphdr *iph,			unsigned int proto_off,			int inverse); 	int (*snat_handler)(struct sk_buff *skb,			    struct ip_vs_protocol *pp, struct ip_vs_conn *cp); 	int (*dnat_handler)(struct sk_buff *skb,			    struct ip_vs_protocol *pp, struct ip_vs_conn *cp); 	int (*csum_check)(struct sk_buff *skb, struct ip_vs_protocol *pp); 	const char *(*state_name)(int state); 	int (*state_transition)(struct ip_vs_conn *cp, int direction,				const struct sk_buff *skb,				struct ip_vs_protocol *pp); 	int (*register_app)(struct ip_vs_app *inc); 	void (*unregister_app)(struct ip_vs_app *inc); 	int (*app_conn_bind)(struct ip_vs_conn *cp); 	void (*debug_packet)(struct ip_vs_protocol *pp,			     const struct sk_buff *skb,			     int offset,			     const char *msg); 	void (*timeout_change)(struct ip_vs_protocol *pp, int flags); 	int (*set_state_timeout)(struct ip_vs_protocol *pp, char *sname, int to);}; extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto); /* *	IP_VS structure allocated for each dynamically scheduled connection */struct ip_vs_conn {	struct list_head        c_list;         /* hashed list heads */ 	/* Protocol, addresses and port numbers */	__be32                   caddr;          /* client address */	__be32                   vaddr;          /* virtual address */	__be32                   daddr;          /* destination address */	__be16                   cport;	__be16                   vport;	__be16                   dport;	__u16                   protocol;       /* Which protocol (TCP/UDP) */ 	/* counter and timer */	atomic_t		refcnt;		/* reference count */	struct timer_list	timer;		/* Expiration timer */	volatile unsigned long	timeout;	/* timeout */ 	/* Flags and state transition */	spinlock_t              lock;           /* lock for state transition */	volatile __u16          flags;          /* status flags */	volatile __u16          state;          /* state info */	volatile __u16          old_state;      /* old state, to be used for						 * state transition triggerd						 * synchronization						 */ 	/* Control members */	struct ip_vs_conn       *control;       /* Master control connection */	atomic_t                n_control;      /* Number of controlled ones */	struct ip_vs_dest       *dest;          /* real server */	atomic_t                in_pkts;        /* incoming packet counter */ 	/* packet transmitter for different forwarding methods.  If it	   mangles the packet, it must return NF_DROP or better NF_STOLEN,	   otherwise this must be changed to a sk_buff **.	 */	int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp,			   struct ip_vs_protocol *pp); 	/* Note: we can group the following members into a structure,	   in order to save more space, and the following members are	   only used in VS/NAT anyway */	struct ip_vs_app        *app;           /* bound ip_vs_app object */	void                    *app_data;      /* Application private data */	struct ip_vs_seq        in_seq;         /* incoming seq. struct */	struct ip_vs_seq        out_seq;        /* outgoing seq. struct */};  /* *	The information about the virtual service offered to the net *	and the forwarding entries */struct ip_vs_service {	struct list_head	s_list;   /* for normal service table */	struct list_head	f_list;   /* for fwmark-based service table */	atomic_t		refcnt;   /* reference counter */	atomic_t		usecnt;   /* use counter */ 	__u16			protocol; /* which protocol (TCP/UDP) */	__be32			addr;	  /* IP address for virtual service */	__be16			port;	  /* port number for the service */	__u32                   fwmark;   /* firewall mark of the service */	unsigned		flags;	  /* service status flags */	unsigned		timeout;  /* persistent timeout in ticks */	__be32			netmask;  /* grouping granularity */ 	struct list_head	destinations;  /* real server d-linked list */	__u32			num_dests;     /* number of servers */	struct ip_vs_stats      stats;         /* statistics for the service */	struct ip_vs_app	*inc;	  /* bind conns to this app inc */ 	/* for scheduling */	struct ip_vs_scheduler	*scheduler;    /* bound scheduler object */	rwlock_t		sched_lock;    /* lock sched_data */	void			*sched_data;   /* scheduler application data */};  /* *	The real server destination forwarding entry *	with ip address, port number, and so on. */struct ip_vs_dest {	struct list_head	n_list;   /* for the dests in the service */	struct list_head	d_list;   /* for table with all the dests */ 	__be32			addr;		/* IP address of the server */	__be16			port;		/* port number of the server */	volatile unsigned	flags;		/* dest status flags */	atomic_t		conn_flags;	/* flags to copy to conn */	atomic_t		weight;		/* server weight */ 	atomic_t		refcnt;		/* reference counter */	struct ip_vs_stats      stats;          /* statistics */ 	/* connection counters and thresholds */	atomic_t		activeconns;	/* active connections */	atomic_t		inactconns;	/* inactive connections */	atomic_t		persistconns;	/* persistent connections */	__u32			u_threshold;	/* upper threshold */	__u32			l_threshold;	/* lower threshold */ 	/* for destination cache */	spinlock_t		dst_lock;	/* lock of dst_cache */	struct dst_entry	*dst_cache;	/* destination cache entry */	u32			dst_rtos;	/* RT_TOS(tos) for dst */ 	/* for virtual service */	struct ip_vs_service	*svc;		/* service it belongs to */	__u16			protocol;	/* which protocol (TCP/UDP) */	__be32			vaddr;		/* virtual IP address */	__be16			vport;		/* virtual port number */	__u32			vfwmark;	/* firewall mark of service */};  /* *	The scheduler object */struct ip_vs_scheduler {	struct list_head	n_list;		/* d-linked list head */	char			*name;		/* scheduler name */	atomic_t		refcnt;		/* reference counter */	struct module		*module;	/* THIS_MODULE/NULL */ 	/* scheduler initializing service */	int (*init_service)(struct ip_vs_service *svc);	/* scheduling service finish */	int (*done_service)(struct ip_vs_service *svc);	/* scheduler updating service */	int (*update_service)(struct ip_vs_service *svc); 	/* selecting a server from the given service */	struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc,				       const struct sk_buff *skb);};  /* *	The application module object (a.k.a. app incarnation) */struct ip_vs_app{	struct list_head	a_list;		/* member in app list */	int			type;		/* IP_VS_APP_TYPE_xxx */	char			*name;		/* application module name */	__u16			protocol;	struct module		*module;	/* THIS_MODULE/NULL */	struct list_head	incs_list;	/* list of incarnations */ 	/* members for application incarnations */	struct list_head	p_list;		/* member in proto app list */	struct ip_vs_app	*app;		/* its real application */	__be16			port;		/* port number in net order */	atomic_t		usecnt;		/* usage counter */ 	/* output hook: return false if can't linearize. diff set for TCP.  */	int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *,		       struct sk_buff *, int *diff); 	/* input hook: return false if can't linearize. diff set for TCP. */	int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *,		      struct sk_buff *, int *diff); 	/* ip_vs_app initializer */	int (*init_conn)(struct ip_vs_app *, struct ip_vs_conn *); 	/* ip_vs_app finish */	int (*done_conn)(struct ip_vs_app *, struct ip_vs_conn *);  	/* not used now */	int (*bind_conn)(struct ip_vs_app *, struct ip_vs_conn *,			 struct ip_vs_protocol *); 	void (*unbind_conn)(struct ip_vs_app *, struct ip_vs_conn *); 	int *			timeout_table;	int *			timeouts;	int			timeouts_size; 	int (*conn_schedule)(struct sk_buff *skb, struct ip_vs_app *app,			     int *verdict, struct ip_vs_conn **cpp); 	struct ip_vs_conn *	(*conn_in_get)(const struct sk_buff *skb, struct ip_vs_app *app,		       const struct iphdr *iph, unsigned int proto_off,		       int inverse); 	struct ip_vs_conn *	(*conn_out_get)(const struct sk_buff *skb, struct ip_vs_app *app,			const struct iphdr *iph, unsigned int proto_off,			int inverse); 	int (*state_transition)(struct ip_vs_conn *cp, int direction,				const struct sk_buff *skb,				struct ip_vs_app *app); 	void (*timeout_change)(struct ip_vs_app *app, int flags);};  /* *      IPVS core functions *      (from ip_vs_core.c) */extern const char *ip_vs_proto_name(unsigned proto);extern void ip_vs_init_hash_table(struct list_head *table, int rows);#define IP_VS_INIT_HASH_TABLE(t) ip_vs_init_hash_table((t), ARRAY_SIZE((t))) #define IP_VS_APP_TYPE_FTP	1 /* *     ip_vs_conn handling functions *     (from ip_vs_conn.c) */ /* *     IPVS connection entry hash table */#ifndef CONFIG_IP_VS_TAB_BITS#define CONFIG_IP_VS_TAB_BITS   12#endif/* make sure that IP_VS_CONN_TAB_BITS is located in [8, 20] */#if CONFIG_IP_VS_TAB_BITS < 8#define IP_VS_CONN_TAB_BITS	8#endif#if CONFIG_IP_VS_TAB_BITS > 20#define IP_VS_CONN_TAB_BITS	20#endif#if 8 <= CONFIG_IP_VS_TAB_BITS && CONFIG_IP_VS_TAB_BITS <= 20#define IP_VS_CONN_TAB_BITS	CONFIG_IP_VS_TAB_BITS#endif#define IP_VS_CONN_TAB_SIZE     (1 << IP_VS_CONN_TAB_BITS)#define IP_VS_CONN_TAB_MASK     (IP_VS_CONN_TAB_SIZE - 1) enum {	IP_VS_DIR_INPUT = 0,	IP_VS_DIR_OUTPUT,	IP_VS_DIR_INPUT_ONLY,	IP_VS_DIR_LAST,};

Lines 1–500 of 771.