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. vue-router路由元信息详解

    一.官方文档 路由元信息:定义路由的时候可以配置 meta 字段 const router = new VueRouter({ routes: [ { path: '/foo', component: ...

  2. MyEclipse 全面的快捷键

    摘自: http://www.360doc.com/content/11/0406/10/6704374_107513559.shtml 引用 MyEclipse快捷键(全面) 程序代码自动排版:Ct ...

  3. 走进C++程序世界------异常处理

    一. 概述 C++自身有着很强的纠错能力,发展到现在,已经建立了比較完好的异常处理机制. C++的异常情况无非两种,一种是语法错误.即程序中出现了错误的语句,函数.结构和类,致使编译程序无法进行.还有 ...

  4. Python-urllib学习记录

    urllib是python自带库,不要专门安装,还挺好用的. 脚本语言的好处之一就是随写随用,有些东西用C语言写真的是能把人累死,换成python就是几行代码,so easy,对于喜欢偷懒的同学绝对是 ...

  5. 如何获取浏览器URL中查询字符串的参数?

    如何获取浏览器URL中查询字符串的参数? 想要知道怎样解决这个问题,首先我们先认识一下Location对象. Location对象包含了当前页面与位置(url)相关的信息 URL示例:http://w ...

  6. ASP服务器I I S出现authentication mode=Windows错误解决办法

    网上下载的asp.net源码出现 <authentication mode="Windows"/>错误信息 属性 说明 mode 必选的属性. 指定应用程序的默认身份验 ...

  7. vnc/route/ifconfig 配置

    重启网卡的方法: 1 network 利用root帐户 # service network restart ############################################## ...

  8. (四)hibernate关联映射之——一对多映射

    0.   映射分四种类型: 一对多 多对一 一对一 多对多 前两者最常用 1.单向一对多关联 1.1  如何在JAVA和数据库中表示一对多的关系. 2.多对一关联 以学生对应班级来解释 步骤(1)创建 ...

  9. nginx配置用户认证

    location ~ .*admin\.php$ {             auth_basic "weifenglinux auth";             auth_ba ...

  10. AI:人工智能搜索策略

    人工智能搜索策略: