忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台论坛 博客 认证专区 大话IT 文库 沙龙 自测 下载 频道自动化运维 虚拟化 服务器 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 1137 | 回复: 0

linux forward的实现(ip_rcv__iprcv_slow_ip_route_input [复制链接]

帖子
161
主题
117
精华
0
可用积分
155
专家积分
0
在线时间
25 小时
注册时间
2005-03-28
最后登录
2014-08-14
论坛徽章:
0
发表于 2008-04-07 17:03:43 |显示全部楼层
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 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
[/url]


本文来自ChinaUnix博客,如果查看原文请点:[url]http://blog.chinaunix.net/u/15071/showart_520336.html

您需要登录后才可以回帖 登录 | 注册

走进电商大数据技术沙龙(11月22日)

沙龙时间:2014年11月22日
大会地点:北京巴比特互联网主题茶馆
沙龙主题:让每一个生命都绽放
活动礼品:四面锁扣乐扣乐扣格拉斯
2014年注定是电商领域波澜壮阔的一年,企业与互联网的全面拥抱将有力地推动新商业文明的诞生和社会资源的优化。在电子商务时代,如何将最合适的业务和产品推荐给合适的客户,成为电商企业的重要目标。


北京皓辰网域网络信息技术有限公司. 版权所有 京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:1101082001
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP