Chinaunix首页 | 论坛 | 博客
  • 博客访问: 436505
  • 博文数量: 75
  • 博客积分: 556
  • 博客等级: 中士
  • 技术积分: 712
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-12 10:10
文章分类
文章存档

2015年(4)

2014年(4)

2013年(31)

2012年(8)

2011年(8)

2010年(20)

分类:

2012-11-06 20:21:11


点击(此处)折叠或打开

  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 cache for 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. }

阅读(2172) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~