linux-Netfilter钩子注册与网络子系统
作者:互联网
在探索netfilter功能时,我尝试编写一个简单的netfilter模块并注册了一个钩子,如下所示:
dhcp_nfho.owner = THIS_MODULE;
dhcp_nfho.hook = dhcp_hook_function;
dhcp_nfho.hooknum = NF_INET_POST_ROUTING;
dhcp_nfho.priority = NF_IP_PRI_FIRST;
dhcp_nfho.pf = PF_INET; // not on bridge interface
nf_register_hook(&dhcp_nfho);
我在LXR页面中查看了nf_register_hook的代码:(3.13版)
int nf_register_hook(struct nf_hook_ops *reg)
69 {
70 struct nf_hook_ops *elem;
71 int err;
72
73 err = mutex_lock_interruptible(&nf_hook_mutex);
74 if (err < 0)
75 return err;
76 list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) {
77 if (reg->priority < elem->priority)
78 break;
79 }
80 list_add_rcu(®->list, elem->list.prev);
81 mutex_unlock(&nf_hook_mutex);
82 #if defined(CONFIG_JUMP_LABEL)
83 static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]);
84 #endif
85 return 0;
86 }
这个2D链表nf_hooks [PF] [hooknum]是什么.似乎对于每个协议系列,都有一个PRE / INPUT / FORWARD / OUTPUT / POST挂钩列表?
netfilter子系统如何使用此2D数组?
netfilter子系统代码是否与网络驱动程序代码交互? (因为挂钩是在Soft-irq中处理的,并且网络驱动程序也使用soft-irq来处理数据包)?
驱动程序接收到数据包后,在哪里可以找到调用Netfilter挂钩的代码?
解决方法:
你是对的.对于每个协议族,确实有一个挂钩列表,这些挂钩实际上是由PF本身设置的(例如NFPROTO_BRIDGE有一个BROUTE挂钩列表,但IPv4或IPv6都没有).
当数据包进入逻辑网络接口(以太网桥,以太网接口等)时,它将在堆栈中传递.如果是IPv4数据包,则最终将调用ip_rcv().在继续进行正确的数据包路由之前,这将调用NF_INET_PRE_ROUTING挂钩.同样,在实际发送数据包之前,ip_output会调用NF_INET_POST_ROUTING挂钩.
将Netfilter挂钩放入主要的网络代码中,可以使网络接口驱动程序本身完全忽略整个过程.
为了更好地了解所有流程,请查看http://lxr.free-electrons.com/source/net/ipv4/ip_input.c和http://lxr.free-electrons.com/source/net/ipv4/ip_output.c.当数据包过渡到不同的层时,您将看到NF_HOOK和NF_HOOK_COND宏被调用,等等.
标签:network-programming,linux-kernel,kernel-module,netfilter,linux 来源: https://codeday.me/bug/20191119/2038813.html