- 论坛徽章:
- 0
|
本帖最后由 pywj777 于 2012-05-30 12:36 编辑
Iptables利用Xtable初始化filter表的结构图
- 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。
|
|