From the logs I can see these two differences (between the cases)
Confd invokes get_next_object() (compared to get_next() in the case it returns proper xml reply)
get_attrs() callback was not implemented in second case. However providing a dummy get_attrs() callback does not help either. So I think this may be unrelated.
This are the snippets of netconf.log between the two cases
The difference seems to be confd progress db=undefined usid=31 thandle=315: netconf: netconf handling ok log working case. That log does not come in second case.
Next I enabled netconf.trace log too, which gave me this extra information
Do you have also get_next/get_elem implemented for the callpoint lldp_neigh_brief? If yes, is there any change if you comment get_next_object registration (replace it with get_next , get_elem?
So I think I have found out the issue. It was a case of invalid API usage. Sharing it here to confirm it from community.
So my idea of get_next_object() callback implementation was that, if your external DB has m rows and n columns to send to confd at one go,
// Allocate space for (m + 1) number of struct confd_next_object *obj
// Fill 0 ... m - 1 entry of obj as follows
- obj[i].v = confd_value_t type array of size n
- obj[i].n = n + 1;
- obj[i].next = -1;
// Fill the (m + 1)'th entry as obj[m].v = NULL
// Reply to confd as confd_data_reply_next_object_arrays(tctx, obj, m + 1, 0);
I had a misunderstanding that, usage like this handles case where m = 0 too. But that was working with CLI, but was resulting the NETCONF error.
Currently I added a special case for m == 0,
if (m == 0)
{
confd_data_reply_next_object_arrays(tctx, NULL, 0, 0);
}
which seems to please confd and confd is now returning the proper empty data xml in NETCONF.
So I must ask is this the correct way to use the get_next_object() API? (I have a feeling that returning m + 1 objects is wrong, but not sure why it does not cause any issue in CLI).
The API description of confd_data_reply_next_object_arrays says
To indicate the end of the list we can either pass a NULL pointer for the obj array, or pass an array where the last struct confd_next_object element has the v element set to NULL. The latter is preferable, since we can then combine the final list entries with the end-of-list indication in the reply to a single callback invocation.
It does not say that first object cannot be obj[0].v = NULL to indicate end. I assume it is not correctly described o this is a bug.
I’m not sure how you allocate the arrays (dynamically using malloc or pre-allocated?)? Please, also note that after calling confd_data_reply_next_object_arrays you are still owner of memory (need call free if memory is allocated dynamically).