linux ip forward不起作用,linux-ipforward实现

对于linux的数据包流向,大家应该是比较了解,如果还不是很了解,可以参考《OReilly.Understanding.Linux.Network.Internals.Dec.2005》,其中有一个图非常清楚的描述了数据包的流向。

ip的数据包接收函数是ip_rcv()==>ip_rcv_finish()

在ip_rcv_finish()中:

if (skb->dst == NULL) {

int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,

skb->dev);

刚接收到的数据包,skb->dst项是空的,因此会调用ip_route_input()函数,我们来追踪ip_route_input函数:

ip_route_input()==>ip_route_input_slow()

在ip_route_input_slow()中:

if ((err = fib_lookup(&fl, &res)) != 0) {

if (!IN_DEV_FORWARD(in_dev))

goto e_hostunreach;

goto no_route;

}

调用fib_lookup()函数用来在fib中查询路由信息,将路由查询结果保存在fib_result结构的res中。

接下来:

if (res.type == RTN_LOCAL) {

int result;

result = fib_validate_source(saddr, daddr, tos,

loopback_dev.ifindex,

dev, &spec_dst, &itag);

if (result dst->input=ip_local_deliver*/

goto local_input;

}

如果查询的结果显示,路由类型RTN_LOCAL的话,跳转到local_input段,设置skb->dst->input = ip_local_deliver

接下来,路由类型是RTN_LOCAL的已经跳转到下面去了,剩下的就是非LCOAL的,也就是Forward的:

if (!IN_DEV_FORWARD(in_dev))

goto e_hostunreach;

if (res.type != RTN_UNICAST)

goto martian_destination;

/*设置skb->dst->input=ip_forward*/

err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos);

调用IN_DEV_FORWARD宏来判断网络设备是否处于FORWARD状态;调用ip_mkroute_input()函数来设置skb->dst->input=ip_forward

我们来分析一下IN_DEV_FORWARD这个宏:

#define IN_DEV_FORWARD(in_dev)    ((in_dev)->cnf.forwarding)

在ipv4_sysctl_forward()函数中调用inet_forward_change()函数:

在inet_forward_change()函数中:

int on = ipv4_devconf.forwarding;

in_dev->cnf.forwarding = on;

在sysctl_net_ipv4.c中

{

.ctl_name    = NET_IPV4_FORWARD,

.procname    = "ip_forward",

.data        = &ipv4_devconf.forwarding,

.maxlen        = sizeof(int),

.mode        = 0644,

.proc_handler    = &ipv4_sysctl_forward,

.strategy    = &ipv4_sysctl_forward_strategy

},

这样,我们通过

echo 1 > /proc/sys/net/ipv4/ip_forward

来打开forward功能,实际上就调用了

ipv4_sysctl_forward()==>inet_forward_change()

设置了in_dev->cnf.forwarding = 1;

这样IN_DEV_FORWARD(in_dev)返回为1,当forward的数据包到来的时候,能够调用ip_mkroute_input()函数,设置skb->dst->input=ip_forward。

==========

再回到ip_rcv_finish()中,最后函数调用了dst_input函数,我们来追踪一下dst_input()函数:

dst_input()==>skb->dst->input

对于LOCAL的数据包来说调用的是:ip_local_deliver()函数

对于FORWARD的数据包来说调用的是:ip_forward()函数

对于fib_lookup的细节,可以参考:

http://blog.chinaunix.net/u/28366/showart_215Array22.html

[url=http://control.cublog.cn/index.php][/url]

阅读(444) | 评论(0) | 转发(0) |

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java常见的面试题

1.什么是B/S架构?什么是C/S架构 B/S(Browser/Server),浏览器/服务器程序C/S(Client/Server),客户端/服务端,桌面应用程序2.你所知道网络协议有那些? HTTP:超文本传输协议 FTP:文件传输协议 SMPT:简单邮件协议 TELNET:远程终端协议 POP3:邮件读取协议 3.Java都有…

java实现原数组根据下标分隔成两个子数组并且在原数组中交换两个子数组的位置...

此类实现:输出一行数组数据,根据输入的下标,以下标位置为结束,将原数组分割成两组子数组。并交换两个子数组的位置,保持子数组中的元素序号不变.如:原数组为7,9,8,5,3,2 以下标3为分割点,分割为子数组一:7,…

linux共享磁盘给指定ip,linux想挂载通过ipsan协议推送上来的磁盘,两个ip共分配了21个未分区的盘,...

先安装iSCSI initiator以及iscsiadmiscsiadm是基于命令行的iscsi管理工具,提供了对iscsi节点、会话、连接以及发现记录的操作。iscsiadm的使用说明可以查看/usr/share/doc/iscsi-initiator-utils-6.2.0.742/README,也可以运行man iscsiadm或iscsiadm --h…

dto与dto相互转换_在DTO上

dto与dto相互转换通常使用DTO或数据传输对象 。 什么不是s? 众所周知,它们源自DDD(域驱动设计)。 在那里很有意义–域对象具有状态,身份和业务逻辑,而DTO仅具有状态。 但是,当今许多项目正在使用…

动态生成表格呈现还是将表格直接绑定gridview等控件呈现的开发方式选择依据...

动态生成表格呈现还是将表格直接绑定gridview等控件呈现的开发方式选择依据:由存储过程决定,如果编写的存储过程可以生成需要呈现的表格则直接绑定,否则要动态生成表格转载于:https://www.cnblogs.com/yzl495/p/4269571.html

【APICloud系列|1】华为应用市场 应用版权证书或代理证书怎么填

将apk上传到华为应用市场 首页提交的时候是没有问题的,但是第二次需要更新的时候发现多了一个必填的选项 我的应用被打回来啦,说明这个免责函需要要填写。今天公章还不在公司,还着急上线,不能准时上线就扣20%的工资。

Lambdas中的例外:有点混乱的优雅解决方案

考虑以下用于写入文件的功能: 该方法背后的想法是,以允许用户在不同的实施方式中通过InputStream的方法,以便writeToFile可以被称为例如用GZIPOuputStream , SnappyOuputStream (快速压缩)或简单的FileIn…

linux ub查看ftp安装,Linux Ubuntu 18.04 安装 FTP服务

安装更新数据源 : apt-get update安装FTP: sudo apt-get install vsftpd服务启动FTP服务: sudo service vsftpd startTip可以使用screen后台运行服务停止FTP服务: sudo service vsftpd stop查看FTP服务状态: sudo service vsftpd status配置新建用户新建/home/uftp目录作为用户…

图片上的文字怎么转换为word

图片上的文字怎么转换为word 很多软件因为自身技术不成熟所有对使用环境操作步骤等有诸多的要求,使得用户使用的时候很不方便。一般的ocr文字识别软件不能在win7系统中使用,有的时候要使用这个软件还要重装系统或是找一台xp系统的电脑,使用受…

【APICloud系列|2】上架安卓应用商店全套流程(小米应用商店、华为应用市场、阿里应用商店、百度手机助手、腾讯应用宝)

​​本次主要讲解前5个平台上架流程及注意事项(注册登录信息自行准备) 1. 腾讯应用宝:http://open.qq.com/ 2. 阿里应用商店(淘宝手机助手,UC应用商店,豌豆荚):http://open.uc.cn/ 3. 百度手机助手:http://app.baidu.com/ 4. 华为应用市场:http://developer.huaw…

socket阻塞与非阻塞,同步与异步、I/O模型

socket阻塞与非阻塞,同步与异步 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:同步: 所谓同步,就是在发出一个功能调用时,…

linux基于域名的虚拟主机,Nginx虚拟主机应用——基于域名、IP、端口的虚拟主机...

Nginx支持的虚拟主机有三种●基于域名的虚拟主机●基于IP的虚拟主机●基于端口的虚拟主机每一种虚拟主机均可通过“server{}" 配置段实现各自的功能基于域名的虚拟主机实验环境1.基础源码包(无密码):https://pan.baidu.com/s/14WvcmNMC6CFX1SnjHxE7JQ2.CentOS 7版本Linux虚…

解决Chrome谷歌浏览器″Adobe Flash Player 插件已被屏蔽″的问题

​​解决Chrome谷歌浏览器"Adobe Flash Player 插件已被屏蔽"的问题如果你确定在电脑上确实已经安装了 Adobe Flash Player 插件,但是打开网页时仍然提示"已屏蔽 Adobe Flash Player 插件" ,你可以试试修改下面这两个选项&#xff0…

powermock模拟对象_使用PowerMock测试对象的内部状态

powermock模拟对象大多数单元测试都集中于测试对象的行为以证明其有效。 这可以通过编写一个JUnit测试来实现,该测试调用对象的公共方法,然后测试这些调用的返回值是否与先前定义的一组期望值匹配。 这是一种非常常见且成功的技术。 但是,不应…

Mono for android,Xamarin点击事件的多种写法

(一)原本java的写法(相信很多是学过java的): 需要实现接口View.IOnClickListener,最好也继承类:Activity,因为View.IOnClickListener接口又继承了IJavaObject, IDisposable接口&…

51个赚钱的好方法

有很多方法赚钱。你可以在家工作,你可以做各种自由职业者,你可以在博客,也可以只保存。时间紧迫,我不知道任何人谁不喜欢做一些额外的现金。所以,我得给你51如何赚钱最好的方法的列表。 1.作为自由职业者的工作 工作作…

一句话木马绕过linux安全模式,一句话木马(webshell)是如何执行命令的

在很多的渗透过程中,渗透人员会上传一句话木马(简称webshell)到目前web服务目录继而提权获取系统权限,不论asp、php、jsp、aspx都是如此,那么一句话木马到底是如何执行的呢,下面我们就对webshell进行一个简单的分析。首先我们先看…

如何从finally块访问方法的结果值

尽管JVM是基于堆栈的计算机 ,但Java语言实际上并没有为您提供任何访问该堆栈的方法。 即使有时,在极少数情况下,它也会非常有用。 一个例子 方法结果值放在堆栈中。 如果查看以下示例: public int method() {if (something)retu…

第六章 Qt布局管理器Layout

第六章 Qt布局管理器Layout 大家有没有发现一个现象,我们放置一个组件,给组件最原始的定位是给出这个控件的坐标和宽高值,这样Qt就知道这个组件的位置。当用户改变窗口的大小,组件还静静地呆在原来的位置,这有时候显然…

kafka集群状态Linux,Kafka集群配置

本文只要讲述Kafka集群的配置事项,包括zookeeper集群的配置。本文讲述的前提是kafka和zookeeper在单机情况下已正确安装和配置。如有疑问,可以参考《Linux(CentOS)中常用软件安装,使用及异常——Zookeeper, Kafka》。假设集群中有三台机器, i…