白领ol嘉嘉tiffany:linux forward的实现
来源:百度文库 编辑:偶看新闻 时间:2024/04/23 14:22:29
博客首页注册建议与交流排行榜推荐投诉 搜索:帮助
CUDev
Hello,all like Unix Linux and CU ! ^_^
CUDev.cublog.cn管理博客
发表文章
留言
收藏夹· Linux
博客圈
音乐
相册
文章· 嵌入式Linux· 心情日记· 算法研究· 网络安全· 网络编程· Kernel and Driver· Linux深入学习· Linux应用· perl· python· QT4学习笔记· SF· Shell· 操作系统研究· 程序设计· 服务器管理
首页
linux forward的实现 对于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 < 0)
goto martian_source;
if (result)
flags |= RTCF_DIRECTSRC;
spec_dst = daddr;
/*设置skb->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_215922.html
发表于: 2008-01-17 ,修改于: 2008-01-17 12:08,已浏览1079次,有评论0条推荐投诉
网友评论
发表评论
CUDev
Hello,all like Unix Linux and CU ! ^_^
CUDev.cublog.cn管理博客
发表文章
留言
收藏夹· Linux
博客圈
音乐
相册
文章· 嵌入式Linux· 心情日记· 算法研究· 网络安全· 网络编程· Kernel and Driver· Linux深入学习· Linux应用· perl· python· QT4学习笔记· SF· Shell· 操作系统研究· 程序设计· 服务器管理
首页
linux forward的实现 对于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 < 0)
goto martian_source;
if (result)
flags |= RTCF_DIRECTSRC;
spec_dst = daddr;
/*设置skb->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_215922.html
发表于: 2008-01-17 ,修改于: 2008-01-17 12:08,已浏览1079次,有评论0条推荐投诉
网友评论
发表评论
Forward You Lore的中文翻译
linux 和Solariss的线程实现方式是怎样的?
linux系统中能够实现的主流网络应用:
怎么用JAVA实现监控LINUX下CPU的使用率???
在Linux中怎样实现单线双网的策略
在Linux中怎样实现单线双网的策略
怎样实现XP和LINUX的双系统安装?
VMWARE LINUX 下怎样实现中英文输入法的转化
如何在linux实现动态的更新一个动态库
电影pay it forward哪有卖的?
struts 中 forward 后地址栏的问题
look forward to doing sth和look forward to do sth的区别?
想安装一个linux玩玩,有什么好介绍的吗?另外linux可以与xp实现双启动吗?
黄金的Forward Rate和Libor Rate分别是什么率?
怎么去找有关forward rate(远期利率)的网址
全攻全守的英文说法是不是:Six forward offence
ahead、front、forward、advance的区别,请举例说明
跪求 战火遗孤和PAY IT FORWARD的下载
请问 哪里能下载 desert rose 的 one step forward。
举出几个LINUX下的利用服务器实现的应用功能(详细点)
在 Linux 中怎样实现类似 DOS 环境下的 AUTOEXEC.BAT 批处理功能?
在 Linux 中怎样实现类似 DOS 环境下的 AUTOEXEC.BAT 批处理功能?
请问:Linux中的ioctl函数,在windows中是用什么实现的?
在linux下如何实现图形桌面与文本桌面的转换?