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. 刷新SqlServer所有视图元数据的存储过程

    摘自: http://www.cnblogs.com/yashen/archive/2004/12/23/81000.html 我们在使用SqlServer时经常遇到这种情况,当修改某个表的结构后,相 ...

  2. C# 网络斗地主源码开源

    C# 网络斗地主源码开源多线程 讨论交流及  下载地址 可以发送聊天消息

  3. HDU2089 ------不要62(数位dp)

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  4. ExtAspNet下通过文档路径实现文档的下载

    <ext:Button ID="Button1" runat="server" Text="Button" OnClick=" ...

  5. Thinkpad X201 Gobi2000 上电信3G网络

    网上的教程大多有点小问题,许多都不完整,今天放出系统化.理论化的设置方法,附送上所有软件. 一.本教程适用范围:1.gobi 2000 正式版 FRU:60Y3263 (带MEID.IMEI)2.- ...

  6. 深入一点 让细节帮你和Fragment更熟络

    有一段时间没有写博客了.作为2017年的第一篇,初衷起始于前段时间一个接触安卓开发还不算太长时间的朋友聊到的一个问题: "假设,想要对一个Fragment每次在隐藏/显示之间做状态切换时进行 ...

  7. 算法笔记_133:最大连续乘积子数组(Java)

    目录 1 问题描述 2 解决方案 2.1 蛮力法 2.2 动态规划法   1 问题描述 给定一个浮点数组,任意取出数组中的若干个连续的数相乘,请找出其中乘积最大的子数组. 2 解决方案 2.1 蛮力法 ...

  8. QtGui.QSlider

    A QtGui.QSlider is a widget that has a simple handle. This handle can be pulled back and forth. This ...

  9. Openerp 中打开 URL 的三种 方法

    来自:http://shine-it.net/index.php/topic,8013.0.html 最近总结了,Openerp 中打开 URL 的三种 方法: 一.在form view 添加 < ...

  10. 查看IE浏览器安装的插件

      请移步至文章:http://blog.sina.com.cn/u/6452627072