Friday, October 16, 2009

10.5 Reassembly

Team-Fly
 

 

TCP/IP Illustrated, Volume 2: The Implementation
By
Gary R. Wright, W. Richard Stevens
Table of Contents
Chapter 10. 
IP Fragmentation and Reassembly


10.5 Reassembly


Now that we have described the fragmentation of a datagram (or of a fragment), we return to ipintr and the reassembly process. In Figure 8.15 we omitted the reassembly code from ipintr and postponed its discussion. ipintr can pass only entire datagrams up to the transport layer for processing. Fragments that are received by ipintr are passed to ip_reass, which attempts to reassemble fragments into complete datagrams. The code from ipintr is shown in Figure 10.11.



Figure 10.11. ipintr function: fragment processing.




271-279

Recall that ip_off contains the DF bit, the MF bit, and the fragment offset. The DF bit is masked out and if either the MF bit or fragment offset is nonzero, the packet is a fragment that must be reassembled. If both are zero, the packet is a complete datagram, the reassembly code is skipped and the else clause at the end of Figure 10.11 is executed, which excludes the header length from the total datagram length.


280-286

m_pullup moves data in an external cluster into the data area of the mbuf. Recall that the SLIP interface (Section 5.3) may return an entire IP packet in an external cluster if it does not fit in a single mbuf. Also m_devget can return the entire packet in a cluster (Section 2.6). Before the dtom macro will work (Section 2.6), m_pullup must move the IP header from the cluster into the data area of an mbuf.


287-297

Net/3 keeps incomplete datagrams on the global doubly linked list, ipq. The name is somewhat confusing since the data structure isn't a queue. That is, insertions and deletions can occur anywhere in the list, not just at the ends. We'll use the term list to emphasize this fact.


ipintr performs a linear search of the list to locate the appropriate datagram for the current fragment. Remember that fragments are uniquely identified by the 4-tuple: {ip_id, ip_src, ip_dst, ip_p}. Each entry in ipq is a list of fragments and fp points to the appropriate list if ipintr finds a match.



Net/3 uses linear searches to access many of its data structures. While simple, this method can become a bottleneck in hosts supporting large numbers of network connections.



298-303

At found, the packet is modified by ipintr to facilitate reassembly:


  • 304

    ipintr changes ip_len to exclude the standard IP header and any options.We must keep this in mind to avoid confusion with the standard interpretation of ip_len, which includes the standard header, options, and data. ip_len is also changed if the reassembly code is skipped because this is not a fragment.

  • 305-307

    ipintr copies the MF flag into the low-order bit of ipf_mff, which overlays ip_tos (&= ~1 clears the low-order bit only). Notice that ip must be cast to a pointer to an ipasfrag structure before ipf_mff is a valid member. Section 10.6 and Figure 10.14 describe the ipasfrag structure.

    Although RFC 1122 requires the IP layer to provide a mechanism that enables the transport layer to set ip_tos for every outgoing datagram, it only recommends that the IP layer pass ip_tos values to the transport layer at the destination host. Since the low-order bit of the TOS field must always be 0, it is available to hold the MF bit while ip_off (where the MF bit is normally found) is used by the reassembly algorithm.

    ip_off can now be accessed as a 16-bit offset instead of 3 flag bits and a 13-bit offset.

  • 308

    ip_off is multiplied by 8 to convert from 8-byte to 1-byte units.


ipf_mff and ip_off determine if ipintr should attempt reassembly. Figure 10.12 describes the different cases and the corresponding actions. Remember that fp points to the list of fragments the system has previously received for the datagram. Most of the work is done by ip_reass.



Figure 10.12. IP fragment processing in ipintr and ip_reass.


309-322

If ip_reass is able to assemble a complete datagram by combining the current fragment with previously received fragments, it returns a pointer to the reassembled datagram. If reassembly is not possible, ip_reass saves the fragment and ipintr jumps to next to process the next packet (Figure 8.12).


323-324

This else branch is taken when a complete datagram arrives and ip_hlen is modified as described earlier. This is the normal flow, since most received datagrams are not fragments.


If a complete datagram is available after reassembly processing, it is passed up to the appropriate transport protocol by ipintr (Figure 8.15):



(*inetsw[ip_protox[ip->ip_p]].pr_input) (m, hlen);



    Team-Fly
     

     
    Top
     


    No comments:

    Post a Comment