1.首先指出。NF_HOOK系列宏的outdev參数的传递方式(直接传递一个net_device结构体指针)是不对的

正确的方式要么是不传递。要么是传递指针的地址,即地址的地址。

2.接下来指出,仅仅传递一个地址为何不对

由于在该HOOK点可能存在多个HOOK函数,每个函数都有可能改变skb的路由,即调用reroute,比方NAT,比方IP Mark等,这样兴许的HOOK函数看到的依旧是旧的outdev參数,而不是reroute之后的skb_dst(skb)->dev。

3.然后看一个实际出错样例

设置默认路由
0.0.0.0/0 via 192.168.1.1 eth0
设置策略路由
iptables -t mangle -A OUTPUT -d 1.1.1.1 -j MARK --set-mark 100
ip rule fwmark 100 table my
ip route add 0.0.0.0/0 via 192.168.2.1 dev eth1 table my
防止mark 100的数据包从eth0出去(这实际上仅仅是为了展现问题而加入的多余的一条规则)
iptables -A OUTPUT -d 1.1.1.1 -o eth0 -j DROP
效果是到达1.1.1.1的数据包被DROP掉了。是的,策略路由确实生效了,问题在于进入OUTPUT的filter HOOK函数的时候,outdev还是旧的outdev。由于OUTPUT处在路由之后。假设当中的mangle表改变了skb的mark,那么会reroute,不幸的是,reroute并无法改变OUTPUT点上NF_HOOK的outdev參数值!

4.怎么修正

办法非常多,依次介绍:
a.使用setsockopt打mark而不是iptables打mark,绕开OUTPUT和路由的暧昧关系;
b.改动NF_HOOK的dev參数为struct net_device **类型,然后在reroute中重路由成功后运行*out = (struct dst_entry*)skb_dst(skb)->dev;从而改变NF_HOOK中的outdev的值;
c.去掉NF_HOOK宏的outdev參数。须要时从skb_dst(skb)->dev中实时获取。
非常easy。在ipt_do_table的开头位置。即变量声明的完结处,加入以下的代码:

    struct xt_target_param tgpar;
#if 1
struct dst_entry *dst_e = skb_dst(skb);
if (dst_e) {
out = dst_e->dev;
}
#endif

实时替换掉參数定义的out值。
d.使用非传值机制!

C语言是传值的啊!

使用连续的******能够为了寻址一个字节遍历整个内存。即整个内存仅仅存储一个字节的值,其他的都被填满为它的直接或者间接的地址,地址,地址...

5.彻底仿真世界

一个实体仅仅能同一时候存在于一个位置!

就像人一样,进入了一个房间,外面就没有这个人了,可惜编程语言不是这种。

关于Netfilter NF_HOOK宏的outdev參数bug的更多相关文章

  1. C语言利用va_list、va_start、va_end、va_arg宏定义可变參数的函数

    在定义可变參数的函数之前,先来理解一下函数參数的传递原理: 1.函数參数是以栈这样的数据结构来存取的,在函数參数列表中,从右至左依次入栈. 2.參数的内存存放格式:參数的内存地址存放在内存的堆栈段中, ...

  2. C语言变长參数的认识以及宏实现

    1.认识 变长參数是C语言的特殊參数形式.比如例如以下函数声明: int printf(const char *format, ....); 如此的声明表明,printf函数除了第一个參数类型为con ...

  3. OC可变參数的函数实现va_start、va_end、va_list的使用

    一.简单介绍 我们常常在编程的时候看见类似这种代码,如图1.1 图1.1 或者是这种可变參数,如图1.2 图1.2 二.基本知识介绍 在学习怎样写这样的格式的函数前,先简介几个经常使用的宏: 下面摘自 ...

  4. C语言中的system函数參数具体解释

    http://blog.csdn.net/pipisorry/article/details/33024727 函数名: system 功   能: 发出一个DOS命令   用   法: int sy ...

  5. RPM安装包-Spec文件參数具体解释与演示样例分析

    spec文件是整个RPM包建立过程的中心,它的作用就如同编译程序时的Makefile文件. 1.Spec文件參数 spec文件包括建立一个RPM包必需的信息,包括哪些文件是包的一部分以及它们安装在哪个 ...

  6. C语言可变长參数实现原理

    微博:http://weibo.com/u/2203007022             (1)      C语言可变參数 我们能够从C语言的printf得出可变參数的作用.printf函数的原型例如 ...

  7. 【深夜福利】Caffe 添加自己定义 Layer 及其 ProtoBuffer 參数

    在飞驰的列车上,无法入眠.外面阴雨绵绵,思绪被拉扯到天边. 翻看之前聊天,想起还欠一个读者一篇博客. 于是花了点时间整理一下之前学习 Caffe 时添加自己定义 Layer 及自己定义 ProtoBu ...

  8. Direcshow中视频捕捉和參数设置报告

    Direcshow中视频捕捉和參数设置报告 1.      关于视频捕捉(About Video Capture in Dshow) 1视频捕捉Graph的构建 一个能够捕捉音频或者视频的graph图 ...

  9. linux kernel的cmdline參数解析原理分析

    利用工作之便,今天研究了kernel下cmdline參数解析过程.记录在此.与大家共享.转载请注明出处.谢谢. Kernel 版本:3.4.55 Kernel启动时会解析cmdline,然后依据这些參 ...

随机推荐

  1. 使用SQL查询连续号码段

    原文http://www.cnblogs.com/tc310/archive/2010/09/17/1829276.html CREATE TABLE #test(fphm INT ,kshm CHA ...

  2. 解决Windows server 2012 R2 系统使用IIS8浏览Asp程序出现"An error occurred on the server when processing the URL"错误

    进入IIS并将ASP里的“Send Error To Browser”设置为True后点击Appley保存即可 原因是IIS里的Asp设置禁用上当错误信息发送给浏览器,只要启用即可 如果没有Asp选项 ...

  3. 为大家推荐一款很不错的MarkDown编辑器——stackEdit

    自己细致体验了一下下:认为它还是很不错的! !! https://stackedit.io 这是它的官网,我们能够在chrome浏览器的"应用"里找到相应的插件. ps:它但是一款 ...

  4. Array.prototype.slice.call 和 slice以及call

    单独的简单介绍,后续再补上一些资料. 对象转换为数组. /** * slice : 数组->slice(截取) * 参数有两个,开始截取和结束截取,并返回原数组: * a.slice(1) || ...

  5. Quartz.Net的使用(简单配置方法)定时任务框架

    Quartz.dll 安装nuget在线获取dll包管理器,从中获取最新版 Quartz.Net是一个定时任务框架,可以实现异常灵活的定时任务,开发人员只要编写少量的代码就可以实现“每隔1小时执行”. ...

  6. 使用CopyTable工具方法在线备份HBase表

    CopyTable is a simple Apache HBase utility that, unsurprisingly, can be used for copying individual ...

  7. 深入理解磁盘文件系统之inode(转)

    一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统 ...

  8. Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'

    setup slave from backup i got error Got fatal error 1236 from master when reading data from binary l ...

  9. python 的集合 set()操作

      Python 的集合 set(),是一个无序不重复元素集,可以用于关系测试和消除重复元素.     有以下运算:   1.创建一个set ()集合:   2.add:增加集合元素   3.clea ...

  10. android Handler的使用(一)

    Handler的使用(一) Handler基本概念: Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分逐个的在消息队列中将消息取出 ...