http://blog.csdn.net/wangdm0826/archive/2011/03/08/6232177.aspx
5、 几个细节 5.1 Step 14:在_FRAG链表中插入的位置 代码: if (next->offset >= offset) break; 当prev和next结点都存在时满足的条件 offset ∊ ( prev->offset , next->offset ] 隐含意思:当前分片与prev之前的结点无重叠,与prev可能有重叠 5.2 step 15:和prev有重叠,调整当前分片 调整前图 调整后图 step 15:和prev有重叠,调整当前分片后没有判断当前数据的长度,之后会创建一个无用结点! 2.6.17内核已处理! ~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetextsearch ] ~ [ file search ] ~ Linux Cross ReferenceLinux-2.6.17/net/ipv4/ip_fragment.c Version: ~ [ 2.6.16 ] ~ [ 2.6.17 ] ~ Architecture: ~ [ ia64 ] ~ [ i386 ] ~ [ arm ] ~ [ ppc ] ~ [ sparc64 ] ~ 1 /* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * The IP fragmentation functionality. 7 * 8 * Version: $Id: ip_fragment.c,v 1.59 2002/01/12 07:54:56 davem Exp $ 9 * 10 * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG> 11 * Alan Cox <Alan.Cox@linux.org> 12 * 13 * Fixes: 14 * Alan Cox : Split from ip.c , see ip_input.c for history. 15 * David S. Miller : Begin massive cleanup... 16 * Andi Kleen : Add sysctls. 17 * xxxx : Overlapfrag bug. 18 * Ultima : ip_expire() kernel panic. 19 * Bill Hawes : Frag accounting and evictor fixes. 20 * John McDonald : 0 length frag bug. 21 * Alexey Kuznetsov: SMP races, threading, cleanup. 22 * Patrick McHardy : LRU queue of frag heads for evictor. 23 */ 24 465 466 /* Add new segment to existing queue. */ 467 static void ip_frag_queue (struct ipq * qp , struct sk_buff * skb ) 468 { 469 struct sk_buff *prev, * next ; 470 int flags , offset ; ........................ ........................ ........................ ........................ 522 /* Find out which fragments are in front and at the back of us 523 * in the chain of fragments so far. We must know where to put 524 * this fragment, right? 525 */ 526 prev = NULL ; 527 for( next = qp -> fragments ; next != NULL ; next = next -> next ) { 528 if ( FRAG_CB ( next )-> offset >= offset ) 529 break; /* bingo! */ 530 prev = next ; 531 } 532 533 /* We found where to put this one. Check for overlap with 534 * preceding fragment, and, if needed, align things so that 535 * any overlaps are eliminated. 536 */ 537 if (prev) { 538 int i = ( FRAG_CB (prev)-> offset + prev-> len ) - offset ; 539 540 if ( i > 0) { 541 offset += i ; 542 if (end <= offset) 543 goto err; 544 if (! pskb_pull ( skb , i )) 545 goto err ; 546 if ( skb ->ip_summed != CHECKSUM_UNNECESSARY ) 547 skb ->ip_summed = CHECKSUM_NONE ; 548 } 549 } 550 551 while ( next && FRAG_CB ( next )-> offset < end ) { 552 int i = end - FRAG_CB ( next )-> offset ; /* overlap is 'i' bytes */ 553 554 if ( i < next -> len ) { 555 /* Eat head of the next overlapped fragment 556 * and leave the loop. The next ones cannot overlap. 557 */ 558 if (! pskb_pull ( next , i )) 559 goto err ; 560 FRAG_CB ( next )-> offset += i ; 561 qp ->meat -= i ; ........................ ........................ ........................ ........................ ~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~ This page was automatically generated by the LXR engine . Visit the LXR main site for more information. 5.3 step 18: i = end - next->offset tmp->len -= i tmp->offset += i tmp->ptr += i 和next有重叠时的两种情况: 1: 2: 5.4 ipq结构中的特殊成员timer 作用:描述已经收到的属于同一IP包的所有分片的存活期限 创建:step 8 初始设置:step 10 expires为当前时间+30秒 function:失效时的处理函数地址 data:失效时的处理函数的参数,即timer所在的ipq结点首地址 5.5 ipq结构中的特殊成员timer 更新: 所有ipq结点中的timer成员组成一个双向链表_TIMER,链首:timer_head,链尾:timer_tail 分片链表超时处理 step 1 : 当一个_IPQ链表在30秒内没有再收到分片数据时,放弃重组 timer的更新step 13 :当收到一个分片时,重新设置失效时间,并将该分片所属ipq中的timer移到_TIMER的尾部 5.6 分片数据是否可重组的判断 借助ipq结构中的成员变量len 初始值:0 更新:仅当收到最后一个分片时才设置len 判断: 当ipq.len为0时直接返回 当收到最后一个分片后才检查_FRAG链表中的各分片是否相连 (ip_done函数中)判断 代码: 参tag: zeq_final_frag