Chinaunix首页 | 论坛 | 博客
  • 博客访问: 825585
  • 博文数量: 264
  • 博客积分: 592
  • 博客等级: 中士
  • 技术积分: 1574
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-24 22:02
文章分类

全部博文(264)

文章存档

2019年(2)

2018年(1)

2017年(1)

2016年(4)

2015年(14)

2014年(57)

2013年(88)

2012年(97)

分类: LINUX

2014-02-12 15:49:39

转:http://blog.csdn.net/nerdx/article/details/12656597
  1. //分片子模块初始化函数  
  2. //  1.ipq hash 函数的随机因子  
  3. //  2.定时器,到期更新随机因子  
  4. //  3.ipq_hash 静态全局变量,静态分配64个buckets  
  5. //调用路径:inet_init->ipfrag_init  
  6. 1.1 void ipfrag_init(void)  
  7. {  
  8.     //分片暂存的hash表  
  9.     ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^  
  10.                  (jiffies ^ (jiffies >> 6)));  
  11.     //定期修改ip分片的哈希函数,将hash表中的所有分片根据信息的哈希函数搬到新的位置  
  12.     init_timer(&ipfrag_secret_timer);  
  13.     ipfrag_secret_timer.function = ipfrag_secret_rebuild;  
  14.     ipfrag_secret_timer.expires = jiffies + sysctl_ipfrag_secret_interval;  
  15.     add_timer(&ipfrag_secret_timer);  
  16. }  
  17.   
  18. //调用路径:ip_local_deliver->ip_defrag  
  19. //  1.检查检查ipq hash是否超过内存阈值  
  20. //      1.1 如果超过阈值则清除超时的分片  
  21. //  2.从ipq hash表中找到与入口分片相关的ipq结构  
  22. //  3.将分片插入到ipq的分片列表中  
  23. //  4.如果分片接收完全,重组  
  24.   
  25. 1.2 struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user)  
  26. {  
  27.     struct iphdr *iph = skb->nh.iph;  
  28.     struct ipq *qp;  
  29.     struct net_device *dev;  
  30.       
  31.     IP_INC_STATS_BH(IPSTATS_MIB_REASMREQDS);  
  32.   
  33.     //重组ip片段使用的内存已经超过阀值  
  34.     if (atomic_read(&ip_frag_mem) > sysctl_ipfrag_high_thresh)  
  35.         ip_evictor();//通过LRU链表,删除不完整封包的ipq结构  
  36.   
  37.     dev = skb->dev;  
  38.   
  39.     if ((qp = ip_find(iph, user)) != NULL) {//找出和正在被处理的片段相关的封包  
  40.         struct sk_buff *ret = NULL;  
  41.   
  42.         spin_lock(&qp->lock);  
  43.   
  44.         ip_frag_queue(qp, skb);//将skb加入到ipq中  
  45.   
  46.         if (qp->last_in == (FIRST_IN|LAST_IN) &&//第一个和最后一个分片都已经收到  
  47.             qp->meat == qp->len)//meat为已经收到的skb的数据长度,len为通过iph->tot,iph->offset猜测的最大长度  
  48.             ret = ip_frag_reasm(qp, dev);//重组  
  49.   
  50.         spin_unlock(&qp->lock);  
  51.         ipq_put(qp, NULL);  
  52.         return ret;  
  53.     }  
  54.   
  55.     IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);  
  56.     kfree_skb(skb);  
  57.     return NULL;  
  58. }  
阅读(679) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~