/* * IP virtual server * data structure and funcationality definitions */ #include #ifndef _IP_VS_H #define _IP_VS_H #define IP_VS_VERSION_CODE 0x00090C #define NVERSION(version) \ (version >> 16) & 0xFF, \ (version >> 8) & 0xFF, \ version & 0xFF /* * Virtual Service Flags */ #define IP_VS_SVC_F_PERSISTENT 0x0001 /* persistent port */ #define IP_VS_SVC_F_HASHED 0x0002 /* hashed entry */ /* * Destination Server Flags */ #define IP_VS_DEST_F_AVAILABLE 0x0001 /* Available tag */ /* * The default IP_VS_TEMPLATE_TIMEOUT is a little larger than average * connection time plus MASQUERADE_EXPIRE_TCP_FIN(2*60*HZ). Because the * template won't be released until its controlled masq entries are * expired. * If IP_VS_TEMPLATE_TIMEOUT is too less, the template will soon expire * and will be put in expire again and again, which requires additional * overhead. If it is too large, the same will always visit the same * server, which will make dynamic load imbalance worse. */ #define IP_VS_TEMPLATE_TIMEOUT 6*60*HZ #ifdef __KERNEL__ #ifdef CONFIG_IP_VS_DEBUG #define IP_VS_DBG(msg...) printk(KERN_DEBUG "IPVS: " ## msg ) #else /* NO DEBUGGING at ALL */ #define IP_VS_DBG(msg...) #endif #define IP_VS_ERR(msg...) printk(KERN_ERR "IPVS: " ## msg ) #define IP_VS_INFO(msg...) printk(KERN_INFO "IPVS: " ## msg ) #define IP_VS_WARNING(msg...) \ printk(KERN_WARNING "IPVS: " ## msg) struct ip_vs_dest; struct ip_vs_scheduler; /* * The information about the virtual service offered to the net * and the forwarding entries */ struct ip_vs_service { struct list_head s_list; /* hashed d-linked list head */ struct list_head f_list; /* hashed d-linked list head */ __u16 protocol; /* which protocol (TCP/UDP) */ __u32 addr; /* IP address for virtual service */ __u16 port; /* port number for the service */ __u32 fwmark; /* firewall mark of the service */ unsigned flags; /* service status flags */ unsigned timeout; /* persistent timeout in ticks */ __u32 netmask; /* grouping granularity */ struct list_head destinations; /* real server d-linked list */ struct ip_vs_scheduler *scheduler; /* bound scheduler object */ void *sched_data; /* scheduler application data */ }; /* * The real server destination forwarding entry * with ip address, port */ struct ip_vs_dest { struct list_head n_list; /* d-linked list head */ __u32 addr; /* IP address of real server */ __u16 port; /* port number of the service */ unsigned flags; /* dest status flags */ unsigned masq_flags; /* flags to copy to masq */ atomic_t activeconns; /* active connections */ atomic_t inactconns; /* inactive connections */ atomic_t refcnt; /* reference counter */ int weight; /* server weight */ struct list_head d_list; /* table with all dests */ /* for virtual service */ __u16 protocol; /* which protocol (TCP/UDP) */ __u32 vaddr; /* IP address for virtual service */ __u16 vport; /* port number for the service */ __u32 vfwmark; /* firewall mark of the service */ }; /* * The scheduler object */ struct ip_vs_scheduler { struct list_head n_list; /* d-linked list head */ char *name; /* scheduler name */ atomic_t refcnt; /* reference counter */ /* scheduler initializing service */ int (*init_service)(struct ip_vs_service *svc); /* scheduling service finish */ int (*done_service)(struct ip_vs_service *svc); /* scheduler updating service */ int (*update_service)(struct ip_vs_service *svc); /* selecting a server from the given service */ struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc); }; /* * IP Virtual Server masq entry hash table */ #define IP_VS_TAB_BITS CONFIG_IP_MASQUERADE_VS_TAB_BITS #define IP_VS_TAB_SIZE (1 << IP_VS_TAB_BITS) #define IP_VS_TAB_MASK (IP_VS_TAB_SIZE - 1) extern struct list_head *ip_vs_table; /* * Hash and unhash functions */ extern int ip_vs_hash(struct ip_masq *ms); extern int ip_vs_unhash(struct ip_masq *ms); /* * Registering/unregistering scheduler functions */ extern int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler); extern int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler); /* * Lookup functions for the hash table (caller must lock table) */ extern struct ip_masq * __ip_vs_in_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); extern struct ip_masq * __ip_vs_out_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); /* * Creating a masquerading entry for IPVS */ extern struct ip_masq * ip_masq_new_vs(int proto, __u32 maddr, __u16 mport, __u32 saddr, __u16 sport, __u32 daddr, __u16 dport, unsigned flags); /* * IPVS data and functions */ extern rwlock_t __ip_vs_lock; extern void ip_vs_set_state(struct ip_masq *ms, int new_state); extern void ip_vs_bind_masq(struct ip_masq *ms, struct ip_vs_dest *dest); extern void ip_vs_unbind_masq(struct ip_masq *ms); extern int ip_vs_ctl(int optname, struct ip_masq_ctl *mctl, int optlen); extern struct ip_vs_service * ip_vs_lookup_service(__u32 fwmark, __u16 protocol, __u32 vaddr, __u16 vport); extern struct ip_vs_service * ip_vs_lookup_svc_fwm(__u32 fwmark); extern struct ip_vs_dest * __ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport); extern struct ip_masq * ip_vs_schedule(struct ip_vs_service *svc, struct iphdr *iph); extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb); extern int ip_vs_tunnel_xmit(struct sk_buff *skb, __u32 daddr); extern int ip_vs_dr_xmit(struct sk_buff *skb, __u32 daddr); /* * init function */ extern int ip_vs_init(void); /* * init function prototypes for scheduling modules * these function will be called when they are built in kernel */ extern int ip_vs_rr_init(void); extern int ip_vs_wrr_init(void); extern int ip_vs_lc_init(void); extern int ip_vs_wlc_init(void); /* * Slow timer functions for IPVS */ extern void add_sltimer(struct timer_list * timer); extern int del_sltimer(struct timer_list * timer); extern void mod_sltimer(struct timer_list *timer, unsigned long expires); /* * ip_vs_fwd_tag returns the forwarding tag of the masq */ extern __inline__ char ip_vs_fwd_tag(struct ip_masq *ms) { char fwd = 'M'; switch (IP_MASQ_VS_FWD(ms)) { case IP_MASQ_F_VS_LOCALNODE: fwd = 'L'; break; case IP_MASQ_F_VS_TUNNEL: fwd = 'T'; break; case IP_MASQ_F_VS_DROUTE: fwd = 'R'; break; } return fwd; } extern __inline__ char * ip_vs_fwd_name(unsigned masq_flags) { char *fwd; switch (masq_flags & IP_MASQ_F_VS_FWD_MASK) { case IP_MASQ_F_VS_LOCALNODE: fwd = "Local"; break; case IP_MASQ_F_VS_TUNNEL: fwd = "Tunnel"; break; case IP_MASQ_F_VS_DROUTE: fwd = "Route"; break; default: fwd = "Masq"; } return fwd; } /* * ip_vs_forward forwards the packet through tunneling, direct * routing or local node (passing to the upper layer). * Return values mean: * 0 skb must be passed to the upper layer * -1 skb must be released * -2 skb has been released */ extern __inline__ int ip_vs_forward(struct sk_buff *skb, struct ip_masq *ms) { int ret = -1; atomic_inc(&ms->in_pkts); switch (IP_MASQ_VS_FWD(ms)) { case IP_MASQ_F_VS_TUNNEL: if (ip_vs_tunnel_xmit(skb, ms->saddr) == 0) { IP_VS_DBG("tunneling failed.\n"); } else { IP_VS_DBG("tunneling succeeded.\n"); } ret = -2; break; case IP_MASQ_F_VS_DROUTE: if (ip_vs_dr_xmit(skb, ms->saddr) == 0) { IP_VS_DBG("direct routing failed.\n"); } else { IP_VS_DBG("direct routing succeeded.\n"); } ret = -2; break; case IP_MASQ_F_VS_LOCALNODE: ret = 0; } return ret; } #endif /* __KERNEL__ */ #endif /* _IP_VS_H */