/* * 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, "[%pI6]", &addr->in6) + 1; else#endif len = snprintf(&buf[*idx], buf_len - *idx, "%pI4", &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 pr_fmt(msg), ##__VA_ARGS__); \ } while (0)#define IP_VS_ERR_BUF(msg...) \ do { \ char ip_vs_dbg_buf[160]; \ int ip_vs_dbg_idx = 0; \ pr_err(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 pr_fmt(msg), ##__VA_ARGS__); \ } while (0)#define IP_VS_DBG_RL(msg, ...) \ do { \ if (net_ratelimit()) \ printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__); \ } 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_RL(msg, ...) \ do { \ if (net_ratelimit()) \ pr_err(msg, ##__VA_ARGS__); \ } while (0) #ifdef CONFIG_IP_VS_DEBUG#define EnterFunction(level) \ do { \ if (level <= ip_vs_get_debug_level()) \ printk(KERN_DEBUG \ pr_fmt("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 \ pr_fmt("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 cpu_to_be16(21)#define FTPDATA cpu_to_be16(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 */struct ip_vs_scheduler { struct list_head n_list; /* d-linked list head */Lines 1–500 of 938. Load more
/* * 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 void ip_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, "[%pI6]", &addr->in6) + 1; else #endif len = snprintf(&buf[*idx], buf_len - *idx, "%pI4", &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 pr_fmt(msg), ##__VA_ARGS__); \ } while (0) #define IP_VS_ERR_BUF(msg...) \ do { \ char ip_vs_dbg_buf[160]; \ int ip_vs_dbg_idx = 0; \ pr_err(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 pr_fmt(msg), ##__VA_ARGS__); \ } while (0) #define IP_VS_DBG_RL(msg, ...) \ do { \ if (net_ratelimit()) \ printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__); \ } 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_RL(msg, ...) \ do { \ if (net_ratelimit()) \ pr_err(msg, ##__VA_ARGS__); \ } while (0) #ifdef CONFIG_IP_VS_DEBUG #define EnterFunction(level) \ do { \ if (level <= ip_vs_get_debug_level()) \ printk(KERN_DEBUG \ pr_fmt("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 \ pr_fmt("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 cpu_to_be16(21) #define FTPDATA cpu_to_be16(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 */ struct ip_vs_scheduler { struct list_head n_list; /* d-linked list head */