10

如果我编写了几个内核模块,并且在所有模块中都指定它们应该是第一个(或最后一个)调用的 netfilter 钩子,那么它们实际上会以什么顺序被调用?

netfilter_ops_out.hook     = hook_func_out;
netfilter_ops_out.pf       = PF_INET;
netfilter_ops_out.hooknum  = NF_IP_LOCAL_OUT;
netfilter_ops_out.priority = NF_IP_PRI_FIRST;

ret = nf_register_hook(&netfilter_ops_out);
if (0 > ret) {
    printk("Error registering netfilter hook: %d\n", ret);
    return ret;
}    

netfilter_ops_in.hook      = hook_func_in;
netfilter_ops_in.pf        = PF_INET;
netfilter_ops_in.hooknum   = NF_IP_LOCAL_IN;
netfilter_ops_in.priority  = NF_IP_PRI_LAST;

ret = nf_register_hook(&netfilter_ops_in);
if (0 > ret) {
    printk("Error registering netfilter hook: %d\n", ret);
    return ret;
}    

实验性地,我制作了两个模块,insmod以两种不同的顺序编辑它们——但它们给出了相同的结果,这意味着存在一些不只是“先到先得”的子顺序。(它也不是按字母顺序排列的......)

4

1 回答 1

4

从nf_register_hook()代码中我们可以知道,如果两个hook属于同一个nf_hooks[reg->pf][reg->hooknum],那么hook的执行顺序是由优先级决定的。如果优先级也相同,则顺序为“先到先得”。请参阅以下代码:

int nf_register_hook(struct nf_hook_ops *reg)
{
    struct nf_hook_ops *elem;
    int err;

    err = mutex_lock_interruptible(&nf_hook_mutex);
    if (err < 0)
        return err;
    list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) {
        if (reg->priority < elem->priority)
            break;
    }
    list_add_rcu(&reg->list, elem->list.prev);
    mutex_unlock(&nf_hook_mutex);
#if defined(CONFIG_JUMP_LABEL)
    static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]);
#endif
    return 0;
}
于 2013-03-13T09:40:33.350 回答