../_images/logo.png

YumaPro YANG Automation Guide

YANG Automation Uses

The YANG language includes many ways to specify conditions for database validity, which traditionally are only documented in description statements and external developer documentation.

Even with all the machine-readable properties defined in YANG (see the the YANG-based Automation section), there are many standard and non-standard extensions to YANG, to increase the ability to automate tool behavior related to YANG data models.

YANG supports external statements, which allows anybody to add new statements to the standard syntax, in a way that allows all tools to either use the extension or skip over the extension. A YANG 1.1 compliant tool MAY ignore any external statement, but it MUST be able to at least parse it and ignore it.

Extension statements are used two ways in YANG:

  1. Metadata associated with other YANG statements

  2. Abstract data structure definitions

YANG Extensions as Metadata

The main mechanism available in YANG for tool automation is the extension statement, when used to define metadata that is associated with the parent statement. This is usually a data definition statement, but it could be any YANG statement.

Servers and clients and other tools can code to the metadata instead of hard-wired to specific YANG identifiers. All objects using the same metadata get the same treatment.

  1. Define the YANG extension (or use an existing one)

    extension my-extension {
      description
        " - Define the purpose of the extension
          - Define an argument if needed
          - Define which parent statements are allowed
          - Provide an example of the statement usage
        ";
    }
    
  2. Use the extension as an external statement in other YANG statements

    container data1 {
      ex:my-extension;
      leaf leaf1 { type string; }
      // ...
    }
    
  3. Parse and save the extension statements as metadata in the server

  4. Use the metadata to control various server and protocol behavior

YANG Extensions as Abstract Data

YANG is very useful for defining data structures that can be used within client and server implementations. They are also used to define file and artifact representations of YANG data.

Unfortunately, plain YANG data definition statements (e.g., container, list) cannot be used because these statements define YANG and NMDA datastore contents. Only data structures for datastore contents can use these statements as top-level statements in YANG.

Note

Abstract data structure names cannot conflict with any other structure or plain YANG data definition statement.

  1. Use the sx:structure extension as an external top level statement in a YANG module:

    sx:structure mydata1 {
      leaf leaf1 { type string; }
    }
    
  1. The server will automatically process the 'structure' extension and save a top-level object named 'mydata1'

  2. Use the object access APIs to retrieve the obj_template_t for the data structure so it can be used within the program (e.g., parse input or generate output).

SIL Code Access to Metadata

The netconfd-pro server saves all the external language statements it finds, even those it does not recognize. These are stored in the 'ncx_appinfo_t' data structure in ncx/ncxtypes.h.

This data structure is not accessed directly. There are SIL access functions defined in ncx/ncx_appinfo.h (described in the following sections) that allow these language statements to be accessed.

  • The YANG prefix and extension name are saved

  • The YANG prefix must be used in the 'find' APIs (not the module name)

  • If an argument string was provided, it is saved along with the command name.

  • If extensions are nested then they will be saved as well.

  • Each appinfo contains a child queue of appinfo to store nested statements

Server Data Structures with Metadata

Several data structures contains an 'appinfoQ' field to contain all the ncx_appinfo_t structures that were generated within the same YANG syntax block (E.g., within a typedef, type, leaf, import statement).

Data Structure

Struct Name

Parent Statement

YANG Module

ncx_module_t

module-stmt or submodule-stmt

Extension

ext_template_t

extension-stmt

Grouping

grp_template_t

grouping-stmt

Feature

ncx_feature_t

feature-stmt

Identity

ncx_identity_t

identity-stmt

Import

ncx_import_t

import-stmt

Include

ncx_include_t

include-stmt

Object

obj_template_t

data-def-stmt

Deviate

obj_deviate_t

deviate-stmt

Deviation

obj_deviation_t

deviation-stmt

Enumeration

typ_enum_t

enum-stmt

Type

typ_def_t

type-stmt

Typedef

typ_template_t

typedef-stmt

Server APIs to Access Metadata

The SIL code should already know which YANG statements to check for specific external statements. The allowed parent YANG statements should be defined in the extension statement.

There are 3 steps the SIL code must follow to access the metadata:

  1. Retrieve the data structure containing the metadata (e.g. obj_template_t). This step is out of scope here. Refer to the YANG Objects section for API functions to access the obj_template_t data structure.

  2. Retrieve the 'appinfoQ' for the data structure

  3. Use ncx_appinfo_t API functions to traverse all metadata or find specific external statements

The following table highlights the SIL functions in ncx/ncx_appinfo.h that allow SIL code to examine any of the non-standard language statements that were found in the YANG module:

API Function

Description

ncx_find_appinfo

Find an ncx_appinfo_t structure by its prefix and name

ncx_find_const_appinfo

Find a const ncx_appinfo_t structure by its prefix and name

ncx_find_next_appinfo

Find the next const ncx_appinfo_t

ncx_find_next_appinfo2

Find the next ncx_appinfo_t

ncx_find_appinfo

ncx_appinfo_t *ncx_find_appinfo(dlq_hdr_t *appinfoQ, const xmlChar *prefix, const xmlChar *varname)

Find an appinfo entry by name (First match is returned) The entry returned is not removed from the Q.

This original code design is very fragile because it relies on the YANG prefix being unique within the server.

This is a customer API to support custom object flags All extensions are stored in the object appinfoQ dusring parsing

Parameters
  • appinfoQ -- pointer to Q of ncx_appinfo_t data structure to check

  • prefix --

    module prefix that defines the extension

    NULL to pick the first match (not expecting appinfo name collisions)

  • varname -- name string of the appinfo variable to find

Returns

pointer to the ncx_appinfo_t struct for the entry if found NULL if the entry is not found

Example showing non-const appinfo usage:

dlq_hdr_t *appinfoQ = obj_get_datadefQ(obj);
ncx_appinfo_t *appinfo =
    ncx_find_appinfo(appinfoQ,
                     (const xmlChar *)"acme",
                     (const xmlChar *)"my-extension");
if (appinfo) {
    if (appinfo->value) {
        // this string contains the extension parameter value
    }
}

ncx_find_const_appinfo

const ncx_appinfo_t *ncx_find_const_appinfo(const dlq_hdr_t *appinfoQ, const xmlChar *prefix, const xmlChar *varname)

Find an appinfo entry by name (First match is returned) The entry returned is not removed from the Q (CONST version)

Parameters
  • appinfoQ -- pointer to Q of ncx_appinfo_t data structure to check

  • prefix --

    module prefix that defines the extension

    NULL to pick the first match (not expecting appinfo name collisions)

  • varname -- name string of the appinfo variable to find

Returns

pointer to the ncx_appinfo_t

struct for the entry if found

NULL if the entry is not found

Example showing const appinfo usage:

dlq_hdr_t *appinfoQ = obj_get_datadefQ(obj);
const ncx_appinfo_t *appinfo =
    ncx_find_const_appinfo(appinfoQ,
                           (const xmlChar *)"acme",
                           (const xmlChar *)"my-extension");
if (appinfo) {
    if (appinfo->value) {
        // this string contains the extension parameter value
    }
}

mcx_find_next_appinfo

const ncx_appinfo_t *ncx_find_next_appinfo(const ncx_appinfo_t *current, const xmlChar *prefix, const xmlChar *varname)

Find the next instance of an appinfo entry by name (First match is returned) The entry returned is not removed from the Q.

Parameters
  • current -- pointer to current ncx_appinfo_t data structure to check

  • prefix --

    module prefix that defines the extension

    NULL to pick the first match (not expecting appinfo name collisions)

  • varname -- name string of the appinfo variable to find

Returns

pointer to the ncx_appinfo_t

struct for the entry if found

NULL if the entry is not found

This API function is used after the 'ncx_find_const_appinfo' API function to find an extension used multiple times within the same parent statement.

Example showing const appinfo usage:

// using appinfo from ncx_find_const_appinfo
while (appinfo) {
    if (appinfo->value) {
        // this string contains the extension parameter value
    }

    appinfo = ncx_find_next_appinfo(appinfo,
                                    (const xmlChar *)"acme",
                                    (const xmlChar *)"my-extension");
}

ncx_find_next_appinfo2

ncx_appinfo_t *ncx_find_next_appinfo2(ncx_appinfo_t *current, const xmlChar *prefix, const xmlChar *varname)

Find the next instance of an appinfo entry by name (First match is returned, not const version) The entry returned is not removed from the Q.

Parameters
  • current -- pointer to current ncx_appinfo_t data structure to check

  • prefix --

    module prefix that defines the extension

    NULL to pick the first match (not expecting appinfo name collisions)

  • varname -- name string of the appinfo variable to find

Returns

pointer to the ncx_appinfo_t

struct for the entry if found

NULL if the entry is not found

This API function is used after the 'ncx_find_appinfo' API function to find a non-const extension used multiple times within the same parent statement.

Example showing non-const appinfo usage:

// using appinfo from ncx_find_appinfo
while (appinfo) {
    if (appinfo->value) {
        // this string contains the extension parameter value
    }

    appinfo = ncx_find_next_appinfo2(appinfo,
                                     (const xmlChar *)"acme",
                                     (const xmlChar *)"my-extension");
}

Defining Abstract YANG Data

YANG can be used to define abstract data that can be used within server SIL callbacks and system callbacks. This sort of data is commonly used to read/write files containing YANG data or protocol messages defined in YANG.

This functionality replaces the deprecated ncx:abstract extension, because it is based on standards. There are 4 YANG extensions available that can be used to define abstract data structures in YANG modules.

Extension

Source

Module

Description

sx:structure

RFC 8791

ietf-yang-structure-ext.yang

Define a YANG data structure (current)

sx:augment-structure

RFC 8791

ietf-yang-structure-ext.yang

Augment a YANG data structure (current)

rc:yang-data

RFC 8040

ietf-restconf.yang

Define a YANG data structure (deprecated)

yd:augment-yang-data

none

yang-data-ext.yang

Augment a YANG data structure (deprecated)

sx:structure

The YANG Data Structures (RFC 8791) includes this YANG extension definition. It is not the same as the RESTCONF version.

The structure name defines the abstract YANG container.
There is no restriction on the child data nodes.

The following example shows how the abstract container test1 would be created with this extension:

module foo {
   // header
   import ietf-yang-structure-ext { prefix sx; }

   sx:structure test1 {
      leaf leaf1 { type string; }
      leaf leaf2 { type int32; }
   }
}

sx:augment-structure

The YANG Data Structures (RFC 8791) includes this YANG extension definition. It is not the same as the YumaPro version.

The structure name defines the abstract YANG container.
The first node in the augment path is the structure name.

The following example shows how the abstract container test1 would be augmented with this extension:

module bar {
   // header
   import ietf-yang-structure-ext { prefix sx; }
   import foo { prefix f; }

   sx:augment-structure "/f:test1"  {
      leaf leaf3 { type uint32; }
      leaf leaf4 { type boolean; }
   }
}

rc:yang-data

The RESTCONF Protocol (RFC 8040) includes the YANG extension definition for yang-data. It is used within ietf-restconf.yang and ietf-yang-patch.yang. Any module can define YANG data structures;

Restrictions:

  • YANG does not allow multiple top-level nodes with the same name to be defined in the same module.

    Make sure that the top-level nodes defined within the yang-data statement do not conflict with other top-level object names.

  • The data defined within the yang-data statement must be 1 container statement or 1 uses statement where the grouping contains one container.

Note

This extension is deprecated. Use sx:structure instead.

module foo {
   // header
   import ietf-restconf { prefix rc; }

   rc:yang-data test1 {
      container test1 {
        leaf leaf1 { type string; }
        leaf leaf2 { type int32; }
      }
   }
}

yd:augment-yang-data

The yang-data-ext.yang module defines a YANG extension to allow yang-data nodes to be augmented from a different module.

  • This is not supported by the RESTCONF standard, just supported in netconfd-pro.

  • The plain augment statement can be used instead of this extension, but this should be avoided because a standard YANG compiler is not required to support the RESTCONF yang-data extension (so it will not find the augmented node)

Note

This extension is deprecated. Use sx:augment-structure instead.

module bar {
   // header
   import yang-data-ext { prefix yd; }
   import foo { prefix f; }

   yd:augment-yang-data /f:test1 {
      leaf test2 { type string; }
   }
}

Accessing Abstract YANG Data

The netconfd-pro server will automatically parse any abstract data created in any manner described in the previous section. YANG data definitions are represented internally with the obj_template_t data structure.

The server will create this data structure for abstract data, but the data will not be added to the server datastores in any way. No SIL or SIL-SA callbacks for abstract data are supported.

API functions such as 'obj_find_template_top' can be used to retrieve the object template for abstract data. Refer to the Find Top-Level Object section for details on this API function.

Once the object template is available, the API functions to access the child and descendant nodes can be used. Refer to the Find a Specific Child Node section for details on some of these API functions.

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;
    }

}

YANG Extension Handlers

The YANG compiler supports user callbacks to handle specific extension statements. There are two types of callbacks:

Top-level extensions:

  • These extensions have the module statement itself as its parent.

  • These extensions may be wrappers for additional statements, such as the reserved extension “yang-data”.

  • The callback for these extensions is invoked during the module parsing phase (E.g,., 'consume_extension').

  • The callback is responsible for completing the parsing phase and consume all tokens for the external statement, including the final semi-colon or right brace.

Nested extensions:

  • These extensions are contained within nested statements, which are not at the top-level.

  • They are expected to be simple statements and not wrappers for YANG statements.

  • The callback for these extensions is invoked during the module validation phase (E.g., 'resolve_extension').

  • This callback is not responsible for parsing any module token input.

  • All parsing has already been completed.

YANG Extension Handler Callback

The following callback API is defined in ncx/ext.h:

typedef status_t (*ext_cbfn_t)(void *rawpcb, ncx_module_t *mod, tk_chain_t *tkc, struct ext_template_t_ *ext, void *cookie, const xmlChar *arg, ncx_node_t node_type, void *node)

One YANG Extension Handler Callback.

ext_cbfn_t

Handle the parsing and processing of an external statement using the associated YANG extension statement

This callback is invoked when the external statement is first encountered. The current token is the argument string if any or the identifier token if none. The next token is expected to be a semi-colon or a left brace The callback is expected to parse the closing semi-colon or entire sub-section including starting brace

Param rawpcb

parser control block in progress (cast as void *)

Param mod

module being processed

Param tkc

token chain of module tokens parse in progress

Param ext

extension definition record (allows a handler to process multiple extension types)

Param cookie

cbfn_cookie from the extension 'ext'

Param arg

argument string used in the external statement (if any)

Param node_type

type of node being processed; direct parent statement of the external statement using the extension If NULL, then the parent statement is the module itself, and 'mod' should be used as the 'node' pointer

Param node

pointer to node indicated by node_type

Return

status of processing

The registration function is defined in ncx/etc.h. This API should be registered in the yp-system initialization phase, before YANG modules are parsed.

status_t ext_register_cbfn(const xmlChar *modname, const xmlChar *extname, ext_cbfn_t cbfn, void *cbfn_cookie)

Register a callback function for the specified extension If multiple callbacks for same extension, then last one wins.

Parameters
  • modname -- module name defining the extension

  • extname -- extension name

  • cbfn -- pointer to callback function to register

  • cbfn_cookie -- optional cookie to register; will not be freed when the extension is freed Use macro EXT_CBFN_COOKIE(ext) to access from callback; (may be NULL if not used)

Returns

status

Example registration inside yp_system_init1:

#include “ext.h”

status_t yp_system_init1 (boolean pre_cli)
{
    status_t res = NO_ERR;
    log_debug("\nyp_system init1\n");

    if (pre_cli) {
        ;
    } else {

        /* example -- Register a Extension Handler Callback */
        res = ext_register_cbfn((const xmlChar *)"acme-ext",
                                (const xmlChar *)"acme1",
                                example_ext_cbfn,
                                NULL);   // cookie

    }
    return res;

}  /* yp_system_init1 */

YANG Extension Usage Example

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

It uses the same YANG module as the YANG Object Template Callback.

/*
 * Callback is invoked to check a specific extension in an
 * obj_template_t, typ_template_t, typ_def_t
 *
 * Assume the same YANG module foo exists with extension acme1
 *
 * The example callback does the same task as the
 * example_obj_template_cbfn, using the per-callback approach
 */

/* One YANG Extension Handler Callback
 *
 * example_ext_cbfn
 *
 * Handle the parsing and processing of an external statement
 * using the associated YANG extension statement
 *
 * This callback is invoked when the external statement is
 * first encountered. The current token is the argument string
 * if any or the identifier token if none.
 * The next token is expected to be a semi-colon or a left brace
 * The callback is expected to parse the closing semi-colon or
 * entire sub-section including starting brace
 *
 * INPUTS:
 *   rawpcb == parser control block in progress (cast as void *)
 *   mod == module being processed
 *   tkc == token chain of module tokens parse in progress
 *   ext == extension definition record (allows a handler to
 *         process multiple extension types)
 *   cookie == cbfn_cookie from the extension 'ext'
 *   arg == argument string used in the external statement (if any)
 *   node_type == type of node being processed; direct parent
 *         statement of the external statement using the extension
 *         If NULL, then the parent statement is the module itself,
 *         and 'mod' should be used as the 'node' pointer
 *   node == pointer to node indicated by node_type
 * OUTPUTS:
 *
 * RETURNS:
 *   status of processing
 */
static status_t
     example_ext_cbfn (void *rawpcb,  // struct yang_pcb_t_ *pcb
                       ncx_module_t *mod,
                       tk_chain_t *tkc,
                       struct ext_template_t_ *ext,
                       void *cookie,
                       const xmlChar *arg,
                       ncx_node_t node_type,
                       void *node)
{
    (void)rawpcb;
    (void)mod;
    (void)tkc;
    (void)ext;
    (void)cookie;
    (void)arg;

    /* ignore this extension in all contexts except object template */
    if (node_type != NCX_NT_OBJ) {
        return NO_ERR;
    }

    /* get the object template */
    obj_template_t *obj = (obj_template_t *)node;

    /* set the acme1 bit */
    OBJ_USER_FLAGS(obj) |= FL_ACME_1;

    return NO_ERR;
}

Built-in YANG Language Extensions

There are several YANG extensions that are supported by YumaPro. They are all defined in the following YANG files:

These YANG extensions are used to 'tag' YANG definitions for some sort of automatic processing by YumaPro programs. Extensions are position-sensitive, and if not used in the proper context, they will be ignored. A YANG extension statement must be defined (somewhere) for every extension used in a YANG file, or an error will be occur.

Most of these extensions apply to netconfd-pro server behavior, but not all of them. For example, the ncx:hidden extension will prevent yangcli-pro from displaying help for an object containing this extension. Also, yangdump-pro will skip this object in HTML output mode.

The following sections describe the supported YANG language extensions. All other YANG extension statements will be ignored by YumaPro, if encountered in a YANG file.

ncx:abstract

The ncx:abstract extension is used with object definitions to indicate that they do not represent CLI or NETCONF configuration database data instances. Instead, the node is simply an object identifier, an 'error-info' extension, or some other abstract data structure.

Warning

This extension is not compliant with YANG 1.1 It SHOULD NOT be used. Use the sx:structure extension instead.

YANG File: yuma-ncx.yang
Argument: none
Example:
container server-hello {
    description "Generic Server Hello Message Parameters.";

    uses NcCapabilities;

    leaf session-id {
        type session-id-type;
        config false;
    }

    ncx:hidden;
    ncx:abstract;
}

ywx:alt-name

The ywx:alt-name extension is used within a data node definition to specify an alternate name for the node. The --alt-names parameter must be enabled for these names to be used.

Argument:
  • name: alternate YANG identifier name string to use for the object

Example:

leaf system-reset-time {
  ywx:alt-name last-reset;
  type yang:date-and-time;
  config false;
}

ncx:cli

The ncx:cli extension is used within a container definition to indicate it is only used as a conceptual container for a set of CLI parameters. A top-level container containing this extension will not be included in any NETCONF configuration databases.

Only the following types of YANG objects are allowed within the CLI container at this time:

  • leaf

  • leaf-list

  • choice

  • case

  • uses (if resolves to only the allowed node types)

Note

This is an internal extension and should not be used.

YANG File: yuma-ncx.yang
Argument: none
Example:
container yangcli-pro {
   ncx:cli;
   // leafs and choices of leafs inserted here
}

ywx:cli-text-block

The ywx:cli-text-block extension is used to force CLI text syntax within a container. It is only used by yangcli-pro for test-suite 'setup' and 'cleanup' sections at this time.

If this extension is present in an empty container or list, it will be treated in unit-test parsing as a container or list of ordered text commands, 1 per line. Line extension is needed to wrap a command into many lines.

Argument: none
Example:
container setup {
   ywx:cli-text-block;
}

Example test script or conf file usage:

setup {
  run test1-script
  get-config source=running
  lock target=candidate
  some-long-command parms='this is a wrapped \
    line in a text block'
}

ywx:datapath

The ywx:datapath extension is used by the YControl subsystem to specify the real object to use for parsing an “anyxml” or “container” node as a different object type.

It is used within a container or anyxml definition to indicate that the object path for the data node should be sent in the value as an attribute. The YANG parser will use the datapath attribute to select the object template to use for parsing, instead of generic anyxml.

Argument: path string
Example:
anyxml newval {
    ywx:datapath;
}
anyxml curval {
    ywx:datapath;
}

If /foo/bar/leaf2 is edited, the <edit> message will be generated with the datapath attribute from the yumaworks-attrs.yang module.

<newval ywattrs:datapath='/foo/bar/leaf2'>42</newval>
<curval ywattrs:datapath='/foo/bar/leaf2'>67</curval>

nacm:default-deny-all

The nacm:default-deny-all extension is used by the to indicate that the data model node represents a sensitive security system parameter. It is defined in RFC 8341.

If present, and the NACM module is enabled (E.g., /nacm/enable-nacm object equals 'true'), the NETCONF server will only allow the designated 'recovery session' to have read, write, or execute access to the node. An explicit access control rule is required for all other users. The 'default-deny-write' extension MAY appear within a data definition statement. It is ignored otherwise.

Argument: none
Example:
rpc shutdown {
    nacm:default-deny-all;
}

nacm:default-deny-write

The nacm:default-deny-write extension is used by the to indicate that the data model node represents a sensitive security system parameter. It is defined in RFC 8341.

If present, and the NACM module is enabled (E.g., /nacm/enable-nacm object equals 'true'), the NETCONF server will only allow the designated 'recovery session' to have write access to the node. An explicit access control rule is required for all other users. The 'default-deny-write' extension MAY appear within a data definition statement. It is ignored otherwise.

Argument: none
Example:
leaf enable-system {
    nacm:default-deny-write;
    type boolean;
}

ncx:default-parm

The ncx:default-parm extension is used by the yangcli-pro program to select a default parameter for the specified RPC input section. It can be used within a CLI container or rpc definition to specify leaf parameter within the CLI container or rpc input section, that is used as the default if no parameter name is entered.

These values must not begin with a dash (-) or double dash (--) sequence or they will be mistaken for CLI parameter names.

This option is somewhat risky because any unrecognized parameter without any prefix (- or --) will be tried as the default parameter type, instead of catching the unknown parameter error. It can also be useful though, for assigning file name parameters through shell expansion, or if there is only one parameter.

YANG File: yuma-ncx.yang
Argument:
  • parm: name of the leaf to use as the default parameter

Example:

rpc connect {
  description "Connect to a NETCONF server.";
  input {
    ncx:default-parm server;

    uses ConnectParms {
      refine user {
        mandatory true;
      }
      refine server {
        mandatory true;
      }
      refine password {
        mandatory true;
      }
    }
 }

The "server" parameter does not need a keyword when used in yangcli-pro:

yangcli-pro>  connect localhost user=andy password=yang-rocks

ncx:default-parm-equals-ok

The ncx:default-parm-equals-ok extension is used by the yangcli-pro program to select a default parameter for the specified RPC input section. It is used within a CLI container or rpc definition to specify a leaf parameter within the CLI container or rpc input section, that is used as the default if no parameter name is entered.

This can be used in addition to ncx:default-parm to allow an equals sign '=' in the default 'parm' string value.

This option is quite risky because any unrecognized parameter without any prefix (- or --) will be tried as the default parameter type, instead of catching the unknown parameter error. This includes strings containing an equals sign, so an unknown parameter error will never be generated.

YANG File: yuma-ncx.yang
Argument: none
Example:
rpc foo {
  input {
    ncx:default-parm a;
    ncx:default-parm-equals-ok;
    leaf a { type string; }
    leaf b { type int32; }
  }
}

The "a" parameter can be entered without a keyword as "name=value"

yangcli> foo bogus-parm=fred

This will interpreted as if parameter 'a' were entered:

yangcli> foo a='bogus-parm=fred'

ywx:get-filter-element-attributes

The ietf:get-filter-element-attributes extension is defined in the ietf-netconf.yang module.

This is a reserved extension name, used to define the filter and type attributes used in the <get> operation. It cannot be used in other YANG modules.

Argument: none

ywx:exclusive-rpc

This extension is used to force "1 at a time" access to an RPC operation.

It can be used within an rpc definition statement to indicate that the RPC is not allowed to be called concurrently by different sessions. The server will return an 'in-use' error if another session is currently invoking the RPC operation and this extension is present in the rpc-stmt.

Argument: none
Example:
rpc reset-system {
    ywx:exclusive-rpc;
    // only allow 1 session at a time to reset system
}

ywx:help

The ywx:help extension is used to define a help text string for CLI.

It can be defined within a rpc or data definition statement to provide a short help text string for CLI and other applications to use in addition to the description statement.

Argument:
  • helptext: The help text string which should be 60 characters or less in length.

Example:

leaf mtu {
    ywx:help “Maximum transmission unit size”;
    type uint32;
    description “... long description …”;
}

ncx:hidden

The ncx:hidden extension is used to prevent publication of a YANG data object. It will be ignored for typedefs and other constructs. If present within a data object, that node and any sub-nodes will be ignored when generating HTML documentation or YANG output.

The yangdump-pro --format=copy mode is not be affected by this extension.

YANG File: yuma-ncx.yang
Argument: none
Example:
container struct {
    ncx:hidden;
    ncx:abstract;
}

ncx:metadata

The ncx:metadata extension is used to define an XML attribute to be associated with a data-def-stmt node. Only optional metadata can be defined. Errors for missing XML attributes (except as specified by the YANG language) will not be checked automatically.

YANG File: yuma-ncx.yang
Argument:
  • syntax-string: syntax of the meta-data attribute The syntax string has the following format:

    [prefix:]typename attribute-name
    

    Any YANG typedef of builtin type can be specified as the type name, except 'empty'.

Example:

container rpc-reply {
    description "Remote Procedure Call response message";
    reference "RFC 4741, section 4.2";
    uses RpcReplyType;
    // do not treat missing message-id as an error

    ncx:metadata "MessageId message-id";
    ncx:abstract;
}

ncx:no-duplicates

Warning

The "xsdlist" data type is not supported in YANG. Do not use this extension.

The ncx:no-duplicates extension is used to indicate that no duplicate values are allowed in an ncx:xsdlist leaf or leaf-list object.

YANG File: yuma-ncx.yang
Argument: none
Example:
leaf number-list {
    type string {
        ncx:xsdlist int32;
        ncx:no-duplicates;
    }
}
<number-list>32 1 -6 103</number-list>

ncx:password

Warning

This extension is NOT SECURE. Use the "crypt-hash" data type from iana-crypt-hash.yang instead for secure password configuration.

The ncx:password extension is used to indicate the data type for the leaf is really a password. Only the encrypted version of the password is allowed to be generated in any output.

YANG File: yuma-ncx.yang
Argument: none
Example:
leaf system-password {
    ncx:password;
    type string {
        length “8 .. 16”;
    }
}

ncx:qname

The ncx:qname extension is used to indicate that the content of a data type is a Qualified Name. This is needed to properly evaluate the namespace prefix, if used.

The qname extension may appear within the type-stmt, within a typedef, leaf, or leaf-list. The builtin data type must be 'string', or the 'qname' extension will be ignored.

YANG File: yuma-ncx.yang
Argument: none
Example:
leaf bad-element {
    ncx:qname;
    type string;
}

oc-ext:openconfig-hashed-value

The oc-ext:openconfig-hashed-value extension is used to indicate that the leaf or leaf-list contains an openconfig hashed password string.

  • The openconfig-extensions module contains this extension. It is available from the OpenConfig github repository, and not included in the YumaPro SDK distribution.

  • The qname extension may appear as a sub-statement of a leaf or leaf-list statement. It will be ignored otherwise.

  • If this extension is found then the leaf or leaf-list will be treated as an OpenConfig Hashed Value:

  • value passed by client is a cleartext password

    • It is not a crypt-hash beginning with the prefix “$0$”

  • server immediately converts the cleartext to a hash

  • Only the hash value is ever returned to a client in a data retrieval operation

  • Only the hash value is stored in NV-storage (E.g., startup-cfg.xml)

YANG File: Not Available in YumaPro SDK
Argument: none
Example:
module test-ochash {
    yang-version 1.1;
    namespace "http://netconfcentral.org/ns/test-ochash";
    prefix toch;
    import openconfig-extensions { prefix oc-ext; }

    revision 2021-02-26;

    container octop {
      leaf ochash {
        type string;
        oc-ext:openconfig-hashed-value;
      }
    }
}

Example: Set the ochash leaf to the value ‘this is a test’

Note the value is passed as a string (highlighted below)

Incoming msg for session 3

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="2"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <edit-config>
  <target>
   <candidate/>
  </target>
  <default-operation>merge</default-operation>
  <test-option>set</test-option>
  <config>
   <octop xmlns="http://netconfcentral.org/ns/test-ochash">
    <ochash
     xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
     nc:operation="merge">this is a test</ochash>
   </octop>
  </config>
 </edit-config>
</rpc>

If logging is enabled a similar log trace should be present to this example:

agt_crypt: altering openconfig-hashed-value value from cleartext to
  '$6$PE1fq4I22dYjomxn$' for node 'ochash'

If the data is retrieved (E.g., get-config from <candidate>) then the hashed value will be returned.

The server never stores the original plaintext version and it cannot be retrieved from the server at all.

<data>
  <octop xmlns="http://netconfcentral.org/ns/test-ochash">
    <ochash>$6$PE1fq4I22dYjomxn$E60QUJiDIB6uZ.cx7WbsWATrs/.2Zp8NROf7SW3VnSrM4ZrTBlJUHbjtxxMb/hFcPxgdxZOQdzzKNRWiX6AF2/</ochash>
  </octop>
</data>

oc-ext:regexp-posix

The oc-ext:regexp-posix extension is used to indicate that the module uses Posix pattern statements instead of the XSD syntax defined in YANG.

  • The openconfig-extensions module contains this extension. It is available from the OpenConfig github repository, and not included in the YumaPro SDK distribution.

  • The qname extension may appear as a body-stmt at the top-level of the module. It will be ignored otherwise.

  • If this extension is found then the module will be treated as an OpenConfig style module using Posix pattern statements.

  • This extension overrides the --with-ocpattern CLI parameter, so even if this parameter is false or the module does not begin with the string “openconfig-”, the Posix pattern syntax will be used.

YANG File: Not Available in YumaPro SDK
Argument: none
Example:
module my-openconfig-ext {

    // ….

    import openconfig-extensions { prefix oc-ext; }

    // ….

    oc-ext:regexp-posix;

}

ncx:root

The ncx:root extension is used within a container definition to indicate it is really a root container for a conceptual NETCONF database, instead of just an empty container. This is needed for YumaPro to correctly process any RPC method that contains a 'config' parameter.

YANG File: yuma-ncx.yang
Argument: none
Example:
rpc my-edit {
    input {
        container my-config {
            ncx:root;
        }
    }
}

ywx:rpc-root

The ywx:rpc-root extension is used internally with the YANG-API protocol to identify a container definition to indicate it is really a root container for a conceptual NETCONF operations, instead of just a container. The container is expected to be empty. Any top-level rpc-stmt can be specified using a QName value with the same module and local name as the RPC operation definition.

This extension is reserved and only used internally by the server.

Argument: none

ncx:schema-instance

The ncx:schema-instance extension is used to indicate that the typedef or type statement for a string data type really identifies a special schema-instance node, not a generic string.

  • A schema-instance value string is an unrestricted YANG instance-identifier expression. All the same rules as an instance-identifier apply except:

    • Predicates for keys are optional.

    • The dataRule will apply to all instance of any missing key leaf predicate.

  • This extension will be ignored unless it is present in the type-stmt of a typedef-stmt, leaf-stmt, or leaf-list-stmt, or directly within a leaf-stmt or leaf-list-stmt..

YANG File: yuma-ncx.yang
Argument: none
Example:
leaf target {
    ncx:schema-instance;
    type string {
        length “1 .. max;
    }
}

nacm:secure

Warning

This extension is obsolete! Use nacm:default-deny-write instead.

The nacm:secure extension is used to indicate that the data model node represents a sensitive security system parameter. It is equivalent to the IETF nacm:default-deny-write extension. The IETF access control model is derived from the yuma-nacm module.

If present, the NETCONF server will only allow the designated 'superuser' to have write or execute default nacm-rights for the node. An explicit access control rule is required for all other users.

The 'secure' extension may appear within a data, rpc, or notification node definition. It is ignored otherwise.

YANG File: yuma-nacm.yang
Argument: none
Example:
leaf my-leaf {
    nacm:secure;
    type string {
        length “1 .. max;
    }
}

ncx:sil-aio-get2

The ncx:sil-aio-get2 extension is used within a data definition statement to define the GET2 retrieval mechanism. This extension affects the descendant data nodes.

  • This extension can be used in a container or list to force the server to treat that data subtree as a All In One AIO node for GET2 callback.

  • The entire subtree would be expected in one retrieval in one callback invocation.

  • The entire subtree can be specified in the JSON or XML buffer that will be used for return values.

  • The server will parse and handle the buffer and process retrieval based on the provided JSON or XML encoded buffer.

  • The 'parmstr' argument can specify the encoding that will be used in the callback. Available options are:*

    • val: val_value_t tree is expected in return value

    • xml: XML element in a buffer is expected in return value

    • json: JSON object in a buffer is expected in return value

  • If not specified default val value retrieval mechanism will be assumed.

Argument:
  • string (val | xml | json)

Example:

/* All in One callback for Container with List */
 container get3-cont-list {            // All in One get2 CB
   ywx:sil-aio-get2 "json";
   config false;

   leaf D { type int8; }

   list nonconfig-list {               // No callback
     key name;
     leaf name { type string; }
     leaf not-keyname { type string; }

     container int-con {               // No callback
       leaf con-leaf { type int32; }
     }
   }
 }

ncx:sil-delete-children-first

The ncx:sil-delete-children-first extension is used within a container or list definition to indicate that the SIL callbacks for descendant nodes should be invoked first, when a data node instance of the object containing this extension is deleted.

  • Normally, the parent node is expected to delete all its own sub-structures when the SIL edit callback is invoked.

  • If this extension is present, then any SIL callbacks for any of the child nodes will be invoked first instead.

  • If a child node is a list or a container, and it also contains this extension, then its children will be checked first.

  • The SIL edit callback will not be invoked for leaf, leaf-list, or anyxml descendant nodes in this mode.

  • They will only will called if their parent node is not getting deleted.

YANG File: yuma-ncx.yang
Argument: none
Example:
container foo {
    ncx:sil-delete-children-first;
    list foos {
       ncx:sil-delete-children-first;
       key a;
       leaf a { type string; }
       container b {
         list c { type string; }
       }
       leaf d { type empty; }
    }
}

In this example, assume node /foo gets deleted. Then the SIL edit callbacks would be done as follows:

  1. /foo/foos[a='n']/b (called for row 'n' of /foo/foos)

  2. /foo/foos[a='n'] (called for row 'n' of /foo/foos)

  3. repeat (1,2) until all rows in /foo/foos are deleted

  4. /foo

Note that the SIL edit callback is not done for list /foo/foos[a='n']/b/c because this extension is not present in container /foo/foos/b.

Note that the SIL edit callback is not done for nodes /foo/foos[a='n']/a or /foo/foos[a='n']/d because they are leafs.

ywx:sil-force-replace-replay

The ywx:sil-force-replace-replay extension is used within a configuration data node definition statement to indicate that the SIL (or SIL-SA) callback should be invoked even for nodes that are not changing, during a replace operation.

  • All SIL callbacks for child nodes in the replace request (where the parent node contains this extension) will be invoked during edit processing.

  • This extension can be used with the ywx:sil-force-replay extension.

  • If this extension is used within a list statement, then SIL callbacks for all instances of the list that are provided in the replace operation will be invoked.

Argument: none
Example:
container top {
  list bar {
    ywx:sil-force-replace-replay;

    key name;
    leaf name { type string; }
    leaf b { type int32; }
    leaf c { type int32; }
  }
}

Replace config example:

<config>
  <top nc:operation=”replace”>
    <bar>   // this entry is changing
      <name>fred</name>
      <b>22</b>
      <c>99</c>
    </bar>
    <bar>   // not changing but SIL will be called anyway
      <name>barney</name>
      <b>18</b>
      <c>82</c>
    </bar>
  </top>
</config>

In this example, all instances of /top/bar will get replaced. Normally the server will skip replacement of instances which are not changing at all. If this extension is present, then the server will not skip any instances that are provided.

Instead, the SIL edit callbacks would be done for these nodes as well. The 'newval' and 'curval' parameters will be the same for the replayed entries.

ywx:sil-force-replay

The ywx:sil-force-replay extension is used within a container or list definition to indicate that the SIL callbacks for all child nodes should be invoked when one of the child nodes is modified.

  • Normally, only the SIL callbacks for the child nodes that are changed are called during an edit transaction.

  • If the parent node for the changed child node contains the “sil-force-replay” extension, then all the child node SIL callbacks will be invoked instead.

Argument: none
Example:
list foo {
       ywx:sil-force-replay;
       key a;
       leaf a { type string; }
       container b {
         list c { ... }
       }
       leaf d { type int32; }
       leaf e { type int32; }
   }

In this example, assume node /foo/d gets modified. Then the SIL edit callbacks would be done for sibling nodes as well. The 'newval' and 'curval' parameters will be the same for the replayed sibling nodes.

ywx:sil-priority

The ywx:sil-priority extension is used within a configuration data node definition to set the SIL priority for an object.

  • The lower the number of the SIL priority, the higher priority it is assigned.

  • SIL callbacks are normally invoked in the order that the edits appear in the edit request. If the sil-priority is set then the order SIL callbacks are invoked will be based on the numeric priority value instead.

  • Used to control the order that SIL or SIL-SA callbacks are invoked for specific objects.

  • If this extension is used within a configuration database object then the SIL priority for the object will be assigned the value of the 'prio' argument.

  • Only the order of the 'apply', 'commit' and 'rollback' callback phases will be affected by this parameter. The 'validate' phase callbacks are invoked in the order they appear in the edit request.

  • The 'prio' argument must be a number between 1 and 255. If two objects are edited in the same edit request, the the one with the lowest SIL priority number will be executed first.

  • If no sil-priority is set, then the default value of '255' will be used instead.

  • If the SIL priority is the same for two objects in the same edit request, then the server will pick an order in an implementation-specific manner.

Argument:
  • prio: number from 1 to 255

Example:

 leaf A1 {
   type string;
    ywx:sil-priority 30;
 }

 leaf A2 {
   type string;
   ywx:sil-priority 20;
 }

 leaf A3 {
  type string;
  ywx:sil-priority 10;
}

ywx:sil-test-get-when

The ywx:sil-test-get-when extension is used within an operational data node definition to set the --sil-test-get-when parameter setting for an object.

  • This parameter controls whether “when-stmt” expressions will be evaluated by the server.

  • Normally the SIL or SIL-SA code is expected to check these conditions but the server can run the Xpath test during retrieval operations.

  • Used within a data definition statement to define the --sil-test-get-when CLI parameter behavior for a single object. This extension does not affect the descendant data nodes.

  • The 'boolval' argument must be the string 'true' or 'false'

    • If 'true' the object will be tested for when-stmts if any need to be evaluated during retrieval operations.

    • If 'false' then any when-stmts will be ignored during retrieval operations.

  • This extension will override the --sil-test-get-when global CLI parameter. This extension will have no affect unless the value is different than this CLI parameter.

Argument:
  • boolval: (true or false)

Example:

leaf myoperleaf {
    ywx:sil-test-get-when true;
    type string;
}

ywx:urlpath

The ywx:urlpath extension is used to indicate that a string data node is really using the YANG-API URL path expression syntax. It can be used within a leaf or leaf-list definition.

Argument: none
Example:
leaf restpath {
    ywx:urlpath;
    type string;
}

Example XML Usage:

<restpath>/interfaces/interface/eth0/mtu</restpath>

ncx:user-write

The ncx:user-write extension is used within database configuration data definition statements to control user write access to the database object containing this statement.

  • The 'exceptions' argument is a list of operations that users are permitted to invoke for the specified node. These permissions will override all NACM access control rules, even if NACM is disabled.

  • This extension does not apply to descendant nodes!

  • This extension has no effect if config-stmt is false!

The following values are supported:

  • create: allow users to create instances of the object

  • update : allow users to modify instances of the object

  • delete : allow users to delete instances of the object

  • To dis-allow all user access, provide an empty string for the 'exceptions' argument (user-write '';)

  • To allow only create and delete user access, provide the string 'create delete' for the 'exceptions' parameter.

  • Use this for parameters that cannot be changed once they are set.

  • Providing all 3 parameters has the same affect as not using this extension at all, but can be used anyway.

Equivalent YANG leaf for this extension:

leaf user-write {
    type bits {
      bit create;
      bit update;
      bit delete;
    }
    default 'create update delete';
    description 'equivalent YANG definition';
  }
YANG File: yuma-ncx.yang
Argument:
  • exceptions: the list of operations to permit for the data node. The YANG bits definition shown above defines the syntax for the exceptions string.

Example:

container interfaces {
    ncx:user-write “update”;
    list physical-interface {
        ncx:user-write “update”;
        // ... more fields
    }
}

nacm:very-secure

Warning

This extension is obsolete! Use the nacm:default-deny-all extension instead.

The nacm:very-secure extension is used to indicate that the data model node represents a sensitive security system parameter. It is equivalent to the IETF nacm:default-deny-all extension. The IETF access control model is derived from the yuma-nacm.yang module.

  • If present, the NETCONF server will only allow a designated 'superuser' account to have read, write, or execute nacm-rights for the node.

  • An explicit access control rule is required for all other users.

  • The 'very-secure' extension may appear within a data, rpc, or notification node definition. It is ignored otherwise.

YANG File: yuma-nacm.yang
Argument: none
Example:
leaf social-security-id {
    nacm:very-secure;
    type string {
        length “1 .. max;
    }
}

ncx:xpath

The ncx:xpath extension is used to indicate that the content of a data type is an XPath expression. This is sometimes needed to properly evaluate the namespace prefixes within the expression.

Note

This extension is deprecated. Use the xpath1.0 data type found in ietf-yang-types.yang instead.

The xpath extension may appear within the type-stmt, within a typedef, leaf, or leaf-list. The builtin data type must be 'string', or the 'xpath' extension will be ignored.

All data using the 'instance-identifier' built-in type will automatically be processed as an XPath string, so the xpath extension is not needed in that case.

YANG File: yuma-ncx.yang
Argument: none
Example:
leaf target {
    ncx:xpath;
    type string {
        length “1 .. max;
    }
}

ywx:xpath-operational-ok

The ywx:xpath-operational-ok extension is used to indicate that the “must” and “when” expressions within the indicated object are allowed to access config=false data nodes.

  • This extension is used within a data-definition statement for a configuration data node to alter the must-stmt and when-stmt found within the data node.

  • This allows an XPath expression in such a node to reference config=false data nodes.

  • This property does not apply to any child nodes, just the data node containing this external statement.

  • There is no parameter for this extension.

Warning

Use of this extension violates the standard in RFC 7950, sec 6.4.1 so use with caution since the YANG module will not be valid according to YANG 1.1 rules.

Argument: none
Example:

In the following example, the list “/c3/l3” has a when-stmt that accesses the /interfaces-state subtree:

module mytest2 {
  namespace "urn:yumaworks:params:xml:ns:yang:mytest2";
  prefix "mt2";
  import ietf-interfaces { prefix if; }
  import yumaworks-extensions { prefix ywx; }

  revision 2019-12-06 {
  description
  "Initial version";
  }

  container c3 {
    list l3 {
      ywx:xpath-operational-ok;
      when "/if:interfaces-state/if:interface/if:speed > 1000";
      key "name";
      leaf name{type string;}
      leaf if-index {type int32;}
    }
  }
}

ncx:xsdlist

The ncx:xsdlist extension is used to indicate the leaf string type is really an XSD list, which is a series of white space separated token strings.

  • The type argument represents the data type to use for the list members, for validation purposes.

  • This extension is allowed to be present within the type sub-section for a string.

Warning

This non-standard extension should not be used. Use the 'bits' data type instead.

YANG File: yuma-ncx.yang
Argument:
  • type: name of the data type to use for list members

Example:

typedef MyEnumType {
  enum up;
  enum down;
  enum left;
  enum right;
}

leaf enum-list {
  ncx:xsdlist MyEnumType;
  type string;
}

Example XML Usage:

<enum-list>up right down</enum-list>