linux netfilter 五个钩子点
参考http://www.linuxtcpipstack.com/685.html#NF_INET_PRE_ROUTING
https://opengers.github.io/openstack/openstack-base-netfilter-framework-overview/
http://blog.chinaunix.net/uid-26517122-id-4293010.html
https://netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-3.html
https://en.wikipedia.org/wiki/Netfilter
在三层IPv4数据包的处理过程中,可能经过Netfilter的五个钩子点,分别为NF_INET_PRE_ROUTING、NF_INET_LOCAL_IN、NF_INET_FORWARD、NF_INET_LOCAL_OUT、NF_INET_POST_ROUTING,在每个点都可以设置一些规则,来对数据包进行匹配检查处理,这些规则的配置、布局和匹配流程。



Netfilter 提供了一个基本的报文拦截框架,即hook机制;
Netfilter 中定义了一个全局二维数组,来存放注册了的处理函数。
struct list_head hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly;
在每个关键点上,有很多已经按照优先级预先注册了的回调函数;
每个钩子函数最后必须向Netfilter框架返回下列几个值其中之一
netfilter 回调函数注册
nf_hook_ops是注册的钩子函数的核心结构,字段含义如下所示,一般待注册的钩子函数会组成一个nf_hook_ops数组,在注册过程中调用nf_register_net_hooks将所有规则加入到指定的钩子点;
/*
list:因为在一个HOOK点有可能注册多个钩子函数,因此这个变量用来将某个HOOK点所注册的所有钩子函数组织
成一个双向链表;
hook:该参数是一个指向nf_hookfn类型的函数的指针,由该函数指针所指向的回调函数在该hook被激活时调用【nf_hookfn在后面做解释】;
owner:表示这个hook是属于哪个模块的
pf:该hook函数所处理的协议。目前我们主要处理IPv4,所以该参数总是PF_INET;
hooknum:钩子函数的挂载点,即HOOK点;
priority:优先级。前面也说过,一个HOOK点可能挂载了多个钩子函数,当Netfilter在这些HOOK点上遍历查找所注册的钩子函数时,这些钩子函数的先后执行顺序便由该参数来制定。
*/
struct nf_hook_ops {
struct list_head list; /* User fills in from here down. */
nf_hookfn *hook; /* 钩子函数 */
struct net_device *dev; /* 设备 */
void *priv; /* 私有数据 */
u_int8_t pf; /* 协议族 */
unsigned int hooknum; /* 钩子点 */
/* Hooks are ordered in ascending priority. */
int priority; /* 优先级 */
};
钩子函数原型为:
typedef unsigned int nf_hookfn(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state);
nf_register_net_hook为钩子函数注册的主流程,首先找到钩子点函数的入口,然后根据优先级将当前注册的钩子函数插入到链表中;
int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
{
struct list_head *hook_list;
struct nf_hook_entry *entry;
struct nf_hook_ops *elem;
/* 分配钩子入口结构 */
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return -ENOMEM; entry->orig_ops = reg;
entry->ops = *reg;
/* 找到钩子点链表头部 */
hook_list = nf_find_hook_list(net, reg);
if (!hook_list) {
kfree(entry);
return -ENOENT;
} mutex_lock(&nf_hook_mutex);
/* 找到钩子应该插入的位置 */
list_for_each_entry(elem, hook_list, list) {
if (reg->priority < elem->priority)
break;
}
/* 插入钩子点 */
list_add_rcu(&entry->ops.list, elem->list.prev);
mutex_unlock(&nf_hook_mutex);
#ifdef CONFIG_NETFILTER_INGRESS
if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS)
net_inc_ingress_queue();
#endif
#ifdef HAVE_JUMP_LABEL
static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]);
#endif
return 0;
}
/*
对于nf
其钩子函数入口形式为hooks[协议族][钩子点],在二维数组的每个节点都对应着一个钩子函数链表,内部多个nf_hook_entry通过优先级从小到大排列;
*/
struct netns_nf {
#if defined CONFIG_PROC_FS
struct proc_dir_entry *proc_netfilter;
#endif
const struct nf_queue_handler __rcu *queue_handler;
const struct nf_logger __rcu *nf_loggers[NFPROTO_NUMPROTO];
#ifdef CONFIG_SYSCTL
struct ctl_table_header *nf_log_dir_header;
#endif
struct list_head hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
}; enum {
NFPROTO_UNSPEC = 0,
NFPROTO_INET = 1,
NFPROTO_IPV4 = 2,
NFPROTO_ARP = 3,
NFPROTO_NETDEV = 5,
NFPROTO_BRIDGE = 7,
NFPROTO_IPV6 = 10,
NFPROTO_DECNET = 12,
NFPROTO_NUMPROTO,
};
//IPv4钩子点的定义如下:
enum nf_inet_hooks {
NF_INET_PRE_ROUTING,
NF_INET_LOCAL_IN,
NF_INET_FORWARD,
NF_INET_LOCAL_OUT,
NF_INET_POST_ROUTING,
NF_INET_NUMHOOKS
};
linux netfilter 五个钩子点的更多相关文章
- Netfilter 之 五个钩子点
概述 在协议栈的三层IPv4(IPv6还没看,不清楚)数据包的处理过程中,可能经过Netfilter的五个钩子点,分别为NF_INET_PRE_ROUTING.NF_INET_LOCAL_IN.NF_ ...
- 《sed的流艺术之四》-linux命令五分钟系列之二十四
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之三》-linux命令五分钟系列之二十三
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之二》-linux命令五分钟系列之二十二
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之一》-linux命令五分钟系列之二十一
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《paste命令》-linux命令五分钟系列之二十
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《vi中的替换艺术》-linux命令五分钟系列之十一
vi方面的内容不知道分类到哪里好,就放到<Linux命令五分钟系列>里吧! 今天编程,关于栈的一个小例子,其间我需要把”S.”替换为”S->”(替换不包括双引号). 其实这个不难,不 ...
- linux type 命令和Linux的五个查找命令
type命令用来显示指定命令的类型.一个命令的类型可以是如下之一 alias 别名 keyword 关键字,Shell保留字 function 函数,Shell函数 builtin 内建命令,Shel ...
- Linux的五个查找命令find,locate,whereis,which,type
Linux的五个查找命令 1. find 最常见且最强大的命令,可以查找任何文件. 格式 $ find 指定目录 指定条件 指定动作 指定目录: 所要搜索的目录及其子目录,默认当前目录 ...
随机推荐
- 空间视频和GIS
摘要. GIS的空间数据基本单位表示通常是根据 点,线和面.但是,另一种类型的空间数据正在变得越来越频繁 捕获的是视频,但在GIS中却被很大程度上忽略了.数字录像时 是现代社会中常见的一种媒介,包含多 ...
- python数据清洗
盖帽法 分箱法 简单随机抽和分层抽
- 如何从0到1的构建一款Java数据生成器-第一章
前提 某天晚上老夫在神游时,想起白天公司同事说起的问题,这老表抱怨使用mysql生成大批的随机测试数据太过麻烦,问大家有没有好的工具推荐,老夫对这种事情当然不关心,毕竟我也不知道. 秉承着不懂就要问, ...
- 【循环矩阵乘优化DP】BZOJ 2510 弱题
题目大意 有 \(M\) 个球,一开始每个球均有一个初始标号,标号范围为 \(1\) - \(N\) 且为整数,标号为 \(i\) 的球有 \(a_i\) 个,并保证 \(\sum a_i = M\) ...
- 机器分配----线性dp难题(对于我来说)
题目: 总公司拥有高效设备M台, 准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M <= 15, ...
- 痞子衡嵌入式:MCUBootUtility v2.4发布,轻松更换Flashloader文件
-- 痞子衡维护的NXP-MCUBootUtility工具距离上一个版本(v2.3.1)发布过去2个月了,这一次痞子衡为大家带来了版本升级v2.4.0,这个版本主要有一个非常重要的更新需要跟大家特别说 ...
- 解决Django本地接口不能跨域访问的问题
1.安装django-cors-headers模块: pip install django-cors-headers 2.插入Django的APP配置中: # 修改settings.py中的INSTA ...
- 在Linux上成功启动Jenkins却无法访问的问题
本鸟最近打算学习Jenkins,正准备在Linux上面鼓捣一番,,却没想被入门级别问题当头一棒 下载完jenkins.war,使用java -jar命令在8088端口开启服务:java -jar je ...
- JS变量作用域与解构赋值
用var变量是有作用域的 变量在函数内部声明时,那么该变量只属于整个函数体,函数外不可调用 当两个不同的函数里,使用了用一个相同的变量名,二者不互相影响,相互独立 遇到嵌套函数时,外部函数不可调用内部 ...
- ansible-hoc命令行
ansible一种开源的自动化工具 ansible: hoc命令行: 是一款开源的自动化运维工具 python paramiko #模拟ssh协议批量管理主机 jinja2 #模板语言,主要用来传递变 ...