Default Node Handling
The handling of a 'default' node is somewhat complex. There are some standards, CLI parameters, and protocol operation parameters that affect server behavior.
Default Data Node Definition
The YANG language contains a 'default-stmt'. This is called a schema-default. For example, RFC 7950 Section 7.6.4 specifies the behavior for a default leaf node.
Note
The YANG default is the value used if the leaf (or leaf-list) is not present.
The standards are not clear wrt/ whether 'present' means 'provided by a client'.
If the client provides a value in the edit request for the NP-container, then it is not treated as a default or an empty NP-container.
Default Leaf or Leaf-List
Within the netconfd-pro server, a default leaf or leaf-list node is defined to follow the 'With-defaults Capability for NETCONF' (RFC 6243)
The --default-style CLI parameter is used to select the default handling behavior the server will follow.
If not set, then the 'explicit' mode will be used.
If set to 'report-all' then all default nodes are treated as real nodes. If this mode is used then it is as if all retrieval operations use with-defaults='report-all', unless that parameter is actually provided.
Default NP Container
An empty non-presence container has no meaning in NETCONF/YANG so it may be created by the server or not. It is an implementation choice. All clients must be capable of receiving empty NP containers in a response.
A 'Default NP Container' is an NP container that has at least one child node with a schema default defined. This default node can also be nested within additional empty NP containers.
Example: The 'enabled' leaf makes the 'npcon1' container a Default NP Container.
container npcon1 {
leaf name {
type string;
}
leaf enabled {
type boolean;
default true;
}
}
The 'default' property of an NP-container is passed to its parent, same as other properties.
Example: The 'npcon2' container is also a Default NP Container due to the 'timeout' leaf.
container npcon2 {
container npcon-child {
leaf timeout {
type uint8;
units "seconds";
default 10;
}
}
}
The --default-style CLI parameter will affect whether default NP containers are returned in retrieval operations.
If set to 'report-all' then Default NP containers will always be returned.
Otherwise Default NP Containers will only be returned if the with-defaults' parameter is set to 'report-all' or 'report-all-tagged'
Empty NP Container
An Empty NP Container has the following properties:
A configuration NP container
Not a Default NP Container
No configuration child nodes are present in the datastore expect possibly nested empty NP containers.
There are no read-only (config=false) child nodes defined
Note
The --create-empty-npcontainers CLI parameter controls whether empty NP containers are created or not.
The default value 'true' should be used or XPath evaluations may not be done correctly.
This parameter is deprecated and may be removed in the future.
Example: The 'npcon3' container is considered an empty NP Container when it is created or deleted:
container npcon3 {
container npcon-child {
leaf timeout {
type uint8;
units "seconds";
}
}
}
If the ancestor configuration nodes for a read-only data node are not present then that node will not be returned, and no GET2 callbacks will be invoked for the object. If these ancestor nodes are NP containers, then they are normally created by the server.
The server usually creates these empty NP containers when configuration is added to the 'candidate' or 'running' datastore.
This usually applies when the parent of the Empty NP Container is created.
These NP containers are returned to clients in retrieval operations under two conditions:
Client uses the 'with-defaults' parameter set to 'report-all' or 'report-all-tagged'
Server is configured with --default-style='report-all'
Starting in release 23.10-6, the server can be configured so these empty NP containers are not returned to clients at all. The --return-empty-npcontainers parameter should be set to 'false' to prune empty configuration NP containers in responses to clients.
Note
The default behavior is to return empty NP containers for backward-compatibility.
Set --return-empty-npcontainers='false' instead of setting --create-empty-npcontainers to 'false'
Example: <get-config> operation with server using default setting 'true'.
The highlighted parts are empty NP containers.
andy@localhost> get-config source=candidate with-defaults=report-all
RPC Data Reply 4 for session 3 [default]:
rpc-reply {
data {
event-streams {
}
nacm {
enable-nacm true
read-default permit
write-default deny
exec-default permit
enable-external-groups true
groups {
}
}
templates {
}
}
}
Example: <get-config> operation with server using setting 'false'.
The empty NP containers are not returned by the server.
The '/nacm' container is returned because it has default child nodes, but the '/nacm/groups' container is not returned.
andy@localhost> get-config source=candidate with-defaults=report-all
RPC Data Reply 3 for session 3 [default]:
rpc-reply {
data {
nacm {
enable-nacm true
read-default permit
write-default deny
exec-default permit
enable-external-groups true
}
}
}
For backwards compatibility for some deployments, there are two CLI parameters to control creation of these data nodes within the configuration.
The --create-empty-npcontainers CLI parameter can be set to 'false' to disable creation of Empty NP Containers in every case. This parameter is deprecated and should not be used.
The --create-empty-npcontainers-ro CLI parameter can be set to 'true' to disable creation of Empty NP Containers in every case except if the NP container has read-only child nodes. This parameter is deprecated and should not be used.
Refer to the Empty NP Container Example section for more details.
Mandatory NP Container
A mandatory NP Container has the following properties:
A configuration NP container
Contains a mandatory child node:
mandatory leaf or container
leaf or leaf-list with min-elements > 0
NP container with mandatory node(s)
Example: The 'npcon4' container is considered a mandatory NP Container when it is created or deleted:
container npcon4 {
container npcon-child {
leaf timeout {
mandatory true;
type uint8;
units "seconds";
}
}
}
Deleting an NP Container
A non-presence container has no semantics in YANG, and the YANG constraints of its child nodes often apply even if the NP-container is deleted.
Deleting a Default NP-container
Deleting an NP container that has default nodes does not usually delete the container:
All child nodes with defaults will be deleted and replaced with default values.
All child nodes without defaults will be deleted
The deleted container will only be returned of 'with-defaults' are requested by the client.
Deleting an Empty NP-container
Deleting an NP container that has no child nodes at all may delete the container:
if --create-empty-npcontainers='false'
The NP container is completely deleted and no empty container will remain after the delete operation.
if --create-empty-npcontainers='true'
If the NP-container is a child node within an optional YANG choice, then the NP container is completely deleted and no empty container will remain after the delete operation.
If the NP-container is not a child node within an optional YANG choice, then the NP container converted to an empty NP container
Deleting a Mandatory NP-container
Deleting any mandatory data node is allowed if it is no longer considered accessible in the data tree, according to RFC 7950.
In this example:
The 'list1' list is not mandatory and entries can be created or deleted
The 't201' top-level NP-container is not mandatory because its only child is not mandatory'
Normally, the mandatory 'leaf1' leaf would make the 'mand1' container mandatory. This would be true if the 'case1' case contained any sibling nodes that existed in the data tree.
The 'mand1' container is optional here, and does not have to be created, and can be deleted from the 'list1' parent.
The default 'leaf3' leaf does not exist if no nodes are selected from the 'choice1' choice.
The read-only 'leaf4' leaf does not exist if no nodes are selected from the 'choice1' choice.
container t201 {
list list1 {
key name;
leaf name { type string; }
choice choice1 {
case case1 {
container mand1 {
leaf leaf1 {
type string;
mandatory true;
}
leaf leaf2 {
type string;
}
leaf leaf3 {
type string;
default "test1";
}
leaf leaf4 {
config false;
type string;
}
}
}
}
}
}