Linux kernel version: 3.18.14 file: net/ipv4/netfilter/iptables_filter.c
先贴出重要的全局变量struct xt_table packet_filter:
#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) | (1 << NF_INET_LOCAL_OUT)) static const struct xt_table packet_filter = { .name = "filter", .valid_hooks = FILTER_VALID_HOOKS, .me = THIS_MODULE, .af = NFPROTO_IPV4, .priority = NF_IP_PRI_FILTER, };
看代码:
1. 最开始的 module_init(iptables_filter_init)
2. iptables_filter_init --> register_pernet_subsys(&iptable_filter_net_ops)
--> xt_hook_link(&packet_filter, iptable_filter_hook) /* iptable_filter_hook 也存在于当前这个文件iptables_filter.c 中 */
看看 iptable_filter_net_ops:
static struct pernet_operations iptable_filter_net_ops = { .init = iptable_filter_net_init, .exit = iptable_filter_net_exit, };
3. 看看这个网络subsystem的初始化函数:iptable_filter_net_init
--> struct ipt_replace *repl = ipt_alloc_initial_table(&packet_filter) /* 分配一个初始化的table */
--> net->ipv4.ipvtable_filter = ipt_register_table(net, &packet_filter, repl) /* 注册一个table, 并且把它挂在当前这个ipv4命名空间中(Control Groups相关的东东)*/
好! ipt_alloc_initial_table 后的相关存储结构如下图所示:
注意 柔性数组的使用,结构设计的巧妙之处!
a. 这个结构的分配时由xt_alloc_initial_table宏(net/netfilter/xt_repldata.h文件中)完成的
b. tbl->repl.size = nhooks * sizeof(struct ipt_standard) + sizeof(struct ipt_error)
故事发展到这里,内核已经初始化了一个initial table,接下来就把它register到当前的namespace
调用ipt_register_table(net, &packet_filter, repl) /* 这个 repl就是指向了initial table */
来看注册的table的存储结构
其中每个entries指向的内存空间是这样赋值的
memcpy(entry, repl->entries, repl->size)
就是把初始化的table的entries指向的内存空间内容copy过来(上一幅图虚线方框的部分)
table注册完后,初始化的initial table被kfree了
表注册好了,接下来执行的是最要的一步:往INET_PROTO的HOOK点上挂载钩子函数:
xt_hook_link(&packet_filter, iptable_filter_hook),xt_hook_link最后调用的就是nf_register_hooks
未完待续...