<div class="multicntwrap">
<div class="multicnt">
<div>
<h3 class="title pre fs1"><span class="tcnt">ip_rcv_finish</span> <span class="bgc0 fc07 fw0 fs0"></span></h3>
<p class="tdep clearfix nbw-act fc06" style="line-height:20px"><span class="pleft"><span class="blogsep">2013-04-20 14:37:14</span><span class="blogsep">| 分类:</span> <a class="fc03 m2a" href="http://h1372865100.blog.163.com/blog/#m=0&t=1&c=fks_084069086084083074087086080095086087081071086095087067087" rel="noopener noreferrer" target="_blank" title="linux-NET"> linux-NET</a> </span><span class="pright fc07 ztag"><span class="blogsep">|</span><span class="fc03 m2a" id="$_spanReport">举报</span></span> <span class="pright fc07 ztag"><span class="blogsep">|</span><span class="zihao fc03" id="$_fontswitch">字号</span></span><span class="pright pnt fc03" id="$_blog_subscribe"><span class="iblock icn0 icn0-919"> </span><a class="m2a" target="_blank">订阅</a></span> </p>
</div>
</div>
<div class="m-shareAndDownLoad">
<div class="share-wrap pleft">
<span class="shareitm lofter f-bkicons" id="$_shareBtn_lofter2" title="分享到LOFTER"> </span>
<span class="shareitm sinawb f-bkicons" id="$_shareBtn_sinaweibo2" title="分享到新浪微博"> </span>
<span class="shareitm qqzone f-bkicons" id="$_shareBtn_qq2" title="分享到QQ空间"> </span>
<span class="shareitm qqweibo f-bkicons" id="$_shareBtn_qqweibo2" title="分享到腾讯微博"> </span>
<div class="shareitm weixin f-bkicons" id="$_shareBtn_weixin2" title="分享到微信">
<div class="code2dimlayer fc06">
<img alt="" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-3b073d0e866270796f594d0deb6dcfec.do">
<div class="tips"></div>
</div>
</div>
<div class="shareitm yixin f-bkicons" id="$_shareBtn_yixin2" title="分享到易信">
<div class="code2dimlayer fc06">
<img alt="" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-7a0256c5c616bfbc77e18506b3c7247b.do">
<div class="tips"></div>
</div>
</div>
</div>
<a class="pright fc03 noul" href="http://www.lofter.com/app?act=qbbkrzydb_20150408_01" rel="noopener noreferrer" target="_blank"> 下载LOFTER</a>
<a class="pright fc03 noul" href="http://yxp.163.com" rel="noopener noreferrer" target="_blank"> 我的照片书 |</a>
</div>
</div>
<div></div>
<div class="bct fc05 fc11 nbw-blog ztag">
执行完钩子函数后,IP数据包被传送到ip_rcv_finish做进一步处理,这个函数主要功能是做路由选择(kernel/net/ipv4/ip_input.c)
<br> static int ip_rcv_finish(struct sk_buff *skb)
<br> {
<br> const struct iphdr *iph = ip_hdr(skb);
<br> struct rtable *rt;
<br>
<br> /*
<br> * Initialise the virtual path cache for the packet. It describes
<br> * how the packet travels inside Linux networking.
<br> */
<br> if (skb_dst(skb) == NULL) {
<br> int err =
<span style="color:#ff0000">ip_route_input_noref</span>(skb, iph->daddr, iph->saddr,
<br> iph->tos, skb->dev);
<br> if (unlikely(err)) {
<br> if (err == -EHOSTUNREACH)
<br> IP_INC_STATS_BH(dev_net(skb->dev),
<br> IPSTATS_MIB_INADDRERRORS);
<br> else if (err == -ENETUNREACH)
<br> IP_INC_STATS_BH(dev_net(skb->dev),
<br> IPSTATS_MIB_INNOROUTES);
<br> else if (err == -EXDEV)
<br> NET_INC_STATS_BH(dev_net(skb->dev),
<br> LINUX_MIB_IPRPFILTER);
<br> goto drop;
<br> }
<br> }
<br>
<br> #ifdef CONFIG_IP_ROUTE_CLASSID
<br> if (unlikely(skb_dst(skb)->tclassid)) {
<br> struct ip_rt_acct *st = this_cpu_ptr(ip_rt_acct);
<br> u32 idx = skb_dst(skb)->tclassid;
<br> st[idx&0xFF].o_packets++;
<br> st[idx&0xFF].o_bytes += skb->len;
<br> st[(idx>>16)&0xFF].i_packets++;
<br> st[(idx>>16)&0xFF].i_bytes += skb->len;
<br> }
<br> #endif
<br>
<br> if (iph->ihl > 5 && ip_rcv_options(skb))
<br> goto drop;
<br>
<br> rt = skb_rtable(skb);
<br> if (rt->rt_type == RTN_MULTICAST) {
<br> IP_UPD_PO_STATS_BH(dev_net(rt->dst.dev), IPSTATS_MIB_INMCAST,
<br> skb->len);
<br> } else if (rt->rt_type == RTN_BROADCAST)
<br> IP_UPD_PO_STATS_BH(dev_net(rt->dst.dev), IPSTATS_MIB_INBCAST,
<br> skb->len);
<br>
<br> return dst_input(skb);
<br>
<br> drop:
<br> kfree_skb(skb);
<br> return NET_RX_DROP;
<br> }
<br> 我们现看(kernel/include/net/route.h)ip_route_input_noref()--->(kernel/net/route.c)ip_route_input_common()
<br>
<br>
<br> int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
<br> u8 tos, struct net_device *dev, bool noref)
<br> {
<br> struct rtable * rth;
<br> unsigned hash;
<br> int iif = dev->ifindex;
<br> struct net *net;
<br> int res;
<br>
<br> net = dev_net(dev);
<br>
<br> rcu_read_lock();
<br>
<br> if (!rt_caching(net))
<br> goto skip_cache;
<br>
<br> tos &= IPTOS_RT_MASK;
<br> hash = rt_hash(daddr, sadd |
|