分享

IPVS代码阅读笔记(一):重要数据结构

 jijo 2009-11-16
 

IPVS是基于Netfilter框架实现的内核模块。它实现了IP层的负载均衡功能。IPVS完全在内核态实现,效率非常高。IPVS的官方网站:www.
 
首先来看一下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模式分别对应不同的传输函数。

 

 

发表于: 2008-05-09 ,修改于: 2008-05-19 21:32,已浏览164次,有评论0条 推荐 投诉


 



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多