tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Glossaries     Architecture     IMS     UICC    |    search     info

RFC 7950

 
 
 

The YANG 1.1 Data Modeling Language

Part 4 of 9, p. 62 to 84
Prev Section       Next Section

 


prevText      Top      ToC       Page 62 
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>
     }

Top      Up      ToC       Page 63 
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.

Top      Up      ToC       Page 64 
                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | prefix       | 7.1.4   | 1           |
                 +--------------+---------+-------------+

                       The belongs-to's Substatement

7.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...
     }

Top      Up      ToC       Page 65 
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.

Top      Up      ToC       Page 66 
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.

Top      Up      ToC       Page 67 
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.

Top      Up      ToC       Page 68 
   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        |
                 +--------------+---------+-------------+

Top      Up      ToC       Page 69 
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.

Top      Up      ToC       Page 70 
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";
       }
     }

Top      Up      ToC       Page 71 
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.

Top      Up      ToC       Page 72 
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...
         }
       }
     }

Top      Up      ToC       Page 73 
   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.

Top      Up      ToC       Page 74 
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.

Top      Up      ToC       Page 75 
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
     }

Top      Up      ToC       Page 76 
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.

Top      Up      ToC       Page 77 
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.

Top      Up      ToC       Page 78 
   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.

Top      Up      ToC       Page 79 
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.

Top      Up      ToC       Page 80 
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.

Top      Up      ToC       Page 81 
   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.

Top      Up      ToC       Page 82 
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.

Top      Up      ToC       Page 83 
   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>

Top      Up      ToC       Page 84 
   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>



(page 84 continued on part 5)

Next Section