7.2. The "submodule" Statement
While the primary unit in YANG is a module, a YANG module can itself be constructed out of several submodules. Submodules allow a module designer to split a complex model into several pieces where all the submodules contribute to a single namespace, which is defined by the module that includes the submodules. The "submodule" statement defines the submodule's name, and it groups all statements that belong to the submodule together. The "submodule" statement's argument is the name of the submodule, followed by a block of substatements that holds detailed submodule information. The submodule name is an identifier (see Section 6.2). Names of submodules published in RFC streams [RFC4844] MUST be assigned by IANA; see Section 14 in [RFC6020]. Private submodule names are assigned by the organization owning the submodule without a central registry. See Section 5.1 for recommendations on how to name submodules. A submodule typically has the following layout: submodule <module-name> { <yang-version statement> // module identification <belongs-to statement> // linkage statements <import statements> // meta-information <organization statement> <contact statement> <description statement> <reference statement> // revision history <revision statements> // module definitions <other statements> }
7.2.1. The submodule's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | anydata | 7.10 | 0..n | | anyxml | 7.11 | 0..n | | augment | 7.17 | 0..n | | belongs-to | 7.2.2 | 1 | | choice | 7.9 | 0..n | | contact | 7.1.8 | 0..1 | | container | 7.5 | 0..n | | description | 7.21.3 | 0..1 | | deviation | 7.20.3 | 0..n | | extension | 7.19 | 0..n | | feature | 7.20.1 | 0..n | | grouping | 7.12 | 0..n | | identity | 7.18 | 0..n | | import | 7.1.5 | 0..n | | include | 7.1.6 | 0..n | | leaf | 7.6 | 0..n | | leaf-list | 7.7 | 0..n | | list | 7.8 | 0..n | | notification | 7.16 | 0..n | | organization | 7.1.7 | 0..1 | | reference | 7.21.4 | 0..1 | | revision | 7.1.9 | 0..n | | rpc | 7.14 | 0..n | | typedef | 7.3 | 0..n | | uses | 7.13 | 0..n | | yang-version | 7.1.2 | 1 | +--------------+---------+-------------+7.2.2. The "belongs-to" Statement
The "belongs-to" statement specifies the module to which the submodule belongs. The argument is an identifier that is the name of the module. A submodule MUST only be included by either the module to which it belongs or another submodule that belongs to that module. The mandatory "prefix" substatement assigns a prefix for the module to which the submodule belongs. All definitions in the module that the submodule belongs to and all its submodules can be accessed by using the prefix.
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | prefix | 7.1.4 | 1 | +--------------+---------+-------------+ The belongs-to's Substatement7.2.3. Usage Example
submodule example-types { yang-version 1.1; belongs-to "example-system" { prefix "sys"; } import ietf-yang-types { prefix "yang"; } organization "Example Inc."; contact "Joe L. User Example Inc. 42 Anywhere Drive Nowhere, CA 95134 USA Phone: +1 800 555 0100 Email: joe@example.com"; description "This submodule defines common Example types."; revision "2007-06-09" { description "Initial revision."; } // definitions follow... }
7.3. The "typedef" Statement
The "typedef" statement defines a new type that may be used locally in the module or submodule, and by other modules that import from it, according to the rules in Section 5.5. The new type is called the "derived type", and the type from which it was derived is called the "base type". All derived types can be traced back to a YANG built-in type. The "typedef" statement's argument is an identifier that is the name of the type to be defined and MUST be followed by a block of substatements that holds detailed typedef information. The name of the type MUST NOT be one of the YANG built-in types. If the typedef is defined at the top level of a YANG module or submodule, the name of the type to be defined MUST be unique within the module.7.3.1. The typedef's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | default | 7.3.4 | 0..1 | | description | 7.21.3 | 0..1 | | reference | 7.21.4 | 0..1 | | status | 7.21.2 | 0..1 | | type | 7.3.2 | 1 | | units | 7.3.3 | 0..1 | +--------------+---------+-------------+7.3.2. The typedef's "type" Statement
The "type" statement, which MUST be present, defines the base type from which this type is derived. See Section 7.4 for details.7.3.3. The "units" Statement
The "units" statement, which is optional, takes as an argument a string that contains a textual definition of the units associated with the type.
7.3.4. The typedef's "default" Statement
The "default" statement takes as an argument a string that contains a default value for the new type. The value of the "default" statement MUST be valid according to the type specified in the "type" statement. If the base type has a default value and the new derived type does not specify a new default value, the base type's default value is also the default value of the new derived type. If the type's default value is not valid according to the new restrictions specified in a derived type or leaf definition, the derived type or leaf definition MUST specify a new default value compatible with the restrictions.7.3.5. Usage Example
typedef listen-ipv4-address { type inet:ipv4-address; default "0.0.0.0"; }7.4. The "type" Statement
The "type" statement takes as an argument a string that is the name of a YANG built-in type (see Section 9) or a derived type (see Section 7.3), followed by an optional block of substatements that is used to put further restrictions on the type. The restrictions that can be applied depend on the type being restricted. The restriction statements for all built-in types are described in the subsections of Section 9.
7.4.1. The type's Substatements
+------------------+---------+-------------+ | substatement | section | cardinality | +------------------+---------+-------------+ | base | 7.18.2 | 0..n | | bit | 9.7.4 | 0..n | | enum | 9.6.4 | 0..n | | fraction-digits | 9.3.4 | 0..1 | | length | 9.4.4 | 0..1 | | path | 9.9.2 | 0..1 | | pattern | 9.4.5 | 0..n | | range | 9.2.4 | 0..1 | | require-instance | 9.9.3 | 0..1 | | type | 7.4 | 0..n | +------------------+---------+-------------+7.5. The "container" Statement
The "container" statement is used to define an interior data node in the schema tree. It takes one argument, which is an identifier, followed by a block of substatements that holds detailed container information. A container node does not have a value, but it has a list of child nodes in the data tree. The child nodes are defined in the container's substatements.7.5.1. Containers with Presence
YANG supports two styles of containers, those that exist only for organizing the hierarchy of data nodes and those whose presence in the data tree has an explicit meaning. In the first style, the container has no meaning of its own, existing only to contain child nodes. In particular, the presence of the container node with no child nodes is semantically equivalent to the absence of the container node. YANG calls this style a "non-presence container". This is the default style. For example, the set of scrambling options for Synchronous Optical Network (SONET) interfaces may be placed inside a "scrambling" container to enhance the organization of the configuration hierarchy and to keep these nodes together. The "scrambling" node itself has no meaning, so removing the node when it becomes empty relieves the user from performing this task.
In the second style, the presence of the container itself carries some meaning, representing a single bit of data. For configuration data, the container acts as both a configuration knob and a means of organizing related configuration nodes. These containers are explicitly created and deleted. YANG calls this style a "presence container", and it is indicated using the "presence" statement, which takes as its argument a text string indicating what the presence of the node means. For example, an "ssh" container may turn on the ability to log into the server using Secure SHell (SSH) but can also contain any SSH-related configuration knobs, such as connection rates or retry limits. The "presence" statement (see Section 7.5.5) is used to give semantics to the existence of the container in the data tree.7.5.2. The container's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | action | 7.15 | 0..n | | anydata | 7.10 | 0..n | | anyxml | 7.11 | 0..n | | choice | 7.9 | 0..n | | config | 7.21.1 | 0..1 | | container | 7.5 | 0..n | | description | 7.21.3 | 0..1 | | grouping | 7.12 | 0..n | | if-feature | 7.20.2 | 0..n | | leaf | 7.6 | 0..n | | leaf-list | 7.7 | 0..n | | list | 7.8 | 0..n | | must | 7.5.3 | 0..n | | notification | 7.16 | 0..n | | presence | 7.5.5 | 0..1 | | reference | 7.21.4 | 0..1 | | status | 7.21.2 | 0..1 | | typedef | 7.3 | 0..n | | uses | 7.13 | 0..n | | when | 7.21.5 | 0..1 | +--------------+---------+-------------+
7.5.3. The "must" Statement
The "must" statement, which is optional, takes as an argument a string that contains an XPath expression (see Section 6.4). It is used to formally declare a constraint on valid data. The constraint is enforced according to the rules in Section 8. When a datastore is validated, all "must" constraints are conceptually evaluated once for each node in the accessible tree (see Section 6.4.1). All such constraints MUST evaluate to "true" for the data to be valid. The XPath expression is conceptually evaluated in the following context, in addition to the definition in Section 6.4.1: o If the "must" statement is a substatement of a "notification" statement, the context node is the node representing the notification in the accessible tree. o If the "must" statement is a substatement of an "input" statement, the context node is the node representing the operation in the accessible tree. o If the "must" statement is a substatement of an "output" statement, the context node is the node representing the operation in the accessible tree. o Otherwise, the context node is the node in the accessible tree for which the "must" statement is defined. The result of the XPath expression is converted to a boolean value using the standard XPath rules. Note that since all leaf values in the data tree are conceptually stored in their canonical form (see Section 9.1), any XPath comparisons are done on the canonical value. Also note that the XPath expression is conceptually evaluated. This means that an implementation does not have to use an XPath evaluator in the server. How the evaluation is done in practice is an implementation decision.
7.5.4. The must's Substatements
+---------------+---------+-------------+ | substatement | section | cardinality | +---------------+---------+-------------+ | description | 7.21.3 | 0..1 | | error-app-tag | 7.5.4.2 | 0..1 | | error-message | 7.5.4.1 | 0..1 | | reference | 7.21.4 | 0..1 | +---------------+---------+-------------+7.5.4.1. The "error-message" Statement
The "error-message" statement, which is optional, takes a string as an argument. If the constraint evaluates to "false", the string is passed as <error-message> in the <rpc-error> in NETCONF.7.5.4.2. The "error-app-tag" Statement
The "error-app-tag" statement, which is optional, takes a string as an argument. If the constraint evaluates to "false", the string is passed as <error-app-tag> in the <rpc-error> in NETCONF.7.5.4.3. Usage Example of must and error-message
container interface { leaf ifType { type enumeration { enum ethernet; enum atm; } } leaf ifMTU { type uint32; } must 'ifType != "ethernet" or ifMTU = 1500' { error-message "An Ethernet MTU must be 1500"; } must 'ifType != "atm" or' + ' (ifMTU <= 17966 and ifMTU >= 64)' { error-message "An ATM MTU must be 64 .. 17966"; } }
7.5.5. The "presence" Statement
The "presence" statement assigns a meaning to the presence of a container in the data tree. It takes as an argument a string that contains a textual description of what the node's presence means. If a container has the "presence" statement, the container's existence in the data tree carries some meaning. Otherwise, the container is used to give some structure to the data, and it carries no meaning by itself. See Section 7.5.1 for additional information.7.5.6. The container's Child Node Statements
Within a container, the "container", "leaf", "list", "leaf-list", "uses", "choice", "anydata", and "anyxml" statements can be used to define child nodes to the container.7.5.7. XML Encoding Rules
A container node is encoded as an XML element. The element's local name is the container's identifier, and its namespace is the module's XML namespace (see Section 7.1.3). The container's child nodes are encoded as subelements to the container element. If the container defines RPC or action input or output parameters, these subelements are encoded in the same order as they are defined within the "container" statement. Otherwise, the subelements are encoded in any order. Any whitespace between the subelements to the container is insignificant, i.e., an implementation MAY insert whitespace characters between subelements. If a non-presence container does not have any child nodes, the container may or may not be present in the XML encoding.
7.5.8. NETCONF <edit-config> Operations
Containers can be created, deleted, replaced, and modified through <edit-config> by using the "operation" attribute (see Section 7.2 in [RFC6241]) in the container's XML element. If a container does not have a "presence" statement and the last child node is deleted, the NETCONF server MAY delete the container. When a NETCONF server processes an <edit-config> request, the elements of procedure for the container node are as follows: o If the operation is "merge" or "replace", the node is created if it does not exist. o If the operation is "create", the node is created if it does not exist. If the node already exists, a "data-exists" error is returned. o If the operation is "delete", the node is deleted if it exists. If the node does not exist, a "data-missing" error is returned.7.5.9. Usage Example
Given the following container definition: container system { description "Contains various system parameters."; container services { description "Configure externally available services."; container "ssh" { presence "Enables SSH"; description "SSH service-specific configuration."; // more leafs, containers, and stuff here... } } }
A corresponding XML instance example: <system> <services> <ssh/> </services> </system> Since the <ssh> element is present, SSH is enabled. To delete a container with an <edit-config>: <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config> <target> <running/> </target> <config> <system xmlns="urn:example:config"> <services> <ssh nc:operation="delete"/> </services> </system> </config> </edit-config> </rpc>7.6. The "leaf" Statement
The "leaf" statement is used to define a leaf node in the schema tree. It takes one argument, which is an identifier, followed by a block of substatements that holds detailed leaf information. A leaf node has a value, but no child nodes, in the data tree. Conceptually, the value in the data tree is always in the canonical form (see Section 9.1). A leaf node exists in zero or one instance in the data tree. The "leaf" statement is used to define a scalar variable of a particular built-in or derived type.
7.6.1. The leaf's Default Value
The default value of a leaf is the value that the server uses if the leaf does not exist in the data tree. The usage of the default value depends on the leaf's closest ancestor node in the schema tree that is not a non-presence container (see Section 7.5.1): o If no such ancestor exists in the schema tree, the default value MUST be used. o Otherwise, if this ancestor is a case node, the default value MUST be used if any node from the case exists in the data tree or the case node is the choice's default case, and if no nodes from any other case exist in the data tree. o Otherwise, the default value MUST be used if the ancestor node exists in the data tree. In these cases, the default value is said to be in use. Note that if the leaf or any of its ancestors has a "when" condition or "if-feature" expression that evaluates to "false", then the default value is not in use. When the default value is in use, the server MUST operationally behave as if the leaf was present in the data tree with the default value as its value. If a leaf has a "default" statement, the leaf's default value is the value of the "default" statement. Otherwise, if the leaf's type has a default value and the leaf is not mandatory, then the leaf's default value is the type's default value. In all other cases, the leaf does not have a default value.
7.6.2. The leaf's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | config | 7.21.1 | 0..1 | | default | 7.6.4 | 0..1 | | description | 7.21.3 | 0..1 | | if-feature | 7.20.2 | 0..n | | mandatory | 7.6.5 | 0..1 | | must | 7.5.3 | 0..n | | reference | 7.21.4 | 0..1 | | status | 7.21.2 | 0..1 | | type | 7.6.3 | 1 | | units | 7.3.3 | 0..1 | | when | 7.21.5 | 0..1 | +--------------+---------+-------------+7.6.3. The leaf's "type" Statement
The "type" statement, which MUST be present, takes as an argument the name of an existing built-in or derived type. The optional substatements specify restrictions on this type. See Section 7.4 for details.7.6.4. The leaf's "default" Statement
The "default" statement, which is optional, takes as an argument a string that contains a default value for the leaf. The value of the "default" statement MUST be valid according to the type specified in the leaf's "type" statement. The "default" statement MUST NOT be present on nodes where "mandatory" is "true". The definition of the default value MUST NOT be marked with an "if-feature" statement. For example, the following is illegal: leaf color { type enumeration { enum blue { if-feature blue; } ... } default blue; // illegal - enum value is conditional }
7.6.5. The leaf's "mandatory" Statement
The "mandatory" statement, which is optional, takes as an argument the string "true" or "false" and puts a constraint on valid data. If not specified, the default is "false". If "mandatory" is "true", the behavior of the constraint depends on the type of the leaf's closest ancestor node in the schema tree that is not a non-presence container (see Section 7.5.1): o If no such ancestor exists in the schema tree, the leaf MUST exist. o Otherwise, if this ancestor is a case node, the leaf MUST exist if any node from the case exists in the data tree. o Otherwise, the leaf MUST exist if the ancestor node exists in the data tree. This constraint is enforced according to the rules in Section 8.7.6.6. XML Encoding Rules
A leaf node is encoded as an XML element. The element's local name is the leaf's identifier, and its namespace is the module's XML namespace (see Section 7.1.3). The value of the leaf node is encoded to XML according to the type and is sent as character data in the element. See Section 7.6.8 for an example.7.6.7. NETCONF <edit-config> Operations
When a NETCONF server processes an <edit-config> request, the elements of procedure for the leaf node are as follows: o If the operation is "merge" or "replace", the node is created if it does not exist, and its value is set to the value found in the XML RPC data. o If the operation is "create", the node is created if it does not exist. If the node already exists, a "data-exists" error is returned. o If the operation is "delete", the node is deleted if it exists. If the node does not exist, a "data-missing" error is returned.
7.6.8. Usage Example
Given the following "leaf" statement, placed in the previously defined "ssh" container (see Section 7.5.9): leaf port { type inet:port-number; default 22; description "The port to which the SSH server listens."; } A corresponding XML instance example: <port>2022</port> To set the value of a leaf with an <edit-config>: <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config> <target> <running/> </target> <config> <system xmlns="urn:example:config"> <services> <ssh> <port>2022</port> </ssh> </services> </system> </config> </edit-config> </rpc>7.7. The "leaf-list" Statement
Where the "leaf" statement is used to define a simple scalar variable of a particular type, the "leaf-list" statement is used to define an array of a particular type. The "leaf-list" statement takes one argument, which is an identifier, followed by a block of substatements that holds detailed leaf-list information. In configuration data, the values in a leaf-list MUST be unique.
The definitions of the default values MUST NOT be marked with an "if-feature" statement. Conceptually, the values in the data tree MUST be in the canonical form (see Section 9.1).7.7.1. Ordering
YANG supports two styles for ordering the entries within lists and leaf-lists. In many lists, the order of list entries does not impact the implementation of the list's configuration, and the server is free to sort the list entries in any reasonable order. The "description" string for the list may suggest an order to the server implementor. YANG calls this style of list "system ordered"; such lists are indicated with the statement "ordered-by system". For example, a list of valid users would typically be sorted alphabetically, since the order in which the users appeared in the configuration would not impact the creation of those users' accounts. In the other style of lists, the order of list entries matters for the implementation of the list's configuration and the user is responsible for ordering the entries, while the server maintains that order. YANG calls this style of list "user ordered"; such lists are indicated with the statement "ordered-by user". For example, the order in which packet filter entries are applied to incoming traffic may affect how that traffic is filtered. The user would need to decide if the filter entry that discards all TCP traffic should be applied before or after the filter entry that allows all traffic from trusted interfaces. The choice of order would be crucial. YANG provides a rich set of facilities within NETCONF's <edit-config> operation that allows the order of list entries in user-ordered lists to be controlled. List entries may be inserted or rearranged, positioned as the first or last entry in the list, or positioned before or after another specific entry. The "ordered-by" statement is covered in Section 7.7.7.
7.7.2. The leaf-list's Default Values
The default values of a leaf-list are the values that the server uses if the leaf-list does not exist in the data tree. The usage of the default values depends on the leaf-list's closest ancestor node in the schema tree that is not a non-presence container (see Section 7.5.1): o If no such ancestor exists in the schema tree, the default values MUST be used. o Otherwise, if this ancestor is a case node, the default values MUST be used if any node from the case exists in the data tree or the case node is the choice's default case, and if no nodes from any other case exist in the data tree. o Otherwise, the default values MUST be used if the ancestor node exists in the data tree. In these cases, the default values are said to be in use. Note that if the leaf-list or any of its ancestors has a "when" condition or "if-feature" expression that evaluates to "false", then the default values are not in use. When the default values are in use, the server MUST operationally behave as if the leaf-list was present in the data tree with the default values as its values. If a leaf-list has one or more "default" statements, the leaf-list's default values are the values of the "default" statements, and if the leaf-list is user ordered, the default values are used in the order of the "default" statements. Otherwise, if the leaf-list's type has a default value and the leaf-list does not have a "min-elements" statement with a value greater than or equal to one, then the leaf-list's default value is one instance of the type's default value. In all other cases, the leaf-list does not have any default values.
7.7.3. The leaf-list's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | config | 7.21.1 | 0..1 | | default | 7.7.4 | 0..n | | description | 7.21.3 | 0..1 | | if-feature | 7.20.2 | 0..n | | max-elements | 7.7.6 | 0..1 | | min-elements | 7.7.5 | 0..1 | | must | 7.5.3 | 0..n | | ordered-by | 7.7.7 | 0..1 | | reference | 7.21.4 | 0..1 | | status | 7.21.2 | 0..1 | | type | 7.4 | 1 | | units | 7.3.3 | 0..1 | | when | 7.21.5 | 0..1 | +--------------+---------+-------------+7.7.4. The leaf-list's "default" Statement
The "default" statement, which is optional, takes as an argument a string that contains a default value for the leaf-list. The value of the "default" statement MUST be valid according to the type specified in the leaf-list's "type" statement. The "default" statement MUST NOT be present on nodes where "min-elements" has a value greater than or equal to one.7.7.5. The "min-elements" Statement
The "min-elements" statement, which is optional, takes as an argument a non-negative integer that puts a constraint on valid list entries. A valid leaf-list or list MUST have at least min-elements entries. If no "min-elements" statement is present, it defaults to zero. The behavior of the constraint depends on the type of the leaf-list's or list's closest ancestor node in the schema tree that is not a non-presence container (see Section 7.5.1): o If no such ancestor exists in the schema tree, the constraint is enforced. o Otherwise, if this ancestor is a case node, the constraint is enforced if any other node from the case exists.
o Otherwise, it is enforced if the ancestor node exists. The constraint is further enforced according to the rules in Section 8.7.7.6. The "max-elements" Statement
The "max-elements" statement, which is optional, takes as an argument a positive integer or the string "unbounded", which puts a constraint on valid list entries. A valid leaf-list or list always has at most max-elements entries. If no "max-elements" statement is present, it defaults to "unbounded". The "max-elements" constraint is enforced according to the rules in Section 8.7.7.7. The "ordered-by" Statement
The "ordered-by" statement defines whether the order of entries within a list are determined by the user or the system. The argument is one of the strings "system" or "user". If not present, ordering defaults to "system". This statement is ignored if the list represents state data, RPC output parameters, or notification content. See Section 7.7.1 for additional information.7.7.7.1. ordered-by system
The entries in the list are ordered according to an order determined by the system. The "description" string for the list may suggest an order to the server implementor. If not, an implementation is free to order the entries in any order. An implementation SHOULD use the same order for the same data, regardless of how the data were created. Using a deterministic order will make comparisons possible using simple tools like "diff". This is the default order.7.7.7.2. ordered-by user
The entries in the list are ordered according to an order defined by the user. In NETCONF, this order is controlled by using special XML attributes in the <edit-config> request. See Section 7.7.9 for details.
7.7.8. XML Encoding Rules
A leaf-list node is encoded as a series of XML elements. Each element's local name is the leaf-list's identifier, and its namespace is the module's XML namespace (see Section 7.1.3). The value of each leaf-list entry is encoded to XML according to the type and is sent as character data in the element. The XML elements representing leaf-list entries MUST appear in the order specified by the user if the leaf-list is "ordered-by user"; otherwise, the order is implementation dependent. The XML elements representing leaf-list entries MAY be interleaved with elements for siblings of the leaf-list, unless the leaf-list defines RPC or action input or output parameters. See Section 7.7.10 for an example.7.7.9. NETCONF <edit-config> Operations
Leaf-list entries can be created and deleted, but not modified, through <edit-config>, by using the "operation" attribute in the leaf-list entry's XML element. In an "ordered-by user" leaf-list, the attributes "insert" and "value" in the YANG XML namespace (Section 5.3.1) can be used to control where in the leaf-list the entry is inserted. These can be used during "create" operations to insert a new leaf-list entry, or during "merge" or "replace" operations to insert a new leaf-list entry or move an existing one. The "insert" attribute can take the values "first", "last", "before", and "after". If the value is "before" or "after", the "value" attribute MUST also be used to specify an existing entry in the leaf-list. If no "insert" attribute is present in the "create" operation, it defaults to "last". If several entries in an "ordered-by user" leaf-list are modified in the same <edit-config> request, the entries are modified one at a time, in the order of the XML elements in the request. In a <copy-config> or in an <edit-config> with a "replace" operation that covers the entire leaf-list, the leaf-list order is the same as the order of the XML elements in the request.
When a NETCONF server processes an <edit-config> request, the elements of procedure for a leaf-list node are as follows: o If the operation is "merge" or "replace", the leaf-list entry is created if it does not exist. o If the operation is "create", the leaf-list entry is created if it does not exist. If the leaf-list entry already exists, a "data-exists" error is returned. o If the operation is "delete", the entry is deleted from the leaf-list if it exists. If the leaf-list entry does not exist, a "data-missing" error is returned.7.7.10. Usage Example
leaf-list allow-user { type string; description "A list of user name patterns to allow."; } A corresponding XML instance example: <allow-user>alice</allow-user> <allow-user>bob</allow-user> To create a new element in this list, using the default <edit-config> operation "merge": <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config> <target> <running/> </target> <config> <system xmlns="urn:example:config"> <services> <ssh> <allow-user>eric</allow-user> </ssh> </services> </system> </config> </edit-config> </rpc>
Given the following ordered-by user leaf-list: leaf-list cipher { type string; ordered-by user; description "A list of ciphers."; } The following would be used to insert a new cipher "blowfish-cbc" after "3des-cbc": <rpc message-id="102" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:yang="urn:ietf:params:xml:ns:yang:1"> <edit-config> <target> <running/> </target> <config> <system xmlns="urn:example:config"> <services> <ssh> <cipher nc:operation="create" yang:insert="after" yang:value="3des-cbc">blowfish-cbc</cipher> </ssh> </services> </system> </config> </edit-config> </rpc>