Retrieving the Service Set Information on the PIC

The data daemon running on the PIC uses functions in the jbuf library to extract the service set information and populate a policy database.

(For more information about using jbufs in general, see Using the Services SDK jbuf Library for Packet Processing.)

The jbuf_svc_set_info_t structure stores all relevant information from the jbuf for service set processing.

jbuf_svc_set_info_t is defined as follows:

#define JBUF_SVC_TYPE_INTERFACE     0
#define JBUF_SVC_TYPE_NEXTHOP       1   

typedef struct jbuf_svc_set_info_s {
  u_int8_t    svc_id;							/* Classifies the packet based on the
  																		service filter applied on the packet */
  u_int8_t    mon_svc;						/* Indicates whether the packet is applied 
 																			with a monitoring service filter.  */
  u_int8_t    svc_type;						/* Interface or nexthop service type */
  u_int8_t    pkt_dir;						/* Direction of the packet */
  ifl_idx_t   rcv_if;							/* Interface index of the media ifl */
  union {
     struct {
        u_int16_t svc_set_id 			/* Service Set Id */  
      } intf_type;
     struct {
        u_int16_t   rcv_subunit;	/* Subunit of the MultiSservices PIC  */    
        u_int16_t   rcv_vrf;			/* VRF associated with the packet */    
      } nexthop_type; 
   ) info   

} jbuf_svc_set_info_t;

An application calls the jbuf_get_svc_set_info() function, passing a pointer to the received jbuf and to the jbuf_svc_set_info_t structure. The function is defined as follows:

int jbuf_get_svc_set_info (struct jbuf* jb, jbuf_svc_set_info_t* svc_set_info);

The sample application function jnx_flow_data_process_packet() calls jbuf_get_svc_set_info() in the packet loop and extracts the service set information. The following structures are background for understanding the function call.

The packet context is defined in the structure jnx_flow_data_pkt_ctxt_t, in file jnx-flow-data.h:

typedef struct jnx_flow_data_pkt_ctxt {
    uint32_t                      thread_idx;     /* thread cpu num */
    msp_data_handle_t             thread_handle;  /* thread handle */
    jnx_flow_data_cb_t           *data_cb;        /* data control block */
                                                  
    struct jbuf                  *pkt_buf;        /* packet buffer */
    struct ip                    *ip_hdr;         /* ip header */
    struct tcphdr                *tcp_hdr;        /* tcp header */
                                                  
    uint32_t                      pkt_len;        /* packet length */
    uint64_t                      pkt_ts;         /* packet timestamp */
                                                  
    jnx_flow_svc_key_t            svc_key;        /* service key */
    jnx_flow_session_key_t        flow_key;       /* flow key */
                                                  
    jnx_flow_data_flow_entry_t   *flow_entry;     /* flow entry */
    jnx_flow_data_rule_entry_t   *rule_entry;     /* rule entry */
    jnx_flow_svc_type_t           flow_type;      /* flow type */
    jnx_flow_rule_dir_type_t      flow_direction; /* flow direction */
    jnx_flow_rule_action_type_t   flow_action;    /* flow action */
    uint32_t                      rule_count;     /* rule count */
    uint32_t                      flow_hash;      /* flow hash */

} jnx_flow_data_pkt_ctxt_t;

The packet context structure includes structures that fully describe the rules and service set:

/*
 * rule entry information structure 
 */
typedef struct jnx_flow_data_rule_entry {
    patnode                     rule_node;      /* rule patricia node */
    char                        rule_name[JNX_FLOW_STR_SIZE]; /* rule name */
    uint32_t                    rule_id;        /* rule index, key*/
    uint32_t                    rule_flags;     /* rule flags, if any */
    jnx_flow_data_status_t      rule_status;    /* rule status*/
    jnx_flow_rule_action_type_t rule_action;    /* rule action type*/
    jnx_flow_rule_match_type_t  rule_match;     /* rule match type*/
    jnx_flow_rule_dir_type_t    rule_direction; /* rule direction */
    jnx_flow_rule_match_t       rule_session;   /* rule match info*/
    jnx_flow_rule_stats_t       rule_stats;     /* rule statistics*/
} jnx_flow_data_rule_entry_t;

/*
 * service-set entry information structure 
 */
typedef struct jnx_flow_data_svc_set {
    patnode                  svc_node;      /* service patnode */
    patnode                  svc_id_node;   /* service patnode */
    jnx_flow_svc_key_t       svc_key;       /* service key */
    jnx_flow_data_status_t   svc_status;    /* service status */
    jnx_flow_svc_type_t      svc_type;      /* service flags */
    uint32_t                 svc_id;        /* service index */
    char                     svc_name[JNX_FLOW_STR_SIZE]; /* service name */
    char                     svc_intf[JNX_FLOW_STR_SIZE]; /* interface name */
                                           
    uint32_t                 svc_iif;       /* service ingress subunit */
    uint32_t                 svc_oif;       /* service egress subunit */
                                     
    uint32_t                   svc_rule_count;/* service rule count*/
    jnx_flow_data_list_head_t  svc_rule_set;  /* service rule set */
    jnx_flow_svc_stats_t       svc_stats;     /* service statistics */
} jnx_flow_data_svc_set_t;

The following code is a small portion of the packet loop code that shows the function call as well as how the code branches according to the service set type. For the complete code, see the file jnx-flow-data_packet.c

...
        /*
         * dequeue packets from the FIFO queue for the packet processing thread
         */
        if ((pkt_ctxt->pkt_buf = msp_data_recv(pkt_ctxt->thread_handle,
                                               &pkt_type))
            == NULL) {
            continue;
        }

        jbuf_get_svc_set_info(pkt_ctxt->pkt_buf, &svc_set_info);

        /*
         * get the service type from the packet buffer
         */

        if (svc_set_info.svc_type == JBUF_SVC_TYPE_INTERFACE) {
            pkt_ctxt->svc_key.svc_type = pkt_ctxt->flow_key.svc_key.svc_type = 
                JNX_FLOW_SVC_TYPE_INTERFACE;
        } else {
            pkt_ctxt->svc_key.svc_type = pkt_ctxt->flow_key.svc_key.svc_type = 
                JNX_FLOW_SVC_TYPE_NEXTHOP;
        }

        /*
         * Get the service application direction
         */
        pkt_ctxt->flow_direction = svc_set_info.pkt_dir;

        /*
         * if the packet service type is nexthop-style,
         * extract the ingress interface from the packet buffer; 
         * otherwise, extract the service ID from the packet buffer
         */
        if (pkt_ctxt->svc_key.svc_type == JNX_FLOW_SVC_TYPE_NEXTHOP) {

            pkt_ctxt->svc_key.svc_iif =
                pkt_ctxt->flow_key.svc_key.svc_iif = 
                svc_set_info.info.nexthop_type.rcv_subunit;

        } else {

            pkt_ctxt->svc_key.svc_id =
                pkt_ctxt->flow_key.svc_key.svc_id = 
                svc_set_info.info.intf_type.svc_set_id;
        }


...

Using the Database on the PIC


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