162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* IP Virtual Server 362306a36Sopenharmony_ci * data structure and functionality definitions 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef _NET_IP_VS_H 762306a36Sopenharmony_ci#define _NET_IP_VS_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/ip_vs.h> /* definitions shared with userland */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <asm/types.h> /* for __uXX types */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/list.h> /* for struct list_head */ 1462306a36Sopenharmony_ci#include <linux/spinlock.h> /* for struct rwlock_t */ 1562306a36Sopenharmony_ci#include <linux/atomic.h> /* for struct atomic_t */ 1662306a36Sopenharmony_ci#include <linux/refcount.h> /* for struct refcount_t */ 1762306a36Sopenharmony_ci#include <linux/workqueue.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include <linux/compiler.h> 2062306a36Sopenharmony_ci#include <linux/timer.h> 2162306a36Sopenharmony_ci#include <linux/bug.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#include <net/checksum.h> 2462306a36Sopenharmony_ci#include <linux/netfilter.h> /* for union nf_inet_addr */ 2562306a36Sopenharmony_ci#include <linux/ip.h> 2662306a36Sopenharmony_ci#include <linux/ipv6.h> /* for struct ipv6hdr */ 2762306a36Sopenharmony_ci#include <net/ipv6.h> 2862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NF_CONNTRACK) 2962306a36Sopenharmony_ci#include <net/netfilter/nf_conntrack.h> 3062306a36Sopenharmony_ci#endif 3162306a36Sopenharmony_ci#include <net/net_namespace.h> /* Netw namespace */ 3262306a36Sopenharmony_ci#include <linux/sched/isolation.h> 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define IP_VS_HDR_INVERSE 1 3562306a36Sopenharmony_ci#define IP_VS_HDR_ICMP 2 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* Generic access of ipvs struct */ 3862306a36Sopenharmony_cistatic inline struct netns_ipvs *net_ipvs(struct net* net) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci return net->ipvs; 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* Connections' size value needed by ip_vs_ctl.c */ 4462306a36Sopenharmony_ciextern int ip_vs_conn_tab_size; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ciextern struct mutex __ip_vs_mutex; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistruct ip_vs_iphdr { 4962306a36Sopenharmony_ci int hdr_flags; /* ipvs flags */ 5062306a36Sopenharmony_ci __u32 off; /* Where IP or IPv4 header starts */ 5162306a36Sopenharmony_ci __u32 len; /* IPv4 simply where L4 starts 5262306a36Sopenharmony_ci * IPv6 where L4 Transport Header starts */ 5362306a36Sopenharmony_ci __u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/ 5462306a36Sopenharmony_ci __s16 protocol; 5562306a36Sopenharmony_ci __s32 flags; 5662306a36Sopenharmony_ci union nf_inet_addr saddr; 5762306a36Sopenharmony_ci union nf_inet_addr daddr; 5862306a36Sopenharmony_ci}; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset, 6162306a36Sopenharmony_ci int len, void *buffer) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci return skb_header_pointer(skb, offset, len, buffer); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* This function handles filling *ip_vs_iphdr, both for IPv4 and IPv6. 6762306a36Sopenharmony_ci * IPv6 requires some extra work, as finding proper header position, 6862306a36Sopenharmony_ci * depend on the IPv6 extension headers. 6962306a36Sopenharmony_ci */ 7062306a36Sopenharmony_cistatic inline int 7162306a36Sopenharmony_ciip_vs_fill_iph_skb_off(int af, const struct sk_buff *skb, int offset, 7262306a36Sopenharmony_ci int hdr_flags, struct ip_vs_iphdr *iphdr) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci iphdr->hdr_flags = hdr_flags; 7562306a36Sopenharmony_ci iphdr->off = offset; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6 7862306a36Sopenharmony_ci if (af == AF_INET6) { 7962306a36Sopenharmony_ci struct ipv6hdr _iph; 8062306a36Sopenharmony_ci const struct ipv6hdr *iph = skb_header_pointer( 8162306a36Sopenharmony_ci skb, offset, sizeof(_iph), &_iph); 8262306a36Sopenharmony_ci if (!iph) 8362306a36Sopenharmony_ci return 0; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci iphdr->saddr.in6 = iph->saddr; 8662306a36Sopenharmony_ci iphdr->daddr.in6 = iph->daddr; 8762306a36Sopenharmony_ci /* ipv6_find_hdr() updates len, flags */ 8862306a36Sopenharmony_ci iphdr->len = offset; 8962306a36Sopenharmony_ci iphdr->flags = 0; 9062306a36Sopenharmony_ci iphdr->protocol = ipv6_find_hdr(skb, &iphdr->len, -1, 9162306a36Sopenharmony_ci &iphdr->fragoffs, 9262306a36Sopenharmony_ci &iphdr->flags); 9362306a36Sopenharmony_ci if (iphdr->protocol < 0) 9462306a36Sopenharmony_ci return 0; 9562306a36Sopenharmony_ci } else 9662306a36Sopenharmony_ci#endif 9762306a36Sopenharmony_ci { 9862306a36Sopenharmony_ci struct iphdr _iph; 9962306a36Sopenharmony_ci const struct iphdr *iph = skb_header_pointer( 10062306a36Sopenharmony_ci skb, offset, sizeof(_iph), &_iph); 10162306a36Sopenharmony_ci if (!iph) 10262306a36Sopenharmony_ci return 0; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci iphdr->len = offset + iph->ihl * 4; 10562306a36Sopenharmony_ci iphdr->fragoffs = 0; 10662306a36Sopenharmony_ci iphdr->protocol = iph->protocol; 10762306a36Sopenharmony_ci iphdr->saddr.ip = iph->saddr; 10862306a36Sopenharmony_ci iphdr->daddr.ip = iph->daddr; 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci return 1; 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic inline int 11562306a36Sopenharmony_ciip_vs_fill_iph_skb_icmp(int af, const struct sk_buff *skb, int offset, 11662306a36Sopenharmony_ci bool inverse, struct ip_vs_iphdr *iphdr) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci int hdr_flags = IP_VS_HDR_ICMP; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci if (inverse) 12162306a36Sopenharmony_ci hdr_flags |= IP_VS_HDR_INVERSE; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci return ip_vs_fill_iph_skb_off(af, skb, offset, hdr_flags, iphdr); 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic inline int 12762306a36Sopenharmony_ciip_vs_fill_iph_skb(int af, const struct sk_buff *skb, bool inverse, 12862306a36Sopenharmony_ci struct ip_vs_iphdr *iphdr) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci int hdr_flags = 0; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci if (inverse) 13362306a36Sopenharmony_ci hdr_flags |= IP_VS_HDR_INVERSE; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci return ip_vs_fill_iph_skb_off(af, skb, skb_network_offset(skb), 13662306a36Sopenharmony_ci hdr_flags, iphdr); 13762306a36Sopenharmony_ci} 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistatic inline bool 14062306a36Sopenharmony_ciip_vs_iph_inverse(const struct ip_vs_iphdr *iph) 14162306a36Sopenharmony_ci{ 14262306a36Sopenharmony_ci return !!(iph->hdr_flags & IP_VS_HDR_INVERSE); 14362306a36Sopenharmony_ci} 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistatic inline bool 14662306a36Sopenharmony_ciip_vs_iph_icmp(const struct ip_vs_iphdr *iph) 14762306a36Sopenharmony_ci{ 14862306a36Sopenharmony_ci return !!(iph->hdr_flags & IP_VS_HDR_ICMP); 14962306a36Sopenharmony_ci} 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cistatic inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst, 15262306a36Sopenharmony_ci const union nf_inet_addr *src) 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6 15562306a36Sopenharmony_ci if (af == AF_INET6) 15662306a36Sopenharmony_ci dst->in6 = src->in6; 15762306a36Sopenharmony_ci else 15862306a36Sopenharmony_ci#endif 15962306a36Sopenharmony_ci dst->ip = src->ip; 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistatic inline void ip_vs_addr_set(int af, union nf_inet_addr *dst, 16362306a36Sopenharmony_ci const union nf_inet_addr *src) 16462306a36Sopenharmony_ci{ 16562306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6 16662306a36Sopenharmony_ci if (af == AF_INET6) { 16762306a36Sopenharmony_ci dst->in6 = src->in6; 16862306a36Sopenharmony_ci return; 16962306a36Sopenharmony_ci } 17062306a36Sopenharmony_ci#endif 17162306a36Sopenharmony_ci dst->ip = src->ip; 17262306a36Sopenharmony_ci dst->all[1] = 0; 17362306a36Sopenharmony_ci dst->all[2] = 0; 17462306a36Sopenharmony_ci dst->all[3] = 0; 17562306a36Sopenharmony_ci} 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistatic inline int ip_vs_addr_equal(int af, const union nf_inet_addr *a, 17862306a36Sopenharmony_ci const union nf_inet_addr *b) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6 18162306a36Sopenharmony_ci if (af == AF_INET6) 18262306a36Sopenharmony_ci return ipv6_addr_equal(&a->in6, &b->in6); 18362306a36Sopenharmony_ci#endif 18462306a36Sopenharmony_ci return a->ip == b->ip; 18562306a36Sopenharmony_ci} 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_DEBUG 18862306a36Sopenharmony_ci#include <linux/net.h> 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ciint ip_vs_get_debug_level(void); 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_cistatic inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len, 19362306a36Sopenharmony_ci const union nf_inet_addr *addr, 19462306a36Sopenharmony_ci int *idx) 19562306a36Sopenharmony_ci{ 19662306a36Sopenharmony_ci int len; 19762306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6 19862306a36Sopenharmony_ci if (af == AF_INET6) 19962306a36Sopenharmony_ci len = snprintf(&buf[*idx], buf_len - *idx, "[%pI6c]", 20062306a36Sopenharmony_ci &addr->in6) + 1; 20162306a36Sopenharmony_ci else 20262306a36Sopenharmony_ci#endif 20362306a36Sopenharmony_ci len = snprintf(&buf[*idx], buf_len - *idx, "%pI4", 20462306a36Sopenharmony_ci &addr->ip) + 1; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci *idx += len; 20762306a36Sopenharmony_ci BUG_ON(*idx > buf_len + 1); 20862306a36Sopenharmony_ci return &buf[*idx - len]; 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci#define IP_VS_DBG_BUF(level, msg, ...) \ 21262306a36Sopenharmony_ci do { \ 21362306a36Sopenharmony_ci char ip_vs_dbg_buf[160]; \ 21462306a36Sopenharmony_ci int ip_vs_dbg_idx = 0; \ 21562306a36Sopenharmony_ci if (level <= ip_vs_get_debug_level()) \ 21662306a36Sopenharmony_ci printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__); \ 21762306a36Sopenharmony_ci } while (0) 21862306a36Sopenharmony_ci#define IP_VS_ERR_BUF(msg...) \ 21962306a36Sopenharmony_ci do { \ 22062306a36Sopenharmony_ci char ip_vs_dbg_buf[160]; \ 22162306a36Sopenharmony_ci int ip_vs_dbg_idx = 0; \ 22262306a36Sopenharmony_ci pr_err(msg); \ 22362306a36Sopenharmony_ci } while (0) 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci/* Only use from within IP_VS_DBG_BUF() or IP_VS_ERR_BUF macros */ 22662306a36Sopenharmony_ci#define IP_VS_DBG_ADDR(af, addr) \ 22762306a36Sopenharmony_ci ip_vs_dbg_addr(af, ip_vs_dbg_buf, \ 22862306a36Sopenharmony_ci sizeof(ip_vs_dbg_buf), addr, \ 22962306a36Sopenharmony_ci &ip_vs_dbg_idx) 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci#define IP_VS_DBG(level, msg, ...) \ 23262306a36Sopenharmony_ci do { \ 23362306a36Sopenharmony_ci if (level <= ip_vs_get_debug_level()) \ 23462306a36Sopenharmony_ci printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__); \ 23562306a36Sopenharmony_ci } while (0) 23662306a36Sopenharmony_ci#define IP_VS_DBG_RL(msg, ...) \ 23762306a36Sopenharmony_ci do { \ 23862306a36Sopenharmony_ci if (net_ratelimit()) \ 23962306a36Sopenharmony_ci printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__); \ 24062306a36Sopenharmony_ci } while (0) 24162306a36Sopenharmony_ci#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg) \ 24262306a36Sopenharmony_ci do { \ 24362306a36Sopenharmony_ci if (level <= ip_vs_get_debug_level()) \ 24462306a36Sopenharmony_ci pp->debug_packet(af, pp, skb, ofs, msg); \ 24562306a36Sopenharmony_ci } while (0) 24662306a36Sopenharmony_ci#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) \ 24762306a36Sopenharmony_ci do { \ 24862306a36Sopenharmony_ci if (level <= ip_vs_get_debug_level() && \ 24962306a36Sopenharmony_ci net_ratelimit()) \ 25062306a36Sopenharmony_ci pp->debug_packet(af, pp, skb, ofs, msg); \ 25162306a36Sopenharmony_ci } while (0) 25262306a36Sopenharmony_ci#else /* NO DEBUGGING at ALL */ 25362306a36Sopenharmony_ci#define IP_VS_DBG_BUF(level, msg...) do {} while (0) 25462306a36Sopenharmony_ci#define IP_VS_ERR_BUF(msg...) do {} while (0) 25562306a36Sopenharmony_ci#define IP_VS_DBG(level, msg...) do {} while (0) 25662306a36Sopenharmony_ci#define IP_VS_DBG_RL(msg...) do {} while (0) 25762306a36Sopenharmony_ci#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg) do {} while (0) 25862306a36Sopenharmony_ci#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) do {} while (0) 25962306a36Sopenharmony_ci#endif 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci#define IP_VS_BUG() BUG() 26262306a36Sopenharmony_ci#define IP_VS_ERR_RL(msg, ...) \ 26362306a36Sopenharmony_ci do { \ 26462306a36Sopenharmony_ci if (net_ratelimit()) \ 26562306a36Sopenharmony_ci pr_err(msg, ##__VA_ARGS__); \ 26662306a36Sopenharmony_ci } while (0) 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci/* The port number of FTP service (in network order). */ 26962306a36Sopenharmony_ci#define FTPPORT cpu_to_be16(21) 27062306a36Sopenharmony_ci#define FTPDATA cpu_to_be16(20) 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci/* TCP State Values */ 27362306a36Sopenharmony_cienum { 27462306a36Sopenharmony_ci IP_VS_TCP_S_NONE = 0, 27562306a36Sopenharmony_ci IP_VS_TCP_S_ESTABLISHED, 27662306a36Sopenharmony_ci IP_VS_TCP_S_SYN_SENT, 27762306a36Sopenharmony_ci IP_VS_TCP_S_SYN_RECV, 27862306a36Sopenharmony_ci IP_VS_TCP_S_FIN_WAIT, 27962306a36Sopenharmony_ci IP_VS_TCP_S_TIME_WAIT, 28062306a36Sopenharmony_ci IP_VS_TCP_S_CLOSE, 28162306a36Sopenharmony_ci IP_VS_TCP_S_CLOSE_WAIT, 28262306a36Sopenharmony_ci IP_VS_TCP_S_LAST_ACK, 28362306a36Sopenharmony_ci IP_VS_TCP_S_LISTEN, 28462306a36Sopenharmony_ci IP_VS_TCP_S_SYNACK, 28562306a36Sopenharmony_ci IP_VS_TCP_S_LAST 28662306a36Sopenharmony_ci}; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci/* UDP State Values */ 28962306a36Sopenharmony_cienum { 29062306a36Sopenharmony_ci IP_VS_UDP_S_NORMAL, 29162306a36Sopenharmony_ci IP_VS_UDP_S_LAST, 29262306a36Sopenharmony_ci}; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci/* ICMP State Values */ 29562306a36Sopenharmony_cienum { 29662306a36Sopenharmony_ci IP_VS_ICMP_S_NORMAL, 29762306a36Sopenharmony_ci IP_VS_ICMP_S_LAST, 29862306a36Sopenharmony_ci}; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci/* SCTP State Values */ 30162306a36Sopenharmony_cienum ip_vs_sctp_states { 30262306a36Sopenharmony_ci IP_VS_SCTP_S_NONE, 30362306a36Sopenharmony_ci IP_VS_SCTP_S_INIT1, 30462306a36Sopenharmony_ci IP_VS_SCTP_S_INIT, 30562306a36Sopenharmony_ci IP_VS_SCTP_S_COOKIE_SENT, 30662306a36Sopenharmony_ci IP_VS_SCTP_S_COOKIE_REPLIED, 30762306a36Sopenharmony_ci IP_VS_SCTP_S_COOKIE_WAIT, 30862306a36Sopenharmony_ci IP_VS_SCTP_S_COOKIE, 30962306a36Sopenharmony_ci IP_VS_SCTP_S_COOKIE_ECHOED, 31062306a36Sopenharmony_ci IP_VS_SCTP_S_ESTABLISHED, 31162306a36Sopenharmony_ci IP_VS_SCTP_S_SHUTDOWN_SENT, 31262306a36Sopenharmony_ci IP_VS_SCTP_S_SHUTDOWN_RECEIVED, 31362306a36Sopenharmony_ci IP_VS_SCTP_S_SHUTDOWN_ACK_SENT, 31462306a36Sopenharmony_ci IP_VS_SCTP_S_REJECTED, 31562306a36Sopenharmony_ci IP_VS_SCTP_S_CLOSED, 31662306a36Sopenharmony_ci IP_VS_SCTP_S_LAST 31762306a36Sopenharmony_ci}; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci/* Connection templates use bits from state */ 32062306a36Sopenharmony_ci#define IP_VS_CTPL_S_NONE 0x0000 32162306a36Sopenharmony_ci#define IP_VS_CTPL_S_ASSURED 0x0001 32262306a36Sopenharmony_ci#define IP_VS_CTPL_S_LAST 0x0002 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci/* Delta sequence info structure 32562306a36Sopenharmony_ci * Each ip_vs_conn has 2 (output AND input seq. changes). 32662306a36Sopenharmony_ci * Only used in the VS/NAT. 32762306a36Sopenharmony_ci */ 32862306a36Sopenharmony_cistruct ip_vs_seq { 32962306a36Sopenharmony_ci __u32 init_seq; /* Add delta from this seq */ 33062306a36Sopenharmony_ci __u32 delta; /* Delta in sequence numbers */ 33162306a36Sopenharmony_ci __u32 previous_delta; /* Delta in sequence numbers 33262306a36Sopenharmony_ci * before last resized pkt */ 33362306a36Sopenharmony_ci}; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci/* counters per cpu */ 33662306a36Sopenharmony_cistruct ip_vs_counters { 33762306a36Sopenharmony_ci u64_stats_t conns; /* connections scheduled */ 33862306a36Sopenharmony_ci u64_stats_t inpkts; /* incoming packets */ 33962306a36Sopenharmony_ci u64_stats_t outpkts; /* outgoing packets */ 34062306a36Sopenharmony_ci u64_stats_t inbytes; /* incoming bytes */ 34162306a36Sopenharmony_ci u64_stats_t outbytes; /* outgoing bytes */ 34262306a36Sopenharmony_ci}; 34362306a36Sopenharmony_ci/* Stats per cpu */ 34462306a36Sopenharmony_cistruct ip_vs_cpu_stats { 34562306a36Sopenharmony_ci struct ip_vs_counters cnt; 34662306a36Sopenharmony_ci struct u64_stats_sync syncp; 34762306a36Sopenharmony_ci}; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci/* Default nice for estimator kthreads */ 35062306a36Sopenharmony_ci#define IPVS_EST_NICE 0 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci/* IPVS statistics objects */ 35362306a36Sopenharmony_cistruct ip_vs_estimator { 35462306a36Sopenharmony_ci struct hlist_node list; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci u64 last_inbytes; 35762306a36Sopenharmony_ci u64 last_outbytes; 35862306a36Sopenharmony_ci u64 last_conns; 35962306a36Sopenharmony_ci u64 last_inpkts; 36062306a36Sopenharmony_ci u64 last_outpkts; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci u64 cps; 36362306a36Sopenharmony_ci u64 inpps; 36462306a36Sopenharmony_ci u64 outpps; 36562306a36Sopenharmony_ci u64 inbps; 36662306a36Sopenharmony_ci u64 outbps; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci s32 ktid:16, /* kthread ID, -1=temp list */ 36962306a36Sopenharmony_ci ktrow:8, /* row/tick ID for kthread */ 37062306a36Sopenharmony_ci ktcid:8; /* chain ID for kthread tick */ 37162306a36Sopenharmony_ci}; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci/* 37462306a36Sopenharmony_ci * IPVS statistics object, 64-bit kernel version of struct ip_vs_stats_user 37562306a36Sopenharmony_ci */ 37662306a36Sopenharmony_cistruct ip_vs_kstats { 37762306a36Sopenharmony_ci u64 conns; /* connections scheduled */ 37862306a36Sopenharmony_ci u64 inpkts; /* incoming packets */ 37962306a36Sopenharmony_ci u64 outpkts; /* outgoing packets */ 38062306a36Sopenharmony_ci u64 inbytes; /* incoming bytes */ 38162306a36Sopenharmony_ci u64 outbytes; /* outgoing bytes */ 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci u64 cps; /* current connection rate */ 38462306a36Sopenharmony_ci u64 inpps; /* current in packet rate */ 38562306a36Sopenharmony_ci u64 outpps; /* current out packet rate */ 38662306a36Sopenharmony_ci u64 inbps; /* current in byte rate */ 38762306a36Sopenharmony_ci u64 outbps; /* current out byte rate */ 38862306a36Sopenharmony_ci}; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_cistruct ip_vs_stats { 39162306a36Sopenharmony_ci struct ip_vs_kstats kstats; /* kernel statistics */ 39262306a36Sopenharmony_ci struct ip_vs_estimator est; /* estimator */ 39362306a36Sopenharmony_ci struct ip_vs_cpu_stats __percpu *cpustats; /* per cpu counters */ 39462306a36Sopenharmony_ci spinlock_t lock; /* spin lock */ 39562306a36Sopenharmony_ci struct ip_vs_kstats kstats0; /* reset values */ 39662306a36Sopenharmony_ci}; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_cistruct ip_vs_stats_rcu { 39962306a36Sopenharmony_ci struct ip_vs_stats s; 40062306a36Sopenharmony_ci struct rcu_head rcu_head; 40162306a36Sopenharmony_ci}; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ciint ip_vs_stats_init_alloc(struct ip_vs_stats *s); 40462306a36Sopenharmony_cistruct ip_vs_stats *ip_vs_stats_alloc(void); 40562306a36Sopenharmony_civoid ip_vs_stats_release(struct ip_vs_stats *stats); 40662306a36Sopenharmony_civoid ip_vs_stats_free(struct ip_vs_stats *stats); 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci/* Process estimators in multiple timer ticks (20/50/100, see ktrow) */ 40962306a36Sopenharmony_ci#define IPVS_EST_NTICKS 50 41062306a36Sopenharmony_ci/* Estimation uses a 2-second period containing ticks (in jiffies) */ 41162306a36Sopenharmony_ci#define IPVS_EST_TICK ((2 * HZ) / IPVS_EST_NTICKS) 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci/* Limit of CPU load per kthread (8 for 12.5%), ratio of CPU capacity (1/C). 41462306a36Sopenharmony_ci * Value of 4 and above ensures kthreads will take work without exceeding 41562306a36Sopenharmony_ci * the CPU capacity under different circumstances. 41662306a36Sopenharmony_ci */ 41762306a36Sopenharmony_ci#define IPVS_EST_LOAD_DIVISOR 8 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci/* Kthreads should not have work that exceeds the CPU load above 50% */ 42062306a36Sopenharmony_ci#define IPVS_EST_CPU_KTHREADS (IPVS_EST_LOAD_DIVISOR / 2) 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci/* Desired number of chains per timer tick (chain load factor in 100us units), 42362306a36Sopenharmony_ci * 48=4.8ms of 40ms tick (12% CPU usage): 42462306a36Sopenharmony_ci * 2 sec * 1000 ms in sec * 10 (100us in ms) / 8 (12.5%) / 50 42562306a36Sopenharmony_ci */ 42662306a36Sopenharmony_ci#define IPVS_EST_CHAIN_FACTOR \ 42762306a36Sopenharmony_ci ALIGN_DOWN(2 * 1000 * 10 / IPVS_EST_LOAD_DIVISOR / IPVS_EST_NTICKS, 8) 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci/* Compiled number of chains per tick 43062306a36Sopenharmony_ci * The defines should match cond_resched_rcu 43162306a36Sopenharmony_ci */ 43262306a36Sopenharmony_ci#if defined(CONFIG_DEBUG_ATOMIC_SLEEP) || !defined(CONFIG_PREEMPT_RCU) 43362306a36Sopenharmony_ci#define IPVS_EST_TICK_CHAINS IPVS_EST_CHAIN_FACTOR 43462306a36Sopenharmony_ci#else 43562306a36Sopenharmony_ci#define IPVS_EST_TICK_CHAINS 1 43662306a36Sopenharmony_ci#endif 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci#if IPVS_EST_NTICKS > 127 43962306a36Sopenharmony_ci#error Too many timer ticks for ktrow 44062306a36Sopenharmony_ci#endif 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci/* Multiple chains processed in same tick */ 44362306a36Sopenharmony_cistruct ip_vs_est_tick_data { 44462306a36Sopenharmony_ci struct rcu_head rcu_head; 44562306a36Sopenharmony_ci struct hlist_head chains[IPVS_EST_TICK_CHAINS]; 44662306a36Sopenharmony_ci DECLARE_BITMAP(present, IPVS_EST_TICK_CHAINS); 44762306a36Sopenharmony_ci DECLARE_BITMAP(full, IPVS_EST_TICK_CHAINS); 44862306a36Sopenharmony_ci int chain_len[IPVS_EST_TICK_CHAINS]; 44962306a36Sopenharmony_ci}; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci/* Context for estimation kthread */ 45262306a36Sopenharmony_cistruct ip_vs_est_kt_data { 45362306a36Sopenharmony_ci struct netns_ipvs *ipvs; 45462306a36Sopenharmony_ci struct task_struct *task; /* task if running */ 45562306a36Sopenharmony_ci struct ip_vs_est_tick_data __rcu *ticks[IPVS_EST_NTICKS]; 45662306a36Sopenharmony_ci DECLARE_BITMAP(avail, IPVS_EST_NTICKS); /* tick has space for ests */ 45762306a36Sopenharmony_ci unsigned long est_timer; /* estimation timer (jiffies) */ 45862306a36Sopenharmony_ci struct ip_vs_stats *calc_stats; /* Used for calculation */ 45962306a36Sopenharmony_ci int tick_len[IPVS_EST_NTICKS]; /* est count */ 46062306a36Sopenharmony_ci int id; /* ktid per netns */ 46162306a36Sopenharmony_ci int chain_max; /* max ests per tick chain */ 46262306a36Sopenharmony_ci int tick_max; /* max ests per tick */ 46362306a36Sopenharmony_ci int est_count; /* attached ests to kthread */ 46462306a36Sopenharmony_ci int est_max_count; /* max ests per kthread */ 46562306a36Sopenharmony_ci int add_row; /* row for new ests */ 46662306a36Sopenharmony_ci int est_row; /* estimated row */ 46762306a36Sopenharmony_ci}; 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_cistruct dst_entry; 47062306a36Sopenharmony_cistruct iphdr; 47162306a36Sopenharmony_cistruct ip_vs_conn; 47262306a36Sopenharmony_cistruct ip_vs_app; 47362306a36Sopenharmony_cistruct sk_buff; 47462306a36Sopenharmony_cistruct ip_vs_proto_data; 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_cistruct ip_vs_protocol { 47762306a36Sopenharmony_ci struct ip_vs_protocol *next; 47862306a36Sopenharmony_ci char *name; 47962306a36Sopenharmony_ci u16 protocol; 48062306a36Sopenharmony_ci u16 num_states; 48162306a36Sopenharmony_ci int dont_defrag; 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci void (*init)(struct ip_vs_protocol *pp); 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci void (*exit)(struct ip_vs_protocol *pp); 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci int (*init_netns)(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd); 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci void (*exit_netns)(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd); 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci int (*conn_schedule)(struct netns_ipvs *ipvs, 49262306a36Sopenharmony_ci int af, struct sk_buff *skb, 49362306a36Sopenharmony_ci struct ip_vs_proto_data *pd, 49462306a36Sopenharmony_ci int *verdict, struct ip_vs_conn **cpp, 49562306a36Sopenharmony_ci struct ip_vs_iphdr *iph); 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci struct ip_vs_conn * 49862306a36Sopenharmony_ci (*conn_in_get)(struct netns_ipvs *ipvs, 49962306a36Sopenharmony_ci int af, 50062306a36Sopenharmony_ci const struct sk_buff *skb, 50162306a36Sopenharmony_ci const struct ip_vs_iphdr *iph); 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci struct ip_vs_conn * 50462306a36Sopenharmony_ci (*conn_out_get)(struct netns_ipvs *ipvs, 50562306a36Sopenharmony_ci int af, 50662306a36Sopenharmony_ci const struct sk_buff *skb, 50762306a36Sopenharmony_ci const struct ip_vs_iphdr *iph); 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci int (*snat_handler)(struct sk_buff *skb, struct ip_vs_protocol *pp, 51062306a36Sopenharmony_ci struct ip_vs_conn *cp, struct ip_vs_iphdr *iph); 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci int (*dnat_handler)(struct sk_buff *skb, struct ip_vs_protocol *pp, 51362306a36Sopenharmony_ci struct ip_vs_conn *cp, struct ip_vs_iphdr *iph); 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci const char *(*state_name)(int state); 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci void (*state_transition)(struct ip_vs_conn *cp, int direction, 51862306a36Sopenharmony_ci const struct sk_buff *skb, 51962306a36Sopenharmony_ci struct ip_vs_proto_data *pd); 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci int (*register_app)(struct netns_ipvs *ipvs, struct ip_vs_app *inc); 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci void (*unregister_app)(struct netns_ipvs *ipvs, struct ip_vs_app *inc); 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci int (*app_conn_bind)(struct ip_vs_conn *cp); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci void (*debug_packet)(int af, struct ip_vs_protocol *pp, 52862306a36Sopenharmony_ci const struct sk_buff *skb, 52962306a36Sopenharmony_ci int offset, 53062306a36Sopenharmony_ci const char *msg); 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci void (*timeout_change)(struct ip_vs_proto_data *pd, int flags); 53362306a36Sopenharmony_ci}; 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci/* protocol data per netns */ 53662306a36Sopenharmony_cistruct ip_vs_proto_data { 53762306a36Sopenharmony_ci struct ip_vs_proto_data *next; 53862306a36Sopenharmony_ci struct ip_vs_protocol *pp; 53962306a36Sopenharmony_ci int *timeout_table; /* protocol timeout table */ 54062306a36Sopenharmony_ci atomic_t appcnt; /* counter of proto app incs. */ 54162306a36Sopenharmony_ci struct tcp_states_t *tcp_state_table; 54262306a36Sopenharmony_ci}; 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_cistruct ip_vs_protocol *ip_vs_proto_get(unsigned short proto); 54562306a36Sopenharmony_cistruct ip_vs_proto_data *ip_vs_proto_data_get(struct netns_ipvs *ipvs, 54662306a36Sopenharmony_ci unsigned short proto); 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_cistruct ip_vs_conn_param { 54962306a36Sopenharmony_ci struct netns_ipvs *ipvs; 55062306a36Sopenharmony_ci const union nf_inet_addr *caddr; 55162306a36Sopenharmony_ci const union nf_inet_addr *vaddr; 55262306a36Sopenharmony_ci __be16 cport; 55362306a36Sopenharmony_ci __be16 vport; 55462306a36Sopenharmony_ci __u16 protocol; 55562306a36Sopenharmony_ci u16 af; 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci const struct ip_vs_pe *pe; 55862306a36Sopenharmony_ci char *pe_data; 55962306a36Sopenharmony_ci __u8 pe_data_len; 56062306a36Sopenharmony_ci}; 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci/* IP_VS structure allocated for each dynamically scheduled connection */ 56362306a36Sopenharmony_cistruct ip_vs_conn { 56462306a36Sopenharmony_ci struct hlist_node c_list; /* hashed list heads */ 56562306a36Sopenharmony_ci /* Protocol, addresses and port numbers */ 56662306a36Sopenharmony_ci __be16 cport; 56762306a36Sopenharmony_ci __be16 dport; 56862306a36Sopenharmony_ci __be16 vport; 56962306a36Sopenharmony_ci u16 af; /* address family */ 57062306a36Sopenharmony_ci union nf_inet_addr caddr; /* client address */ 57162306a36Sopenharmony_ci union nf_inet_addr vaddr; /* virtual address */ 57262306a36Sopenharmony_ci union nf_inet_addr daddr; /* destination address */ 57362306a36Sopenharmony_ci volatile __u32 flags; /* status flags */ 57462306a36Sopenharmony_ci __u16 protocol; /* Which protocol (TCP/UDP) */ 57562306a36Sopenharmony_ci __u16 daf; /* Address family of the dest */ 57662306a36Sopenharmony_ci struct netns_ipvs *ipvs; 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci /* counter and timer */ 57962306a36Sopenharmony_ci refcount_t refcnt; /* reference count */ 58062306a36Sopenharmony_ci struct timer_list timer; /* Expiration timer */ 58162306a36Sopenharmony_ci volatile unsigned long timeout; /* timeout */ 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci /* Flags and state transition */ 58462306a36Sopenharmony_ci spinlock_t lock; /* lock for state transition */ 58562306a36Sopenharmony_ci volatile __u16 state; /* state info */ 58662306a36Sopenharmony_ci volatile __u16 old_state; /* old state, to be used for 58762306a36Sopenharmony_ci * state transition triggered 58862306a36Sopenharmony_ci * synchronization 58962306a36Sopenharmony_ci */ 59062306a36Sopenharmony_ci __u32 fwmark; /* Fire wall mark from skb */ 59162306a36Sopenharmony_ci unsigned long sync_endtime; /* jiffies + sent_retries */ 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci /* Control members */ 59462306a36Sopenharmony_ci struct ip_vs_conn *control; /* Master control connection */ 59562306a36Sopenharmony_ci atomic_t n_control; /* Number of controlled ones */ 59662306a36Sopenharmony_ci struct ip_vs_dest *dest; /* real server */ 59762306a36Sopenharmony_ci atomic_t in_pkts; /* incoming packet counter */ 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci /* Packet transmitter for different forwarding methods. If it 60062306a36Sopenharmony_ci * mangles the packet, it must return NF_DROP or better NF_STOLEN, 60162306a36Sopenharmony_ci * otherwise this must be changed to a sk_buff **. 60262306a36Sopenharmony_ci * NF_ACCEPT can be returned when destination is local. 60362306a36Sopenharmony_ci */ 60462306a36Sopenharmony_ci int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp, 60562306a36Sopenharmony_ci struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci /* Note: we can group the following members into a structure, 60862306a36Sopenharmony_ci * in order to save more space, and the following members are 60962306a36Sopenharmony_ci * only used in VS/NAT anyway 61062306a36Sopenharmony_ci */ 61162306a36Sopenharmony_ci struct ip_vs_app *app; /* bound ip_vs_app object */ 61262306a36Sopenharmony_ci void *app_data; /* Application private data */ 61362306a36Sopenharmony_ci struct_group(sync_conn_opt, 61462306a36Sopenharmony_ci struct ip_vs_seq in_seq; /* incoming seq. struct */ 61562306a36Sopenharmony_ci struct ip_vs_seq out_seq; /* outgoing seq. struct */ 61662306a36Sopenharmony_ci ); 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci const struct ip_vs_pe *pe; 61962306a36Sopenharmony_ci char *pe_data; 62062306a36Sopenharmony_ci __u8 pe_data_len; 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci struct rcu_head rcu_head; 62362306a36Sopenharmony_ci}; 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci/* Extended internal versions of struct ip_vs_service_user and ip_vs_dest_user 62662306a36Sopenharmony_ci * for IPv6 support. 62762306a36Sopenharmony_ci * 62862306a36Sopenharmony_ci * We need these to conveniently pass around service and destination 62962306a36Sopenharmony_ci * options, but unfortunately, we also need to keep the old definitions to 63062306a36Sopenharmony_ci * maintain userspace backwards compatibility for the setsockopt interface. 63162306a36Sopenharmony_ci */ 63262306a36Sopenharmony_cistruct ip_vs_service_user_kern { 63362306a36Sopenharmony_ci /* virtual service addresses */ 63462306a36Sopenharmony_ci u16 af; 63562306a36Sopenharmony_ci u16 protocol; 63662306a36Sopenharmony_ci union nf_inet_addr addr; /* virtual ip address */ 63762306a36Sopenharmony_ci __be16 port; 63862306a36Sopenharmony_ci u32 fwmark; /* firewall mark of service */ 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci /* virtual service options */ 64162306a36Sopenharmony_ci char *sched_name; 64262306a36Sopenharmony_ci char *pe_name; 64362306a36Sopenharmony_ci unsigned int flags; /* virtual service flags */ 64462306a36Sopenharmony_ci unsigned int timeout; /* persistent timeout in sec */ 64562306a36Sopenharmony_ci __be32 netmask; /* persistent netmask or plen */ 64662306a36Sopenharmony_ci}; 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_cistruct ip_vs_dest_user_kern { 65062306a36Sopenharmony_ci /* destination server address */ 65162306a36Sopenharmony_ci union nf_inet_addr addr; 65262306a36Sopenharmony_ci __be16 port; 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci /* real server options */ 65562306a36Sopenharmony_ci unsigned int conn_flags; /* connection flags */ 65662306a36Sopenharmony_ci int weight; /* destination weight */ 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci /* thresholds for active connections */ 65962306a36Sopenharmony_ci u32 u_threshold; /* upper threshold */ 66062306a36Sopenharmony_ci u32 l_threshold; /* lower threshold */ 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci /* Address family of addr */ 66362306a36Sopenharmony_ci u16 af; 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci u16 tun_type; /* tunnel type */ 66662306a36Sopenharmony_ci __be16 tun_port; /* tunnel port */ 66762306a36Sopenharmony_ci u16 tun_flags; /* tunnel flags */ 66862306a36Sopenharmony_ci}; 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci/* 67262306a36Sopenharmony_ci * The information about the virtual service offered to the net and the 67362306a36Sopenharmony_ci * forwarding entries. 67462306a36Sopenharmony_ci */ 67562306a36Sopenharmony_cistruct ip_vs_service { 67662306a36Sopenharmony_ci struct hlist_node s_list; /* for normal service table */ 67762306a36Sopenharmony_ci struct hlist_node f_list; /* for fwmark-based service table */ 67862306a36Sopenharmony_ci atomic_t refcnt; /* reference counter */ 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci u16 af; /* address family */ 68162306a36Sopenharmony_ci __u16 protocol; /* which protocol (TCP/UDP) */ 68262306a36Sopenharmony_ci union nf_inet_addr addr; /* IP address for virtual service */ 68362306a36Sopenharmony_ci __be16 port; /* port number for the service */ 68462306a36Sopenharmony_ci __u32 fwmark; /* firewall mark of the service */ 68562306a36Sopenharmony_ci unsigned int flags; /* service status flags */ 68662306a36Sopenharmony_ci unsigned int timeout; /* persistent timeout in ticks */ 68762306a36Sopenharmony_ci __be32 netmask; /* grouping granularity, mask/plen */ 68862306a36Sopenharmony_ci struct netns_ipvs *ipvs; 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci struct list_head destinations; /* real server d-linked list */ 69162306a36Sopenharmony_ci __u32 num_dests; /* number of servers */ 69262306a36Sopenharmony_ci struct ip_vs_stats stats; /* statistics for the service */ 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci /* for scheduling */ 69562306a36Sopenharmony_ci struct ip_vs_scheduler __rcu *scheduler; /* bound scheduler object */ 69662306a36Sopenharmony_ci spinlock_t sched_lock; /* lock sched_data */ 69762306a36Sopenharmony_ci void *sched_data; /* scheduler application data */ 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci /* alternate persistence engine */ 70062306a36Sopenharmony_ci struct ip_vs_pe __rcu *pe; 70162306a36Sopenharmony_ci int conntrack_afmask; 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci struct rcu_head rcu_head; 70462306a36Sopenharmony_ci}; 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci/* Information for cached dst */ 70762306a36Sopenharmony_cistruct ip_vs_dest_dst { 70862306a36Sopenharmony_ci struct dst_entry *dst_cache; /* destination cache entry */ 70962306a36Sopenharmony_ci u32 dst_cookie; 71062306a36Sopenharmony_ci union nf_inet_addr dst_saddr; 71162306a36Sopenharmony_ci struct rcu_head rcu_head; 71262306a36Sopenharmony_ci}; 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci/* The real server destination forwarding entry with ip address, port number, 71562306a36Sopenharmony_ci * and so on. 71662306a36Sopenharmony_ci */ 71762306a36Sopenharmony_cistruct ip_vs_dest { 71862306a36Sopenharmony_ci struct list_head n_list; /* for the dests in the service */ 71962306a36Sopenharmony_ci struct hlist_node d_list; /* for table with all the dests */ 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci u16 af; /* address family */ 72262306a36Sopenharmony_ci __be16 port; /* port number of the server */ 72362306a36Sopenharmony_ci union nf_inet_addr addr; /* IP address of the server */ 72462306a36Sopenharmony_ci volatile unsigned int flags; /* dest status flags */ 72562306a36Sopenharmony_ci atomic_t conn_flags; /* flags to copy to conn */ 72662306a36Sopenharmony_ci atomic_t weight; /* server weight */ 72762306a36Sopenharmony_ci atomic_t last_weight; /* server latest weight */ 72862306a36Sopenharmony_ci __u16 tun_type; /* tunnel type */ 72962306a36Sopenharmony_ci __be16 tun_port; /* tunnel port */ 73062306a36Sopenharmony_ci __u16 tun_flags; /* tunnel flags */ 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci refcount_t refcnt; /* reference counter */ 73362306a36Sopenharmony_ci struct ip_vs_stats stats; /* statistics */ 73462306a36Sopenharmony_ci unsigned long idle_start; /* start time, jiffies */ 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci /* connection counters and thresholds */ 73762306a36Sopenharmony_ci atomic_t activeconns; /* active connections */ 73862306a36Sopenharmony_ci atomic_t inactconns; /* inactive connections */ 73962306a36Sopenharmony_ci atomic_t persistconns; /* persistent connections */ 74062306a36Sopenharmony_ci __u32 u_threshold; /* upper threshold */ 74162306a36Sopenharmony_ci __u32 l_threshold; /* lower threshold */ 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_ci /* for destination cache */ 74462306a36Sopenharmony_ci spinlock_t dst_lock; /* lock of dst_cache */ 74562306a36Sopenharmony_ci struct ip_vs_dest_dst __rcu *dest_dst; /* cached dst info */ 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_ci /* for virtual service */ 74862306a36Sopenharmony_ci struct ip_vs_service __rcu *svc; /* service it belongs to */ 74962306a36Sopenharmony_ci __u16 protocol; /* which protocol (TCP/UDP) */ 75062306a36Sopenharmony_ci __be16 vport; /* virtual port number */ 75162306a36Sopenharmony_ci union nf_inet_addr vaddr; /* virtual IP address */ 75262306a36Sopenharmony_ci __u32 vfwmark; /* firewall mark of service */ 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci struct rcu_head rcu_head; 75562306a36Sopenharmony_ci struct list_head t_list; /* in dest_trash */ 75662306a36Sopenharmony_ci unsigned int in_rs_table:1; /* we are in rs_table */ 75762306a36Sopenharmony_ci}; 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci/* The scheduler object */ 76062306a36Sopenharmony_cistruct ip_vs_scheduler { 76162306a36Sopenharmony_ci struct list_head n_list; /* d-linked list head */ 76262306a36Sopenharmony_ci char *name; /* scheduler name */ 76362306a36Sopenharmony_ci atomic_t refcnt; /* reference counter */ 76462306a36Sopenharmony_ci struct module *module; /* THIS_MODULE/NULL */ 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci /* scheduler initializing service */ 76762306a36Sopenharmony_ci int (*init_service)(struct ip_vs_service *svc); 76862306a36Sopenharmony_ci /* scheduling service finish */ 76962306a36Sopenharmony_ci void (*done_service)(struct ip_vs_service *svc); 77062306a36Sopenharmony_ci /* dest is linked */ 77162306a36Sopenharmony_ci int (*add_dest)(struct ip_vs_service *svc, struct ip_vs_dest *dest); 77262306a36Sopenharmony_ci /* dest is unlinked */ 77362306a36Sopenharmony_ci int (*del_dest)(struct ip_vs_service *svc, struct ip_vs_dest *dest); 77462306a36Sopenharmony_ci /* dest is updated */ 77562306a36Sopenharmony_ci int (*upd_dest)(struct ip_vs_service *svc, struct ip_vs_dest *dest); 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci /* selecting a server from the given service */ 77862306a36Sopenharmony_ci struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc, 77962306a36Sopenharmony_ci const struct sk_buff *skb, 78062306a36Sopenharmony_ci struct ip_vs_iphdr *iph); 78162306a36Sopenharmony_ci}; 78262306a36Sopenharmony_ci 78362306a36Sopenharmony_ci/* The persistence engine object */ 78462306a36Sopenharmony_cistruct ip_vs_pe { 78562306a36Sopenharmony_ci struct list_head n_list; /* d-linked list head */ 78662306a36Sopenharmony_ci char *name; /* scheduler name */ 78762306a36Sopenharmony_ci atomic_t refcnt; /* reference counter */ 78862306a36Sopenharmony_ci struct module *module; /* THIS_MODULE/NULL */ 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci /* get the connection template, if any */ 79162306a36Sopenharmony_ci int (*fill_param)(struct ip_vs_conn_param *p, struct sk_buff *skb); 79262306a36Sopenharmony_ci bool (*ct_match)(const struct ip_vs_conn_param *p, 79362306a36Sopenharmony_ci struct ip_vs_conn *ct); 79462306a36Sopenharmony_ci u32 (*hashkey_raw)(const struct ip_vs_conn_param *p, u32 initval, 79562306a36Sopenharmony_ci bool inverse); 79662306a36Sopenharmony_ci int (*show_pe_data)(const struct ip_vs_conn *cp, char *buf); 79762306a36Sopenharmony_ci /* create connections for real-server outgoing packets */ 79862306a36Sopenharmony_ci struct ip_vs_conn* (*conn_out)(struct ip_vs_service *svc, 79962306a36Sopenharmony_ci struct ip_vs_dest *dest, 80062306a36Sopenharmony_ci struct sk_buff *skb, 80162306a36Sopenharmony_ci const struct ip_vs_iphdr *iph, 80262306a36Sopenharmony_ci __be16 dport, __be16 cport); 80362306a36Sopenharmony_ci}; 80462306a36Sopenharmony_ci 80562306a36Sopenharmony_ci/* The application module object (a.k.a. app incarnation) */ 80662306a36Sopenharmony_cistruct ip_vs_app { 80762306a36Sopenharmony_ci struct list_head a_list; /* member in app list */ 80862306a36Sopenharmony_ci int type; /* IP_VS_APP_TYPE_xxx */ 80962306a36Sopenharmony_ci char *name; /* application module name */ 81062306a36Sopenharmony_ci __u16 protocol; 81162306a36Sopenharmony_ci struct module *module; /* THIS_MODULE/NULL */ 81262306a36Sopenharmony_ci struct list_head incs_list; /* list of incarnations */ 81362306a36Sopenharmony_ci 81462306a36Sopenharmony_ci /* members for application incarnations */ 81562306a36Sopenharmony_ci struct list_head p_list; /* member in proto app list */ 81662306a36Sopenharmony_ci struct ip_vs_app *app; /* its real application */ 81762306a36Sopenharmony_ci __be16 port; /* port number in net order */ 81862306a36Sopenharmony_ci atomic_t usecnt; /* usage counter */ 81962306a36Sopenharmony_ci struct rcu_head rcu_head; 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci /* output hook: Process packet in inout direction, diff set for TCP. 82262306a36Sopenharmony_ci * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok, 82362306a36Sopenharmony_ci * 2=Mangled but checksum was not updated 82462306a36Sopenharmony_ci */ 82562306a36Sopenharmony_ci int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *, 82662306a36Sopenharmony_ci struct sk_buff *, int *diff, struct ip_vs_iphdr *ipvsh); 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci /* input hook: Process packet in outin direction, diff set for TCP. 82962306a36Sopenharmony_ci * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok, 83062306a36Sopenharmony_ci * 2=Mangled but checksum was not updated 83162306a36Sopenharmony_ci */ 83262306a36Sopenharmony_ci int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *, 83362306a36Sopenharmony_ci struct sk_buff *, int *diff, struct ip_vs_iphdr *ipvsh); 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci /* ip_vs_app initializer */ 83662306a36Sopenharmony_ci int (*init_conn)(struct ip_vs_app *, struct ip_vs_conn *); 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_ci /* ip_vs_app finish */ 83962306a36Sopenharmony_ci int (*done_conn)(struct ip_vs_app *, struct ip_vs_conn *); 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci /* not used now */ 84362306a36Sopenharmony_ci int (*bind_conn)(struct ip_vs_app *, struct ip_vs_conn *, 84462306a36Sopenharmony_ci struct ip_vs_protocol *); 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci void (*unbind_conn)(struct ip_vs_app *, struct ip_vs_conn *); 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_ci int * timeout_table; 84962306a36Sopenharmony_ci int * timeouts; 85062306a36Sopenharmony_ci int timeouts_size; 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_ci int (*conn_schedule)(struct sk_buff *skb, struct ip_vs_app *app, 85362306a36Sopenharmony_ci int *verdict, struct ip_vs_conn **cpp); 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci struct ip_vs_conn * 85662306a36Sopenharmony_ci (*conn_in_get)(const struct sk_buff *skb, struct ip_vs_app *app, 85762306a36Sopenharmony_ci const struct iphdr *iph, int inverse); 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci struct ip_vs_conn * 86062306a36Sopenharmony_ci (*conn_out_get)(const struct sk_buff *skb, struct ip_vs_app *app, 86162306a36Sopenharmony_ci const struct iphdr *iph, int inverse); 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci int (*state_transition)(struct ip_vs_conn *cp, int direction, 86462306a36Sopenharmony_ci const struct sk_buff *skb, 86562306a36Sopenharmony_ci struct ip_vs_app *app); 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci void (*timeout_change)(struct ip_vs_app *app, int flags); 86862306a36Sopenharmony_ci}; 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_cistruct ipvs_master_sync_state { 87162306a36Sopenharmony_ci struct list_head sync_queue; 87262306a36Sopenharmony_ci struct ip_vs_sync_buff *sync_buff; 87362306a36Sopenharmony_ci unsigned long sync_queue_len; 87462306a36Sopenharmony_ci unsigned int sync_queue_delay; 87562306a36Sopenharmony_ci struct delayed_work master_wakeup_work; 87662306a36Sopenharmony_ci struct netns_ipvs *ipvs; 87762306a36Sopenharmony_ci}; 87862306a36Sopenharmony_ci 87962306a36Sopenharmony_cistruct ip_vs_sync_thread_data; 88062306a36Sopenharmony_ci 88162306a36Sopenharmony_ci/* How much time to keep dests in trash */ 88262306a36Sopenharmony_ci#define IP_VS_DEST_TRASH_PERIOD (120 * HZ) 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_cistruct ipvs_sync_daemon_cfg { 88562306a36Sopenharmony_ci union nf_inet_addr mcast_group; 88662306a36Sopenharmony_ci int syncid; 88762306a36Sopenharmony_ci u16 sync_maxlen; 88862306a36Sopenharmony_ci u16 mcast_port; 88962306a36Sopenharmony_ci u8 mcast_af; 89062306a36Sopenharmony_ci u8 mcast_ttl; 89162306a36Sopenharmony_ci /* multicast interface name */ 89262306a36Sopenharmony_ci char mcast_ifn[IP_VS_IFNAME_MAXLEN]; 89362306a36Sopenharmony_ci}; 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_ci/* IPVS in network namespace */ 89662306a36Sopenharmony_cistruct netns_ipvs { 89762306a36Sopenharmony_ci int gen; /* Generation */ 89862306a36Sopenharmony_ci int enable; /* enable like nf_hooks do */ 89962306a36Sopenharmony_ci /* Hash table: for real service lookups */ 90062306a36Sopenharmony_ci #define IP_VS_RTAB_BITS 4 90162306a36Sopenharmony_ci #define IP_VS_RTAB_SIZE (1 << IP_VS_RTAB_BITS) 90262306a36Sopenharmony_ci #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1) 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ci struct hlist_head rs_table[IP_VS_RTAB_SIZE]; 90562306a36Sopenharmony_ci /* ip_vs_app */ 90662306a36Sopenharmony_ci struct list_head app_list; 90762306a36Sopenharmony_ci /* ip_vs_proto */ 90862306a36Sopenharmony_ci #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */ 90962306a36Sopenharmony_ci struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE]; 91062306a36Sopenharmony_ci /* ip_vs_proto_tcp */ 91162306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_PROTO_TCP 91262306a36Sopenharmony_ci #define TCP_APP_TAB_BITS 4 91362306a36Sopenharmony_ci #define TCP_APP_TAB_SIZE (1 << TCP_APP_TAB_BITS) 91462306a36Sopenharmony_ci #define TCP_APP_TAB_MASK (TCP_APP_TAB_SIZE - 1) 91562306a36Sopenharmony_ci struct list_head tcp_apps[TCP_APP_TAB_SIZE]; 91662306a36Sopenharmony_ci#endif 91762306a36Sopenharmony_ci /* ip_vs_proto_udp */ 91862306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_PROTO_UDP 91962306a36Sopenharmony_ci #define UDP_APP_TAB_BITS 4 92062306a36Sopenharmony_ci #define UDP_APP_TAB_SIZE (1 << UDP_APP_TAB_BITS) 92162306a36Sopenharmony_ci #define UDP_APP_TAB_MASK (UDP_APP_TAB_SIZE - 1) 92262306a36Sopenharmony_ci struct list_head udp_apps[UDP_APP_TAB_SIZE]; 92362306a36Sopenharmony_ci#endif 92462306a36Sopenharmony_ci /* ip_vs_proto_sctp */ 92562306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_PROTO_SCTP 92662306a36Sopenharmony_ci #define SCTP_APP_TAB_BITS 4 92762306a36Sopenharmony_ci #define SCTP_APP_TAB_SIZE (1 << SCTP_APP_TAB_BITS) 92862306a36Sopenharmony_ci #define SCTP_APP_TAB_MASK (SCTP_APP_TAB_SIZE - 1) 92962306a36Sopenharmony_ci /* Hash table for SCTP application incarnations */ 93062306a36Sopenharmony_ci struct list_head sctp_apps[SCTP_APP_TAB_SIZE]; 93162306a36Sopenharmony_ci#endif 93262306a36Sopenharmony_ci /* ip_vs_conn */ 93362306a36Sopenharmony_ci atomic_t conn_count; /* connection counter */ 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci /* ip_vs_ctl */ 93662306a36Sopenharmony_ci struct ip_vs_stats_rcu *tot_stats; /* Statistics & est. */ 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci int num_services; /* no of virtual services */ 93962306a36Sopenharmony_ci int num_services6; /* IPv6 virtual services */ 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci /* Trash for destinations */ 94262306a36Sopenharmony_ci struct list_head dest_trash; 94362306a36Sopenharmony_ci spinlock_t dest_trash_lock; 94462306a36Sopenharmony_ci struct timer_list dest_trash_timer; /* expiration timer */ 94562306a36Sopenharmony_ci /* Service counters */ 94662306a36Sopenharmony_ci atomic_t ftpsvc_counter; 94762306a36Sopenharmony_ci atomic_t nullsvc_counter; 94862306a36Sopenharmony_ci atomic_t conn_out_counter; 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 95162306a36Sopenharmony_ci /* delayed work for expiring no dest connections */ 95262306a36Sopenharmony_ci struct delayed_work expire_nodest_conn_work; 95362306a36Sopenharmony_ci /* 1/rate drop and drop-entry variables */ 95462306a36Sopenharmony_ci struct delayed_work defense_work; /* Work handler */ 95562306a36Sopenharmony_ci int drop_rate; 95662306a36Sopenharmony_ci int drop_counter; 95762306a36Sopenharmony_ci int old_secure_tcp; 95862306a36Sopenharmony_ci atomic_t dropentry; 95962306a36Sopenharmony_ci /* locks in ctl.c */ 96062306a36Sopenharmony_ci spinlock_t dropentry_lock; /* drop entry handling */ 96162306a36Sopenharmony_ci spinlock_t droppacket_lock; /* drop packet handling */ 96262306a36Sopenharmony_ci spinlock_t securetcp_lock; /* state and timeout tables */ 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_ci /* sys-ctl struct */ 96562306a36Sopenharmony_ci struct ctl_table_header *sysctl_hdr; 96662306a36Sopenharmony_ci struct ctl_table *sysctl_tbl; 96762306a36Sopenharmony_ci#endif 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci /* sysctl variables */ 97062306a36Sopenharmony_ci int sysctl_amemthresh; 97162306a36Sopenharmony_ci int sysctl_am_droprate; 97262306a36Sopenharmony_ci int sysctl_drop_entry; 97362306a36Sopenharmony_ci int sysctl_drop_packet; 97462306a36Sopenharmony_ci int sysctl_secure_tcp; 97562306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_NFCT 97662306a36Sopenharmony_ci int sysctl_conntrack; 97762306a36Sopenharmony_ci#endif 97862306a36Sopenharmony_ci int sysctl_snat_reroute; 97962306a36Sopenharmony_ci int sysctl_sync_ver; 98062306a36Sopenharmony_ci int sysctl_sync_ports; 98162306a36Sopenharmony_ci int sysctl_sync_persist_mode; 98262306a36Sopenharmony_ci unsigned long sysctl_sync_qlen_max; 98362306a36Sopenharmony_ci int sysctl_sync_sock_size; 98462306a36Sopenharmony_ci int sysctl_cache_bypass; 98562306a36Sopenharmony_ci int sysctl_expire_nodest_conn; 98662306a36Sopenharmony_ci int sysctl_sloppy_tcp; 98762306a36Sopenharmony_ci int sysctl_sloppy_sctp; 98862306a36Sopenharmony_ci int sysctl_expire_quiescent_template; 98962306a36Sopenharmony_ci int sysctl_sync_threshold[2]; 99062306a36Sopenharmony_ci unsigned int sysctl_sync_refresh_period; 99162306a36Sopenharmony_ci int sysctl_sync_retries; 99262306a36Sopenharmony_ci int sysctl_nat_icmp_send; 99362306a36Sopenharmony_ci int sysctl_pmtu_disc; 99462306a36Sopenharmony_ci int sysctl_backup_only; 99562306a36Sopenharmony_ci int sysctl_conn_reuse_mode; 99662306a36Sopenharmony_ci int sysctl_schedule_icmp; 99762306a36Sopenharmony_ci int sysctl_ignore_tunneled; 99862306a36Sopenharmony_ci int sysctl_run_estimation; 99962306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 100062306a36Sopenharmony_ci cpumask_var_t sysctl_est_cpulist; /* kthread cpumask */ 100162306a36Sopenharmony_ci int est_cpulist_valid; /* cpulist set */ 100262306a36Sopenharmony_ci int sysctl_est_nice; /* kthread nice */ 100362306a36Sopenharmony_ci int est_stopped; /* stop tasks */ 100462306a36Sopenharmony_ci#endif 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci /* ip_vs_lblc */ 100762306a36Sopenharmony_ci int sysctl_lblc_expiration; 100862306a36Sopenharmony_ci struct ctl_table_header *lblc_ctl_header; 100962306a36Sopenharmony_ci struct ctl_table *lblc_ctl_table; 101062306a36Sopenharmony_ci /* ip_vs_lblcr */ 101162306a36Sopenharmony_ci int sysctl_lblcr_expiration; 101262306a36Sopenharmony_ci struct ctl_table_header *lblcr_ctl_header; 101362306a36Sopenharmony_ci struct ctl_table *lblcr_ctl_table; 101462306a36Sopenharmony_ci /* ip_vs_est */ 101562306a36Sopenharmony_ci struct delayed_work est_reload_work;/* Reload kthread tasks */ 101662306a36Sopenharmony_ci struct mutex est_mutex; /* protect kthread tasks */ 101762306a36Sopenharmony_ci struct hlist_head est_temp_list; /* Ests during calc phase */ 101862306a36Sopenharmony_ci struct ip_vs_est_kt_data **est_kt_arr; /* Array of kthread data ptrs */ 101962306a36Sopenharmony_ci unsigned long est_max_threads;/* Hard limit of kthreads */ 102062306a36Sopenharmony_ci int est_calc_phase; /* Calculation phase */ 102162306a36Sopenharmony_ci int est_chain_max; /* Calculated chain_max */ 102262306a36Sopenharmony_ci int est_kt_count; /* Allocated ptrs */ 102362306a36Sopenharmony_ci int est_add_ktid; /* ktid where to add ests */ 102462306a36Sopenharmony_ci atomic_t est_genid; /* kthreads reload genid */ 102562306a36Sopenharmony_ci atomic_t est_genid_done; /* applied genid */ 102662306a36Sopenharmony_ci /* ip_vs_sync */ 102762306a36Sopenharmony_ci spinlock_t sync_lock; 102862306a36Sopenharmony_ci struct ipvs_master_sync_state *ms; 102962306a36Sopenharmony_ci spinlock_t sync_buff_lock; 103062306a36Sopenharmony_ci struct ip_vs_sync_thread_data *master_tinfo; 103162306a36Sopenharmony_ci struct ip_vs_sync_thread_data *backup_tinfo; 103262306a36Sopenharmony_ci int threads_mask; 103362306a36Sopenharmony_ci volatile int sync_state; 103462306a36Sopenharmony_ci struct mutex sync_mutex; 103562306a36Sopenharmony_ci struct ipvs_sync_daemon_cfg mcfg; /* Master Configuration */ 103662306a36Sopenharmony_ci struct ipvs_sync_daemon_cfg bcfg; /* Backup Configuration */ 103762306a36Sopenharmony_ci /* net name space ptr */ 103862306a36Sopenharmony_ci struct net *net; /* Needed by timer routines */ 103962306a36Sopenharmony_ci /* Number of heterogeneous destinations, needed because heterogeneous 104062306a36Sopenharmony_ci * are not supported when synchronization is enabled. 104162306a36Sopenharmony_ci */ 104262306a36Sopenharmony_ci unsigned int mixed_address_family_dests; 104362306a36Sopenharmony_ci unsigned int hooks_afmask; /* &1=AF_INET, &2=AF_INET6 */ 104462306a36Sopenharmony_ci}; 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_ci#define DEFAULT_SYNC_THRESHOLD 3 104762306a36Sopenharmony_ci#define DEFAULT_SYNC_PERIOD 50 104862306a36Sopenharmony_ci#define DEFAULT_SYNC_VER 1 104962306a36Sopenharmony_ci#define DEFAULT_SLOPPY_TCP 0 105062306a36Sopenharmony_ci#define DEFAULT_SLOPPY_SCTP 0 105162306a36Sopenharmony_ci#define DEFAULT_SYNC_REFRESH_PERIOD (0U * HZ) 105262306a36Sopenharmony_ci#define DEFAULT_SYNC_RETRIES 0 105362306a36Sopenharmony_ci#define IPVS_SYNC_WAKEUP_RATE 8 105462306a36Sopenharmony_ci#define IPVS_SYNC_QLEN_MAX (IPVS_SYNC_WAKEUP_RATE * 4) 105562306a36Sopenharmony_ci#define IPVS_SYNC_SEND_DELAY (HZ / 50) 105662306a36Sopenharmony_ci#define IPVS_SYNC_CHECK_PERIOD HZ 105762306a36Sopenharmony_ci#define IPVS_SYNC_FLUSH_TIME (HZ * 2) 105862306a36Sopenharmony_ci#define IPVS_SYNC_PORTS_MAX (1 << 6) 105962306a36Sopenharmony_ci 106062306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_cistatic inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) 106362306a36Sopenharmony_ci{ 106462306a36Sopenharmony_ci return ipvs->sysctl_sync_threshold[0]; 106562306a36Sopenharmony_ci} 106662306a36Sopenharmony_ci 106762306a36Sopenharmony_cistatic inline int sysctl_sync_period(struct netns_ipvs *ipvs) 106862306a36Sopenharmony_ci{ 106962306a36Sopenharmony_ci return READ_ONCE(ipvs->sysctl_sync_threshold[1]); 107062306a36Sopenharmony_ci} 107162306a36Sopenharmony_ci 107262306a36Sopenharmony_cistatic inline unsigned int sysctl_sync_refresh_period(struct netns_ipvs *ipvs) 107362306a36Sopenharmony_ci{ 107462306a36Sopenharmony_ci return READ_ONCE(ipvs->sysctl_sync_refresh_period); 107562306a36Sopenharmony_ci} 107662306a36Sopenharmony_ci 107762306a36Sopenharmony_cistatic inline int sysctl_sync_retries(struct netns_ipvs *ipvs) 107862306a36Sopenharmony_ci{ 107962306a36Sopenharmony_ci return ipvs->sysctl_sync_retries; 108062306a36Sopenharmony_ci} 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_cistatic inline int sysctl_sync_ver(struct netns_ipvs *ipvs) 108362306a36Sopenharmony_ci{ 108462306a36Sopenharmony_ci return ipvs->sysctl_sync_ver; 108562306a36Sopenharmony_ci} 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_cistatic inline int sysctl_sloppy_tcp(struct netns_ipvs *ipvs) 108862306a36Sopenharmony_ci{ 108962306a36Sopenharmony_ci return ipvs->sysctl_sloppy_tcp; 109062306a36Sopenharmony_ci} 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_cistatic inline int sysctl_sloppy_sctp(struct netns_ipvs *ipvs) 109362306a36Sopenharmony_ci{ 109462306a36Sopenharmony_ci return ipvs->sysctl_sloppy_sctp; 109562306a36Sopenharmony_ci} 109662306a36Sopenharmony_ci 109762306a36Sopenharmony_cistatic inline int sysctl_sync_ports(struct netns_ipvs *ipvs) 109862306a36Sopenharmony_ci{ 109962306a36Sopenharmony_ci return READ_ONCE(ipvs->sysctl_sync_ports); 110062306a36Sopenharmony_ci} 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_cistatic inline int sysctl_sync_persist_mode(struct netns_ipvs *ipvs) 110362306a36Sopenharmony_ci{ 110462306a36Sopenharmony_ci return ipvs->sysctl_sync_persist_mode; 110562306a36Sopenharmony_ci} 110662306a36Sopenharmony_ci 110762306a36Sopenharmony_cistatic inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs) 110862306a36Sopenharmony_ci{ 110962306a36Sopenharmony_ci return ipvs->sysctl_sync_qlen_max; 111062306a36Sopenharmony_ci} 111162306a36Sopenharmony_ci 111262306a36Sopenharmony_cistatic inline int sysctl_sync_sock_size(struct netns_ipvs *ipvs) 111362306a36Sopenharmony_ci{ 111462306a36Sopenharmony_ci return ipvs->sysctl_sync_sock_size; 111562306a36Sopenharmony_ci} 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_cistatic inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs) 111862306a36Sopenharmony_ci{ 111962306a36Sopenharmony_ci return ipvs->sysctl_pmtu_disc; 112062306a36Sopenharmony_ci} 112162306a36Sopenharmony_ci 112262306a36Sopenharmony_cistatic inline int sysctl_backup_only(struct netns_ipvs *ipvs) 112362306a36Sopenharmony_ci{ 112462306a36Sopenharmony_ci return ipvs->sync_state & IP_VS_STATE_BACKUP && 112562306a36Sopenharmony_ci ipvs->sysctl_backup_only; 112662306a36Sopenharmony_ci} 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_cistatic inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs) 112962306a36Sopenharmony_ci{ 113062306a36Sopenharmony_ci return ipvs->sysctl_conn_reuse_mode; 113162306a36Sopenharmony_ci} 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_cistatic inline int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs) 113462306a36Sopenharmony_ci{ 113562306a36Sopenharmony_ci return ipvs->sysctl_expire_nodest_conn; 113662306a36Sopenharmony_ci} 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_cistatic inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs) 113962306a36Sopenharmony_ci{ 114062306a36Sopenharmony_ci return ipvs->sysctl_schedule_icmp; 114162306a36Sopenharmony_ci} 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_cistatic inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs) 114462306a36Sopenharmony_ci{ 114562306a36Sopenharmony_ci return ipvs->sysctl_ignore_tunneled; 114662306a36Sopenharmony_ci} 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_cistatic inline int sysctl_cache_bypass(struct netns_ipvs *ipvs) 114962306a36Sopenharmony_ci{ 115062306a36Sopenharmony_ci return ipvs->sysctl_cache_bypass; 115162306a36Sopenharmony_ci} 115262306a36Sopenharmony_ci 115362306a36Sopenharmony_cistatic inline int sysctl_run_estimation(struct netns_ipvs *ipvs) 115462306a36Sopenharmony_ci{ 115562306a36Sopenharmony_ci return ipvs->sysctl_run_estimation; 115662306a36Sopenharmony_ci} 115762306a36Sopenharmony_ci 115862306a36Sopenharmony_cistatic inline const struct cpumask *sysctl_est_cpulist(struct netns_ipvs *ipvs) 115962306a36Sopenharmony_ci{ 116062306a36Sopenharmony_ci if (ipvs->est_cpulist_valid) 116162306a36Sopenharmony_ci return ipvs->sysctl_est_cpulist; 116262306a36Sopenharmony_ci else 116362306a36Sopenharmony_ci return housekeeping_cpumask(HK_TYPE_KTHREAD); 116462306a36Sopenharmony_ci} 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_cistatic inline int sysctl_est_nice(struct netns_ipvs *ipvs) 116762306a36Sopenharmony_ci{ 116862306a36Sopenharmony_ci return ipvs->sysctl_est_nice; 116962306a36Sopenharmony_ci} 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_ci#else 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_cistatic inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) 117462306a36Sopenharmony_ci{ 117562306a36Sopenharmony_ci return DEFAULT_SYNC_THRESHOLD; 117662306a36Sopenharmony_ci} 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_cistatic inline int sysctl_sync_period(struct netns_ipvs *ipvs) 117962306a36Sopenharmony_ci{ 118062306a36Sopenharmony_ci return DEFAULT_SYNC_PERIOD; 118162306a36Sopenharmony_ci} 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_cistatic inline unsigned int sysctl_sync_refresh_period(struct netns_ipvs *ipvs) 118462306a36Sopenharmony_ci{ 118562306a36Sopenharmony_ci return DEFAULT_SYNC_REFRESH_PERIOD; 118662306a36Sopenharmony_ci} 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_cistatic inline int sysctl_sync_retries(struct netns_ipvs *ipvs) 118962306a36Sopenharmony_ci{ 119062306a36Sopenharmony_ci return DEFAULT_SYNC_RETRIES & 3; 119162306a36Sopenharmony_ci} 119262306a36Sopenharmony_ci 119362306a36Sopenharmony_cistatic inline int sysctl_sync_ver(struct netns_ipvs *ipvs) 119462306a36Sopenharmony_ci{ 119562306a36Sopenharmony_ci return DEFAULT_SYNC_VER; 119662306a36Sopenharmony_ci} 119762306a36Sopenharmony_ci 119862306a36Sopenharmony_cistatic inline int sysctl_sloppy_tcp(struct netns_ipvs *ipvs) 119962306a36Sopenharmony_ci{ 120062306a36Sopenharmony_ci return DEFAULT_SLOPPY_TCP; 120162306a36Sopenharmony_ci} 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_cistatic inline int sysctl_sloppy_sctp(struct netns_ipvs *ipvs) 120462306a36Sopenharmony_ci{ 120562306a36Sopenharmony_ci return DEFAULT_SLOPPY_SCTP; 120662306a36Sopenharmony_ci} 120762306a36Sopenharmony_ci 120862306a36Sopenharmony_cistatic inline int sysctl_sync_ports(struct netns_ipvs *ipvs) 120962306a36Sopenharmony_ci{ 121062306a36Sopenharmony_ci return 1; 121162306a36Sopenharmony_ci} 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_cistatic inline int sysctl_sync_persist_mode(struct netns_ipvs *ipvs) 121462306a36Sopenharmony_ci{ 121562306a36Sopenharmony_ci return 0; 121662306a36Sopenharmony_ci} 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_cistatic inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs) 121962306a36Sopenharmony_ci{ 122062306a36Sopenharmony_ci return IPVS_SYNC_QLEN_MAX; 122162306a36Sopenharmony_ci} 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_cistatic inline int sysctl_sync_sock_size(struct netns_ipvs *ipvs) 122462306a36Sopenharmony_ci{ 122562306a36Sopenharmony_ci return 0; 122662306a36Sopenharmony_ci} 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_cistatic inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs) 122962306a36Sopenharmony_ci{ 123062306a36Sopenharmony_ci return 1; 123162306a36Sopenharmony_ci} 123262306a36Sopenharmony_ci 123362306a36Sopenharmony_cistatic inline int sysctl_backup_only(struct netns_ipvs *ipvs) 123462306a36Sopenharmony_ci{ 123562306a36Sopenharmony_ci return 0; 123662306a36Sopenharmony_ci} 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_cistatic inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs) 123962306a36Sopenharmony_ci{ 124062306a36Sopenharmony_ci return 1; 124162306a36Sopenharmony_ci} 124262306a36Sopenharmony_ci 124362306a36Sopenharmony_cistatic inline int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs) 124462306a36Sopenharmony_ci{ 124562306a36Sopenharmony_ci return 0; 124662306a36Sopenharmony_ci} 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_cistatic inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs) 124962306a36Sopenharmony_ci{ 125062306a36Sopenharmony_ci return 0; 125162306a36Sopenharmony_ci} 125262306a36Sopenharmony_ci 125362306a36Sopenharmony_cistatic inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs) 125462306a36Sopenharmony_ci{ 125562306a36Sopenharmony_ci return 0; 125662306a36Sopenharmony_ci} 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_cistatic inline int sysctl_cache_bypass(struct netns_ipvs *ipvs) 125962306a36Sopenharmony_ci{ 126062306a36Sopenharmony_ci return 0; 126162306a36Sopenharmony_ci} 126262306a36Sopenharmony_ci 126362306a36Sopenharmony_cistatic inline int sysctl_run_estimation(struct netns_ipvs *ipvs) 126462306a36Sopenharmony_ci{ 126562306a36Sopenharmony_ci return 1; 126662306a36Sopenharmony_ci} 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_cistatic inline const struct cpumask *sysctl_est_cpulist(struct netns_ipvs *ipvs) 126962306a36Sopenharmony_ci{ 127062306a36Sopenharmony_ci return housekeeping_cpumask(HK_TYPE_KTHREAD); 127162306a36Sopenharmony_ci} 127262306a36Sopenharmony_ci 127362306a36Sopenharmony_cistatic inline int sysctl_est_nice(struct netns_ipvs *ipvs) 127462306a36Sopenharmony_ci{ 127562306a36Sopenharmony_ci return IPVS_EST_NICE; 127662306a36Sopenharmony_ci} 127762306a36Sopenharmony_ci 127862306a36Sopenharmony_ci#endif 127962306a36Sopenharmony_ci 128062306a36Sopenharmony_ci/* IPVS core functions 128162306a36Sopenharmony_ci * (from ip_vs_core.c) 128262306a36Sopenharmony_ci */ 128362306a36Sopenharmony_ciconst char *ip_vs_proto_name(unsigned int proto); 128462306a36Sopenharmony_civoid ip_vs_init_hash_table(struct list_head *table, int rows); 128562306a36Sopenharmony_cistruct ip_vs_conn *ip_vs_new_conn_out(struct ip_vs_service *svc, 128662306a36Sopenharmony_ci struct ip_vs_dest *dest, 128762306a36Sopenharmony_ci struct sk_buff *skb, 128862306a36Sopenharmony_ci const struct ip_vs_iphdr *iph, 128962306a36Sopenharmony_ci __be16 dport, 129062306a36Sopenharmony_ci __be16 cport); 129162306a36Sopenharmony_ci#define IP_VS_INIT_HASH_TABLE(t) ip_vs_init_hash_table((t), ARRAY_SIZE((t))) 129262306a36Sopenharmony_ci 129362306a36Sopenharmony_ci#define IP_VS_APP_TYPE_FTP 1 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_ci/* ip_vs_conn handling functions 129662306a36Sopenharmony_ci * (from ip_vs_conn.c) 129762306a36Sopenharmony_ci */ 129862306a36Sopenharmony_cienum { 129962306a36Sopenharmony_ci IP_VS_DIR_INPUT = 0, 130062306a36Sopenharmony_ci IP_VS_DIR_OUTPUT, 130162306a36Sopenharmony_ci IP_VS_DIR_INPUT_ONLY, 130262306a36Sopenharmony_ci IP_VS_DIR_LAST, 130362306a36Sopenharmony_ci}; 130462306a36Sopenharmony_ci 130562306a36Sopenharmony_cistatic inline void ip_vs_conn_fill_param(struct netns_ipvs *ipvs, int af, int protocol, 130662306a36Sopenharmony_ci const union nf_inet_addr *caddr, 130762306a36Sopenharmony_ci __be16 cport, 130862306a36Sopenharmony_ci const union nf_inet_addr *vaddr, 130962306a36Sopenharmony_ci __be16 vport, 131062306a36Sopenharmony_ci struct ip_vs_conn_param *p) 131162306a36Sopenharmony_ci{ 131262306a36Sopenharmony_ci p->ipvs = ipvs; 131362306a36Sopenharmony_ci p->af = af; 131462306a36Sopenharmony_ci p->protocol = protocol; 131562306a36Sopenharmony_ci p->caddr = caddr; 131662306a36Sopenharmony_ci p->cport = cport; 131762306a36Sopenharmony_ci p->vaddr = vaddr; 131862306a36Sopenharmony_ci p->vport = vport; 131962306a36Sopenharmony_ci p->pe = NULL; 132062306a36Sopenharmony_ci p->pe_data = NULL; 132162306a36Sopenharmony_ci} 132262306a36Sopenharmony_ci 132362306a36Sopenharmony_cistruct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p); 132462306a36Sopenharmony_cistruct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p); 132562306a36Sopenharmony_ci 132662306a36Sopenharmony_cistruct ip_vs_conn * ip_vs_conn_in_get_proto(struct netns_ipvs *ipvs, int af, 132762306a36Sopenharmony_ci const struct sk_buff *skb, 132862306a36Sopenharmony_ci const struct ip_vs_iphdr *iph); 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_cistruct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p); 133162306a36Sopenharmony_ci 133262306a36Sopenharmony_cistruct ip_vs_conn * ip_vs_conn_out_get_proto(struct netns_ipvs *ipvs, int af, 133362306a36Sopenharmony_ci const struct sk_buff *skb, 133462306a36Sopenharmony_ci const struct ip_vs_iphdr *iph); 133562306a36Sopenharmony_ci 133662306a36Sopenharmony_ci/* Get reference to gain full access to conn. 133762306a36Sopenharmony_ci * By default, RCU read-side critical sections have access only to 133862306a36Sopenharmony_ci * conn fields and its PE data, see ip_vs_conn_rcu_free() for reference. 133962306a36Sopenharmony_ci */ 134062306a36Sopenharmony_cistatic inline bool __ip_vs_conn_get(struct ip_vs_conn *cp) 134162306a36Sopenharmony_ci{ 134262306a36Sopenharmony_ci return refcount_inc_not_zero(&cp->refcnt); 134362306a36Sopenharmony_ci} 134462306a36Sopenharmony_ci 134562306a36Sopenharmony_ci/* put back the conn without restarting its timer */ 134662306a36Sopenharmony_cistatic inline void __ip_vs_conn_put(struct ip_vs_conn *cp) 134762306a36Sopenharmony_ci{ 134862306a36Sopenharmony_ci smp_mb__before_atomic(); 134962306a36Sopenharmony_ci refcount_dec(&cp->refcnt); 135062306a36Sopenharmony_ci} 135162306a36Sopenharmony_civoid ip_vs_conn_put(struct ip_vs_conn *cp); 135262306a36Sopenharmony_civoid ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport); 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_cistruct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p, int dest_af, 135562306a36Sopenharmony_ci const union nf_inet_addr *daddr, 135662306a36Sopenharmony_ci __be16 dport, unsigned int flags, 135762306a36Sopenharmony_ci struct ip_vs_dest *dest, __u32 fwmark); 135862306a36Sopenharmony_civoid ip_vs_conn_expire_now(struct ip_vs_conn *cp); 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ciconst char *ip_vs_state_name(const struct ip_vs_conn *cp); 136162306a36Sopenharmony_ci 136262306a36Sopenharmony_civoid ip_vs_tcp_conn_listen(struct ip_vs_conn *cp); 136362306a36Sopenharmony_ciint ip_vs_check_template(struct ip_vs_conn *ct, struct ip_vs_dest *cdest); 136462306a36Sopenharmony_civoid ip_vs_random_dropentry(struct netns_ipvs *ipvs); 136562306a36Sopenharmony_ciint ip_vs_conn_init(void); 136662306a36Sopenharmony_civoid ip_vs_conn_cleanup(void); 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_cistatic inline void ip_vs_control_del(struct ip_vs_conn *cp) 136962306a36Sopenharmony_ci{ 137062306a36Sopenharmony_ci struct ip_vs_conn *ctl_cp = cp->control; 137162306a36Sopenharmony_ci if (!ctl_cp) { 137262306a36Sopenharmony_ci IP_VS_ERR_BUF("request control DEL for uncontrolled: " 137362306a36Sopenharmony_ci "%s:%d to %s:%d\n", 137462306a36Sopenharmony_ci IP_VS_DBG_ADDR(cp->af, &cp->caddr), 137562306a36Sopenharmony_ci ntohs(cp->cport), 137662306a36Sopenharmony_ci IP_VS_DBG_ADDR(cp->af, &cp->vaddr), 137762306a36Sopenharmony_ci ntohs(cp->vport)); 137862306a36Sopenharmony_ci 137962306a36Sopenharmony_ci return; 138062306a36Sopenharmony_ci } 138162306a36Sopenharmony_ci 138262306a36Sopenharmony_ci IP_VS_DBG_BUF(7, "DELeting control for: " 138362306a36Sopenharmony_ci "cp.dst=%s:%d ctl_cp.dst=%s:%d\n", 138462306a36Sopenharmony_ci IP_VS_DBG_ADDR(cp->af, &cp->caddr), 138562306a36Sopenharmony_ci ntohs(cp->cport), 138662306a36Sopenharmony_ci IP_VS_DBG_ADDR(cp->af, &ctl_cp->caddr), 138762306a36Sopenharmony_ci ntohs(ctl_cp->cport)); 138862306a36Sopenharmony_ci 138962306a36Sopenharmony_ci cp->control = NULL; 139062306a36Sopenharmony_ci if (atomic_read(&ctl_cp->n_control) == 0) { 139162306a36Sopenharmony_ci IP_VS_ERR_BUF("BUG control DEL with n=0 : " 139262306a36Sopenharmony_ci "%s:%d to %s:%d\n", 139362306a36Sopenharmony_ci IP_VS_DBG_ADDR(cp->af, &cp->caddr), 139462306a36Sopenharmony_ci ntohs(cp->cport), 139562306a36Sopenharmony_ci IP_VS_DBG_ADDR(cp->af, &cp->vaddr), 139662306a36Sopenharmony_ci ntohs(cp->vport)); 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_ci return; 139962306a36Sopenharmony_ci } 140062306a36Sopenharmony_ci atomic_dec(&ctl_cp->n_control); 140162306a36Sopenharmony_ci} 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_cistatic inline void 140462306a36Sopenharmony_ciip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp) 140562306a36Sopenharmony_ci{ 140662306a36Sopenharmony_ci if (cp->control) { 140762306a36Sopenharmony_ci IP_VS_ERR_BUF("request control ADD for already controlled: " 140862306a36Sopenharmony_ci "%s:%d to %s:%d\n", 140962306a36Sopenharmony_ci IP_VS_DBG_ADDR(cp->af, &cp->caddr), 141062306a36Sopenharmony_ci ntohs(cp->cport), 141162306a36Sopenharmony_ci IP_VS_DBG_ADDR(cp->af, &cp->vaddr), 141262306a36Sopenharmony_ci ntohs(cp->vport)); 141362306a36Sopenharmony_ci 141462306a36Sopenharmony_ci ip_vs_control_del(cp); 141562306a36Sopenharmony_ci } 141662306a36Sopenharmony_ci 141762306a36Sopenharmony_ci IP_VS_DBG_BUF(7, "ADDing control for: " 141862306a36Sopenharmony_ci "cp.dst=%s:%d ctl_cp.dst=%s:%d\n", 141962306a36Sopenharmony_ci IP_VS_DBG_ADDR(cp->af, &cp->caddr), 142062306a36Sopenharmony_ci ntohs(cp->cport), 142162306a36Sopenharmony_ci IP_VS_DBG_ADDR(cp->af, &ctl_cp->caddr), 142262306a36Sopenharmony_ci ntohs(ctl_cp->cport)); 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci cp->control = ctl_cp; 142562306a36Sopenharmony_ci atomic_inc(&ctl_cp->n_control); 142662306a36Sopenharmony_ci} 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_ci/* Mark our template as assured */ 142962306a36Sopenharmony_cistatic inline void 143062306a36Sopenharmony_ciip_vs_control_assure_ct(struct ip_vs_conn *cp) 143162306a36Sopenharmony_ci{ 143262306a36Sopenharmony_ci struct ip_vs_conn *ct = cp->control; 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_ci if (ct && !(ct->state & IP_VS_CTPL_S_ASSURED) && 143562306a36Sopenharmony_ci (ct->flags & IP_VS_CONN_F_TEMPLATE)) 143662306a36Sopenharmony_ci ct->state |= IP_VS_CTPL_S_ASSURED; 143762306a36Sopenharmony_ci} 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_ci/* IPVS netns init & cleanup functions */ 144062306a36Sopenharmony_ciint ip_vs_estimator_net_init(struct netns_ipvs *ipvs); 144162306a36Sopenharmony_ciint ip_vs_control_net_init(struct netns_ipvs *ipvs); 144262306a36Sopenharmony_ciint ip_vs_protocol_net_init(struct netns_ipvs *ipvs); 144362306a36Sopenharmony_ciint ip_vs_app_net_init(struct netns_ipvs *ipvs); 144462306a36Sopenharmony_ciint ip_vs_conn_net_init(struct netns_ipvs *ipvs); 144562306a36Sopenharmony_ciint ip_vs_sync_net_init(struct netns_ipvs *ipvs); 144662306a36Sopenharmony_civoid ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs); 144762306a36Sopenharmony_civoid ip_vs_app_net_cleanup(struct netns_ipvs *ipvs); 144862306a36Sopenharmony_civoid ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs); 144962306a36Sopenharmony_civoid ip_vs_control_net_cleanup(struct netns_ipvs *ipvs); 145062306a36Sopenharmony_civoid ip_vs_estimator_net_cleanup(struct netns_ipvs *ipvs); 145162306a36Sopenharmony_civoid ip_vs_sync_net_cleanup(struct netns_ipvs *ipvs); 145262306a36Sopenharmony_civoid ip_vs_service_nets_cleanup(struct list_head *net_list); 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_ci/* IPVS application functions 145562306a36Sopenharmony_ci * (from ip_vs_app.c) 145662306a36Sopenharmony_ci */ 145762306a36Sopenharmony_ci#define IP_VS_APP_MAX_PORTS 8 145862306a36Sopenharmony_cistruct ip_vs_app *register_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *app); 145962306a36Sopenharmony_civoid unregister_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *app); 146062306a36Sopenharmony_ciint ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp); 146162306a36Sopenharmony_civoid ip_vs_unbind_app(struct ip_vs_conn *cp); 146262306a36Sopenharmony_ciint register_ip_vs_app_inc(struct netns_ipvs *ipvs, struct ip_vs_app *app, __u16 proto, 146362306a36Sopenharmony_ci __u16 port); 146462306a36Sopenharmony_ciint ip_vs_app_inc_get(struct ip_vs_app *inc); 146562306a36Sopenharmony_civoid ip_vs_app_inc_put(struct ip_vs_app *inc); 146662306a36Sopenharmony_ci 146762306a36Sopenharmony_ciint ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff *skb, 146862306a36Sopenharmony_ci struct ip_vs_iphdr *ipvsh); 146962306a36Sopenharmony_ciint ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb, 147062306a36Sopenharmony_ci struct ip_vs_iphdr *ipvsh); 147162306a36Sopenharmony_ci 147262306a36Sopenharmony_ciint register_ip_vs_pe(struct ip_vs_pe *pe); 147362306a36Sopenharmony_ciint unregister_ip_vs_pe(struct ip_vs_pe *pe); 147462306a36Sopenharmony_cistruct ip_vs_pe *ip_vs_pe_getbyname(const char *name); 147562306a36Sopenharmony_cistruct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name); 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_ci/* Use a #define to avoid all of module.h just for these trivial ops */ 147862306a36Sopenharmony_ci#define ip_vs_pe_get(pe) \ 147962306a36Sopenharmony_ci if (pe && pe->module) \ 148062306a36Sopenharmony_ci __module_get(pe->module); 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci#define ip_vs_pe_put(pe) \ 148362306a36Sopenharmony_ci if (pe && pe->module) \ 148462306a36Sopenharmony_ci module_put(pe->module); 148562306a36Sopenharmony_ci 148662306a36Sopenharmony_ci/* IPVS protocol functions (from ip_vs_proto.c) */ 148762306a36Sopenharmony_ciint ip_vs_protocol_init(void); 148862306a36Sopenharmony_civoid ip_vs_protocol_cleanup(void); 148962306a36Sopenharmony_civoid ip_vs_protocol_timeout_change(struct netns_ipvs *ipvs, int flags); 149062306a36Sopenharmony_ciint *ip_vs_create_timeout_table(int *table, int size); 149162306a36Sopenharmony_civoid ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp, 149262306a36Sopenharmony_ci const struct sk_buff *skb, int offset, 149362306a36Sopenharmony_ci const char *msg); 149462306a36Sopenharmony_ci 149562306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_tcp; 149662306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_udp; 149762306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_icmp; 149862306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_esp; 149962306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_ah; 150062306a36Sopenharmony_ciextern struct ip_vs_protocol ip_vs_protocol_sctp; 150162306a36Sopenharmony_ci 150262306a36Sopenharmony_ci/* Registering/unregistering scheduler functions 150362306a36Sopenharmony_ci * (from ip_vs_sched.c) 150462306a36Sopenharmony_ci */ 150562306a36Sopenharmony_ciint register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler); 150662306a36Sopenharmony_ciint unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler); 150762306a36Sopenharmony_ciint ip_vs_bind_scheduler(struct ip_vs_service *svc, 150862306a36Sopenharmony_ci struct ip_vs_scheduler *scheduler); 150962306a36Sopenharmony_civoid ip_vs_unbind_scheduler(struct ip_vs_service *svc, 151062306a36Sopenharmony_ci struct ip_vs_scheduler *sched); 151162306a36Sopenharmony_cistruct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name); 151262306a36Sopenharmony_civoid ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler); 151362306a36Sopenharmony_cistruct ip_vs_conn * 151462306a36Sopenharmony_ciip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, 151562306a36Sopenharmony_ci struct ip_vs_proto_data *pd, int *ignored, 151662306a36Sopenharmony_ci struct ip_vs_iphdr *iph); 151762306a36Sopenharmony_ciint ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, 151862306a36Sopenharmony_ci struct ip_vs_proto_data *pd, struct ip_vs_iphdr *iph); 151962306a36Sopenharmony_ci 152062306a36Sopenharmony_civoid ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg); 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci/* IPVS control data and functions (from ip_vs_ctl.c) */ 152362306a36Sopenharmony_ciextern struct ip_vs_stats ip_vs_stats; 152462306a36Sopenharmony_ciextern int sysctl_ip_vs_sync_ver; 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_cistruct ip_vs_service * 152762306a36Sopenharmony_ciip_vs_service_find(struct netns_ipvs *ipvs, int af, __u32 fwmark, __u16 protocol, 152862306a36Sopenharmony_ci const union nf_inet_addr *vaddr, __be16 vport); 152962306a36Sopenharmony_ci 153062306a36Sopenharmony_cibool ip_vs_has_real_service(struct netns_ipvs *ipvs, int af, __u16 protocol, 153162306a36Sopenharmony_ci const union nf_inet_addr *daddr, __be16 dport); 153262306a36Sopenharmony_ci 153362306a36Sopenharmony_cistruct ip_vs_dest * 153462306a36Sopenharmony_ciip_vs_find_real_service(struct netns_ipvs *ipvs, int af, __u16 protocol, 153562306a36Sopenharmony_ci const union nf_inet_addr *daddr, __be16 dport); 153662306a36Sopenharmony_cistruct ip_vs_dest *ip_vs_find_tunnel(struct netns_ipvs *ipvs, int af, 153762306a36Sopenharmony_ci const union nf_inet_addr *daddr, 153862306a36Sopenharmony_ci __be16 tun_port); 153962306a36Sopenharmony_ci 154062306a36Sopenharmony_ciint ip_vs_use_count_inc(void); 154162306a36Sopenharmony_civoid ip_vs_use_count_dec(void); 154262306a36Sopenharmony_ciint ip_vs_register_nl_ioctl(void); 154362306a36Sopenharmony_civoid ip_vs_unregister_nl_ioctl(void); 154462306a36Sopenharmony_ciint ip_vs_control_init(void); 154562306a36Sopenharmony_civoid ip_vs_control_cleanup(void); 154662306a36Sopenharmony_cistruct ip_vs_dest * 154762306a36Sopenharmony_ciip_vs_find_dest(struct netns_ipvs *ipvs, int svc_af, int dest_af, 154862306a36Sopenharmony_ci const union nf_inet_addr *daddr, __be16 dport, 154962306a36Sopenharmony_ci const union nf_inet_addr *vaddr, __be16 vport, 155062306a36Sopenharmony_ci __u16 protocol, __u32 fwmark, __u32 flags); 155162306a36Sopenharmony_civoid ip_vs_try_bind_dest(struct ip_vs_conn *cp); 155262306a36Sopenharmony_ci 155362306a36Sopenharmony_cistatic inline void ip_vs_dest_hold(struct ip_vs_dest *dest) 155462306a36Sopenharmony_ci{ 155562306a36Sopenharmony_ci refcount_inc(&dest->refcnt); 155662306a36Sopenharmony_ci} 155762306a36Sopenharmony_ci 155862306a36Sopenharmony_cistatic inline void ip_vs_dest_put(struct ip_vs_dest *dest) 155962306a36Sopenharmony_ci{ 156062306a36Sopenharmony_ci smp_mb__before_atomic(); 156162306a36Sopenharmony_ci refcount_dec(&dest->refcnt); 156262306a36Sopenharmony_ci} 156362306a36Sopenharmony_ci 156462306a36Sopenharmony_cistatic inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest) 156562306a36Sopenharmony_ci{ 156662306a36Sopenharmony_ci if (refcount_dec_and_test(&dest->refcnt)) 156762306a36Sopenharmony_ci kfree(dest); 156862306a36Sopenharmony_ci} 156962306a36Sopenharmony_ci 157062306a36Sopenharmony_ci/* IPVS sync daemon data and function prototypes 157162306a36Sopenharmony_ci * (from ip_vs_sync.c) 157262306a36Sopenharmony_ci */ 157362306a36Sopenharmony_ciint start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *cfg, 157462306a36Sopenharmony_ci int state); 157562306a36Sopenharmony_ciint stop_sync_thread(struct netns_ipvs *ipvs, int state); 157662306a36Sopenharmony_civoid ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts); 157762306a36Sopenharmony_ci 157862306a36Sopenharmony_ci/* IPVS rate estimator prototypes (from ip_vs_est.c) */ 157962306a36Sopenharmony_ciint ip_vs_start_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats); 158062306a36Sopenharmony_civoid ip_vs_stop_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats); 158162306a36Sopenharmony_civoid ip_vs_zero_estimator(struct ip_vs_stats *stats); 158262306a36Sopenharmony_civoid ip_vs_read_estimator(struct ip_vs_kstats *dst, struct ip_vs_stats *stats); 158362306a36Sopenharmony_civoid ip_vs_est_reload_start(struct netns_ipvs *ipvs); 158462306a36Sopenharmony_ciint ip_vs_est_kthread_start(struct netns_ipvs *ipvs, 158562306a36Sopenharmony_ci struct ip_vs_est_kt_data *kd); 158662306a36Sopenharmony_civoid ip_vs_est_kthread_stop(struct ip_vs_est_kt_data *kd); 158762306a36Sopenharmony_ci 158862306a36Sopenharmony_cistatic inline void ip_vs_est_stopped_recalc(struct netns_ipvs *ipvs) 158962306a36Sopenharmony_ci{ 159062306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 159162306a36Sopenharmony_ci /* Stop tasks while cpulist is empty or if disabled with flag */ 159262306a36Sopenharmony_ci ipvs->est_stopped = !sysctl_run_estimation(ipvs) || 159362306a36Sopenharmony_ci (ipvs->est_cpulist_valid && 159462306a36Sopenharmony_ci cpumask_empty(sysctl_est_cpulist(ipvs))); 159562306a36Sopenharmony_ci#endif 159662306a36Sopenharmony_ci} 159762306a36Sopenharmony_ci 159862306a36Sopenharmony_cistatic inline bool ip_vs_est_stopped(struct netns_ipvs *ipvs) 159962306a36Sopenharmony_ci{ 160062306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 160162306a36Sopenharmony_ci return ipvs->est_stopped; 160262306a36Sopenharmony_ci#else 160362306a36Sopenharmony_ci return false; 160462306a36Sopenharmony_ci#endif 160562306a36Sopenharmony_ci} 160662306a36Sopenharmony_ci 160762306a36Sopenharmony_cistatic inline int ip_vs_est_max_threads(struct netns_ipvs *ipvs) 160862306a36Sopenharmony_ci{ 160962306a36Sopenharmony_ci unsigned int limit = IPVS_EST_CPU_KTHREADS * 161062306a36Sopenharmony_ci cpumask_weight(sysctl_est_cpulist(ipvs)); 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_ci return max(1U, limit); 161362306a36Sopenharmony_ci} 161462306a36Sopenharmony_ci 161562306a36Sopenharmony_ci/* Various IPVS packet transmitters (from ip_vs_xmit.c) */ 161662306a36Sopenharmony_ciint ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, 161762306a36Sopenharmony_ci struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 161862306a36Sopenharmony_ciint ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, 161962306a36Sopenharmony_ci struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 162062306a36Sopenharmony_ciint ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, 162162306a36Sopenharmony_ci struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 162262306a36Sopenharmony_ciint ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, 162362306a36Sopenharmony_ci struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 162462306a36Sopenharmony_ciint ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, 162562306a36Sopenharmony_ci struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 162662306a36Sopenharmony_ciint ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, 162762306a36Sopenharmony_ci struct ip_vs_protocol *pp, int offset, 162862306a36Sopenharmony_ci unsigned int hooknum, struct ip_vs_iphdr *iph); 162962306a36Sopenharmony_civoid ip_vs_dest_dst_rcu_free(struct rcu_head *head); 163062306a36Sopenharmony_ci 163162306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6 163262306a36Sopenharmony_ciint ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, 163362306a36Sopenharmony_ci struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 163462306a36Sopenharmony_ciint ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, 163562306a36Sopenharmony_ci struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 163662306a36Sopenharmony_ciint ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, 163762306a36Sopenharmony_ci struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 163862306a36Sopenharmony_ciint ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, 163962306a36Sopenharmony_ci struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 164062306a36Sopenharmony_ciint ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, 164162306a36Sopenharmony_ci struct ip_vs_protocol *pp, int offset, 164262306a36Sopenharmony_ci unsigned int hooknum, struct ip_vs_iphdr *iph); 164362306a36Sopenharmony_ci#endif 164462306a36Sopenharmony_ci 164562306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 164662306a36Sopenharmony_ci/* This is a simple mechanism to ignore packets when 164762306a36Sopenharmony_ci * we are loaded. Just set ip_vs_drop_rate to 'n' and 164862306a36Sopenharmony_ci * we start to drop 1/rate of the packets 164962306a36Sopenharmony_ci */ 165062306a36Sopenharmony_cistatic inline int ip_vs_todrop(struct netns_ipvs *ipvs) 165162306a36Sopenharmony_ci{ 165262306a36Sopenharmony_ci if (!ipvs->drop_rate) 165362306a36Sopenharmony_ci return 0; 165462306a36Sopenharmony_ci if (--ipvs->drop_counter > 0) 165562306a36Sopenharmony_ci return 0; 165662306a36Sopenharmony_ci ipvs->drop_counter = ipvs->drop_rate; 165762306a36Sopenharmony_ci return 1; 165862306a36Sopenharmony_ci} 165962306a36Sopenharmony_ci#else 166062306a36Sopenharmony_cistatic inline int ip_vs_todrop(struct netns_ipvs *ipvs) { return 0; } 166162306a36Sopenharmony_ci#endif 166262306a36Sopenharmony_ci 166362306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 166462306a36Sopenharmony_ci/* Enqueue delayed work for expiring no dest connections 166562306a36Sopenharmony_ci * Only run when sysctl_expire_nodest=1 166662306a36Sopenharmony_ci */ 166762306a36Sopenharmony_cistatic inline void ip_vs_enqueue_expire_nodest_conns(struct netns_ipvs *ipvs) 166862306a36Sopenharmony_ci{ 166962306a36Sopenharmony_ci if (sysctl_expire_nodest_conn(ipvs)) 167062306a36Sopenharmony_ci queue_delayed_work(system_long_wq, 167162306a36Sopenharmony_ci &ipvs->expire_nodest_conn_work, 1); 167262306a36Sopenharmony_ci} 167362306a36Sopenharmony_ci 167462306a36Sopenharmony_civoid ip_vs_expire_nodest_conn_flush(struct netns_ipvs *ipvs); 167562306a36Sopenharmony_ci#else 167662306a36Sopenharmony_cistatic inline void ip_vs_enqueue_expire_nodest_conns(struct netns_ipvs *ipvs) {} 167762306a36Sopenharmony_ci#endif 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci#define IP_VS_DFWD_METHOD(dest) (atomic_read(&(dest)->conn_flags) & \ 168062306a36Sopenharmony_ci IP_VS_CONN_F_FWD_MASK) 168162306a36Sopenharmony_ci 168262306a36Sopenharmony_ci/* ip_vs_fwd_tag returns the forwarding tag of the connection */ 168362306a36Sopenharmony_ci#define IP_VS_FWD_METHOD(cp) (cp->flags & IP_VS_CONN_F_FWD_MASK) 168462306a36Sopenharmony_ci 168562306a36Sopenharmony_cistatic inline char ip_vs_fwd_tag(struct ip_vs_conn *cp) 168662306a36Sopenharmony_ci{ 168762306a36Sopenharmony_ci char fwd; 168862306a36Sopenharmony_ci 168962306a36Sopenharmony_ci switch (IP_VS_FWD_METHOD(cp)) { 169062306a36Sopenharmony_ci case IP_VS_CONN_F_MASQ: 169162306a36Sopenharmony_ci fwd = 'M'; break; 169262306a36Sopenharmony_ci case IP_VS_CONN_F_LOCALNODE: 169362306a36Sopenharmony_ci fwd = 'L'; break; 169462306a36Sopenharmony_ci case IP_VS_CONN_F_TUNNEL: 169562306a36Sopenharmony_ci fwd = 'T'; break; 169662306a36Sopenharmony_ci case IP_VS_CONN_F_DROUTE: 169762306a36Sopenharmony_ci fwd = 'R'; break; 169862306a36Sopenharmony_ci case IP_VS_CONN_F_BYPASS: 169962306a36Sopenharmony_ci fwd = 'B'; break; 170062306a36Sopenharmony_ci default: 170162306a36Sopenharmony_ci fwd = '?'; break; 170262306a36Sopenharmony_ci } 170362306a36Sopenharmony_ci return fwd; 170462306a36Sopenharmony_ci} 170562306a36Sopenharmony_ci 170662306a36Sopenharmony_civoid ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, 170762306a36Sopenharmony_ci struct ip_vs_conn *cp, int dir); 170862306a36Sopenharmony_ci 170962306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6 171062306a36Sopenharmony_civoid ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp, 171162306a36Sopenharmony_ci struct ip_vs_conn *cp, int dir); 171262306a36Sopenharmony_ci#endif 171362306a36Sopenharmony_ci 171462306a36Sopenharmony_ci__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset); 171562306a36Sopenharmony_ci 171662306a36Sopenharmony_cistatic inline __wsum ip_vs_check_diff4(__be32 old, __be32 new, __wsum oldsum) 171762306a36Sopenharmony_ci{ 171862306a36Sopenharmony_ci __be32 diff[2] = { ~old, new }; 171962306a36Sopenharmony_ci 172062306a36Sopenharmony_ci return csum_partial(diff, sizeof(diff), oldsum); 172162306a36Sopenharmony_ci} 172262306a36Sopenharmony_ci 172362306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_IPV6 172462306a36Sopenharmony_cistatic inline __wsum ip_vs_check_diff16(const __be32 *old, const __be32 *new, 172562306a36Sopenharmony_ci __wsum oldsum) 172662306a36Sopenharmony_ci{ 172762306a36Sopenharmony_ci __be32 diff[8] = { ~old[3], ~old[2], ~old[1], ~old[0], 172862306a36Sopenharmony_ci new[3], new[2], new[1], new[0] }; 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci return csum_partial(diff, sizeof(diff), oldsum); 173162306a36Sopenharmony_ci} 173262306a36Sopenharmony_ci#endif 173362306a36Sopenharmony_ci 173462306a36Sopenharmony_cistatic inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) 173562306a36Sopenharmony_ci{ 173662306a36Sopenharmony_ci __be16 diff[2] = { ~old, new }; 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci return csum_partial(diff, sizeof(diff), oldsum); 173962306a36Sopenharmony_ci} 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci/* Forget current conntrack (unconfirmed) and attach notrack entry */ 174262306a36Sopenharmony_cistatic inline void ip_vs_notrack(struct sk_buff *skb) 174362306a36Sopenharmony_ci{ 174462306a36Sopenharmony_ci#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 174562306a36Sopenharmony_ci enum ip_conntrack_info ctinfo; 174662306a36Sopenharmony_ci struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 174762306a36Sopenharmony_ci 174862306a36Sopenharmony_ci if (ct) { 174962306a36Sopenharmony_ci nf_conntrack_put(&ct->ct_general); 175062306a36Sopenharmony_ci nf_ct_set(skb, NULL, IP_CT_UNTRACKED); 175162306a36Sopenharmony_ci } 175262306a36Sopenharmony_ci#endif 175362306a36Sopenharmony_ci} 175462306a36Sopenharmony_ci 175562306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_NFCT 175662306a36Sopenharmony_ci/* Netfilter connection tracking 175762306a36Sopenharmony_ci * (from ip_vs_nfct.c) 175862306a36Sopenharmony_ci */ 175962306a36Sopenharmony_cistatic inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs) 176062306a36Sopenharmony_ci{ 176162306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 176262306a36Sopenharmony_ci return ipvs->sysctl_conntrack; 176362306a36Sopenharmony_ci#else 176462306a36Sopenharmony_ci return 0; 176562306a36Sopenharmony_ci#endif 176662306a36Sopenharmony_ci} 176762306a36Sopenharmony_ci 176862306a36Sopenharmony_civoid ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, 176962306a36Sopenharmony_ci int outin); 177062306a36Sopenharmony_ciint ip_vs_confirm_conntrack(struct sk_buff *skb); 177162306a36Sopenharmony_civoid ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct, 177262306a36Sopenharmony_ci struct ip_vs_conn *cp, u_int8_t proto, 177362306a36Sopenharmony_ci const __be16 port, int from_rs); 177462306a36Sopenharmony_civoid ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp); 177562306a36Sopenharmony_ci 177662306a36Sopenharmony_ci#else 177762306a36Sopenharmony_ci 177862306a36Sopenharmony_cistatic inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs) 177962306a36Sopenharmony_ci{ 178062306a36Sopenharmony_ci return 0; 178162306a36Sopenharmony_ci} 178262306a36Sopenharmony_ci 178362306a36Sopenharmony_cistatic inline void ip_vs_update_conntrack(struct sk_buff *skb, 178462306a36Sopenharmony_ci struct ip_vs_conn *cp, int outin) 178562306a36Sopenharmony_ci{ 178662306a36Sopenharmony_ci} 178762306a36Sopenharmony_ci 178862306a36Sopenharmony_cistatic inline int ip_vs_confirm_conntrack(struct sk_buff *skb) 178962306a36Sopenharmony_ci{ 179062306a36Sopenharmony_ci return NF_ACCEPT; 179162306a36Sopenharmony_ci} 179262306a36Sopenharmony_ci 179362306a36Sopenharmony_cistatic inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp) 179462306a36Sopenharmony_ci{ 179562306a36Sopenharmony_ci} 179662306a36Sopenharmony_ci#endif /* CONFIG_IP_VS_NFCT */ 179762306a36Sopenharmony_ci 179862306a36Sopenharmony_ci/* Using old conntrack that can not be redirected to another real server? */ 179962306a36Sopenharmony_cistatic inline bool ip_vs_conn_uses_old_conntrack(struct ip_vs_conn *cp, 180062306a36Sopenharmony_ci struct sk_buff *skb) 180162306a36Sopenharmony_ci{ 180262306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_NFCT 180362306a36Sopenharmony_ci enum ip_conntrack_info ctinfo; 180462306a36Sopenharmony_ci struct nf_conn *ct; 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_ci ct = nf_ct_get(skb, &ctinfo); 180762306a36Sopenharmony_ci if (ct && nf_ct_is_confirmed(ct)) 180862306a36Sopenharmony_ci return true; 180962306a36Sopenharmony_ci#endif 181062306a36Sopenharmony_ci return false; 181162306a36Sopenharmony_ci} 181262306a36Sopenharmony_ci 181362306a36Sopenharmony_cistatic inline int ip_vs_register_conntrack(struct ip_vs_service *svc) 181462306a36Sopenharmony_ci{ 181562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NF_CONNTRACK) 181662306a36Sopenharmony_ci int afmask = (svc->af == AF_INET6) ? 2 : 1; 181762306a36Sopenharmony_ci int ret = 0; 181862306a36Sopenharmony_ci 181962306a36Sopenharmony_ci if (!(svc->conntrack_afmask & afmask)) { 182062306a36Sopenharmony_ci ret = nf_ct_netns_get(svc->ipvs->net, svc->af); 182162306a36Sopenharmony_ci if (ret >= 0) 182262306a36Sopenharmony_ci svc->conntrack_afmask |= afmask; 182362306a36Sopenharmony_ci } 182462306a36Sopenharmony_ci return ret; 182562306a36Sopenharmony_ci#else 182662306a36Sopenharmony_ci return 0; 182762306a36Sopenharmony_ci#endif 182862306a36Sopenharmony_ci} 182962306a36Sopenharmony_ci 183062306a36Sopenharmony_cistatic inline void ip_vs_unregister_conntrack(struct ip_vs_service *svc) 183162306a36Sopenharmony_ci{ 183262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NF_CONNTRACK) 183362306a36Sopenharmony_ci int afmask = (svc->af == AF_INET6) ? 2 : 1; 183462306a36Sopenharmony_ci 183562306a36Sopenharmony_ci if (svc->conntrack_afmask & afmask) { 183662306a36Sopenharmony_ci nf_ct_netns_put(svc->ipvs->net, svc->af); 183762306a36Sopenharmony_ci svc->conntrack_afmask &= ~afmask; 183862306a36Sopenharmony_ci } 183962306a36Sopenharmony_ci#endif 184062306a36Sopenharmony_ci} 184162306a36Sopenharmony_ci 184262306a36Sopenharmony_ciint ip_vs_register_hooks(struct netns_ipvs *ipvs, unsigned int af); 184362306a36Sopenharmony_civoid ip_vs_unregister_hooks(struct netns_ipvs *ipvs, unsigned int af); 184462306a36Sopenharmony_ci 184562306a36Sopenharmony_cistatic inline int 184662306a36Sopenharmony_ciip_vs_dest_conn_overhead(struct ip_vs_dest *dest) 184762306a36Sopenharmony_ci{ 184862306a36Sopenharmony_ci /* We think the overhead of processing active connections is 256 184962306a36Sopenharmony_ci * times higher than that of inactive connections in average. (This 185062306a36Sopenharmony_ci * 256 times might not be accurate, we will change it later) We 185162306a36Sopenharmony_ci * use the following formula to estimate the overhead now: 185262306a36Sopenharmony_ci * dest->activeconns*256 + dest->inactconns 185362306a36Sopenharmony_ci */ 185462306a36Sopenharmony_ci return (atomic_read(&dest->activeconns) << 8) + 185562306a36Sopenharmony_ci atomic_read(&dest->inactconns); 185662306a36Sopenharmony_ci} 185762306a36Sopenharmony_ci 185862306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_PROTO_TCP 185962306a36Sopenharmony_ciINDIRECT_CALLABLE_DECLARE(int 186062306a36Sopenharmony_ci tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, 186162306a36Sopenharmony_ci struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)); 186262306a36Sopenharmony_ci#endif 186362306a36Sopenharmony_ci 186462306a36Sopenharmony_ci#ifdef CONFIG_IP_VS_PROTO_UDP 186562306a36Sopenharmony_ciINDIRECT_CALLABLE_DECLARE(int 186662306a36Sopenharmony_ci udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, 186762306a36Sopenharmony_ci struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)); 186862306a36Sopenharmony_ci#endif 186962306a36Sopenharmony_ci#endif /* _NET_IP_VS_H */ 1870