Setting Object User Flags

The YANG compiler built into the netconfd-pro server has some yp-system level callback APIs that allow YANG data structures to be customized to assist SIL automation or improve processing performance.

  • The obj_template_t structure contains a 'uflags' field that is not used by the server. It is intended for SIL callbacks to use by using the 'OBJ_USER_FLAGS' macro.

  • The SIL code does not need to use the callback APIs described in this section to set the user flags, but a common use for these flags is to check for YANG metadata in YANG data nodes and set user flags based on this information.

  • This feature allows the object template for YANG data nodes to be examined, and the user flags to be set as needed.

  • The server uses binary flags to represent information parsed from YANG metadata. This is more efficient than searching the 'appinfoQ' data structures each time the data is needed.

  • There is a special field in the obj_template_t structure to allow vendor-specific flag definitions for an object template. This field is 32 bits wide and initialized to zero when the object template is created.

There is an API that is called when the object is parsed.

Field definition: uint32 uflags;

Access Macro: OBJ_USER_FLAGS(obj)

Object Callback to Set User Flags

This API is called for all objects during YANG module parsing. The callback may wish to use filters such as 'obj_is_data_db(obj)' to limit scanning to only database objects.

typedef void (*ncx_yang_obj_cbfn_t)(ncx_module_t *mod, struct obj_template_t_ *obj)

user function callback template when a YANG object is parsed by yang_obj.c.

This API is invoked at the end of the resolve phase if the status is NO_ERR It is skipped if the object has errors detected at the time

ncx_yang_obj_cbfn_t

Run an instrumentation-defined function for a 'object parsed' event

Param mod:

module that is being parsed now

Param obj:

object being parsed

The registration function needs to be called from the yp-system initialization callbacks. This callback should be installed before any SIL-related YANG modules are loaded.

The registration functions are defined in ncx/ncx.h

status_t ncx_set_yang_obj_callback(ncx_yang_obj_cbfn_t cbfn)

Set the callback function for a YANG object parse event.

Parameters:

cbfn -- callback function to set

Returns:

status

void ncx_clear_yang_obj_callback(ncx_yang_obj_cbfn_t cbfn)

Clear the callback function for a parse-object event.

Parameters:

cbfn -- callback function to find and clear

YANG Object Template Callback Usage Example

This example callback function checks for a proprietary YANG extension within a YANG object.

/***********  Example YANG Object Template Callback **********/

/*
 * Assume YANG module foo exists with extension acme1
 *
 * module foo {
 *   prefix f;
 *   ...
 *   extension acme1 { ... }
 *
 * The extension is used inside object definitions. E.g:
 *
 *    leaf X {
 *      f:acme1;
 *      type string;
 *    }
 *
 * Assume there is a vendor bit defined for the user flags field
 */

#define FL_ACME_1  0x1

Example Callback Function:

/* user function callback template when a YANG object is
 * parsed by yang_obj.c. This API is invoked at the
 * end of the resolve phase if the status is NO_ERR
 * It is skipped if the object has errors detected at the time
 *
 * ncx_yang_obj_cbfn_t
 *
 *  Run an instrumentation-defined function
 *  for a 'object parsed' event
 *
 * INPUTS:
 *   mod == module that is being parsed now
 *   obj == object being parsed
 */
void
    example_obj_template_cbfn (ncx_module_t *mod,
                               struct obj_template_t_ *obj)
{
    /* optional: use the module to check certain module names to
     * pre-filter the callback
     */
    (void)mod;

    /* get the appinfoQ for the object */
    dlq_hdr_t *appinfoQ = obj_get_appinfoQ(obj);
    if (appinfoQ == NULL) {
        return;   // error!
    }

    /* check the object template appinfoQ to see if the vendor
     * extensions are present
     */
    ncx_appinfo_t *appinfo =
        ncx_find_appinfo(appinfoQ,
                         (const xmlChar *)"f",
                         (const xmlChar *)"acme1");
    if (appinfo) {
        OBJ_USER_FLAGS(obj) |= FL_ACME_1;
    }

}