Linux kernel 多个内核模块可以使用同一个netfilter钩子而不相互影响吗?

Linux kernel 多个内核模块可以使用同一个netfilter钩子而不相互影响吗?,linux-kernel,kernel-module,netfilter,Linux Kernel,Kernel Module,Netfilter,我正在开发一个内核模块,它将使用netfilter钩子以各种方式损坏/过滤数据包,但是在这样做的过程中,我希望避免绕过使用该钩子的任何其他东西(例如iptables),以便我的模块不会干扰它们的正常操作。到目前为止,我的研究还没有得出关于访问同一钩子的多个服务/模块将如何交互的任何信息 这是可能的(可能已经自动发生),如果是,我可以设置钩子触发服务/模块的顺序吗?正如您所知,钩子只是TCP/IP堆栈中的一个位置,您可以插入一些函数来处理SKB。每个函数通常返回以下一项(请参阅include/ua

我正在开发一个内核模块,它将使用netfilter钩子以各种方式损坏/过滤数据包,但是在这样做的过程中,我希望避免绕过使用该钩子的任何其他东西(例如iptables),以便我的模块不会干扰它们的正常操作。到目前为止,我的研究还没有得出关于访问同一钩子的多个服务/模块将如何交互的任何信息


这是可能的(可能已经自动发生),如果是,我可以设置钩子触发服务/模块的顺序吗?

正如您所知,钩子只是TCP/IP堆栈中的一个位置,您可以插入一些函数来处理SKB。每个函数通常返回以下一项(请参阅include/uapi/linux/netfilter.h)

  • NF_DROP------这是skb的结束。放下这个skb,不要把它传给其他钩子(当然还有更高层)
  • NF_ACCEPT——我处理完这个skb,将skb转发到下一个钩子
  • NF_被盗——我劫持了这个skb(模块将skb排队等待稍后处理)
IPtables使用这些钩子来实现所需的防火墙规则。当然,您可以使用IPtables(和任何其他钩子)存在,但是如果出于某种原因,在IPtables钩子并返回NF_DROP之前调用了您的函数,那么skb将不会被转发到IPtables。另一方面,如果总是返回NF_ACCEPT,则系统中的IPtables和其他挂钩将不会受到任何影响

至于钩子的顺序,当netfilter系统遍历钩子时(从include/uapi/linux/netfilter_ipv4.h)使用以下优先级:


这意味着IPtables mangle表钩子将在过滤器钩子之前执行。使用
nf\u register\u hooks()

注册时,您可以使用这些值中的任何一个,也可以使用自己的值。您可以显示一些代码吗?很久以前,我曾经使用过
ebtables
,但是如果我有机会看一下代码,我可能会想出一些办法。理想情况下,您需要发布一个完整的内核模块来安装钩子(但钩子实际上不需要做任何事情)。在这个阶段,我还没有编写任何代码,但我正试图了解这是否可行,或者我是否需要在用户空间中做些什么。如果在这段时间内没有其他东西弹出,我肯定会在我启动并运行一些代码时发布一些代码。再次感谢你的帮助,我明白了。netfilter支持特定事件的多个钩子还是单个钩子?在前面的例子中,逻辑上应该有一种方法可以在其他钩子之前或之后安装钩子。在后一种情况下,逻辑上应该有一种获取旧处理程序的方法,这样您就可以自己调用它(类似这样:
old\u handler=install\u my\u handler(my\u handler))
之后在
my_handler
中,您调用
old_handler
的开头和结尾都是正确的。不过,这些只是推测,没有看到代码我就说不出来。
enum nf_ip_hook_priorities {
    NF_IP_PRI_FIRST = INT_MIN,
    NF_IP_PRI_CONNTRACK_DEFRAG = -400,
    NF_IP_PRI_RAW = -300,
    NF_IP_PRI_SELINUX_FIRST = -225,
    NF_IP_PRI_CONNTRACK = -200,
    NF_IP_PRI_MANGLE = -150,
    NF_IP_PRI_NAT_DST = -100, 
    NF_IP_PRI_FILTER = 0,
    NF_IP_PRI_SECURITY = 50,
    NF_IP_PRI_NAT_SRC = 100,
    NF_IP_PRI_SELINUX_LAST = 225,
    NF_IP_PRI_CONNTRACK_HELPER = 300,
    NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
    NF_IP_PRI_LAST = INT_MAX,};