首先来看一下IPVS模块的一些重要数据结构。
1、ip_vs_service结构
ip_vs_service结构代表的是一个IPVS服务对象,它包含了IPVS服务的监听地址、端口、协议和调度算法等信息。
/* * The information about the virtual service offered to the net * and the forwarding entries */ struct ip_vs_service { struct list_head s_list; /* for normal service table */ struct list_head f_list; /* for fwmark-based service table */ atomic_t refcnt; /* reference counter */ atomic_t usecnt; /* use counter */
__u16 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 */ __u32 num_dests; /* number of servers */
struct ip_vs_stats stats; /* statistics for the service */ struct ip_vs_app *inc; /* bind conns to this app inc */
/* for scheduling */ struct ip_vs_scheduler *scheduler; /* bound scheduler object */ rwlock_t sched_lock; /* lock sched_data */ void *sched_data; /* scheduler application data */ };
|
s_list是全局hash链表ip_vs_svc_table的一个节点。ip_vs_svc_table是这样定义的:
/* the service table hashed by <protocol, addr, port> */ static struct list_head ip_vs_svc_table[IP_VS_SVC_TAB_SIZE];
|
它是一个数组,每个成员是一个链表头。将ip_vs_service对象的协议类型、地址和端口进行hash,hash值作为数组下标,然后将此对象置入数组成员对应的链表中。
refcnt和usecnt分别是ip_vs_service对象的引用计数和使用计数。它们是atomic_t类型的变量,使用 atomic_XXX系列函数对它们进行操作。refcnt在对象新建时为0,当ip_vs_service对象被加入链表或从链表删除,或者被 ip_vs_dest对象引用时,refcnt相应地增或减1。usecnt初始化为1,然后随着__ip_vs_service_get和 ip_vs_service_put的对称调用,usecnt相应地增减1。
protocol是ip_vs_service对象的协议类型,其值为IPPROTO_XXX,如IPPROTO_TCP等。
addr和port为ip_vs_service对象的监听地址和端口,网络字节序。
flags为ip_vs_service对象的状态标志位,可以取IP_VS_SVC_F_PERSISTENT和 IP_VS_SVC_F_HASHED。前者表示IPVS服务使用了基于IP地址的会话保持,即同一IP地址发起的连接将被负载到同一台真实服务器上。后 者表示ip_vs_service对象已被加入到ip_vs_svc_table链表中。
timeout和netmask只有在IP_VS_SVC_F_PERSISTENT标志位被设置时才有效。timeout是会话的超时时间,超过 此时间后,会话将不再有效。同一IP地址发起的两个连接,如果间隔超过此时间,则未必会被负载到同一台真实服务器上。netmask可以将会话保持设置成 基于IP网段的,即同一网段发起的连接将被负载到同一台真实服务器上。
destinations是ip_vs_dest对象链表,它代指了IPVS服务对应的真实服务器列表。num_dests是服务器个数。
scheduler指向了一个ip_vs_scheduler对象,它代指一种调度算法。sched_lock和sched_data是ip_vs_scheduler对象的锁和私有数据。
2、ip_vs_dest结构
ip_vs_dest结构代表的是一台真实服务器,它包含了真实服务器的地址、端口和权重等信息。
/* * The real server destination forwarding entry * with ip address, port number, and so on. */ struct ip_vs_dest { struct list_head n_list; /* for the dests in the service */ struct list_head d_list; /* for table with all the dests */
__u32 addr; /* IP address of the server */ __u16 port; /* port number of the server */ volatile unsigned flags; /* dest status flags */ atomic_t conn_flags; /* flags to copy to conn */ atomic_t weight; /* server weight */
atomic_t refcnt; /* reference counter */ struct ip_vs_stats stats; /* statistics */
/* connection counters and thresholds */ atomic_t activeconns; /* active connections */ atomic_t inactconns; /* inactive connections */ atomic_t persistconns; /* persistent connections */ __u32 u_threshold; /* upper threshold */ __u32 l_threshold; /* lower threshold */
/* for destination cache */ spinlock_t dst_lock; /* lock of dst_cache */ struct dst_entry *dst_cache; /* destination cache entry */ u32 dst_rtos; /* RT_TOS(tos) for dst */
/* for virtual service */ struct ip_vs_service *svc; /* service it belongs to */ __u16 protocol; /* which protocol (TCP/UDP) */ __u32 vaddr; /* virtual IP address */ __u16 vport; /* virtual port number */ __u32 vfwmark; /* firewall mark of service */ };
|
n_list是ip_vs_service对象中destinations链表中的一个节点,表示此 ip_vs_dest对象是IPVS服务的一个服务器节点。IPVS中有一个全局的ip_vs_dest对象链表ip_vs_dest_trash。每当 要销毁ip_vs_dest对象时,如果其引用计数不为0,则暂时将此ip_vs_dest对象置入链表ip_vs_dest_trash,留待以后销毁 或者重新使用。
d_list是全局hash链表ip_vs_rtable的一个节点。
addr和port是ip_vs_dest对象的真实服务器地址和端口,网络字节序。
flags是ip_vs_dest对象的状态标志位,IP_VS_DEST_F_AVAILABLE表示此真实服务器可用,IP_VS_DEST_F_OVERLOAD表示此真实服务器超负荷。
conn_flags是ip_vs_dest对象的连接标志位。这些标志位本身不是用来标示 ip_vs_dest对象的,而是由ip_vs_dest对象创建ip_vs_conn对象时,赋给后者的。IP_VS_CONN_F_MASQ、 IP_VS_CONN_F_TUNNEL和IP_VS_CONN_F_DROUTE,分别代表NAT、TUN和DR三种模式。后两种模式也暗含了 IP_VS_CONN_F_NOOUTPUT标志位。
weight是ip_vs_dest对象的权重,用于调度。
refcnt是ip_vs_dest对象的引用计数,初值为0,当对象被加入链表或从链表删除,或者被ip_vs_conn对象引用时,refcnt相应地增或减1。
svc、protocol、vaddr、vport分别是相应的ip_vs_service对象的参数。
3、ip_vs_conn结构
ip_vs_conn结构代表的是一个连接对象,它包含客户端、IPVS、真实服务器的地址和端口等信息。
/* * IP_VS structure allocated for each dynamically scheduled connection */ struct ip_vs_conn { struct list_head c_list; /* hashed list heads */
/* Protocol, addresses and port numbers */ __u32 caddr; /* client address */ __u32 vaddr; /* virtual address */ __u32 daddr; /* destination address */ __u16 cport; __u16 vport; __u16 dport; __u16 protocol; /* Which protocol (TCP/UDP) */
/* counter and timer */ atomic_t refcnt; /* reference count */ struct timer_list timer; /* Expiration timer */ volatile unsigned long timeout; /* timeout */
/* Flags and state transition */ spinlock_t lock; /* lock for state transition */ volatile __u16 flags; /* status flags */ volatile __u16 state; /* state info */
/* Control members */ struct ip_vs_conn *control; /* Master control connection */ atomic_t n_control; /* Number of controlled ones */ struct ip_vs_dest *dest; /* real server */ atomic_t in_pkts; /* incoming packet counter */
/* packet transmitter for different forwarding methods. If it mangles the packet, it must return NF_DROP or better NF_STOLEN, otherwise this must be changed to a sk_buff **. */ int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
/* Note: we can group the following members into a structure, in order to save more space, and the following members are only used in VS/NAT anyway */ struct ip_vs_app *app; /* bound ip_vs_app object */ void *app_data; /* Application private data */ struct ip_vs_seq in_seq; /* incoming seq. struct */ struct ip_vs_seq out_seq; /* outgoing seq. struct */ };
|
c_list是全局hash链表ip_vs_conn_tab的一个节点。
caddr、vaddr、daddr、cport、vport、dport分别是客户端、IPVS、真实服务器的地址和端口。
protocol是ip_vs_conn对象的协议类型。
refcnt是ip_vs_conn对象的使用计数。其初值为1,__ip_vs_conn_in_get/__ip_vs_conn_put成对调用,或者对象置入链表中,都会影响到此计数值。
timer是ip_vs_conn对象的生存期,当timer到期时,对象被销毁。
timeout是ip_vs_conn对象动态的超时时间,每当对象操作完毕,timeout值用来更新timer,以延长对象的生存期。timeout受连接状态等的影响。
flags是ip_vs_conn对象的标志位,其中IP_VS_CONN_F_MASQ、IP_VS_CONN_F_TUNNEL、 IP_VS_CONN_F_DROUTE和IP_VS_CONN_F_NOOUTPUT标志位在介绍ip_vs_dest对象时已经解释过了。 IP_VS_CONN_F_HASHED标志位表示此ip_vs_conn对象已经被添加到全局hash链表ip_vs_conn_tab中。 IP_VS_CONN_F_INACTIVE标志位表示当前连接为非活动状态,每个ip_vs_conn对象在创建时都会指定此标志。 IP_VS_CONN_F_NO_CPORT标志位用于一些特殊协议,如ftp等。IP_VS_CONN_F_TEMPLATE标志位用于实现基于IP地 址的会话保持。
state是ip_vs_conn对象用来记录自己的状态的。
control指向ip_vs_conn对象的父连接对象,它与IP_VS_CONN_F_TEMPLATE的作用一样,用于实现基于IP地址的会话保持。
dest指向此连接对象对应的ip_vs_dest对象。
packet_xmit为传输函数,NAT、TUN和DR模式分别对应不同的传输函数。