This document contains the functional specifications for the SDK Your Net Corporation (SYNC) IP Reassembler project. This project consists of the development of a basic IP fragment reassembler that can receive IP fragment packets and reassemble them into one whole IP packet.
The system is designed to demonstrate the ability to quickly manipulate packets while operating on a Juniper Networks MultiServices PIC/DPC hardware module. This makes the system suitable for deployment on Juniper Networks MX-, M- and T-Series routers. The system will be implemented using Juniper's Partner Solution Development Platform (PSDP), also called the JUNOS SDK. This system is targeted to operate with version 9.5 of JUNOS and beyond.
The system will be constructed in the phase-1 and phase-2 SDK models of respectively building a daemon and a plug-in for the MS PIC. Because in the phase-2 model of constructing a plug-in IP fragment reassembly happens automatically, the plug-in will simply pass traffic through it. Thus, it also demonstrates an SDK plug-in in its simplest form. It will only log any fragment packets that it sees which should be none. We, therefore, focus herein on the phase-1 SDK daemon that will have to do the reassembly manually.
While examining the functionality of the system, we start by examining the system's user interface, and progress to the operations of the data component.
-Noption will be used when starting the application as a daemon and there is no need for it to "daemonize" itself. This should be used when the process is being launched in the typical way from the init process on the MS PIC.
-voption can be used alone to show version information for the process.
-loption turns on logging to STDERR as well as to syslog.
-d <#>option set the debug level used for internal SDK APIs.
-m <#>option is optional and specifies a number between 576 and 9192. This number represents the largest size of a packet that the system will build out of IP fragments. This number should ideally match the MTU on the target egress network interface. If it is larger, it is possible that the system builds a packet too large to be sent out an egress interface. In that case, the PFE will re-fragment the IP packet that the system constructed in order to send it successfully. If the number is smaller than the target MTU, then packets will simply be smaller than necessary. The default MTU size used is 9192. If this argument is specified it must be the first one.
In order to accomplish defragmentation, however, it sets up some data structures in object-cache shared memory.
We will setup a shared hashtable based a on hash key of the source IP address, the destination IP address, the protocol encapsulated by the IP header, and the fragment group ID. This enables us to lookup a hash value that will be an ordered list of IP fragment packets seen thus far in the same group.
When we receive a fragment, we add it to this ordered list and check to see if the list is complete. If the list is not complete, we simply move on to receive and process another packet. If the list is complete, and we have all fragments in the fragment group, then we rebuild a new IP packet with the same header as the one at the head of the list without the fragment group set. We then check to see if the new packet is under the configured MTU (see section Command-line Options Interface). As long as the packet is less than or equal to the MTU, we send out the newly constructed packet. If the packet exceeds the MTU, we refragment the packet at the MTU boundaries with the same fragment group ID. We then send out these fragments. When fragmenting we copy all IP options for simplicity (this is not strictly required for all kinds IP options).
The system will always use the maximum number of data CPUs available. It is, therefore, certainly possible that the list of packets associated with each hash key is accessed by multiple data CPUs. This will cause increased lock contention. To minimize this we recommend enabling the data-flow-affinity option in the configuration database for the MS PIC on which the application is run.