Netfilter 为每种网络协议定义了一套钩子;

  • 内核的任何模块可以对每种协议的一个或多个钩子进行注册;
  • 排队的数据包被传递给用户空间并异步进行处理。

钩子点

  1. pre_routing:路由查找前,ip_recv(),在此之前,只简单检查协议版本号、包长度、检验和等
  2. local_in:目的地址为本机的数据包,ip_local_deliver()
  3. forward:经过防火墙转发、目的地址非本机,ip_forward()
  4. post_routing:最终送入物理介质前,适合snat或统计
  5. local_out:本机产生并发送的包

以上几个钩子位置如图(wei: ip_fragments 现在应该是ip_fragment 吧):

LinuxNet1

注册的钩子函数都将返回下列返回值之一(wei:定义于include/uapi/linux/netfilter.h):

  1. NF_ACCEPT:接受并递交;
  2. NF_DROP:完全丢弃;
  3. NF_STOLEN:钩子将对数据包开始处理,Netfilter放弃该数据包的所有权
  4. NF_QUEUE:包发往用户空间,等待用户空间程序处理
  5. NF_REPEAT:请求Netfilter再次调用这个钩子

wei代码里还可以看到还有 NF_STOP,看介绍是接受并阻止后面的钩子继续处理)

 

Netfilter 的内置功能模块有系统初始化配置脚本加载到内核,再由内核自动调用,各模块功能相互独立,如 Filter 在需要过滤控制时加载,NAT 在需要NAT时加载。注册中比较重要的数据结构是 nf_hook_ops ,注册和卸载分别调用 nf_regerister_hook() nf_unregerister_hook() 函数。

nf_hooks 是一个二维数组 nf_hooks[NPROTO][NF_MAX_HOOKS] NPROTO 表示当前内核允许的最大协议数,(wei:位于uapi/linux/net.h#define NPROTO AF_MAXAF_MAX 目前为41,具体见 include/linux/socket.h PF_**,与 AF_** 一致,其中 local UNIXROUTE NETLINK),NF_MAX_HOOKS 表示对任一协议组需要用的钩子的最大数目。其类型是 list_head,可以理解为双向链表,(wei:它有一个变量属性是 __read_mostly,这个是gcc自己实现的语法,可以参考这里:https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html,在这里目的为放入cache中,关于 list_head 的使用可以看这里:http://oss.org.cn/kernel-book/ldd3/ch11s05.html

nf_hook_ops 其定义在 include/linux/netfilter.h

其中,list 是链表指针,hook 是钩子函数指针,其格式格式为 nf_hookfn

hooknum 表示钩子函数挂在哪个钩子点上,如 NF_IP_PRE_ROUTING 等,定义于uapi/linux/netfilter_ipv4.h

 priority 表示优先级,数字越小优先级越高。

 

钩子的注册主要依赖 nf_register_hook() 函数:

 

2 Thoughts on “Netfilter 框架笔记

  1. 好久没来看你啦,少年还是一如既往的牛逼啊!

Post Navigation