Problem: How can I differentiate a MERGE operation that creates a leaf from a MERGE that edits an existing leaf?


When creating a container that has default leaf values you are not able to differentiate a MERGE when creating the container for the first time versus a MERGE for editing a non default leaf.


You need an API to differentiate a creation of a new default node (that is set to default value or set to non default) versus merge on the same node (back to default or another non default value).


Operation on default node is always MERGE regardless of the original operation.


If original operation is CREATE:

curval == default value

newval == new non default value


If original operation is MERGE:

curval == non default value

newval == new non default value


If original operation is DELETE:

curval == non default value

newval == default value


Tip: YANG non-presence (NP) containers do not need to exist like other nodes. You should write your code as if they always exist. Use a presence container instead if you want to treat a create on an NP container differently. Use --create-empty-npcontainers=false to force users to create NP containers.


Solution


The val_set_by_default() API will let you know whether the node has default or non-default value.


You can use the API  val_set_by_default(newval) to test if the NP container is created by default or by user in the callback for the container:


if (newval) {
      test = val_set_by_default(newval);
   }


If test == TRUE then the container is default.

If false then the user is creating the container


You can also add to your code:

If (curval == NULL) then obvious it is a create

if (curval && val_set_by_default(curval)) and newval is not set by default, then the operation is a create.

If neither newval or curval is set by default then the operation is a merge