Netfilter NF_HOOK执行流程分析一

来源:互联网 发布:土地利用空间优化配置 编辑:程序博客网 时间:2024/05/28 11:49
利用Linux我们可以实现复杂的防火墙机制,大家防火墙路由器,得易于Linux强大的内核,这些实现都变得非常简单,通过简单的几条iptables命令就可以定制我们的防火墙功能。那么Linux内核是如何完成对包的处理,流程又是怎么样呢?

一 首先看一下netfilter的整体架构

netfilter的具体实现,以NF_IP_PREROUTING为例

二 NF_HOOK的实现原理

    在网卡收到包之后交由ip层处理的时候,就交给了ip_recv函数

int ip_rcv(struct sk_buff *skb, struct net_device *dev, structpacket_type *pt, struct net_device *orig_dev)

{

    在做了基本的头校验等工作后,就到了我们的重点NF_HOOK钩子函数,此时还未作路由等路处理

    returnNF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, dev, NULL,

        ip_rcv_finish);

    在做完PRE_ROUTING的筛选后,会执行ip_recv_finish函数,继续执行路由等处理,如果是本地的就会交给更高层的协议进行处理,如果不是交由本地的就执行FORWARD

}

通过NF_HOOK的宏定义可以看到,NF_HOOK主要是调用nf_hook_slow,那么,nf_hook_slow主要做了哪些东西呢?

nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh)

{

    elem= &nf_hooks[pf][hook];

next_hook:

    verdict= nf_iterate(&nf_hooks[pf][hook], skb, hook,indev,

            outdev, &elem, okfn, hook_thresh);

}

nf_interate 的作用就是递归调用注册的钩子函数,

unsigned int nf_iterate(struct list_head*head,struct sk_buff *skb,unsigned int hook,const struct net_device*indev,

            conststruct net_device *outdev,struct list_head **i,int (*okfn)(structsk_buff *),int hook_thresh)

{

    list_for_each_continue_rcu(*i,head) {

        structnf_hook_ops *elem = (struct nf_hook_ops *)*i;

        if(hook_thresh > elem->priority)

            continue;  

repeat:

        verdict= elem->hook(hook, skb, indev, outdev,okfn);

        if(verdict != NF_ACCEPT) {

#ifdef CONFIG_NETFILTER_DEBUG

            if(unlikely((verdict & NF_VERDICT_MASK)

                            >NF_MAX_VERDICT)) {

                NFDEBUG("Evilreturn from %p(%u).\n",

                    elem->hook,hook);

                continue;

            }

#endif

            if(verdict != NF_REPEAT)

                returnverdict;

            gotorepeat;

        }

    }

    returnNF_ACCEPT;

}

三 filter NAT mangle链的具体实现

    我们知道,iptables默认的可以配置三个表,分别是FILTER,NAT, MANGLE,那么这三个表是如何跟NF_HOOK联系的呢?

先看一下下面的结构体

struct nf_hook_ops {

    structlist_head list;

    nf_hookfn*hook;

    structmodule *owner;

    u_int8_tpf;

    unsignedint hooknum;

    intpriority;

};

其实nf_iterate就是递归搜索list 执行hook函数。

使用# iptables –nvL,可以看到有如下的输出,这三个表是怎么注册上去的呢?

static int __init iptable_filter_init(void)

{

    filter_ops= xt_hook_link(&packet_filter,iptable_filter_hook);

    if(IS_ERR(filter_ops)) {

        ret= PTR_ERR(filter_ops);

        gotocleanup_table;

}

防火墙分别在(1 << NF_INET_LOCAL_IN) | \(1 << NF_INET_FORWARD) | \ (1<<NF_INET_LOCAL_OUT))注册HOOK函数,并执行iptable_filter_hook函数。

到了这里大体就明白了,NF_HOOK执行相应额HOOK函数,例如在IP_PREROUTING里面执行防火墙注册的HOOK函数,也就是到了iptables_filter_hook,然后遍历FILTER里面的各个table,执行相应的动作。那么table是怎么跟一条规则
0 0