Discrepancy of confd return data in case of no elements in datastore

In general, when a particular namespace does not have any data, get request returns reply of the form

# $CONFD_DIR/bin/netconf-console --host 127.0.0.1 --port 22 -u foo -p foo /tmp/rmon.xml 2>/dev/null

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="106">
  <data/>
</rpc-reply>

However in some namespaces confd is not returning any data at all.

# $CONFD_DIR/bin/netconf-console --host 127.0.0.1 --port 22 -u foo -p foo /tmp/lldp.xml 2>/dev/null
#

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

  • Working:
<INFO> 28-Sep-2020::08:51:48.878 CTX-1002 confd[4620]: netconf id=78 new tcp session for user "foo" from 127.0.0.1
<INFO> 28-Sep-2020::08:51:48.904 CTX-1002 confd[4620]: netconf id=78 got rpc: {urn:ietf:params:xml:ns:netconf:base:1.0}get attrs: message-id="106"
<INFO> 28-Sep-2020::08:51:48.905 CTX-1002 confd[4620]: netconf id=78 get attrs: message-id="106"
<INFO> 28-Sep-2020::08:51:48.908 CTX-1002 confd[4620]: netconf id=78 sending rpc-reply, attrs: message-id="106"
<INFO> 28-Sep-2020::08:51:48.914 CTX-1002 confd[4620]: netconf id=78 close-session attrs: message-id="2"
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="106">
  <data/>
</rpc-reply>
<INFO> 28-Sep-2020::08:51:48.917 CTX-1002 confd[4620]: netconf id=78 sending rpc-reply, attrs: message-id="2"

  • Not working
<INFO> 28-Sep-2020::08:57:49.510 CTX-1002 confd[4620]: netconf id=80 new tcp session for user "foo" from 127.0.0.1
<INFO> 28-Sep-2020::08:57:49.542 CTX-1002 confd[4620]: netconf id=80 got rpc: {urn:ietf:params:xml:ns:netconf:base:1.0}get attrs: message-id="106"
<INFO> 28-Sep-2020::08:57:49.542 CTX-1002 confd[4620]: netconf id=80 get attrs: message-id="106"
<INFO> 28-Sep-2020::08:57:49.544 CTX-1002 confd[4620]: netconf id=80 sending rpc-reply, attrs: message-id="106"

Yes, I also assume get attrs: in logs is not relted to get_attrs callback, but to attributes of NETCONF get message.

Do you also see some messages in the devel.log or confd.log.

  • Working case log
<DEBUG> 30-Sep-2020::09:43:36.164 CTX-1002 confd[2564]: confd progress db=undefined usid=31 thandle=315: netconf: netconf handling...
<DEBUG> 30-Sep-2020::09:43:36.166 CTX-1002 confd[2564]: devel-c new_usess db request daemon id: 4
<DEBUG> 30-Sep-2020::09:43:36.166 CTX-1002 confd[2564]: devel-c db reply daemon id: 4
<DEBUG> 30-Sep-2020::09:43:36.166 CTX-1002 confd[2564]: devel-c new_trans request daemon id: 4 thandle: 315
<DEBUG> 30-Sep-2020::09:43:36.168 CTX-1002 confd[2564]: devel-c new_trans succeeded daemon id: 4 session id: 315 worker id: 6
<DEBUG> 30-Sep-2020::09:43:36.168 CTX-1002 confd[2564]: devel-c get_next request for callpoint showRmonCLIView path /show-rmon:show-rmon/rmon/ethernet-stats
<DEBUG> 30-Sep-2020::09:43:36.172 CTX-1002 confd[2564]: devel-c get_next succeeded for callpoint showRmonCLIView path /show-rmon:show-rmon/rmon/ethernet-stats
<DEBUG> 30-Sep-2020::09:43:36.172 CTX-1002 confd[2564]: devel-c new_usess db request daemon id: 3
<DEBUG> 30-Sep-2020::09:43:36.173 CTX-1002 confd[2564]: devel-c db reply daemon id: 3
<DEBUG> 30-Sep-2020::09:43:36.173 CTX-1002 confd[2564]: devel-c new_trans request daemon id: 3 thandle: 315
<DEBUG> 30-Sep-2020::09:43:36.173 CTX-1002 confd[2564]: devel-c new_trans succeeded daemon id: 3 session id: 315 worker id: 4
<DEBUG> 30-Sep-2020::09:43:36.174 CTX-1002 confd[2564]: devel-c get_next request for callpoint alarm_config_table path /show-rmon:show-rmon/rmon/alarms
<DEBUG> 30-Sep-2020::09:43:36.174 CTX-1002 confd[2564]: devel-c get_next succeeded for callpoint alarm_config_table path /show-rmon:show-rmon/rmon/alarms
<DEBUG> 30-Sep-2020::09:43:36.175 CTX-1002 confd[2564]: confd progress db=undefined usid=31 thandle=315: netconf: netconf handling ok
<DEBUG> 30-Sep-2020::09:43:36.175 CTX-1002 confd[2564]: devel-c close_trans request daemon id: 3 session id: 315
<DEBUG> 30-Sep-2020::09:43:36.176 CTX-1002 confd[2564]: devel-c close_trans succeeded daemon id: 3 session id: 315
<DEBUG> 30-Sep-2020::09:43:36.176 CTX-1002 confd[2564]: devel-c close_trans request daemon id: 4 session id: 315
<DEBUG> 30-Sep-2020::09:43:36.178 CTX-1002 confd[2564]: devel-c close_trans succeeded daemon id: 4 session id: 315
<DEBUG> 30-Sep-2020::09:43:36.179 CTX-1002 confd[2564]: devel-c close_usess db request daemon id: 4
<DEBUG> 30-Sep-2020::09:43:36.180 CTX-1002 confd[2564]: devel-c db reply daemon id: 4
<DEBUG> 30-Sep-2020::09:43:36.180 CTX-1002 confd[2564]: devel-c close_usess db request daemon id: 3
<DEBUG> 30-Sep-2020::09:43:36.180 CTX-1002 confd[2564]: devel-c db reply daemon id: 3
  • Not working case log
<DEBUG> 30-Sep-2020::09:43:54.094 CTX-1002 confd[2564]: confd progress db=undefined usid=32 thandle=316: netconf: netconf handling...
<DEBUG> 30-Sep-2020::09:43:54.096 CTX-1002 confd[2564]: devel-c new_usess db request daemon id: 4
<DEBUG> 30-Sep-2020::09:43:54.097 CTX-1002 confd[2564]: devel-c db reply daemon id: 4
<DEBUG> 30-Sep-2020::09:43:54.097 CTX-1002 confd[2564]: devel-c new_trans request daemon id: 4 thandle: 316
<DEBUG> 30-Sep-2020::09:43:54.100 CTX-1002 confd[2564]: devel-c new_trans succeeded daemon id: 4 session id: 316 worker id: 6
<DEBUG> 30-Sep-2020::09:43:54.100 CTX-1002 confd[2564]: devel-c get_next_object request for callpoint lldp_neigh_brief path /show-lldp:show-lldp/lldp/neighbour/brief
<DEBUG> 30-Sep-2020::09:43:54.137 CTX-1002 confd[2564]: devel-c get_next_object succeeded for callpoint lldp_neigh_brief path /show-lldp:show-lldp/lldp/neighbour/brief
<DEBUG> 30-Sep-2020::09:43:54.138 CTX-1002 confd[2564]: devel-c close_trans request daemon id: 4 session id: 316
<DEBUG> 30-Sep-2020::09:43:54.140 CTX-1002 confd[2564]: devel-c close_trans succeeded daemon id: 4 session id: 316
<DEBUG> 30-Sep-2020::09:43:54.148 CTX-1002 confd[2564]: devel-c close_usess db request daemon id: 4
<DEBUG> 30-Sep-2020::09:43:54.150 CTX-1002 confd[2564]: devel-c db reply daemon id: 4

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

**> sess:35 new session                                                                                                                                                                                            
                                                                                                                                                                                                                   
30-Sep-2020::09:50:06.243 **< sess:35 write:                                                                                                                                                                       
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
   ...
  <session-id>35</session-id>                                                                                                    
</hello>
30-Sep-2020::09:50:06.305 **> sess:35 read:                                                                            
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">                                                                    
  <capabilities>                                                                                                                          
    <capability>urn:ietf:params:netconf:base:1.0</capability>                                                                        
  </capabilities>                                                                                            
</hello>                                                                                                                     
                                                                                                             
]]>]]>                                                                                                         
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="106">                                                               
  <get>                                                                                                                          
    <filter type="subtree">                                                                                                      
      <show-lldp xmlns="http://www.cdot.in/ns/show-lldp"/>                                                       
    </filter>                                                                                                        
  </get>                                                                                                           
</rpc>                                                                                                           
                                                                                                                                     
]]>]]>                                                                                                                               
<rpc message-id="2" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">                                                     
  <close-session/>                                                                                                                         
</rpc>                                                                                                                         
**> sess:35 session aborted                                                                                                                  
                               

In working case I do not get an aborted msg. May be these are all part of symptoms not actual causes.

Any ideas on where to look next?

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).

Regards,

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).