942 lines · 27.7 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>#include <linux/netfilter.h>		/* for union nf_inet_addr */#include <linux/ip.h>#include <linux/ipv6.h>			/* for struct ipv6hdr */#include <net/ipv6.h>			/* for ipv6_addr_copy */ struct ip_vs_iphdr {	int len;	__u8 protocol;	union nf_inet_addr saddr;	union nf_inet_addr daddr;}; static inline voidip_vs_fill_iphdr(int af, const void *nh, struct ip_vs_iphdr *iphdr){#ifdef CONFIG_IP_VS_IPV6	if (af == AF_INET6) {		const struct ipv6hdr *iph = nh;		iphdr->len = sizeof(struct ipv6hdr);		iphdr->protocol = iph->nexthdr;		ipv6_addr_copy(&iphdr->saddr.in6, &iph->saddr);		ipv6_addr_copy(&iphdr->daddr.in6, &iph->daddr);	} else#endif	{		const struct iphdr *iph = nh;		iphdr->len = iph->ihl * 4;		iphdr->protocol = iph->protocol;		iphdr->saddr.ip = iph->saddr;		iphdr->daddr.ip = iph->daddr;	}} static inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst,				   const union nf_inet_addr *src){#ifdef CONFIG_IP_VS_IPV6	if (af == AF_INET6)		ipv6_addr_copy(&dst->in6, &src->in6);	else#endif	dst->ip = src->ip;} 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_IPV6	if (af == AF_INET6)		return ipv6_addr_equal(&a->in6, &b->in6);#endif	return a->ip == b->ip;} #ifdef CONFIG_IP_VS_DEBUG#include <linux/net.h> extern 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){	int len;#ifdef CONFIG_IP_VS_IPV6	if (af == AF_INET6)		len = snprintf(&buf[*idx], buf_len - *idx, "[" NIP6_FMT "]",			       NIP6(addr->in6)) + 1;	else#endif		len = snprintf(&buf[*idx], buf_len - *idx, NIPQUAD_FMT,			       NIPQUAD(addr->ip)) + 1; 	*idx += len;	BUG_ON(*idx > buf_len + 1);	return &buf[*idx - len];} #define IP_VS_DBG_BUF(level, msg...)			\    do {						\	    char ip_vs_dbg_buf[160];			\	    int ip_vs_dbg_idx = 0;			\	    if (level <= ip_vs_get_debug_level())	\		    printk(KERN_DEBUG "IPVS: " msg);	\    } while (0)#define IP_VS_ERR_BUF(msg...)				\    do {						\	    char ip_vs_dbg_buf[160];			\	    int ip_vs_dbg_idx = 0;			\	    printk(KERN_ERR "IPVS: " msg);		\    } while (0) /* Only use from within IP_VS_DBG_BUF() or IP_VS_ERR_BUF macros */#define IP_VS_DBG_ADDR(af, addr)			\    ip_vs_dbg_addr(af, ip_vs_dbg_buf,			\		   sizeof(ip_vs_dbg_buf), addr,		\		   &ip_vs_dbg_idx) #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_BUF(level, msg...)  do {} while (0)#define IP_VS_ERR_BUF(msg...)  do {} while (0)#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",	\			   __func__, __FILE__, __LINE__);		\    } while (0)#define LeaveFunction(level)                                            \    do {                                                                \	    if (level <= ip_vs_get_debug_level())                       \			printk(KERN_DEBUG "Leave: %s, %s line %i\n",    \			       __func__, __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{	struct ip_vs_stats_user	ustats;         /* statistics */	struct ip_vs_estimator	est;		/* estimator */ 	spinlock_t              lock;           /* spin lock */}; 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)(int af, struct sk_buff *skb,			     struct ip_vs_protocol *pp,			     int *verdict, struct ip_vs_conn **cpp); 	struct ip_vs_conn *	(*conn_in_get)(int af,		       const struct sk_buff *skb,		       struct ip_vs_protocol *pp,		       const struct ip_vs_iphdr *iph,		       unsigned int proto_off,		       int inverse); 	struct ip_vs_conn *	(*conn_out_get)(int af,			const struct sk_buff *skb,			struct ip_vs_protocol *pp,			const struct ip_vs_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)(int af, 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 */	u16                      af;		/* address family */	union nf_inet_addr       caddr;          /* client address */	union nf_inet_addr       vaddr;          /* virtual address */	union nf_inet_addr       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 */};  /* *	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 {	/* virtual service addresses */	u16			af;	u16			protocol;	union nf_inet_addr	addr;		/* virtual ip address */	u16			port;	u32			fwmark;		/* firwall mark of service */ 	/* virtual service options */	char			*sched_name;	unsigned		flags;		/* virtual service flags */	unsigned		timeout;	/* persistent timeout in sec */	u32			netmask;	/* persistent netmask */};  struct ip_vs_dest_user_kern {	/* destination server address */	union nf_inet_addr	addr;	u16			port; 	/* real server options */	unsigned		conn_flags;	/* connection flags */	int			weight;		/* destination weight */ 	/* thresholds for active connections */	u32			u_threshold;	/* upper threshold */	u32			l_threshold;	/* lower threshold */};  /* *	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			af;       /* address family */	__u16			protocol; /* which protocol (TCP/UDP) */	union nf_inet_addr	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 */ 	u16			af;		/* address family */	union nf_inet_addr	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) */	union nf_inet_addr	vaddr;		/* virtual IP address */	__be16			vport;		/* virtual port number */	__u32			vfwmark;	/* firewall mark of service */};  /* *	The scheduler object */

Lines 1–500 of 942.