#ifndef _TCP_VS_H #define _TCP_VS_H #define KTCPVS_VSNAME_MAXLEN 16 #define KTCPVS_SCHEDNAME_MAXLEN 32 #define KTCPVS_SCHEDRULE_MAXLEN 256 struct tcp_vs_ctl { int cmd; char name[KTCPVS_VSNAME_MAXLEN]; char sched_name[KTCPVS_SCHEDNAME_MAXLEN]; int serverport; /* server port number */ unsigned timeout; /* timeout in ticks */ int maxSpareServers; int minSpareServers; int startservers; int maxClients; int keepAlive; int maxKeepAliveRequests; int keepAliveTimeout; u_int32_t netmask; u_int32_t daddr; u_int16_t dport; int weight; }; #define TCP_VS_CMD_NONE 0 /* just peek */ #define TCP_VS_CMD_START 1 #define TCP_VS_CMD_STOP 2 #define TCP_VS_CMD_ADD 3 #define TCP_VS_CMD_SET 4 #define TCP_VS_CMD_DEL 6 #define TCP_VS_CMD_FLUSH 7 #define TCP_VS_CMD_LIST 8 /* actually fake: done via read */ #define TCP_VS_CMD_ADD_DEST 10 /* for adding dest in TCPVS */ #define TCP_VS_CMD_DEL_DEST 11 /* for deleting dest in TCPVS */ #define TCP_VS_CMD_SET_DEST 12 /* for setting dest in TCPVS */ #define TCP_VS_TEMPLATE_TIMEOUT 15*HZ /* /proc/sys/net/ktcpvs/unload /proc/sys/net/ktcpvs/config /proc/sys/net/ktcpvs/vs0 maxSpareServers; minSpareServers; startservers maxClients keepAlive maxKeepAliveRequests; keepAliveTimeout; start stop realservers read to show all the real servers cat realservers write to use different command format such as echo "add server port weight" > realservers echo "del server port" > realservers echo "set server port weight" > realservers scheduler {rr|wrr|lc|wlc|http|rewrite|...} scheduler may create some sysctl variables content-based scheduler may create a sysctl variable for to enter the rules while initializing the virtual server. request-rewrite scheduler may create another variable too. /proc/sys/net/ktcpvs/vs1 ... */ #ifdef __KERNEL__ #include /* for list_head */ #include /* for rwlock_t */ #include /* for atomic_t */ #include /* for ctl_table */ #include /* for kmalloc */ /* */ #define CONFIG_TCP_VS_DEBUG #ifdef CONFIG_TCP_VS_DEBUG #define TCP_VS_DBG(msg...) printk(KERN_DEBUG "TCPVS: " ## msg ) #else /* NO DEBUGGING at ALL */ #define TCP_VS_DBG(msg...) #endif #define TCP_VS_ERR(msg...) printk(KERN_ERR "TCPVS: " ## msg ) #define TCP_VS_INFO(msg...) printk(KERN_INFO "TCPVS: " ## msg ) #define TCP_VS_WARNING(msg...) \ printk(KERN_WARNING "TCPVS: " ## msg) #ifdef CONFIG_TCP_VS_DEBUG #define EnterFunction(x) printk("Enter: %s, %s line %i\n", \ x, __FILE__, __LINE__) #define LeaveFunction(x) printk("Leave: %s, %s line %i\n", \ x, __FILE__, __LINE__) #else #define EnterFunction(x) do {} while (0) #define LeaveFunction(x) do {} while (0) #endif /* #define KTCPVS_MAXCONN 1000 */ #define NET_KTCPVS 20 enum { NET_KTCPVS_CONFIG = 1, NET_KTCPVS_UNLOAD = 2, }; enum { NET_KTCPVS_DUMMYVS = 1, }; /* * The following two enum should not repeat, because they create entries * in the same directory. */ enum { NET_KTCPVS_VS_SCHEDULER = 1, NET_KTCPVS_VS_START = 2, NET_KTCPVS_VS_STOP = 3, NET_KTCPVS_VS_SERVERPORT = 9, NET_KTCPVS_VS_DESTINATIONS = 10, NET_KTCPVS_VS_SLOPPYMIME = 11 }; enum { NET_KTCPVS_SCHED_HTTP = 100, NET_KTCPVS_SCHED_REWRITE = 101, }; /* * TCPVS sysctl table */ struct tcp_vs_sysctl_table { struct ctl_table_header *sysctl_header; ctl_table vs_vars[12]; ctl_table vs_dir[2]; ctl_table ktcpvs_dir[2]; ctl_table root_dir[2]; }; /* * The information about Kernel TCP Virtual Server * and the forwarding entries */ struct tcp_vs { /* virtual server list */ struct list_head list; /* tcp_vs list */ /* server control */ int start; int stop; /* server configuration */ char *name; /* server name */ int serverport; /* server port number */ unsigned flags; /* status flags */ unsigned timeout; /* timeout in ticks */ int maxSpareServers; int minSpareServers; int startservers; int maxClients; int keepAlive; int maxKeepAliveRequests; int keepAliveTimeout; /* real server list */ struct list_head destinations; /* real server list */ /* server scheduler */ struct tcp_vs_scheduler *scheduler; /* bound scheduler object */ void *sched_data; /* scheduler application data */ struct tcp_vs_sysctl_table *sched_st; /* scheduler sysctl table */ struct list_head sched_rule; /* scheduler rule list */ /* server sysctl table */ struct tcp_vs_sysctl_table *sysctl; /* vs sysctl table */ /* run-time variables */ struct socket *mainsock; atomic_t conns; /* connection counter */ atomic_t childcount; /* child counter */ atomic_t running; /* running flag */ int index; /* server index */ }; /* * The real server destination forwarding entry * with ip address, port, weight ... */ struct tcp_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 */ int weight; /* server weight */ unsigned flags; /* dest status flags */ atomic_t conns; /* active connections */ /* atomic_t inactconns; */ /* inactive connections */ atomic_t refcnt; /* reference counter */ }; /* * TCPVS connection object */ struct tcp_vs_conn { struct list_head n_list; /* d-linked list head */ __u32 addr; /* client address */ unsigned flags; /* status flag */ struct socket *csock; /* socket connected to client */ struct socket *dsock; /* socket connected to server */ struct tcp_vs_dest *dest; /* destination server */ struct tcp_vs *vs; /* TCPVS it belongs to */ char *buffer; /* buffer for conn handling */ size_t buflen; /* buffer length */ }; /* * The scheduler object */ struct tcp_vs_scheduler { struct list_head n_list; /* d-linked list head */ char *name; /* scheduler name */ atomic_t refcnt; /* reference counter */ /* scheduler initializing vs */ int (*init_vs)(struct tcp_vs *vs); /* scheduling vs finish */ int (*done_vs)(struct tcp_vs *vs); /* scheduler updating vs */ int (*update_vs)(struct tcp_vs *vs); /* scheduler control */ int (*control)(struct tcp_vs *vs, struct tcp_vs_ctl *ctl, char *data); /* select a server and connect to it */ struct socket * (*schedule)(struct tcp_vs_conn *conn, struct tcp_vs *vs); }; extern atomic_t tcp_vs_index; extern rwlock_t __tcp_vs_lock; extern int StartListening(struct tcp_vs *vs); extern void StopListening(struct tcp_vs *vs); extern struct socket * tcp_vs_connect2dest(struct tcp_vs_dest *dest); extern int tcp_vs_sendbuffer(struct socket *sock, const char *Buffer,const size_t Length); extern int tcp_vs_sendbuffer_async(struct socket *sock, const char *Buffer,const size_t Length); extern int tcp_vs_recvbuffer(struct socket *sock, char *Buffer, const size_t BufLen); extern int tcp_vs_recvbuffer_async(struct socket *sock, char *Buffer, const size_t BufLen); #ifndef strdup static __inline__ char *strdup(char *str) { int n = strlen(str)+1; char *s = kmalloc(n, GFP_KERNEL); if (!s) return NULL; return strcpy(s, str); } #endif extern char *tcp_vs_getline(char *s, char *token, int n); extern char *tcp_vs_getword(char *s, char *token, int n); /* from sysctl.c */ extern struct list_head tcp_vs_list; extern int sysctl_ktcpvs_unload; extern struct tcp_vs_dest *tcp_vs_lookup_dest(struct tcp_vs *vs, __u32 daddr, __u16 dport); extern int tcp_vs_del_virtualserver(struct tcp_vs *vs); extern void tcp_vs_control_start(void); extern void tcp_vs_control_stop(void); /* from sched.c */ extern int register_tcp_vs_scheduler(struct tcp_vs_scheduler *scheduler); extern int unregister_tcp_vs_scheduler(struct tcp_vs_scheduler *scheduler); extern int tcp_vs_bind_scheduler(struct tcp_vs *vs, struct tcp_vs_scheduler *scheduler); extern int tcp_vs_unbind_scheduler(struct tcp_vs *vs); extern struct tcp_vs_scheduler *tcp_vs_get_scheduler(const char *name); extern void tcp_vs_put_scheduler(struct tcp_vs_scheduler *sched); #endif /* __KERNEL__ */ #endif /* _TCP_VS_H */