linux TCP/IP协议栈 ---ip_rcv_finish()

来源:互联网 发布:易语言调用淘宝api 编辑:程序博客网 时间:2024/06/06 12:27

  1. static int ip_rcv_finish(struct sk_buff*skb)
  2. {
  3.     const struct iphdr *iph = ip_hdr(skb);
  4.     struct rtable *rt;

  5.     /*
  6.      *    Initialise the virtual path cachefor the packet. It describes
  7.      *    how the packet travels inside Linux networking.
  8.      */
  9.     /*
  10.      * 通常从外界接收的数据包,skb->dst不会包含路由信息,暂时还不知道在何处会设置
  11.      * 这个字段。ip_route_input函数会根据路由表设置路由信息,暂时不考虑路由系统。
  12.      */
  13.     if (skb->dst==NULL){
  14.         int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
  15.                      skb->dev);
  16.         if (unlikely(err)){
  17.             if (err == -EHOSTUNREACH)
  18.                 IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
  19.             else if (err==-ENETUNREACH)
  20.                 IP_INC_STATS_BH(IPSTATS_MIB_INNOROUTES);
  21.             goto drop;
  22.         }
  23.     }
  24. /* 更新流量控制所需要的统计数据,忽略*/
  25. #ifdef CONFIG_NET_CLS_ROUTE
  26.     if (unlikely(skb->dst->tclassid)){
  27.         struct ip_rt_acct *st = ip_rt_acct + 256*smp_processor_id();
  28.         u32 idx = skb->dst->tclassid;
  29.         st[idx&0xFF].o_packets++;
  30.         st[idx&0xFF].o_bytes+=skb->len;
  31.         st[(idx>>16)&0xFF].i_packets++;
  32.         st[(idx>>16)&0xFF].i_bytes+=skb->len;
  33.     }
  34. #endif
  35.     /* 如果IP头部大于20字节,则表示IP头部包含IP选项,需要进行选项处理.暂时忽略,毕竟很少用*/
  36.     if (iph->ihl> 5&& ip_rcv_options(skb))
  37.         goto drop;

  38.     /* skb->dst包含路由信息。根据路由类型更新SNMP统计数据*/
  39.     rt = (struct rtable*)skb->dst;
  40.     if (rt->rt_type== RTN_MULTICAST)
  41.         IP_INC_STATS_BH(IPSTATS_MIB_INMCASTPKTS);
  42.     else if (rt->rt_type== RTN_BROADCAST)
  43.         IP_INC_STATS_BH(IPSTATS_MIB_INBCASTPKTS);
  44.     /*
  45.      * dst_input实际上会调用skb->dst->input(skb).input函数会根据路由信息设置为合适的
  46.      * 函数指针,如果是递交到本地的则为ip_local_deliver,若是转发则为ip_forward.
  47.      * 暂时仅先考虑ip_local_deliver。
  48.      */
  49.     return dst_input(skb);

  50. drop:
  51.     kfree_skb(skb);
  52.     return NET_RX_DROP;
  53. }
0 0
原创粉丝点击