IP之Fragmentation

4.2.3 Fragmentation and Reassembly

IPMTU65536bytes;而EthernetMTU1518bytes,所以需要分片,而router可能会对packet再次分片。

注意:分片的payload部分一定是8bytes的倍数。

属于同一个packet的所有分片的identifier field(位于IP header)的值相同,在flags field中的more fragments bit(位于IP header)设置为0表示是最后一个分片。fragmentation offset field(位于IP header)表示了该分片在IP packet中的位置,以8bytes为单位。要组装分片就是要用到以上3中信息。

 

分片的实现

TCPlayer调用ip_queue_ximit()packet发送到IP layerrouting完成之后,会调用ip_queue_xmit2(),它检查packet的长度是否超过了link layer MTU,如果超过了,就调用ip_fragment(),它负责分片,分片时需要让每个分片的payload部分是8bytes的倍数。这些函数位于src/net/ipv4/ip_output.c。

 

组包的实现

 IP之Fragmentation_第1张图片

 

大部分的函数位于src/net/ipv4/ip_fragment.c,当数据包来自于link layer时,ip_rcv()被调用,它调用ip_route_input()来做routingrouting后发现该packet需要提交给TCPlayerip_local_deliver()被调用,如果more bitfragmentation offset不为0,则ip_defrag()被调用。

每个packet的分片被存放在一个叫做ipq_hashhash table中,该ipq_hash是一个iqp structure

的数组,而hash用的hash function叫做ipqhashfn()ipqhashfn()的参数:identifier, source IP address, destination IP address和上层协议的服务类型。ip_defrag()先调用ip_find()ip_find()调用ipqhashfn()来定位ipq structure,如果定位失败,ipq_frag_create() 会产生一个新的ipq queueipq_frag_intern()会将该queue插入到hash table中。ip_defrag() 调用 ip_frag_queue() 来将分片放到queue中。如果所有的分片都已收到,则ip_frag_reasm()被调用,用来组装数据包。


[此为原创,转载请标明出处,谢谢!]


你可能感兴趣的:(Linux)