The leafref type is restricted to the value space of some leaf or leaf-list node in the schema tree and optionally further restricted by corresponding instance nodes in the data tree. The "path" sub-statement is used to identify the referred leaf or leaf-list node in the schema tree. The value space of the referring node is the value space of the referred node. 

If the "require-instance" property is "true", the referred node must exist with the same value as the leafref value in a valid data tree.


Consider the following YANG module example:


module example {
  namespace "http://yumaworks.com/ns/example";
  prefix "example";

  revision 2019-07-30 {
    description
      "Initial example module for leafref type";
  }  
  
  leaf yang-boolean-example {
    type boolean;
  }
  leaf yang-leafref-example-1 {
    type leafref {
      path "../yang-boolean-example";
      require-instance "false";
    }
  }
  leaf yang-leafref-example-2 {
    type leafref {
      path "../yang-boolean-example";
      require-instance "true";
    }
  }
}


This leaf can be accessed using several ways described below.


1) Using RESTCONF request:


To create a new "yang-leaf-example-1" node using RESTCONF client, the client might send the following POST request:


      POST /restconf/data/  HTTP/1.1
      Host: example-server
      Content-Type: application/yang-data+json

      {
        "yang-leafref-example-1":"false"
      }


If the resource is created, the server might respond as follows:


      HTTP/1.1 201 Created
      Server: example-server
      Location: https://example-server/restconf/data/yang-leafref-example-1


If the POST method succeeds, a "201 Created" Status is returned and there is no response message-body.  A "Location" header field identifying the resource node that was created. If the data resource already exists, then the POST request will fail and a "409 Conflict" status-line will be returned.


To retrieve just created node, the GET method can be sent by the client as follows:


      GET /restconf/data/yang-leafref-example-1 HTTP/1.1
      Host: example-server
      Accept: application/yang-data+xml


The server might respond as follows:


      HTTP/1.1 200 OK
      Server: example-server
      Content-Type: application/yang-data+xml

      <yang-leafref-example-1 xmlns="http://yumaworks.com/ns/example">false</yang-leafref-example-1>


 A new "yang-leaf-example-2" node cannot be created unless a yang-boolean-example is not present in the data tree using following POST request:


      POST /restconf/data/  HTTP/1.1
      Host: example-server
      Content-Type: application/yang-data+json

      {
        "yang-leafref-example-1":"false"
      }


Server might reply with following error message.


{
 "ietf-restconf:errors": {
  "error": [
   {
    "error-type":"application",
    "error-tag":"data-missing",
    "error-app-tag":"instance-required",
    "error-path":"/examle:yang-leafref-example-2",
    "error-message":"required value instance not found",
    "error-info": {
     "bad-value":"yang-leafref-example-2",
     "error-number":310
    }
   }
  ]
 }
}



2) Using yangcli-pro:


To create a new "yang-leafref-example-1" node using yangcli-pro client, the client might send the following POST request:


user@server> create /yang-leafref-example-1 value=false
user@server> commit


To retrieve just created leafref leaf, the following request might be sent:


user@server> sget /yang-leafref-example-1


The server might respond with rpc-reply, containing below information:


<rpc-reply>
 <data>
   <yang-leafref-example-1 xmlns="http://yumaworks.com/ns/example">false</yang-leafref-example-1>
 </data>
</rpc-reply>


The following example illustrates how the leafref leaf can be set by using inline JSON file:


edit-config target=candidate config="""
{"config": {
    "yang-leafref-example-1" : "false"
 }
}
"""


The following example illustrates how the leafref leaf can be set by using inline XML file:


edit-config target=candidate config="""
<config>
  <yang-leafref-example-1>false</yang-leafref-example-1>
</config>
"""


To retrieve just created leafref leaf, the following request might be sent:


user@server> sget /yang-leafref-example-1


The server might respond with rpc-reply, containing below information:


<rpc-reply>
 <data>
   <yang-leafref-example-1 xmlns="http://yumaworks.com/ns/example">false</yang-leafref-example-1>
 </data>
</rpc-reply>


Yangcli-pro might parse the above message as


rpc-reply {
  data {
      yang-leafref-example-1 false
  }
}

3) Using DB-API:


The following example illustrates how to set leafref leaf value using DB-API.


/********************************************************************
* FUNCTION send_test_edit
*
* This is an example send edit function for leafref node.
**********************************************************************/
static void
    send_test_edit (void)
{
    const xmlChar *path_str = (const xmlChar *)"/";
    const xmlChar *operation_str = (const xmlChar *)"merge";
    const xmlChar *value_str = (const xmlChar *)
    "<config>"
    "<yang-leafref-example-1 xmlns='http://yumaworks.com/ns/example'>false</yang-leafref-example-1>"
    "</config>";

    const xmlChar *patch_id_str = NULL;
    boolean system_edit = FALSE;
    status_t res = db_api_send_edit_ex(path_str,
                                       operation_str,
                                       value_str,
                                       patch_id_str,
                                       system_edit);
    if (res != NO_ERR) {
        log_error("\nSend test edit for leafref node failed %s %s = %s (%s)\n",
                  operation_str, path_str, value_str,
                  get_error_string(res));
    } else if (LOGDEBUG) {
        log_debug("\nSend test edit for leafref node OK  %s %s = %s\n",
                  operation_str, path_str, value_str);
    }

}  /* send_test_edit */

LEAFREF leaf and SIL code:


The following APIs and Macros can be used with the bits type val value node. Refer to val.h:

  • val_make_simval_obj()Function that malloc a new val value node and does not need to know the type, it will be picked automatically based on the provided object type.
  • val_get_leafref_typdef(): Function that returns a base type of the referred leaf or leaf-list.
  • VAL_STR(): string value assigned.


Following code example creates the value of leafref node and outputs it to the standard log output using val_make_simval_obj().

This is just an example of how the following API can be used:


...
    /* create a new leafref type node */
    val_value_t *return_val =
        val_make_simval_obj(obj, (const xmlChar *)"false", &res);

    if (return_val) {
        typ_def_t *typdef = NULL;

        /* As an example, get the value's type:
         * If the value has LEAFREF base type, to get its actual type
         * definition would required to call val_get_leafref_typdef()
         * API that will return leafref actual type that it points at.
         * Otherwise, regular macros could be used VAL_TYPDEF()
         */
        if (VAL_BTYPE(return_val) == NCX_BT_LEAFREF) {
            typdef = val_get_leafref_typdef(return_val);
        } else {
            typdef = VAL_TYPDEF(return_val);
        }

        /* Output the value to the standard output log */
        log_info("\nCreated leafref node; type: %s; value: %s",
                  typdef->typenamestr,
                  VAL_STR(return_val));
    }
...



The server might output the following logging information to the standard output:


...
Created leafref node; type: boolean; value: false
...