/* * 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/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 */#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)#include <net/netfilter/nf_conntrack.h>#endif#include <net/net_namespace.h> /* Netw namespace */ /* * Generic access of ipvs struct */static inline struct netns_ipvs *net_ipvs(struct net* net){ return net->ipvs;}/* * Get net ptr from skb in traffic cases * use skb_sknet when call is from userland (ioctl or netlink) */static inline struct net *skb_net(const struct sk_buff *skb){#ifdef CONFIG_NET_NS#ifdef CONFIG_IP_VS_DEBUG /* * This is used for debug only. * Start with the most likely hit * End with BUG */ if (likely(skb->dev && skb->dev->nd_net)) return dev_net(skb->dev); if (skb_dst(skb) && skb_dst(skb)->dev) return dev_net(skb_dst(skb)->dev); WARN(skb->sk, "Maybe skb_sknet should be used in %s() at line:%d\n", __func__, __LINE__); if (likely(skb->sk && skb->sk->sk_net)) return sock_net(skb->sk); pr_err("There is no net ptr to find in the skb in %s() line:%d\n", __func__, __LINE__); BUG();#else return dev_net(skb->dev ? : skb_dst(skb)->dev);#endif#else return &init_net;#endif} static inline struct net *skb_sknet(const struct sk_buff *skb){#ifdef CONFIG_NET_NS#ifdef CONFIG_IP_VS_DEBUG /* Start with the most likely hit */ if (likely(skb->sk && skb->sk->sk_net)) return sock_net(skb->sk); WARN(skb->dev, "Maybe skb_net should be used instead in %s() line:%d\n", __func__, __LINE__); if (likely(skb->dev && skb->dev->nd_net)) return dev_net(skb->dev); pr_err("There is no net ptr to find in the skb in %s() line:%d\n", __func__, __LINE__); BUG();#else return sock_net(skb->sk);#endif#else return &init_net;#endif}/* * This one needed for single_open_net since net is stored directly in * private not as a struct i.e. seq_file_net can't be used. */static inline struct net *seq_file_single_net(struct seq_file *seq){#ifdef CONFIG_NET_NS return (struct net *)seq->private;#else return &init_net;#endif} /* Connections' size value needed by ip_vs_ctl.c */extern int ip_vs_conn_tab_size; 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, af, pp, skb, ofs, msg) \ do { \ if (level <= ip_vs_get_debug_level()) \ pp->debug_packet(af, pp, skb, ofs, msg); \ } while (0)#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) \ do { \ if (level <= ip_vs_get_debug_level() && \ net_ratelimit()) \ pp->debug_packet(af, 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, af, pp, skb, ofs, msg) do {} while (0)#define IP_VS_DBG_RL_PKT(level, af, 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,}; /* * SCTP State Values */enum ip_vs_sctp_states { IP_VS_SCTP_S_NONE, IP_VS_SCTP_S_INIT_CLI, IP_VS_SCTP_S_INIT_SER, IP_VS_SCTP_S_INIT_ACK_CLI, IP_VS_SCTP_S_INIT_ACK_SER, IP_VS_SCTP_S_ECHO_CLI, IP_VS_SCTP_S_ECHO_SER, IP_VS_SCTP_S_ESTABLISHED, IP_VS_SCTP_S_SHUT_CLI, IP_VS_SCTP_S_SHUT_SER, IP_VS_SCTP_S_SHUT_ACK_CLI, IP_VS_SCTP_S_SHUT_ACK_SER, IP_VS_SCTP_S_CLOSED, IP_VS_SCTP_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 */}; /* * counters per cpu */struct ip_vs_counters { __u32 conns; /* connections scheduled */ __u32 inpkts; /* incoming packets */ __u32 outpkts; /* outgoing packets */ __u64 inbytes; /* incoming bytes */ __u64 outbytes; /* outgoing bytes */};/* * Stats per cpu */struct ip_vs_cpu_stats { struct ip_vs_counters ustats; struct u64_stats_sync syncp;}; /* * 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 */ struct ip_vs_cpu_stats *cpustats; /* per cpu counters */ spinlock_t lock; /* spin lock */ struct ip_vs_stats_user ustats0; /* reset values */}; 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 { struct ip_vs_protocol *next; char *name; u16 protocol; u16 num_states; int dont_defrag; void (*init)(struct ip_vs_protocol *pp); void (*exit)(struct ip_vs_protocol *pp); void (*init_netns)(struct net *net, struct ip_vs_proto_data *pd); void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd); int (*conn_schedule)(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, int *verdict, struct ip_vs_conn **cpp); struct ip_vs_conn * (*conn_in_get)(int af, const struct sk_buff *skb, 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, 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_proto_data *pd); int (*register_app)(struct net *net, struct ip_vs_app *inc); void (*unregister_app)(struct net *net, struct ip_vs_app *inc); int (*app_conn_bind)(struct ip_vs_conn *cp); void (*debug_packet)(int af, struct ip_vs_protocol *pp, const struct sk_buff *skb, int offset, const char *msg); void (*timeout_change)(struct ip_vs_proto_data *pd, int flags);}; /* * protocol data per netns */struct ip_vs_proto_data { struct ip_vs_proto_data *next; struct ip_vs_protocol *pp; int *timeout_table; /* protocol timeout table */ atomic_t appcnt; /* counter of proto app incs. */ struct tcp_states_t *tcp_state_table;}; extern struct ip_vs_protocol *ip_vs_proto_get(unsigned short proto);extern struct ip_vs_proto_data *ip_vs_proto_data_get(struct net *net, unsigned short proto); struct ip_vs_conn_param { struct net *net; const union nf_inet_addr *caddr; const union nf_inet_addr *vaddr; __be16 cport; __be16 vport; __u16 protocol; u16 af; const struct ip_vs_pe *pe; char *pe_data; __u8 pe_data_len;}; /* * IP_VS structure allocated for each dynamically scheduled connection */struct ip_vs_conn { struct hlist_node c_list; /* hashed list heads */#ifdef CONFIG_NET_NS struct net *net; /* Name space */#endif /* Protocol, addresses and port numbers */ u16 af; /* address family */ __be16 cport; __be16 vport; __be16 dport; __u32 fwmark; /* Fire wall mark from skb */ union nf_inet_addr caddr; /* client address */ union nf_inet_addr vaddr; /* virtual address */ union nf_inet_addr daddr; /* destination address */ volatile __u32 flags; /* status flags */ __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 */Lines 1–500 of 1432. 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 */ #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 */ #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #include <net/netfilter/nf_conntrack.h> #endif #include <net/net_namespace.h> /* Netw namespace */ /* * Generic access of ipvs struct */ static inline struct netns_ipvs *net_ipvs(struct net* net) { return net->ipvs; } /* * Get net ptr from skb in traffic cases * use skb_sknet when call is from userland (ioctl or netlink) */ static inline struct net *skb_net(const struct sk_buff *skb) { #ifdef CONFIG_NET_NS #ifdef CONFIG_IP_VS_DEBUG /* * This is used for debug only. * Start with the most likely hit * End with BUG */ if (likely(skb->dev && skb->dev->nd_net)) return dev_net(skb->dev); if (skb_dst(skb) && skb_dst(skb)->dev) return dev_net(skb_dst(skb)->dev); WARN(skb->sk, "Maybe skb_sknet should be used in %s() at line:%d\n", __func__, __LINE__); if (likely(skb->sk && skb->sk->sk_net)) return sock_net(skb->sk); pr_err("There is no net ptr to find in the skb in %s() line:%d\n", __func__, __LINE__); BUG(); #else return dev_net(skb->dev ? : skb_dst(skb)->dev); #endif #else return &init_net; #endif } static inline struct net *skb_sknet(const struct sk_buff *skb) { #ifdef CONFIG_NET_NS #ifdef CONFIG_IP_VS_DEBUG /* Start with the most likely hit */ if (likely(skb->sk && skb->sk->sk_net)) return sock_net(skb->sk); WARN(skb->dev, "Maybe skb_net should be used instead in %s() line:%d\n", __func__, __LINE__); if (likely(skb->dev && skb->dev->nd_net)) return dev_net(skb->dev); pr_err("There is no net ptr to find in the skb in %s() line:%d\n", __func__, __LINE__); BUG(); #else return sock_net(skb->sk); #endif #else return &init_net; #endif } /* * This one needed for single_open_net since net is stored directly in * private not as a struct i.e. seq_file_net can't be used. */ static inline struct net *seq_file_single_net(struct seq_file *seq) { #ifdef CONFIG_NET_NS return (struct net *)seq->private; #else return &init_net; #endif } /* Connections' size value needed by ip_vs_ctl.c */ extern int ip_vs_conn_tab_size; 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, af, pp, skb, ofs, msg) \ do { \ if (level <= ip_vs_get_debug_level()) \ pp->debug_packet(af, pp, skb, ofs, msg); \ } while (0) #define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) \ do { \ if (level <= ip_vs_get_debug_level() && \ net_ratelimit()) \ pp->debug_packet(af, 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, af, pp, skb, ofs, msg) do {} while (0) #define IP_VS_DBG_RL_PKT(level, af, 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, }; /* * SCTP State Values */ enum ip_vs_sctp_states { IP_VS_SCTP_S_NONE, IP_VS_SCTP_S_INIT_CLI, IP_VS_SCTP_S_INIT_SER, IP_VS_SCTP_S_INIT_ACK_CLI, IP_VS_SCTP_S_INIT_ACK_SER, IP_VS_SCTP_S_ECHO_CLI, IP_VS_SCTP_S_ECHO_SER, IP_VS_SCTP_S_ESTABLISHED, IP_VS_SCTP_S_SHUT_CLI, IP_VS_SCTP_S_SHUT_SER, IP_VS_SCTP_S_SHUT_ACK_CLI, IP_VS_SCTP_S_SHUT_ACK_SER, IP_VS_SCTP_S_CLOSED, IP_VS_SCTP_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 */ }; /* * counters per cpu */ struct ip_vs_counters { __u32 conns; /* connections scheduled */ __u32 inpkts; /* incoming packets */ __u32 outpkts; /* outgoing packets */ __u64 inbytes; /* incoming bytes */ __u64 outbytes; /* outgoing bytes */ }; /* * Stats per cpu */ struct ip_vs_cpu_stats { struct ip_vs_counters ustats; struct u64_stats_sync syncp; }; /* * 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 */ struct ip_vs_cpu_stats *cpustats; /* per cpu counters */ spinlock_t lock; /* spin lock */ struct ip_vs_stats_user ustats0; /* reset values */ }; 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 { struct ip_vs_protocol *next; char *name; u16 protocol; u16 num_states; int dont_defrag; void (*init)(struct ip_vs_protocol *pp); void (*exit)(struct ip_vs_protocol *pp); void (*init_netns)(struct net *net, struct ip_vs_proto_data *pd); void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd); int (*conn_schedule)(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, int *verdict, struct ip_vs_conn **cpp); struct ip_vs_conn * (*conn_in_get)(int af, const struct sk_buff *skb, 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, 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_proto_data *pd); int (*register_app)(struct net *net, struct ip_vs_app *inc); void (*unregister_app)(struct net *net, struct ip_vs_app *inc); int (*app_conn_bind)(struct ip_vs_conn *cp); void (*debug_packet)(int af, struct ip_vs_protocol *pp, const struct sk_buff *skb, int offset, const char *msg); void (*timeout_change)(struct ip_vs_proto_data *pd, int flags); }; /* * protocol data per netns */ struct ip_vs_proto_data { struct ip_vs_proto_data *next; struct ip_vs_protocol *pp; int *timeout_table; /* protocol timeout table */ atomic_t appcnt; /* counter of proto app incs. */ struct tcp_states_t *tcp_state_table; }; extern struct ip_vs_protocol *ip_vs_proto_get(unsigned short proto); extern struct ip_vs_proto_data *ip_vs_proto_data_get(struct net *net, unsigned short proto); struct ip_vs_conn_param { struct net *net; const union nf_inet_addr *caddr; const union nf_inet_addr *vaddr; __be16 cport; __be16 vport; __u16 protocol; u16 af; const struct ip_vs_pe *pe; char *pe_data; __u8 pe_data_len; }; /* * IP_VS structure allocated for each dynamically scheduled connection */ struct ip_vs_conn { struct hlist_node c_list; /* hashed list heads */ #ifdef CONFIG_NET_NS struct net *net; /* Name space */ #endif /* Protocol, addresses and port numbers */ u16 af; /* address family */ __be16 cport; __be16 vport; __be16 dport; __u32 fwmark; /* Fire wall mark from skb */ union nf_inet_addr caddr; /* client address */ union nf_inet_addr vaddr; /* virtual address */ union nf_inet_addr daddr; /* destination address */ volatile __u32 flags; /* status flags */ __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 */