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. javaScript几个操作数组增减元素的函数

    1. shift:删除原数组第一项,并返回删除元素的值:如果数组为空则返回undefined 2. unshift:将参数添加到原数组开头,并返回数组的长度 var a = [1,2,3,4,5]; ...

  2. Android怎样设置圆角button

    1. 在res文件夹下的drawable文件夹下新建shape.xml文件 <?xml version="1.0" encoding="utf-8"?&g ...

  3. jquery判断滚动条是否到底部

    clientHeight:这个元素的高度,占用整个空间的高度,所以,如果一个div有滚动条,那个这个高度则是不包括滚动条没显示出来的下面部分的内容.而只是单纯的DIV的高度. offsetHeight ...

  4. windows下读取Linux分区软件

    导读 ext3等日志型文件系统是Linux中被广泛应用的,通常是许多流行Linux发行版默认的文件系统.etx4也是Linux下的日志型文件系统,被设计作为ext3的继任者.他消除了64位存储限制,是 ...

  5. 再谈Cognos报表设计中的维度函数

    在报表设计的过程中,客户很多时候会想看同比.环比的数据,很多人会想到利用日期函数在数据库中处理好然后直接在报表拖出来使用,其实这样加大了数据库的压力,当然也是解决问题的一种思路.今天我们就来说一下如何 ...

  6. Discuz常见小问题-如何快速清除帖子

    看别人发的垃圾帖,然后鼠标移到用户名上面,在弹出菜单中点击禁止用户   设置禁止访问-全选所有,删除   然后短期内无法看到效果,帖子还在,你点进去会报错说指定的主题不存在   过三十分钟再刷新页面, ...

  7. 定义查询构建器IFeatureLayerDefinition

    在宗地出图,需要实现,只显示某一户人的地块.在ArcMap里,有个定义查询,可只显示过滤后的要素. 在代码中,也比较好实现,使用IFeatureLayerDefinition接口即可. IFeatur ...

  8. xcode 模拟器,文档,离线安装

    一:xcode上的模拟器,文档,在下载时,通过apple.com下载的速度太慢了,所以我们下载之后,做一下备份,离线安装还原就行了! 二:模拟器安装 目录:/Users/<user name&g ...

  9. UNIX网络编程读书笔记:端口号、套接口对和套接口

    端口号 端口号(port number):16位整数,用来区分不同的进程. 服务器使用的端口号:TCP和UDP定义了一组众所周知的端口(well-known port),用于标识众所周知的服务. 客户 ...

  10. QQ互联简单例子,七彩花都提供

    QQ互联简单例子 源码由七彩花都论坛提供 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &qu ...