Populate leaf-list?

I think I’m misusing cdb_set_object, I’m trying to populate a leaf-list of ip-addresses.

container ip {
            leaf-list servers {
                type ietf-inet:ip-address;
                config false;
                tailf:cdb-oper;
            }
}
cdb_start_session(sock, CDB_OPERATIONAL);
confd_value_t val[1];
inet_aton(p, &ip_address);
CONFD_SET_IPV4(&val[0], ip_address);
cdb_create(ci.cdb, "/ip/servers");  <--- CONFD_OK
cdb_set_object(sock, val, 1, "/ip/servers"); <--- fails with errno 8 "Not a list entry or container"

I’ve read up a bit about using set_values and SET_TAG_XMLBEGIN/END, so I’m trying that instead.

I’m getting a different error now:

module test {
    container ip {
            leaf-list servers {
                type ietf-inet:ip-address;
                config false;
                tailf:cdb-oper;
            }
    }
}

cdb_start_session(sock, CDB_OPERATIONAL);
cdb_set_namespace(sock, test__ns);
i = 0;
CONFD_SET_TAG_XMLBEGIN(&tval[i], test_servers, test__ns); i++;
ip_address.s_addr = inet_addr(p);
CONFD_SET_TAG_IPV4(&tval[i], 0, ip_address); i++;
CONFD_SET_TAG_XMLEND(&tval[i], test_servers, test__ns); i++;
cdb_set_values(ci.cdb, tval, i, "/ip");
cdb_end_session(sock);

Fails with errno 5.

DEBUG item has a bad/wrong type - /ip/servers: expected type 'ip-address', got unknown.

I have verified that the in_addr object, and the tval entry contains a correctly formatted IPv4 address.

CONFD_SET_TAG_IPV4(&tval[i], 0, ip_address); 
log("Inserted: %s", inet_ntoa(CONFD_GET_IPV4(CONFD_GET_TAG_VALUE(&tval[i]))));

Outputs “Inserted: 192.168.1.1” as expected.

Try something like:

confd_value_t ipval;
i = 0;
ip_address.s_addr = inet_addr(p);
CONFD_SET_IPV4(&ipval, ip_address);
CONFD_SET_TAG_LIST(&tval[i], test_servers, &ipval, 1); i++;
cdb_set_values(ci.cdb, tval, i, "/ip");

I didn’t get an error, but it also only populated 1 leaf even though I’ve since put it inside a loop. Is that last param the index?

To clarify, the 1 leaf it populated was from the last iteration of the loop.

i=0;
while (iterating through a list of ips) {
    ip_address.s_addr = inet_addr(p);
    CONFD_SET_IPV4(&ipval, ip_address);
    CONFD_SET_TAG_LIST(&tval[i], test_servers, &ipval, 1); i++;
}
cdb_set_values(ci.cdb, tval, i, "/ip");

The values in the leaf-list is represented by an array of values. So you first create that array (was an array of 1 in my previous example) and then add the array to the leaf-list tag value. Example based on your use case and the confd_lib_types(3) man page under “C_LIST”:

i=0; j=0;
const int num_ips = get number of ips in the list;
confd_value_t ipval[num_ips];
while(iterating through a list of ips) {
  ip_address.s_addr = inet_addr(p);
  CONFD_SET_IPV4(&ipval[j], ip_address);
  j++;
}
CONFD_SET_TAG_LIST(&v[i], test_servers, &ipval[0], num_ips); i++;
cdb_set_values(ci.cdb, tval, i, "/ip");

That works, but the IPs get inserted in reverse order (ie my list goes 192.168.1.1, 192.168.1.2, 192.168.1.3, but when it’s put in the DB it’s listed as .3, .2, .1). Is there a quick way to reverse the array?

How do you check that the IP addresses are listed as “.3, .2, .1” “in the DB”?

cli prints them out

Sorry, it’s not doing .3, .2, .1, it’s ordering them sorted? Do I need to add something to have it not sort them, but keep the order they were inserted?

confd_cli output:
servers [ 192.168.238.10 192.168.238.14 192.168.238.15 2001:192:168:238::10 2001:192:168:238::14 ]

here’s the order they were inserted:

log snippet
Server 2001:0192:0168:0238:0000:0000:0000:0014 
Server 2001:0192:0168:0238:0000:0000:0000:0010 
Server 192.168.238.14 
Server 192.168.238.10 
Server 192.168.238.15 
Inserted 5 Servers

Oh, I found the info on leaf-list ordering. I need to modify the list to specify “ordered-by” user.