ip_conntrack的extend机制以及扩展

ip_conntrack为无状态无连接的IP增加了一个流记录机制,你可以把任何和一个流相关的东西放进去,但是放在哪里呢?原则上ip_conntrack应该是一个可以无限扩展的东西,但事实上,内核的设计者或者说Netfilter的ip_conntrack设计者并没有给用户程序员留下任何可以扩展它的接口和机制,你只能用现有的连接跟踪机制,虽然可以通过nf_ct_extend_register接口注册一个nf_ct_ext_type,但是这个接口也只是内核源码树自己使用的,你无法从外部定义一个心的nf_ct_ext_type。
既然有一个nf_ct_extend_register,为何不让从外部定一个nf_ct_ext_type,然后注册进去呢?除了C语言定义的数据结构不能自己解释自己实现反序列化之外,我觉得这是ip_conntrack代码树的一个缺陷,但是也许是内核开发模式和应用开发模式的不同导致的。一般的,内核API非常不稳定,对于应用来讲,内核的系统调用接口尽可能保持稳定就可以了,至于内部则完全是一个黑盒子。再者,内核开发需要一定的功底,不仅仅是你熟悉一些编程技巧和熟读API文档就能搞得定的。以上的原因,或者说是我的个人猜测,导致了不允许对ip_conntrack的结构体本身进行任何修改,你能改的仅仅是实现逻辑。Linux内核怎么做到这种限制的呢?很简单啊,把相关的头文件放到内核开发的头文件目录就可以了,事实上,只要是那个目录的头文件,你就别指望修改任何结构体和声明,因为那些是要参与符号CRC计算的。
理解了ip_conntrack的extend实际上并不能扩展之后,下面就展示一下老湿是怎么扩展它的。首先看一下ip_conntrack的extend结构是怎么组织的。实际上,我觉得这种组织非常好,非常紧凑,不容易产生内存碎片,它之所以如此紧凑是因为所有的extend相关的内容在内存中全部都是连续的。连续的内存当然没有指针寻址不连续内存方便,但是使用偏移也是不错的,更大的优势是申请/拷贝/释放比较方面,不用考虑深拷贝浅拷贝的问题。类似的数据结构还有iptables的rule在内核中的表示。
连续内存的表示法的最大好处就是可以任意扩展,因为它完全是靠偏移来定位位置的,如果你知道C++和JAVA这类OO语言,就会知道,一个普通类的内存布局中,处在开头的总是基类,所谓的扩展正是处在紧接着基类的内存位置,从而构成了一个子类,当然这只是从实现上来讲的,这里不谈思想!当然这也不是一种有性生殖行为,因为有性生殖从来都不是连续的,你不能说孩子是一个爸爸(是爸爸的一部分...),但是在内存连续的世界里,我们可以说:
struct B {
       struct A a;
       ....
       char *privatedata
};

是一个struct A,毕竟我可以把struct B从a字段往后的字段切掉。知道了这一切之后,我就可以对任意Linux预定义好的所有的nf_ct_ext_type进行任意的扩展了!事实上,我只需要扩展一个指针!虽然我很崇尚连续内存的布局,但是在我还是比较喜欢灵活,毕竟现在的内存价格已经不贵了,干嘛那么在乎内存啊。仅仅扩展一个指针,你想把它解释成一个什么机构都行!我们以一幅图来做解释:




理解了上面的那个图,就明白下面的定义了,不需要改变nf_conn_counter的结构体,只改变它的大小即可,即:

struct nf_conn_counter {
    u_int64_t packets;
    u_int64_t bytes;
};
的大小不是sizeof(struct nf_conn_counter),而是sizeof(struct nf_conn_counter)+sizeof(char *),定义为:
struct nf_conn_counter {
    u_int64_t packets;
    u_int64_t bytes;
    char *p;
};
但是这样便改变了nf_conn_counter结构体的定义,但是考虑以上结构体, 在内存结构上,等价于:
struct my_st {
    struct nf_conn_counter nfc;
    char *p;
};
这样没有改变结构体的定义,结构体my事实上真的就“是一个”结构体nf_conn_counter,在这之后,需要修改的地方真的就不多了,仅仅是一个nf_ct_ext_type的len字段的修改。剩下的工作就是,在需要设置或者取出自己自定义的结构体的时候,按照下面这样:
struct my_st *ms = (struct my_st *)a_instance_of_struct_of_nf_conn_counter;
取出my_st的指针即可。接下来就可以访问my_st里面的p了,至于p是什么,自有作者解释。为何我不提倡连续内存而是用一个指针,关键是我觉得并不是每个conntrack都需要这个字段,为了节省内存只为需要的结构体分配内存,只能用指针。
这就是老湿的做法,JAVA编程思想,真的有思想。老湿很低级,不怎么懂编程,不符合编程高手的口味,但是老湿懂湿想,老湿知道这个机器奴役人的世界是多么的残酷,一个数字化的世界是多么的可悲,而是是编程的人特别是以编程为命的人所很难理解的...
<think>好的,我现在需要回答用户关于IPVS模块的问题,用户要求列出模块的功能和使用方法。首先,我要回忆一下IPVS的相关知识,确保每个模块的信息准确。 用户提到的模块包括:ip_vs、ip_vs_lc、ip_vs_wlc、ip_vs_rr、ip_vs_wrr、ip_vs_lblc、ip_vs_lblcr、ip_vs_dh、ip_vs_sh、ip_vs_nq、ip_vs_sed、ip_vs_ftp、nf_conntrack。这些模块都是IPVS调度算法或相关功能的核心部分。 首先,ip_vs是基础模块,必须加载后才能使用其他调度算法。每个调度算法对应不同的负载均衡策略,比如轮询(RR)、加权轮询(WRR)、最少连接(LC)等。我需要逐个确认每个模块的功能,避免混淆。例如,ip_vs_lc是Least-Connection,而ip_vs_wlc是加权版本,要区分清楚。 然后是ip_vs_lblc和ip_vs_lblcr,这两个可能涉及基于局部的最少连接和带复制的版本,需要查证准确描述。同样,ip_vs_dh是基于目标地址哈希,ip_vs_sh是基于源地址哈希,这些调度算法的具体用途和应用场景需要明确。 接下来是ip_vs_ftp模块,这个用于处理FTP协议的NAT转换,属于特殊协议支持,要说明其作用。nf_conntrack是连接跟踪模块,虽然不是IPVS的直接部分,但IPVS需要它来进行状态跟踪,特别是NAT模式时。 在描述使用方法时,需要说明如何加载模块,比如使用modprobe命令,以及如何通过ipvsadm配置相应的调度算法。例如,使用ipvsadm -A -t VIP:port -s调度算法名称来指定。 同时,需要参考用户提供的引用内容,特别是引用[1]中的模块加载方式和引用[3]中的配置示例,确保回答实际操作一致。用户可能是在配置LVS时遇到问题,需要了解各个模块的作用,以便正确加载和配置。 最后,生成相关问题时要考虑用户可能的后续需求,比如如何选择调度算法、故障排除、性能优化等,这些问题能帮助用户深入理解IPVS的使用。</think>以下是IPVS相关的模块列表及其功能说明使用方法: --- ### 一、IPVS核心模块 1. **ip_vs** - **功能**:IPVS核心模块,提供负载均衡的基础框架,必须加载后才能使用其他调度算法 - **使用方法**: ```bash modprobe ip_vs ``` --- ### 二、调度算法模块 2. **ip_vs_rr** - **功能**:轮询算法(Round Robin),依次将请求分发到后端Real Server[^2] - **配置命令**: ```bash ipvsadm -A -t $VIP:80 -s rr ``` 3. **ip_vs_wrr** - **功能**:加权轮询算法(Weighted RR),根据服务器权重分配请求 - **配置命令**: ```bash ipvsadm -A -t $VIP:80 -s wrr ``` 4. **ip_vs_lc** - **功能**:最少连接算法(Least Connection),将请求发给当前连接数最少的服务器 - **配置命令**: ```bash ipvsadm -A -t $VIP:80 -s lc ``` 5. **ip_vs_wlc** - **功能**:加权最少连接算法(Weighted LC),考虑服务器权重的LC算法 - **配置命令**: ```bash ipvsadm -A -t $VIP:80 -s wlc ``` 6. **ip_vs_lblc** - **功能**:基于局部的最少连接算法(Locality-Based LC),适用于缓存服务器场景 - **配置命令**: ```bash ipvsadm -A -t $VIP:80 -s lblc ``` 7. **ip_vs_lblcr** - **功能**:带复制的基于局部最少连接算法(LBLC with Replication),优化缓存一致性 - **配置命令**: ```bash ipvsadm -A -t $VIP:80 -s lblcr ``` 8. **ip_vs_dh** - **功能**:目标地址哈希算法(Destination Hashing),根据目标地址分配请求 - **配置命令**: ```bash ipvsadm -A -t $VIP:80 -s dh ``` 9. **ip_vs_sh** - **功能**:源地址哈希算法(Source Hashing),根据客户端IP分配请求 - **配置命令**: ```bash ipvsadm -A -t $VIP:80 -s sh ``` 10. **ip_vs_nq** - **功能**:永不排队算法(Never Queue),优先选择空闲服务器 - **配置命令**: ```bash ipvsadm -A -t $VIP:80 -s nq ``` 11. **ip_vs_sed** - **功能**:最短预期延迟算法(Shortest Expected Delay),优化响应时间 - **配置命令**: ```bash ipvsadm -A -t $VIP:80 -s sed ``` --- ### 三、特殊协议支持模块 12. **ip_vs_ftp** - **功能**:支持FTP协议的NAT转换,用于处理FTP被动模式的端口协商[^3] - **使用方法**: ```bash modprobe ip_vs_ftp ``` --- ### 四、依赖模块 13. **nf_conntrack** - **功能**:连接跟踪模块,IPVS在NAT模式下依赖此模块进行会话跟踪 - **使用方法**: ```bash modprobe nf_conntrack ``` --- ### 模块加载示例 ```bash # 手动加载核心模块调度算法 modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr # 查看已加载模块 lsmod | grep ip_vs ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值