免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2103 | 回复: 3
打印 上一主题 下一主题

[网络子系统] ip_rcv_finish 新手学习 望多指教 [复制链接]

论坛徽章:
16
CU十二周年纪念徽章
日期:2013-10-24 15:41:3415-16赛季CBA联赛之广东
日期:2015-12-23 21:21:55青铜圣斗士
日期:2015-12-05 10:35:30黄金圣斗士
日期:2015-11-26 20:42:16神斗士
日期:2015-11-19 12:47:50每日论坛发贴之星
日期:2015-11-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-18 06:20:002015亚冠之城南
日期:2015-11-10 19:10:492015亚冠之萨济拖拉机
日期:2015-10-28 18:47:282015亚冠之柏太阳神
日期:2015-08-30 17:21:492015亚冠之山东鲁能
日期:2015-07-07 18:48:39摩羯座
日期:2014-08-29 23:01:42
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-07-10 21:08 |只看该作者 |倒序浏览
static int ip_rcv_finish(struct sk_buff *skb)
{
        const struct iphdr *iph = ip_hdr(skb);
        struct rtable *rt;

        /*
         *        Initialise the virtual path cache for the packet. It describes
         *        how the packet travels inside Linux networking.
         */
        if (skb->dst == NULL) {
                int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
                                         skb->dev);
                if (unlikely(err)) {
                        if (err == -EHOSTUNREACH)
                                IP_INC_STATS_BH(dev_net(skb->dev),
                                                IPSTATS_MIB_INADDRERRORS);
                        else if (err == -ENETUNREACH)
                                IP_INC_STATS_BH(dev_net(skb->dev),
                                                IPSTATS_MIB_INNOROUTES);
                        goto drop;
                }
        }

#ifdef CONFIG_NET_CLS_ROUTE
        if (unlikely(skb->dst->tclassid)) {
                struct ip_rt_acct *st = per_cpu_ptr(ip_rt_acct, smp_processor_id());
                u32 idx = skb->dst->tclassid;
                st[idx&0xFF].o_packets++;
                st[idx&0xFF].o_bytes+=skb->len;
                st[(idx>>16)&0xFF].i_packets++;
                st[(idx>>16)&0xFF].i_bytes+=skb->len;
        }
#endif

        if (iph->ihl > 5 && ip_rcv_options(skb))
                goto drop;

        rt = skb->rtable;
        if (rt->rt_type == RTN_MULTICAST)
                IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCASTPKTS);
        else if (rt->rt_type == RTN_BROADCAST)
                IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCASTPKTS);

        return dst_input(skb);

drop:
        kfree_skb(skb);
        return NET_RX_DROP;
}


红色的标志:其中,skb->dst为NULL时候,ip_route_input主要查找路由表来决定转发的路径嘛?
如果skb->dst不为NULL,是在哪里进行赋值的呢?好像驱动调用netif_rx之前没有进行此操作,netif_rx也没有进行此操作,net_rx_action,netif_rx_buff以及ip_rcv都没有进行此操作。
望在学习linux网络协议栈的来讨论哈撒  望高手指导

论坛徽章:
0
2 [报告]
发表于 2013-07-10 22:16 |只看该作者
其中,skb->dst为NULL时候,ip_route_input主要查找路由表来决定转发的路径嘛?

这是ip_route_input,是输入过程的路由,用于向上传递,也就是给更高层协议栈处理过程用的。

查找路由表来决定转发的路径

那是ip_route_output。

如果skb->dst不为NULL,是在哪里进行赋值的呢?

比如还回接口(loopback)。

论坛徽章:
16
CU十二周年纪念徽章
日期:2013-10-24 15:41:3415-16赛季CBA联赛之广东
日期:2015-12-23 21:21:55青铜圣斗士
日期:2015-12-05 10:35:30黄金圣斗士
日期:2015-11-26 20:42:16神斗士
日期:2015-11-19 12:47:50每日论坛发贴之星
日期:2015-11-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-18 06:20:002015亚冠之城南
日期:2015-11-10 19:10:492015亚冠之萨济拖拉机
日期:2015-10-28 18:47:282015亚冠之柏太阳神
日期:2015-08-30 17:21:492015亚冠之山东鲁能
日期:2015-07-07 18:48:39摩羯座
日期:2014-08-29 23:01:42
3 [报告]
发表于 2013-07-10 23:09 |只看该作者
回复 2# 卖萌犯法


   
查找路由表来决定转发的路径

那是ip_route_output。

我怎么没有收到ip_route_output函数啊  。。。
是不是交给本地上层协议和转发出去的都是在调用ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
                                          skb->dev);完成的啊??

论坛徽章:
0
4 [报告]
发表于 2013-07-13 19:44 |只看该作者
我怎么没有收到ip_route_output函数啊  。。。

for linux kernel version 2.4.21

route.h:140
/* Deprecated: use ip_route_output_key directly */
static inline int ip_route_output(struct rtable **rp,
                                      u32 daddr, u32 saddr, u32 tos, int oif)
{
        struct rt_key key = { dst:daddr, src:saddr, oifif, tos:tos };

        return ip_route_output_key(rp, &key);
}


是不是交给本地上层协议和转发出去的都是在调用ip_route_input

你所说的转发,是什么意思呢?是发送么?

我想你可能对于路由函数的概念和关系不太理解吧……
一个ip报文被接收时,会如下调用接收接口和路由函数:
ip_rcv_finish -> ip_route_input -> (ip_forward(转发) / ip_local_deliver(本地接收))

一个ip报文被发送时(以UDP为例,TCP较为复杂),会如下调用路由函数和后续接口:
udp_sendmsg -> ip_route_output -> ip_output()((发送) -> ip_finish_output -> ip_finish_output2) -> dst->neighbour->output() (邻网地址转换机制,例如ARP协议)

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

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP