- 論壇徽章:
- 0
|
本帖最后由 pywj777 于 2012-05-30 12:36 編輯
Iptables利用Xtable初始化filter表的結(jié)構(gòu)圖
iptables2.jpg (136.35 KB, 下載次數(shù): 271)
下載附件
2012-05-30 12:25 上傳
- struct xt_table *ipt_register_table(struct net *net, const struct xt_table *table, const struct ipt_replace *repl)(注冊(cè)并初始化一個(gè)表,然后調(diào)用xt_hook_link()引用該表)
該函數(shù)是iptables為filter、nat、mangle模塊提供用于注冊(cè)相應(yīng)表結(jié)構(gòu)的接口。它根據(jù)當(dāng)前表要被掛入的HOOK點(diǎn)來構(gòu)建上圖所示的xt_table_info初始規(guī)則表,并調(diào)用xt_register_table()函數(shù)將filter表的xt_table和xt_table_info結(jié)構(gòu)掛入net.xt.table[IPV4]鏈表中。(上圖是iptables_filter模塊調(diào)用該函數(shù)注冊(cè)的結(jié)構(gòu)圖)
注冊(cè)完一個(gè)表后,就可以通過xt_hook_link()函數(shù)注冊(cè)一個(gè)HOOK點(diǎn)來使用這個(gè)表中的規(guī)則處理數(shù)據(jù)包。
- void ipt_unregister_table(struct net *net, struct xt_table *table)(注銷一個(gè)表,要在xt_hook_unlink()之后使用)
該函數(shù)是iptables為filter、nat、mangle模塊提供用于注銷相應(yīng)表結(jié)構(gòu)的接口。它調(diào)用xt_unregister_table()將xt_table從對(duì)應(yīng)協(xié)議鏈表中取下并釋放,然后將返回的xt_table_info結(jié)構(gòu)中的規(guī)則逐一釋放(同時(shí)也會(huì)釋放規(guī)則引用的match和target模塊的引用計(jì)數(shù)),最后釋放xt_table_info結(jié)構(gòu)。
為保證釋放table表時(shí)沒有其它讀者,所以在調(diào)用該函數(shù)之前要先調(diào)用xt_hook_unlink()函數(shù)注銷在HOOK點(diǎn)掛入的處理函數(shù),保證沒有其它CPU會(huì)再引用到該表。
- struct xt_info_lock xt_info_locks[CPU](用于保證讀取修改表中規(guī)則的鎖,每個(gè)CPU一個(gè)鎖)
struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af, const char *name)
查找name指定的表,使用xt[af].mutex加鎖,保證只有一個(gè)寫者處理該表。并增加表所在模塊的引用計(jì)數(shù),防止該表被錯(cuò)誤釋放。
void xt_table_unlock(struct xt_table *table)
與xt_find_table_lock()配對(duì)使用,釋放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]鎖。這個(gè)鎖主要是用于防止正被使用的規(guī)則表(xt_table_info結(jié)構(gòu))被釋放。(它與get_counters()進(jìn)行互斥)
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()中被調(diào)用,用于獲取所有CPU的寫鎖,保證所有CPU都已完成了對(duì)規(guī)則表的引用。
static void get_counters(const struct xt_table_info *t, struct xt_counters counters[])
它可以保證其它CPU都已完成了一次對(duì)表中所有規(guī)則的引用。因?yàn)樗獙?duì)所有其它CPU調(diào)用xt_info_wrlock(cpu)函數(shù)來獲取其它CPU的xt_info_lock,而其它CPU在讀取表中規(guī)則時(shí),要通過xt_info_rdlock_bh獲取各自的xt_info_lock鎖,所有當(dāng)它獲取完所有其它CPU的xt_info_lock鎖后,就表示其它CPU都已完成了對(duì)表中規(guī)則的引用。這就說明了為什么在do_replace中調(diào)用完get_counters()后能夠安全的釋放舊的xt_table_info結(jié)構(gòu)。
- static int get_info(struct net *net, void __user *user, const int *len, int compat) (讀取表中信息)
該函數(shù)是用戶使用iptables命令操作表中規(guī)則時(shí),用于獲取表中信息的接口。它使用xt_find_table_lock()和xt_table_unlock()保證沒有其它人操作該表。
- static int get_entries(struct net *net, struct ipt_get_entries __user *uptr, const int *len)(讀取表中規(guī)則)
該函數(shù)是用戶使用iptables命令操作表中規(guī)則時(shí),用于獲取表中規(guī)則的接口。它使用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) (讀取表中規(guī)則)
該函數(shù)是iptables為filter、nat、mangle模塊提供用于對(duì)數(shù)據(jù)包匹配各表中規(guī)則的接口。它根據(jù)表對(duì)應(yīng)的xt_table_info結(jié)構(gòu)中的信息,找到相應(yīng)的規(guī)則,對(duì)數(shù)據(jù)包進(jìn)行逐一匹配。為保證所引用表中的規(guī)則(xt_table_info)不被其它寫者釋放,同時(shí)又不影響到其它讀者,使用xt_info_rdlock_bh()和xt_info_rdunlock_bh()來加鎖和解鎖。
- static int do_replace(struct net *net, const void __user *user, unsigned int len) (修改表中規(guī)則)
該函數(shù)是iptables為filter、nat、mangle模塊提供用于在對(duì)應(yīng)表中下規(guī)則的接口。它根據(jù)用戶傳遞過來的規(guī)則,構(gòu)建一個(gè)新的xt_table_info結(jié)構(gòu)和規(guī)則,并將它們與對(duì)應(yīng)表的xt_table->private相關(guān)聯(lián)。它通過xt_find_table_lock()和xt_table_unlock()保證當(dāng)前只有一個(gè)寫者在操作該表。通過local_bh_disable()和local_bh_enable()保證更換table->private指向新的xt_table_info結(jié)構(gòu)時(shí)不被打斷。通過get_counters()保證所有其它CPU都不再使用舊的xt_table_info結(jié)構(gòu),安全釋放舊的xt_table_info結(jié)構(gòu)。
static int translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, const struct ipt_replace *repl)
根據(jù)ipt_replace結(jié)構(gòu)構(gòu)建一個(gè)xt_table_info結(jié)構(gòu),并做一些必要的檢查(鏈?zhǔn)欠癍h(huán)路等),同時(shí)將表中的規(guī)則與相應(yīng)的match和target相關(guān)聯(lián)。
struct xt_table_info *xt_replace_table(struct xt_table *table, unsigned int num_counters, struct xt_table_info *newinfo, int *error)
為newinfo調(diào)用xt_jumpstack_alloc(struct xt_table_info *i)初始化stack相關(guān)數(shù)據(jù),然后使table->private指向newinfo,并返回oldinfo。
|
|