忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT 视频 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
1234下一页
最近访问板块 发新帖
查看: 26461 | 回复: 35

[网络子系统] linux-2.6.35.6 xtables&iptables&hipac [复制链接]

论坛徽章:
0
发表于 2012-05-30 12:12 |显示全部楼层
本帖最后由 pywj777 于 2012-05-30 13:06 编辑

之前总是拜读“独孤九贱”兄的大作,受益匪浅。现也将自己的一些总结分享给大家,由于语言组织能力较差,所以多上图,少上字。

Xtables提供的资源

iptables1.jpg

struct  xt_af  xt[]结构数组
该数组用于挂载各个协议的match和target资源。由于写者(添加、删除)和读者(查找)都是在内核空间进程上下文执行,所以它们只需要用xt[n].mutex信号量进行互斥。读者(查找)在将规则关联上一个match或target时会增加它们所在模块的引用计数,在它释放这个引用计数之前该模块是不会被卸载的,所以另外一个读者(规则匹配)在软中断中可以放心的使用,不需加任何锁。
  • xt_register_match(struct xt_match *match)与xt_unregister_match(struct xt_match *match)
    用于在xt[]数组上挂载对应协议的match,由于它们都是在内核空间的进程上下文被使用,所以它们使用mutex_lock(&xt[af].mutex)信号量进行加锁和解锁。(写者)
  • xt_register_target(struct xt_target *target)与xt_unregister_target(struct xt_target *target)
    用于在xt[]数组上挂载对应协议的target,由于它们都是在内核空间的进程上下文被使用,所以它们使用mutex_lock(&xt[af].mutex)信号量进行加锁和解锁。(写者)
  • struct xt_match *xt_find_match(u8 af, const char *name, u8 revision)与struct xt_target *xt_find_target(u8 af, const char *name, u8 revision)
    用于在xt[]数组中查找对应协议的match或target与对应规则相关联,并增加match和target所在模块的引用计数。由于它们都是在内核空间的进程上下文被使用,所以它们使用mutex_lock(&xt[af].mutex)信号量进行加锁和解锁。同时内核在软中断中进行规则匹时配,它引用规则关联的match和target是安全的,因为match和target所在模块由于引用计数是不会被释放的。(读者)
  • 由于有一个读者是在软中断的中,并且有多个CPU同时使用,是否需要其它保护。答:不需要。因为如果软中断中引用的规则使用了某个match或target,则拥有该match和target模块的引用计数会被加1,该模块将不会被卸载(这也就要求在调用xt_unregister_match()或xt_unregister_target()时必须先判断它们所在模块的引用计数,通常它们被放在模块注销函数中)。如果引用计数为0,则说明没有规则引用该match或target,则在软中断中也不会使用它。


net.xt.tables[]网络命名空间协议链表
该命名空间协议链表用于将不同协议的table表挂到对应协议链表中。
写者(添加、删除)table表都在内核空间进程上下文执行,又由于它需要检查该表与注册的target、match名字不冲突,所以他们只需要用xt[n].mutex信号。
读者在软中断中通过HOOK引用这些表,所以在写者(添加、删除)之前一定要保证没有读者在操作。添加表操作一定要先通过xt_register_table()添加一个表,然后再通过xt_hook_link()使HOOK能够引用这些表;删除表操作一定要先通过xt_hook_unlink()去掉HOOK对表的引用,然后再通过xt_unregister_table()删除一个表。
  • struct xt_table *xt_register_table(struct net *net, const struct xt_table *input_table, struct xt_table_info *bootstrap, struct xt_table_info *newinfo)
    主要是复制input_table到table表,并将newinfo(由调用该函数模块提供的私有数据xt_table_info)与该表的table->private指针相关联,然后根据该表指定的协议挂入对应的net.xt.table[table->af]链表中。它使用xt[n].mutex信号进行加锁(如上所述)。
  • void *xt_unregister_table(struct xt_table *table)
    主要是将table从net.xt.table[table->af]链表中取下来,并返回table->private指针指向的xt_table_info数据。它使用xt[n].mutex信号进行加锁(如上所述)。
  • struct nf_hook_ops *xt_hook_link(const struct xt_table *table, nf_hookfn *fn)与void xt_hook_unlink(const struct xt_table *table, struct nf_hook_ops *ops)
    主要是利用xt_table结构和钩子函数构造出nf_hook_ops钩子项,然后调用nf_register_hooks()或nf_unregisgter_hooks()函数来注册或注销ipv4协议对应点的钩子函数,这两个函数主要用在内核空间的进程上下文。由于nf_regisgter_hooks()已提供了保护,所以它们不需要任何形式的锁保护。

评分

参与人数 2可用积分 +22 收起 理由
embeddedlwp + 10 赞一个!
send_linux + 12 赞一个!

查看全部评分

论坛徽章:
0
发表于 2012-05-30 12:26 |显示全部楼层
本帖最后由 pywj777 于 2012-05-30 12:36 编辑

Iptables利用Xtable初始化filter表的结构图

iptables2.jpg

  • struct xt_table *ipt_register_table(struct net *net, const struct xt_table *table, const struct ipt_replace *repl)(注册并初始化一个表,然后调用xt_hook_link()引用该表)
    该函数是iptables为filter、nat、mangle模块提供用于注册相应表结构的接口。它根据当前表要被挂入的HOOK点来构建上图所示的xt_table_info初始规则表,并调用xt_register_table()函数将filter表的xt_table和xt_table_info结构挂入net.xt.table[IPV4]链表中。(上图是iptables_filter模块调用该函数注册的结构图)
    注册完一个表后,就可以通过xt_hook_link()函数注册一个HOOK点来使用这个表中的规则处理数据包。

  • void ipt_unregister_table(struct net *net, struct xt_table *table)(注销一个表,要在xt_hook_unlink()之后使用)
    该函数是iptables为filter、nat、mangle模块提供用于注销相应表结构的接口。它调用xt_unregister_table()将xt_table从对应协议链表中取下并释放,然后将返回的xt_table_info结构中的规则逐一释放(同时也会释放规则引用的match和target模块的引用计数),最后释放xt_table_info结构。
    为保证释放table表时没有其它读者,所以在调用该函数之前要先调用xt_hook_unlink()函数注销在HOOK点挂入的处理函数,保证没有其它CPU会再引用到该表。

  • struct  xt_info_lock  xt_info_locks[CPU](用于保证读取修改表中规则的锁,每个CPU一个锁)

    struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af, const char *name)
    查找name指定的表,使用xt[af].mutex加锁,保证只有一个写者处理该表。并增加表所在模块的引用计数,防止该表被错误释放。

    void xt_table_unlock(struct xt_table *table)
    与xt_find_table_lock()配对使用,释放xt[table->af].mutex锁。

    static inline void xt_info_rdlock_bh(void) 或 static inline void xt_info_rdunlock_bh(void)
    获取或释放本CPU的xt_info_locks[cpu]锁。这个锁主要是用于防止正被使用的规则表(xt_table_info结构)被释放。(它与get_counters()进行互斥)

    static inline void xt_info_wrlock(unsigned int cpu) 或 static inline void xt_info_wrunlock(unsigned int cpu)
    获取指定CPU的xt_info_locks[cpu]锁。它主要在get_counters()中被调用,用于获取所有CPU的写锁,保证所有CPU都已完成了对规则表的引用。

    static void get_counters(const struct xt_table_info *t, struct xt_counters counters[])
    它可以保证其它CPU都已完成了一次对表中所有规则的引用。因为它要对所有其它CPU调用xt_info_wrlock(cpu)函数来获取其它CPU的xt_info_lock,而其它CPU在读取表中规则时,要通过xt_info_rdlock_bh获取各自的xt_info_lock锁,所有当它获取完所有其它CPU的xt_info_lock锁后,就表示其它CPU都已完成了对表中规则的引用。这就说明了为什么在do_replace中调用完get_counters()后能够安全的释放旧的xt_table_info结构。

  • static int get_info(struct net *net, void __user *user,  const int *len, int compat) (读取表中信息)
    该函数是用户使用iptables命令操作表中规则时,用于获取表中信息的接口。它使用xt_find_table_lock()和xt_table_unlock()保证没有其它人操作该表。

  • static int get_entries(struct net *net,  struct ipt_get_entries __user *uptr,  const int *len)(读取表中规则)
    该函数是用户使用iptables命令操作表中规则时,用于获取表中规则的接口。它使用xt_find_table_lock()和xt_table_unlock()保证没有其它人操作该表。

  • unsigned int ipt_do_table(struct sk_buff *skb, unsigned int hook, const struct net_device *in, const struct net_device *out, struct xt_table *table) (读取表中规则)
    该函数是iptables为filter、nat、mangle模块提供用于对数据包匹配各表中规则的接口。它根据表对应的xt_table_info结构中的信息,找到相应的规则,对数据包进行逐一匹配。为保证所引用表中的规则(xt_table_info)不被其它写者释放,同时又不影响到其它读者,使用xt_info_rdlock_bh()和xt_info_rdunlock_bh()来加锁和解锁。

  • static int do_replace(struct net *net, const void __user *user, unsigned int len) (修改表中规则)
    该函数是iptables为filter、nat、mangle模块提供用于在对应表中下规则的接口。它根据用户传递过来的规则,构建一个新的xt_table_info结构和规则,并将它们与对应表的xt_table->private相关联。它通过xt_find_table_lock()和xt_table_unlock()保证当前只有一个写者在操作该表。通过local_bh_disable()和local_bh_enable()保证更换table->private指向新的xt_table_info结构时不被打断。通过get_counters()保证所有其它CPU都不再使用旧的xt_table_info结构,安全释放旧的xt_table_info结构。

    static int translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, const struct ipt_replace *repl)
    根据ipt_replace结构构建一个xt_table_info结构,并做一些必要的检查(链是否环路等),同时将表中的规则与相应的match和target相关联。

    struct xt_table_info *xt_replace_table(struct xt_table *table, unsigned int num_counters, struct xt_table_info *newinfo, int *error)
    为newinfo调用xt_jumpstack_alloc(struct xt_table_info *i)初始化stack相关数据,然后使table->private指向newinfo,并返回oldinfo。

论坛徽章:
0
发表于 2012-05-30 12:40 |显示全部楼层
Iptables利用Xtables构建的组织形式

iptables3.jpg

论坛徽章:
0
发表于 2012-05-30 12:44 |显示全部楼层
本帖最后由 pywj777 于 2012-05-30 12:52 编辑

Iptable下发规则的执行流程图

iptables4.jpg

iptables内核层与应用层之间传输规则的组织形式

iptables5.jpg

iptables将内核中获取的规则转换为如下图所示可管理的结构

iptables6.jpg

论坛徽章:
0
发表于 2012-05-30 12:56 |显示全部楼层
Iptables包含以下target
  • IPT_ACCEPT:(struct ipt_standard_target *)target->verdict = -NF_ACCEPT-1        < 0        (ipt_do_table()碰到这个target直接返回NF_ACCEPT)
  • IPT_DROP:(struct ipt_standard_target *)target->verdict = -NF_DROP-1 < 0                (ipt_do_table()碰到这个target直接返回NF_DROP)
  • IPT_QUEUE:(struct ipt_standard_target *)target->verdict = -NF_QUEUE-1 < 0        (ipt_do_table()碰到这个target直接返回NF_QUEUE)
  • IPT_RETURN:(struct ipt_standard_target *)target->verdict = -NF_REPATE-1        < 0        (ipt_do_table()碰到这个target特殊处理)
  • 跳转到子链target:(struct ipt_standard_target *)target->verdict = 要跳转子链的偏移量 > 0        (ipt_do_table()碰到这个target会跳转到该子链处理)
  • IPT_CONTINUE:        IPT_CONTINUE = XT_CONTINUE = 0xFFFFFFFF < 0        (ipt_do_table()碰到这个target会处理下一条规则,这个target被扩展target使用)(它不是一个标准target,但可被其它扩展TARGET用作返回值)
  • 扩展target:它是struct xt_entry_target + date[]                                (ipt_do_table()碰到这个target会调用target->target()处理,并根据返回值做处理。扩展target可返回IPT_CONTINUE,或下面netfilter定义的值)


Netfilter处理的返回值
NF_DROP
NF_ACCEPT
NF_STOLEN
NF_QUEUE
NF_REPEAT
NF_STOP

论坛徽章:
0
发表于 2012-05-30 13:03 |显示全部楼层
众所周知,iptables的一大缺点是线性匹配,这样当>1000条规则时,匹配效率会明显下降,为此,我借鉴NF-hipac的算法,将iptables转换为树形匹配,来加快其匹配效率,转换后的结构图如下图所示:

iptables7.jpg

评分

参与人数 1可用积分 +6 收起 理由
Godbach + 6 赞一个!

查看全部评分

论坛徽章:
0
发表于 2012-06-01 22:46 |显示全部楼层
本帖最后由 MoWaters 于 2012-06-01 22:59 编辑

图画得真不错,收藏了。



   

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2012-06-05 12:44 |显示全部楼层
回复 1# pywj777
感谢 LZ 分享,看到 hipac 的汇总了。
   

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2012-06-05 12:51 |显示全部楼层
回复 1# pywj777

LZ 能够简单介绍一下 xtable 和原先版本的 iptables 中主要的变化有哪些?


   

论坛徽章:
0
发表于 2012-06-05 16:19 |显示全部楼层
本帖最后由 pywj777 于 2012-06-05 16:20 编辑

回复 9# Godbach

主要的变化就在于一个是'x'tables,一个是'ip'tables,即iptables只针对IP协议栈,而xtables是针对各种不同的协议栈,例如第一幅图中的IPV4、IPV6、ARP、BRIDGE、DECENT等


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则

久等啦!10张门票开启你的DTCC2017之旅

2017中国数据库技术大会将于2017年5月11-13日如约而至,本届大会以“数据驱动•价值发现”为主题,共设定2大主场和21个技术专场,云集海内外120+位技术大牛,共同探讨Oracle、MySQL、NoSQL、云端数据库、区块链、深度学习等领域的前瞻性热点话题。
即日起,填写DTCC2017会前调查问卷,即有机会赢取价值2600元的大会门票1张!仅限10张!
----------------------------------------
活动截止时间:2017年5月5日统一公布

问卷入口>>
  

北京皓辰网域网络信息技术有限公司. 版权所有 京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:1101082001
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP