Get_modifications_iter() changes include default values for a container that shouldn't exist

I have a list that contains several leafs and 2 containers. One mandatory leaf called “type” is an enumeration type with 2 possible values, A and B. The 2 containers in the list have “when” statements that check the value of “type”:

container A-type {
when “…/type = ‘A’”;

}
container B-type {
when “…/type = ‘B’”;

}

I create a list entry with type=A and container A-type values. Commit is successful and from confd_cli I only see the A-type values. But when I get the subscription notification and parse the changes from get_modifications_iter() I also get values for the B-type container. Specifically, I get all the leafs from container B-type that have a default value. This seems like a violation to me… Aren’t the notifications YANG model compliant?

Hi,

The when statement is used to control what is available to the user over a northbound interface such as NETCONF according to https://tools.ietf.org/html/rfc7950#section-7.21.5.
What is then presented to a ConfD subscriber that is notified when the CDB configuration data changes is a different matter.
In your example, the dependecy introduced by the when statement trigger ConfD to provide the value to the subscriber.

I don’t think the RFC distinguishes between the view from a northbound interface and the view from an api, but as I understand it the api isn’t exactly NETCONF compliant. I guess it’s what is written in cdb that matters. Are all the default values loaded in cdb when an entry is created? How can an api user know which container is valid and not just default?

Hi,

The RFC doesn’t cover the internal workings at all of an application, here consisting of ConfD’s Core/CDB and your application, and the APIs that the internal application, here the ConfD CDB API.

If we can understand better why you need a southbound API that is NETCONF compliant it would be easier to help. Are you developing some sort of manager?

Regarding default value, that is expected behaviour. If we construct a yang model out of your “container when” example adding a couple of leafs to it:

leaf type {
  type string;
}
container A-type {
  when "../type = 'A'";
  leaf testA1 {
    type string;
  }
  leaf testA2 {
    type string;
    default "testA2-defval";
  }
}
container B-type {
  when "../type = 'B'";
  leaf testB1 {
    type string;
  }
  leaf testB2 {
    type string;
    default "testG2-defval";
  }
}

Then we add a subscriber that use the cdb_get_modifications_iter() to print the modifications In MOP_VALUE_SET the get_modifications_iter() function returns changes in reverse

Quick demo:

After playing around with the leafs we for example can get something like this in our libconfd trace + subscriber application printouts:

*** Config updated 
TRACE CDB_SUB_ITERATE 6
/root/NodeB/RFHead{1} modified
TRACE CDB_GET_MODIFICATIONS  --> CONFD_OK
  get_modifications_iter:
  type B
  A-type begin
    testA1 deleted
    testA2 testA2-defval
  A-type end
TRACE CDB_SYNC_SUB CDB_DONE_PRIORITY --> CONFD_OK
TRACE CDB_SUBSCRIPTION_EVENT --> 6

In the above trace we can see how we changed the “type” leaf to “B” from “A”. The “when” statement in the container “A-type” got triggered so we first got a “deleted” on leaf “testA1” since it did not have a default value, then we see that leaf “testA2” also was deleted but since it had a default value it got its default value set.

The subscriber application reading from cdb really knows nothing about the schema. The “type” is used to restrict the operator, it will define the set of leafs they can modify. The application will read what’s in the db. The existence of one or more entries in db will restrict the application.
So in your example, the subscriber receiving the modifications could have a handler for testA2 that gets triggered if a change happens. I guess this handler will have to check the value of “type” too.

If whether or not the leaf was set to its default value matters to you, the application does have access to the schema information, see confd_types man page section “USING SCHEMA INFORMATION”.
Your application can get the default value from the confd_cs_node_info struct.