Netfilter框架的设计与实现1.什么是NetfilerLinux 从2.4.X 开始,引入了Netfilter,代替了原来的ipchain,什么是Netfilter 呢?有人将它称为“Linux下一个优秀的防火墙工具”,这样讲,有一定的道理,但是却是很片面的。
Netfilter 更准确地讲是Linux 内核中,一个包过滤框架,默认地,它在这个框架上实现了包过滤、状态检测、网络地址转换和包标记等多种功能,因为它设计的开放性,任何有内核开发经验的开发人员,也可以很容易地利用它提供接口,在内核的数据链路层、网络层,实现自己的功能模块。
Netfilter的用户空间管理工具,是著名的iptables 工具套件。
Netfilter框架之所以能实现许多强大的功能,是因为它在内核若干网络转发的关键函数,设计了许多巧妙的钩子函数,比如数据转发,由两个主要函数A 和B函数实现,流程为A->B ,现在改变为A->钩子函数->B,就这么简单,在本章里,就让我们来看看Netfilter 框架的设计与实现。
2.从NF_HOOK 谈起在整个Netfilter中,NF_HOOK宏占有重要的作用,它定义在Netfilter.h中:CODE:/* This is gross, but inline doesn't cut it for avoiding the functioncall in fast path: gcc doesn't inline (needs value tracking?). --RR */#ifdef CONFIG_NETFILTER_DEBUG#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \ ({int __ret; \if ((__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, INT_MIN)) == 1) \__ret = (okfn)(skb); \__ret;})#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \ ({int __ret; \if ((__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1) \__ret = (okfn)(skb); \__ret;})#else#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \ ({int __ret; \if (list_empty(&nf_hooks[pf][hook]) || \ (__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, INT_MIN)) == 1) \__ret = (okfn)(skb); \__ret;})#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \ ({int __ret; \if (list_empty(&nf_hooks[pf][hook]) || \ (__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1) \__ret = (okfn)(skb); \__ret;})#endif一开始就摆出这么长一个宏出来,这个宏稍长了一点,缩短来看:CODE:#ifdef CONFIG_NETFILTER_DEBUG……#else……#endif我们暂且忽略用于调试作用的语句,把#else中NF_HOOK的定义提取出来:CODE:#define NF_HOOK(pf, hook, skb, indev, outdev,okfn) \({int __ret; \if (list_empty(&nf_hooks[pf][hook]) || \ (__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, INT_MIN)) == 1) \__ret = (okfn)(skb); \__ret;})首先来看这个宏里边的二维数组nf_hooks[pf][hook] ,其中pf对应协议簇,hook对应了某个hook点,比如ipv4 协议簇(PF_INET)下有一个钩子NF_IP_PRE_ROUTING(路由查找之前),那么这个Hook点对应的这个二维数组中的元素就是nf_hooks[PF_INET][ NF_IP_PRE_ROUTING]。