Oper Data Handler: Nested dynamic elements not allowed

Our yang file contains nested list as shown below:

list protocol{
    key "name";
    tailf:callpoint "get-oper";
    leaf name;        /* string type */
    leaf description; /* string type */

    list layer{
	key "name";
	tailf:callpoint "get-oper";
	leaf name;   /* string type */ 
	leaf number; /* Uint32 type */ 
    }
 }

get_object() is implemented as below:

static int get_object(struct confd_trans_ctx *tctx,
						confd_hkeypath_t *keypath)
{
	if(CONFD_GET_XMLTAG(&(keypath->v[1][0])) == layer) {
		confd_value_t v[2];
		CONFD_SET_STR(&v[0], "ip");
		CONFD_SET_INT32(&v[1], 3);
		confd_data_reply_value_array(tctx, v, 2);
    } else if(CONFD_GET_XMLTAG(&(keypath->v[1][0])) == protocol) {
		confd_value_t v[4];
		CONFD_SET_STR(&v[0], "ospf");
		CONFD_SET_STR(&v[1], "routing protocol");
		confd_data_reply_value_array(tctx, v, 2);
	}
	return CONFD_OK;
}

The below error is seen when the command is given from confd cli:

20-Feb-2017::17:21:28.435 ubuntu confd[3842]: devel-c get_next request for callpoint ‘get-oper’ path /protocol
20-Feb-2017::17:21:28.437 ubuntu confd[3842]: devel-c get_next succeeded for callpoint ‘get-oper’ path /protocol
20-Feb-2017::17:21:28.438 ubuntu confd[3842]: devel-c get_object request for callpoint ‘get-oper’ path /protocol{ospf}
20-Feb-2017::17:21:28.442 ubuntu confd[3842]: devel-c get_object succeeded for callpoint ‘get-oper’ path /protocol{ospf}
20-Feb-2017::17:21:28.442 ubuntu confd[3842]: devel-c bad get_object() return value: /protocol{ospf}/layer: Missing value

After that, the second list “layer” entries are added to get_object() and saw the below issue:

20-Feb-2017::17:21:28.435 ubuntu confd[3842]: devel-c get_next request for callpoint ‘get-oper’ path /protocol
20-Feb-2017::17:21:28.437 ubuntu confd[3842]: devel-c get_next succeeded for callpoint ‘get-oper’ path /protocol
20-Feb-2017::17:21:28.438 ubuntu confd[3842]: devel-c get_object request for callpoint ‘get-oper’ path /protocol{ospf}
20-Feb-2017::17:21:28.442 ubuntu confd[3842]: devel-c get_object succeeded for callpoint ‘get-oper’ path /protocol{ospf}
20-Feb-2017::17:21:28.442 ubuntu confd[3842]: devel-c bad get_object() return value: /protocol{ospf}/layer: Nested dynamic elements not allowed

static int get_object(struct confd_trans_ctx *tctx,
						confd_hkeypath_t *keypath)
{
	if(CONFD_GET_XMLTAG(&(keypath->v[1][0])) == layer) {
		confd_value_t v[2];
		CONFD_SET_STR(&v[0], "ip");
		CONFD_SET_INT32(&v[1], 3);
		confd_data_reply_value_array(tctx, v, 2);
    } else if(CONFD_GET_XMLTAG(&(keypath->v[1][0])) == protocol) {
		confd_value_t v[4];
		CONFD_SET_STR(&v[0], "ospf");
		CONFD_SET_STR(&v[1], "routing protocol");
		CONFD_SET_STR(&v[2], "ip");
		CONFD_SET_INT32(&v[3], 3);
		confd_data_reply_value_array(tctx, v, 4);
	}
	return CONFD_OK;
}

Please let us know if the nested list is not supported for get_object().
Using confd-6.0.2 and the above yang and data provider code are the best approximation of original code.

Should be:

CONFD_SET_STR(&v[0], "ospf");
CONFD_SET_STR(&v[1], "routing protocol");
CONFD_SET_NOEXISTS(&v[2]);
confd_data_reply_value_array(tctx, v, 3);

this is described in more detail in the ConfD user guide and/or man page, relevant to confd_data_reply_value_array() procedure, more specifically, XML STRUCTURES / Value Array sub-sections:

List nodes use a single array element, with type C_NOEXISTS (value ignored), regardless of the actual number of entries or their contents.

As a response to get_object() for “protocol” entry, we just need to tell ConfD there’s some list as a potential content of the object we’re returning - and it’s up to ConfD to get the specific nested contents as necessary (again, invoking further data provider callbacks).

I tried your suggestion as listed below:
confd_value_t v[4];
CONFD_SET_STR(&v[0], “ospf”);
CONFD_SET_STR(&v[1], “routing protocol”);
CONFD_SET_STR(&v[2], “ip”);
CONFD_SET_INT32(&v[3], 3);
CONFD_SET_NOEXISTS(&v[4]);
CONFD_SET_NOEXISTS(&v[5]);
confd_data_reply_value_array(tctx, v, 6);

The devel.log shows below snippet:
15-Feb-2017::02:47:52.734 ubuntu confd[2615]: devel-c bad get_object() return value: /protocols{ospf}: Too many values

Please let me know

  1. if the nested list with same callpoint is not supported for get_object()
  2. if i need to handle any extra conditions for these nested list with key

This is described in the previously referenced ConfD user guide section XML structures:

The simpler format is an array of confd_value_t elements corresponding to the complete contents of a list entry or container. The content of sub-list entries cannot be represented. The array is populated through a “depth first” traversal of the data tree as follows.

So, when using confd_data_reply_value_array() , single get_object() request is to service single specific list entry - you should NOT mix the different (even though nested) lists.
ConfD will invoke subsequent callback (e.g. get_object()) requests for internal lists.
Pseudo code:

if (CONFD_GET_XMLTAG(&(keypath->v[1][0])) == layer) {
	confd_value_t v[2];
	CONFD_SET_STR(&v[0], ...);        // name
	CONFD_SET_INT32(&v[1], ...);        // number
	confd_data_reply_value_array(tctx, v, 2);
} else if (CONFD_GET_XMLTAG(&(keypath->v[1][0])) == protocol) {
	confd_value_t v[3];
	CONFD_SET_STR(&v[0], ...);        // name
	CONFD_SET_STR(&v[1], ...);        // description
	CONFD_SET_NOEXISTS(&v[2]);            // "abstract" representation of "layer" list
	confd_data_reply_value_array(tctx, v, 3);
}

Thanks a lot for the inputs. This issue is resolved.

Hi,

From the above examble, if the list layer has one more sublist say X. Then from the above response, i have send response like

if (CONFD_GET_XMLTAG(&(keypath->v[1][0])) == layer) {
confd_value_t v[2];
CONFD_SET_STR(&v[0], …); // name
CONFD_SET_INT32(&v[1], …); // number
confd_data_reply_value_array(tctx, v, 2);
} else if (CONFD_GET_XMLTAG(&(keypath->v[1][0])) == protocol) {
confd_value_t v[4];
CONFD_SET_STR(&v[0], …); // name
CONFD_SET_STR(&v[1], …); // description
CONFD_SET_NOEXISTS(&v[2]); // “abstract” representation of “layer” list
CONFD_SET_NOEXISTS(&v[3]); // “abstract” representation of “X” list
confd_data_reply_value_array(tctx, v, 4);
}

Receiving “Too many values” error

your description & example code seem to not match - is the new list X the direct child node of “layer”, or “protocol”?

yes, But now it is clear to me, We able to handle the situation by sending CONFD_SET_NOEXISTS for each immediate sublist.

yes, only immediate/direct descendant lists need the “NOEXISTS” placeholder.
great, glad to hear it’s working well.