1、首先来看一个表的结构和已经初始化过的ipt_replace结构
图1 xt_table中的private结构 图2 在一中已经生成了的一个repl结够
在一中提到过,packet_filter结构初始化时只是初始化了一部分信息,还有一个很重要的成员并没有初始化,那就是在xt_table中的ipt_table_info结构的private变量,该结构存放表的具体的规则信息
-
struct xt_table_info {
-
/* Size per table */
-
unsigned int size;
-
/* Number of entries: FIXME. --RR */
-
unsigned int number;
-
/* Initial number of entries. Needed for module usage count */
-
unsigned int initial_entries;
-
/* Entry points and underflows */
-
unsigned int hook_entry[NF_INET_NUMHOOKS];
-
unsigned int underflow[NF_INET_NUMHOOKS];
-
/*
-
* Number of user chains. Since tables cannot have loops, at most
-
* @stacksize jumps (number of user chains) can possibly be made.
-
*/
-
unsigned int stacksize;
-
unsigned int __percpu *stackptr;
-
void ***jumpstack;
-
/* ipt_entry tables: one per CPU */
-
/* Note : this field MUST be the last one, see XT_TABLE_INFO_SZ */
-
void *entries[1];
-
};
2、注册表的第二步就是需要从第一步中生成的repl结构得到一个ipt_table_info(newinfo)结构,该结构最终将会复制给packet_filter结构总得private结构,具体的函数是(translate_table(net, newinfo, loc_cpu_entry, repl))
-
static int
-
translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
-
const struct ipt_replace *repl)
-
{
-
struct ipt_entry *iter;
-
unsigned int i;
-
int ret = 0;
-
-
newinfo->size = repl->size;
-
newinfo->number = repl->num_entries;
-
-
/* Init all hooks to impossible value. */ //将newinfo结构中的入口偏移地址设置为不可能的值
-
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-
newinfo->hook_entry[i] = 0xFFFFFFFF;
-
newinfo->underflow[i] = 0xFFFFFFFF;
-
}
-
-
duprintf("translate_table: size %u\n", newinfo->size);
-
i = 0;
-
/* Walk through entries, checking offsets. */
-
xt_entry_foreach(iter, entry0, newinfo->size) { //根据repl结构中的偏移值给newinfo结构中的偏移赋值
-
ret = check_entry_size_and_hooks(iter, newinfo, entry0,
-
entry0 + repl->size,
-
repl->hook_entry,
-
repl->underflow,
-
repl->valid_hooks);
-
if (ret != 0)
-
return ret;
-
++i;
-
if (strcmp(ipt_get_target(iter)->u.user.name,
-
XT_ERROR_TARGET) == 0)
-
++newinfo->stacksize;
-
}
-
-
if (i != repl->num_entries) {
-
duprintf("translate_table: %u not %u entries\n",
-
i, repl->num_entries);
-
return -EINVAL;
-
}
-
-
/* Check hooks all assigned */ //上一个宏遍历了所有入口,并给所有入口赋了正确的值,如果这里再出现不可用的值则说明有错误
-
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-
/* Only hooks which are valid */
-
if (!(repl->valid_hooks & (1 << i)))
-
continue;
-
if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
-
duprintf("Invalid hook entry %u %u\n",
-
i, repl->hook_entry[i]);
-
return -EINVAL;
-
}
-
if (newinfo->underflow[i] == 0xFFFFFFFF) {
-
duprintf("Invalid underflow %u %u\n",
-
i, repl->underflow[i]);
-
return -EINVAL;
-
}
-
}
-
-
if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) //检查是否形成了规则环,如果有环则出错返回
-
return -ELOOP;
-
-
/* Finally, each sanity check must pass */
-
i = 0;
-
xt_entry_foreach(iter, entry0, newinfo->size) {
-
ret = find_check_entry(iter, net, repl->name, repl->size);
-
if (ret != 0)
-
break;
-
++i;
-
}
-
-
if (ret != 0) {
-
xt_entry_foreach(iter, entry0, newinfo->size) {
-
if (i-- == 0)
-
break;
-
cleanup_entry(iter, net);
-
}
-
return ret;
-
}
-
-
/* And one copy for every other CPU */
-
for_each_possible_cpu(i) {
-
if (newinfo->entries[i] && newinfo->entries[i] != entry0)
-
memcpy(newinfo->entries[i], entry0, newinfo->size);
-
}
-
-
return ret;
-
}
阅读(1825) | 评论(2) | 转发(0) |