Packet Processing Details

jnx_gw_data_process_packet() handles packets in an infinite loop, which looks like this:

while (1) {
  Check application state and exit if shut down.
  Issue a dequeue request from the RX-FIFO queue.
  Get the VRF associated with the packet.
  Perform initial IP layer processing, dropping the packet on error.
  switch {
     GRE packet: call \c jnx_gw_data_process_gre_packet()
     IP-IP packet: call \c jnx_gw_data_process_ipip_packet()
     default: Increment the VRF Error Stats and drop the packet.

jbuf Structure

MP-SDK packets are defined using the jbuf data structure. An MP-SDK packet is a chain of one or more jbufs in a singly-linked list. Applications should use this structure to manipulate packets, as the sample application shows in some of the code later in this topic. The jbuf APIs are declared in the file sandbox/src/junos/lib/libmp-sdk/h/jnx/jbuf.h.

For more about using jbufs, see also the programming task Using the Services SDK jbuf Library for Packet Processing.

The Packet Context

The jnx_gw_pkt_proc_ctxt_t structure, in file jnx-gateway-data/jnx-gateway-data_packet.h, defines the packet processing context for each data thread. It contains most of the variables required by a packet processing thread and is defined as follows:

typedef struct jnx_gw_pkt_proc_ctxt_s{
    struct jnx_gw_data_cb_s*         app_cb;         /* Pointer to the Control Block */
    msp_data_handle_t                dhandle;        /* Data thread handler */
    struct jbuf                     *pkt_buf;        /* Pointer to the packet
                                                          received */
    u_int32_t                        ing_vrf;        /* Ingress VRF of the
                                                           packet */
    u_int32_t                        eg_vrf;         /* Egress VRF of the 
                                                           packet */
    jnx_gw_data_gre_tunnel_t*        gre_tunnel;     /* Pointer to the Gre 
                                                           Tunnel */
    jnx_gw_data_ipip_sub_tunnel_t*  ipip_sub_tunnel; /* Pointer to the 
                                                           IPIP sub tunnel */
    struct ip*                       ip_hdr;         /* Pointer to the IP
                                                        header in the packet */
    jnx_gw_data_vrf_stat_t*          ing_vrf_entry;  /* Pointer to the ingress
                                                          vrf entry */
    jnx_gw_data_vrf_stat_t*          eg_vrf_entry;   /* Pointer to the egress
                                                          vrf entry */
    jnx_gw_gre_key_hash_t            gre_key_info;   /* GRE Tunnel Key */
    jnx_gw_data_ipip_sub_tunnel_key_hash_t  ipip_sub_key_info;  
                                                     /* IP-IP Sub Tunnel Key */
    jnx_gw_gre_encap_header_t*       ip_gre_hdr;     /* Pointer to the Outer
                                                         IP&GRE Header */
    jnx_gw_ipip_encap_header_t*      ipip_hdr;      /* Pointer to the
                                                         Outer IP-IP header */
    jnx_gw_stat_type_t               stat_type;     /* Pointer to the stat
                                                      type to be incremented */
} jnx_gw_pkt_proc_ctxt_t;

This structure is used by subsequent code as described in the following sections.

Dequeuing the Packet

The msp_data_recv() function, which is declared in the file src/junos/lib/libmp-sdk/h/jnx/mpsdk.h, dequeues the packet. pkt_ctxt stores the packet context:

        if ((pkt_ctxt->pkt_buf = msp_data_recv(pkt_ctxt->dhandle, &pkt_type))
            == NULL) {

Validating the Packet

Packet validation occurs in the functions jnx_gw_data_process_gre_packet() and jnx_gw_data_process_ipip_packet(). For the GRE packet, the code checks the key, the sequence number, protocol type, and version, and drops the packet if any of these do not match. If the GRE header contains a checksum, this code computes the GRE checksum and verifies that it matches what was sent in the header. If the checksum is invalid, the error code JNX_GW_DATA_ERR_GRE_CHECKSUM is indicated, and the packet is dropped.

For the IP-IP packet, the code drops the packet if there is no IP sub-tunnel or if the tunnel state is not ready.

Detunneling the Packet

jnx_gw_data_process_gre_packet() performs computations to facilitate removing the outer IP header and GRE header from the packet. It calculates the number of bytes to remove and stores the value in the decap-len variable, and then calls the SDK function jbuf_adj() to return the adjusted packet.

jbuf_adj() takes a pointer to an existing jbuf and returns a pointer to a new jbuf that is adjusted by the number of bytes supplied in req_len. This effectively detunnels the packet. The call looks like this, and returns a pointer to the adjusted buffer in pkt_buf:


Encapsulating and Sending the Packet

2007-2009 Juniper Networks, Inc. All rights reserved. The information contained herein is confidential information of Juniper Networks, Inc., and may not be used, disclosed, distributed, modified, or copied without the prior written consent of Juniper Networks, Inc. in an express license. This information is subject to change by Juniper Networks, Inc. Juniper Networks, the Juniper Networks logo, and JUNOS are registered trademarks of Juniper Networks, Inc. in the United States and other countries. All other trademarks, service marks, registered trademarks, or registered service marks are the property of their respective owners.
Generated on Sun May 30 20:26:47 2010 for Juniper Networks Partner Solution Development Platform JUNOS SDK 10.2R1 by Doxygen 1.4.5