在(1)中提到,数据包会经过内核协议栈中的5个HOOK点,每个HOOK点都会执行钩子函数依次在链表上,那么这些钩子函数是如何与用户使用iptables下发的规则联系起来的呢?这些规则是如何存储的?这篇文章详细描述了这个问题。表(table)内核使用结构体structxt_table来表示一个表(table)。HOOK指向表的结构记录是有效的,它的私有指针保存了表中包含的所有规则。当每一个新的net命名空间被创建时,Netfitler都会创建属于当前net命名空间的所有表,并将它们记录在自己的net命名空间中。从图中可以看出,创建包含默认规则的表需要两步。根据已有模板,生成默认规则。在Netfilter框架中注册表并生成默认规则。如果你用过iptables,你可能知道每个表的每个条目。该链有一个默认策略,即链中所有规则都不匹配,将执行默认行为。这个默认行为可以通过iptables配置。系统启动时,默认行为设置为NF_ACCEPT。这里的默认规则就是这个意思。Netfilter将为每个链创建一个默认规则并将它们添加到tableipt_replace。默认规则使用structipt_replace结构。这个结构的由来与iptables的配置方式密切相关:iptables是以read-modify-write的方式配置的!例如,当你使用iptables向Netfilter的filter表添加一条新规则时,iptables会将整个filter表读入用户空间,用户空间修改完成后,重新设置为Netfilter。所以,这是一个替换的过程。所以ipt_replace一般是指用户使用iptables下发的表。典型结构如下:hook_entry和underflow分别代表每个HOOK上的第一条规则和最后一条规则的偏移量(具体规则在最后一个ipt_entry的灵活数组中!)但是这里,由于还在初始化阶段,所以这里的repl是内核自己通过packet_filter模板生成的。它将为过滤器所在的每个HOOK点LOCAL_IN、FORWARD和LOCAL_OUT创建一个默认规则。内核使用structipt_entry来表示用户使用iptables配置的规则。这个结构体后面会跟着几个ipt_entry_match结构体和1个ipt_standard_target结构体。它与用户配置的iptables的关系如下:其中ipt_entry:表示一个标准的匹配结构。包括消息的源IP、目的IP、入接口、出接口等条件ipt_entry_match:表示扩展匹配。一个完整的规则包含零到多个这个结构ipt_standard_target:表示匹配后的动作保存在ipt_replace),下一步是注册一个新表。xt_table中保存规则的私有指针类型是structxt_table_info,所以这里首先是将repl转换成newinfo。下一步是调用xt_register_table创建一个新表并将其注册到框架中。注册完成后,Netfilter可以通过net->xt.tables[af]链表遍历所有注册的表,或者通过net->ipv4快速访问具体的表。桌子。
