Using GENCFG on the Multiservices PIC

When an application is sending data to the Multiservices PIC, its management component on the Routing Engine must supply values for the peer_info array, and the fields peer_count and dest in the junos_kcom_gencfg_t structure before calling the junos_kcom_gencfg() function.

When you are adding data to the kernel, the value in the peer_count field indicates whether this is a broadcast, unicast, or multicast blob (0 indicates a broadcast blob; 1 indicates a unicast blob; greater than 1 indicates a multicast blob). The peer_count field is relevant only when the dest field is set to JUNOS_KCOM_MPSDK_CFG_DEST_RE_AND_PFE. The recipients are specified in the peer_info array. When you are retrieving data, the system supplies this information to your application.

The application component running on the PIC calls a similar, but not identical, set of GENCFG/SSRB APIs to retrieve data from the kernel. (For details about how the reliable configuration download functionality works to send the system configuration to the PIC, see Reliable Configuration Download.)

The function junos_kcom_mpsdk_cfg_req() is used to request all possible operations involving blobs from the PIC. It takes as a parameter the structure junos_kcom_mpsdk_cfg_req_t with fields for an opcode, the names of asynchronous handlers to receive data notifications and (if needed) retrieve all existing blobs, and an application-specified ID.

The opcode field is one of the following: JUNOS_KCOM_MPSDK_CFG_REG, to register the data handler, JUNOS_KCOM_MPSDK_CFG_DEREG to deregister the handler, or JUNOS_KCOM_MPSDK_CFG_GET_ALL, to retrieve all the blobs for a particular application. You can specify a handler to get all blobs when the application could start later than mspmand and there are already blobs in the kernel. The application should first retrieve all the existing blobs by setting opcode to JUNOS_KCOM_MPSDK_CFG_GET_ALL, and then asynchronously be notified about any new ones.

Once your application has read the configuration, you must free the memory by calling the macro JUNOS_KCOM_MPSDK_CFG_FREE. For example, the following code from the sample equilibrium2_balance plugin (in file equilibrium2-balance_ctrl.c) reads the blob and then frees the memory:

static void
read_gencfg_blob (junos_kcom_gencfg_t *kcom_gencfg)
{
    config_blob_key_t *key;

    key = kcom_gencfg->key.data_p;
    msp_log(LOG_INFO, "%s: %s, tag: %d, key len %d, blob len %d",
            __func__, key->key_name, key->key_tag, kcom_gencfg->key.size,
            kcom_gencfg->blob.size);

    switch (key->key_tag) {
    case CONFIG_BLOB_SVC_SET:
        proc_svc_set_blob(kcom_gencfg->blob.data_p, kcom_gencfg->opcode);
        break;
    case CONFIG_BLOB_SVR_GROUP:
        proc_svr_group_blob(kcom_gencfg->blob.data_p, kcom_gencfg->opcode);
        break;
    default:
        msp_log(LOG_INFO, "%s: Ignore blob.", __func__);
    }
    JUNOS_KCOM_MPSDK_CFG_FREE(kcom_gencfg);
}

(For additional documentation on this example, see The Sync Equilibrium Application Using Plugins.)

The same application ID (app_id, a 16-bit unsigned integer) is used for your application's components on both the Routing Engine and the Multiservices PIC. On the Routing Engine, you use the cfg_index field in the junos_kcom_gencfg_t structure to specify the ID. (The app_id is unrelated to the provider id.) If there is more than one application from the same provider, each new application should specify a unique app_id. Based on the app_id, mspmand demultiplexes the configuration blobs and sends them to the appropriate application on the PIC.

Sample Code with a Multiservices PIC Component

The following code snippets show an application with components running on the Routing Engine and the PIC.

Management component on the Routing Engine:

       junos_kcom_gencfg_t jk_gencfg;
       junos_kcom_gencfg_peer_info_t peer_info;
       uint32_t user_key = 0xc01dfacf;
       char user_blob[GENCFG_USER_BLOB_SIZE] = "This is test blob to PIC application/daemon.";

       /*
      	* Initializing the blob.
	    */
       bzero(&jk_gencfg, sizeof(junos_kcom_gencfg_t));
       jk_gencfg.opcode = JUNOS_KCOM_GENCFG_OPCODE_INIT;
       jk_gencfg.user_info_p = NULL;
       jk_gencfg.user_handler = test_gencfg_async;
       jk_gencfg.cfg_index = GENCFG_APP_ID;
    
       error = junos_kcom_gencfg(&jk_gencfg);
    
        /*
         * Adding a blob.
         */
        bzero(&jk_gencfg, sizeof(junos_kcom_gencfg_t));

        jk_gencfg.opcode = JUNOS_KCOM_GENCFG_OPCODE_BLOB_ADD;
        jk_gencfg.key.size = sizeof(uint32_t);
        jk_gencfg.key.data_p = (void *)&user_key;
        jk_gencfg.blob.size = sizeof(user_blob);
        jk_gencfg.cfg_index = GENCFG_APP_ID;
        jk_gencfg.dest = JUNOS_KCOM_GENCFG_DEST_RE_AND_PFE;
	      peer_info.peer_id.peer_name = peer_name;
        jk_gencfg.peer_info = &peer_info;
        jk_gencfg.peer_count = 1;
        jk_gencfg.blob.data_p = (void *) user_blob;
   
        error = junos_kcom_gencfg(&jk_gencfg);

Data component on the PIC:

       junos_kcom_gencfg_t jk_gencfg;
       junos_kcom_mpsdk_cfg_req_t mpsdk_req;
    
       /*
        * Some required initializations.
        */
       bzero(&jk_gencfg, sizeof(junos_kcom_gencfg_t));
       jk_gencfg.opcode        = JUNOS_KCOM_GENCFG_OPCODE_INIT;
       jk_gencfg.user_handler  = test_gencfg_async;
       jk_gencfg.cfg_index     = GENCFG_APP_ID;
   
       error = junos_kcom_gencfg((junos_kcom_gencfg_t *)&jk_gencfg);
   
       /*
        * Register for the blobs that have been sent to the PIC.
        */
       mpsdk_req.opcode           = JUNOS_KCOM_MPSDK_CFG_REG;
       mpsdk_req.msg_user_handler = mpsdk_cfg_async_handler;
       mpsdk_req.app_id           = GENCFG_APP_ID;
    
	    error = junos_kcom_mpsdk_cfg_req(&mpsdk_req);
  
      /*
       * Get all the local blobs if possible.
       */
      mpsdk_req.opcode               = JUNOS_KCOM_MPSDK_CFG_GET_ALL;
      mpsdk_req.get_all_user_handler = mpsdk_cfg_get_all_handler;
      mpsdk_req.app_id               = GENCFG_APP_ID;
    
      error = junos_kcom_mpsdk_cfg_req(&mpsdk_req);


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