tech-invite   World Map     

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

RFC 6020

 
 
 

YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF)

Part 3 of 7, p. 34 to 61
Prev RFC Part       Next RFC Part

 


prevText      Top      Up      ToC       Page 34 
6.  YANG Syntax

   The YANG syntax is similar to that of SMIng [RFC3780] and programming
   languages like C and C++.  This C-like syntax was chosen specifically
   for its readability, since YANG values the time and effort of the
   readers of models above those of modules writers and YANG tool-chain
   developers.  This section introduces the YANG syntax.

   YANG modules use the UTF-8 [RFC3629] character encoding.

6.1.  Lexical Tokenization

   YANG modules are parsed as a series of tokens.  This section details
   the rules for recognizing tokens from an input stream.  YANG
   tokenization rules are both simple and powerful.  The simplicity is
   driven by a need to keep the parsers easy to implement, while the
   power is driven by the fact that modelers need to express their
   models in readable formats.

6.1.1.  Comments

   Comments are C++ style.  A single line comment starts with "//" and
   ends at the end of the line.  A block comment is enclosed within "/*"
   and "*/".

6.1.2.  Tokens

   A token in YANG is either a keyword, a string, a semicolon (";"), or
   braces ("{" or "}").  A string can be quoted or unquoted.  A keyword
   is either one of the YANG keywords defined in this document, or a

Top      Up      ToC       Page 35 
   prefix identifier, followed by ":", followed by a language extension
   keyword.  Keywords are case sensitive.  See Section 6.2 for a formal
   definition of identifiers.

6.1.3.  Quoting

   If a string contains any space or tab characters, a semicolon (";"),
   braces ("{" or "}"), or comment sequences ("//", "/*", or "*/"), then
   it MUST be enclosed within double or single quotes.

   If the double-quoted string contains a line break followed by space
   or tab characters that are used to indent the text according to the
   layout in the YANG file, this leading whitespace is stripped from the
   string, up to and including the column of the double quote character,
   or to the first non-whitespace character, whichever occurs first.  In
   this process, a tab character is treated as 8 space characters.

   If the double-quoted string contains space or tab characters before a
   line break, this trailing whitespace is stripped from the string.

   A single-quoted string (enclosed within ' ') preserves each character
   within the quotes.  A single quote character cannot occur in a
   single-quoted string, even when preceded by a backslash.

   Within a double-quoted string (enclosed within " "), a backslash
   character introduces a special character, which depends on the
   character that immediately follows the backslash:

    \n      new line
    \t      a tab character
    \"      a double quote
    \\      a single backslash

   If a quoted string is followed by a plus character ("+"), followed by
   another quoted string, the two strings are concatenated into one
   string, allowing multiple concatenations to build one string.
   Whitespace trimming and substitution of backslash-escaped characters
   in double-quoted strings is done before concatenation.

6.1.3.1.  Quoting Examples

   The following strings are equivalent:

     hello
     "hello"
     'hello'
     "hel" + "lo"
     'hel' + "lo"

Top      Up      ToC       Page 36 
   The following examples show some special strings:

     "\""  - string containing a double quote
     '"'   - string containing a double quote
     "\n"  - string containing a new line character
     '\n'  - string containing a backslash followed
             by the character n

   The following examples show some illegal strings:

     ''''  - a single-quoted string cannot contain single quotes
     """   - a double quote must be escaped in a double-quoted string

   The following strings are equivalent:

         "first line
            second line"

     "first line\n" + "  second line"

6.2.  Identifiers

   Identifiers are used to identify different kinds of YANG items by
   name.  Each identifier starts with an uppercase or lowercase ASCII
   letter or an underscore character, followed by zero or more ASCII
   letters, digits, underscore characters, hyphens, and dots.
   Implementations MUST support identifiers up to 64 characters in
   length.  Identifiers are case sensitive.  The identifier syntax is
   formally defined by the rule "identifier" in Section 12.  Identifiers
   can be specified as quoted or unquoted strings.

6.2.1.  Identifiers and Their Namespaces

   Each identifier is valid in a namespace that depends on the type of
   the YANG item being defined.  All identifiers defined in a namespace
   MUST be unique.

   o  All module and submodule names share the same global module
      identifier namespace.

   o  All extension names defined in a module and its submodules share
      the same extension identifier namespace.

   o  All feature names defined in a module and its submodules share the
      same feature identifier namespace.

   o  All identity names defined in a module and its submodules share
      the same identity identifier namespace.

Top      Up      ToC       Page 37 
   o  All derived type names defined within a parent node or at the top
      level of the module or its submodules share the same type
      identifier namespace.  This namespace is scoped to all descendant
      nodes of the parent node or module.  This means that any
      descendent node may use that typedef, and it MUST NOT define a
      typedef with the same name.

   o  All grouping names defined within a parent node or at the top
      level of the module or its submodules share the same grouping
      identifier namespace.  This namespace is scoped to all descendant
      nodes of the parent node or module.  This means that any
      descendent node may use that grouping, and it MUST NOT define a
      grouping with the same name.

   o  All leafs, leaf-lists, lists, containers, choices, rpcs,
      notifications, and anyxmls defined (directly or through a uses
      statement) within a parent node or at the top level of the module
      or its submodules share the same identifier namespace.  This
      namespace is scoped to the parent node or module, unless the
      parent node is a case node.  In that case, the namespace is scoped
      to the closest ancestor node that is not a case or choice node.

   o  All cases within a choice share the same case identifier
      namespace.  This namespace is scoped to the parent choice node.

   Forward references are allowed in YANG.

6.3.  Statements

   A YANG module contains a sequence of statements.  Each statement
   starts with a keyword, followed by zero or one argument, followed
   either by a semicolon (";") or a block of substatements enclosed
   within braces ("{ }"):

     statement = keyword [argument] (";" / "{" *statement "}")

   The argument is a string, as defined in Section 6.1.2.

6.3.1.  Language Extensions

   A module can introduce YANG extensions by using the "extension"
   keyword (see Section 7.17).  The extensions can be imported by other
   modules with the "import" statement (see Section 7.1.5).  When an
   imported extension is used, the extension's keyword MUST be qualified
   using the prefix with which the extension's module was imported.  If
   an extension is used in the module where it is defined, the
   extension's keyword MUST be qualified with the module's prefix.

Top      Up      ToC       Page 38 
   Since submodules cannot include the parent module, any extensions in
   the module that need to be exposed to submodules MUST be defined in a
   submodule.  Submodules can then include this submodule to find the
   definition of the extension.

   If a YANG compiler does not support a particular extension, which
   appears in a YANG module as an unknown-statement (see Section 12),
   the entire unknown-statement MAY be ignored by the compiler.

6.4.  XPath Evaluations

   YANG relies on XML Path Language (XPath) 1.0 [XPATH] as a notation
   for specifying many inter-node references and dependencies.  NETCONF
   clients and servers are not required to implement an XPath
   interpreter, but MUST ensure that the requirements encoded in the
   data model are enforced.  The manner of enforcement is an
   implementation decision.  The XPath expressions MUST be syntactically
   correct, and all prefixes used MUST be present in the XPath context
   (see Section 6.4.1).  An implementation may choose to implement them
   by hand, rather than using the XPath expression directly.

   The data model used in the XPath expressions is the same as that used
   in XPath 1.0 [XPATH], with the same extension for root node children
   as used by XSLT 1.0 [XSLT] (Section 3.1).  Specifically, it means
   that the root node may have any number of element nodes as its
   children.

6.4.1.  XPath Context

   All YANG XPath expressions share the following XPath context
   definition:

   o  The set of namespace declarations is the set of all "import"
      statements' prefix and namespace pairs in the module where the
      XPath expression is specified, and the "prefix" statement's prefix
      for the "namespace" statement's URI.

   o  Names without a namespace prefix belong to the same namespace as
      the identifier of the current node.  Inside a grouping, that
      namespace is affected by where the grouping is used (see
      Section 7.12).

   o  The function library is the core function library defined in
      [XPATH], and a function "current()" that returns a node set with
      the initial context node.

   o  The set of variable bindings is empty.

Top      Up      ToC       Page 39 
   The mechanism for handling unprefixed names is adopted from XPath 2.0
   [XPATH2.0], and helps simplify XPath expressions in YANG.  No
   ambiguity may ever arise because YANG node identifiers are always
   qualified names with a non-null namespace URI.

   The context node varies with the YANG XPath expression, and is
   specified where the YANG statement with the XPath expression is
   defined.

6.5.  Schema Node Identifier

   A schema node identifier is a string that identifies a node in the
   schema tree.  It has two forms, "absolute" and "descendant", defined
   by the rules "absolute-schema-nodeid" and "descendant-schema-nodeid"
   in Section 12, respectively.  A schema node identifier consists of a
   path of identifiers, separated by slashes ("/").  In an absolute
   schema node identifier, the first identifier after the leading slash
   is any top-level schema node in the local module or in all imported
   modules.

   References to identifiers defined in external modules MUST be
   qualified with appropriate prefixes, and references to identifiers
   defined in the current module and its submodules MAY use a prefix.

   For example, to identify the child node "b" of top-level node "a",
   the string "/a/b" can be used.

7.  YANG Statements

   The following sections describe all of the YANG statements.

   Note that even a statement that does not have any substatements
   defined in YANG can have vendor-specific extensions as substatements.
   For example, the "description" statement does not have any
   substatements defined in YANG, but the following is legal:

     description "some text" {
         acme:documentation-flag 5;
     }

7.1.  The module Statement

   The "module" statement defines the module's name, and groups all
   statements that belong to the module together.  The "module"
   statement's argument is the name of the module, followed by a block
   of substatements that hold detailed module information.  The module
   name follows the rules for identifiers in Section 6.2.

Top      Up      ToC       Page 40 
   Names of modules published in RFC streams [RFC4844] MUST be assigned
   by IANA, see Section 14.

   Private module names are assigned by the organization owning the
   module without a central registry.  It is RECOMMENDED to choose
   module names that will have a low probability of colliding with
   standard or other enterprise modules and submodules, e.g., by using
   the enterprise or organization name as a prefix for the module name.

   A module typically has the following layout:

     module <module-name> {

         // header information
         <yang-version statement>
         <namespace statement>
         <prefix statement>

         // linkage statements
         <import statements>
         <include statements>

         // meta information
         <organization statement>
         <contact statement>
         <description statement>
         <reference statement>

         // revision history
         <revision statements>

         // module definitions
         <other statements>
     }

Top      Up      ToC       Page 41 
7.1.1.  The module's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | anyxml       | 7.10    | 0..n        |
                 | augment      | 7.15    | 0..n        |
                 | choice       | 7.9     | 0..n        |
                 | contact      | 7.1.8   | 0..1        |
                 | container    | 7.5     | 0..n        |
                 | description  | 7.19.3  | 0..1        |
                 | deviation    | 7.18.3  | 0..n        |
                 | extension    | 7.17    | 0..n        |
                 | feature      | 7.18.1  | 0..n        |
                 | grouping     | 7.11    | 0..n        |
                 | identity     | 7.16    | 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        |
                 | namespace    | 7.1.3   | 1           |
                 | notification | 7.14    | 0..n        |
                 | organization | 7.1.7   | 0..1        |
                 | prefix       | 7.1.4   | 1           |
                 | reference    | 7.19.4  | 0..1        |
                 | revision     | 7.1.9   | 0..n        |
                 | rpc          | 7.13    | 0..n        |
                 | typedef      | 7.3     | 0..n        |
                 | uses         | 7.12    | 0..n        |
                 | yang-version | 7.1.2   | 0..1        |
                 +--------------+---------+-------------+

7.1.2.  The yang-version Statement

   The optional "yang-version" statement specifies which version of the
   YANG language was used in developing the module.  The statement's
   argument is a string.  If present, it MUST contain the value "1",
   which is the current YANG version and the default value.

   Handling of the "yang-version" statement for versions other than "1"
   (the version defined here) is out of scope for this specification.
   Any document that defines a higher version will need to define the
   backward compatibility of such a higher version.

Top      Up      ToC       Page 42 
7.1.3.  The namespace Statement

   The "namespace" statement defines the XML namespace that all
   identifiers defined by the module are qualified by, with the
   exception of data node identifiers defined inside a grouping (see
   Section 7.12 for details).  The argument to the "namespace" statement
   is the URI of the namespace.

   See also Section 5.3.

7.1.4.  The prefix Statement

   The "prefix" statement is used to define the prefix associated with
   the module and its namespace.  The "prefix" statement's argument is
   the prefix string that is used as a prefix to access a module.  The
   prefix string MAY be used to refer to definitions contained in the
   module, e.g., "if:ifName".  A prefix follows the same rules as an
   identifier (see Section 6.2).

   When used inside the "module" statement, the "prefix" statement
   defines the prefix to be used when this module is imported.  To
   improve readability of the NETCONF XML, a NETCONF client or server
   that generates XML or XPath that use prefixes SHOULD use the prefix
   defined by the module, unless there is a conflict.

   When used inside the "import" statement, the "prefix" statement
   defines the prefix to be used when accessing definitions inside the
   imported module.  When a reference to an identifier from the imported
   module is used, the prefix string for the imported module is used in
   combination with a colon (":") and the identifier, e.g., "if:
   ifIndex".  To improve readability of YANG modules, the prefix defined
   by a module SHOULD be used when the module is imported, unless there
   is a conflict.  If there is a conflict, i.e., two different modules
   that both have defined the same prefix are imported, at least one of
   them MUST be imported with a different prefix.

   All prefixes, including the prefix for the module itself MUST be
   unique within the module or submodule.

7.1.5.  The import Statement

   The "import" statement makes definitions from one module available
   inside another module or submodule.  The argument is the name of the
   module to import, and the statement is followed by a block of
   substatements that holds detailed import information.  When a module
   is imported, the importing module may:

Top      Up      ToC       Page 43 
   o  use any grouping and typedef defined at the top level in the
      imported module or its submodules.

   o  use any extension, feature, and identity defined in the imported
      module or its submodules.

   o  use any node in the imported module's schema tree in "must",
      "path", and "when" statements, or as the target node in "augment"
      and "deviation" statements.

   The mandatory "prefix" substatement assigns a prefix for the imported
   module that is scoped to the importing module or submodule.  Multiple
   "import" statements may be specified to import from different
   modules.

   When the optional "revision-date" substatement is present, any
   typedef, grouping, extension, feature, and identity referenced by
   definitions in the local module are taken from the specified revision
   of the imported module.  It is an error if the specified revision of
   the imported module does not exist.  If no "revision-date"
   substatement is present, it is undefined from which revision of the
   module they are taken.

   Multiple revisions of the same module MUST NOT be imported.

                        The import's Substatements

                 +---------------+---------+-------------+
                 | substatement  | section | cardinality |
                 +---------------+---------+-------------+
                 | prefix        | 7.1.4   | 1           |
                 | revision-date | 7.1.5.1 | 0..1        |
                 +---------------+---------+-------------+

7.1.5.1.  The import's revision-date Statement

   The import's "revision-date" statement is used to specify the exact
   version of the module to import.  The "revision-date" statement MUST
   match the most recent "revision" statement in the imported module.

7.1.6.  The include Statement

   The "include" statement is used to make content from a submodule
   available to that submodule's parent module, or to another submodule
   of that parent module.  The argument is an identifier that is the
   name of the submodule to include.  Modules are only allowed to

Top      Up      ToC       Page 44 
   include submodules that belong to that module, as defined by the
   "belongs-to" statement (see Section 7.2.2).  Submodules are only
   allowed to include other submodules belonging to the same module.

   When a module includes a submodule, it incorporates the contents of
   the submodule into the node hierarchy of the module.  When a
   submodule includes another submodule, the target submodule's
   definitions are made available to the current submodule.

   When the optional "revision-date" substatement is present, the
   specified revision of the submodule is included in the module.  It is
   an error if the specified revision of the submodule does not exist.
   If no "revision-date" substatement is present, it is undefined which
   revision of the submodule is included.

   Multiple revisions of the same submodule MUST NOT be included.

                       The includes's Substatements

                 +---------------+---------+-------------+
                 | substatement  | section | cardinality |
                 +---------------+---------+-------------+
                 | revision-date | 7.1.5.1 | 0..1        |
                 +---------------+---------+-------------+

7.1.7.  The organization Statement

   The "organization" statement defines the party responsible for this
   module.  The argument is a string that is used to specify a textual
   description of the organization(s) under whose auspices this module
   was developed.

7.1.8.  The contact Statement

   The "contact" statement provides contact information for the module.
   The argument is a string that is used to specify contact information
   for the person or persons to whom technical queries concerning this
   module should be sent, such as their name, postal address, telephone
   number, and electronic mail address.

7.1.9.  The revision Statement

   The "revision" statement specifies the editorial revision history of
   the module, including the initial revision.  A series of revision
   statements detail the changes in the module's definition.  The
   argument is a date string in the format "YYYY-MM-DD", followed by a
   block of substatements that holds detailed revision information.  A
   module SHOULD have at least one initial "revision" statement.  For

Top      Up      ToC       Page 45 
   every published editorial change, a new one SHOULD be added in front
   of the revisions sequence, so that all revisions are in reverse
   chronological order.

7.1.9.1.  The revision's Substatement

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | description  | 7.19.3  | 0..1        |
                 | reference    | 7.19.4  | 0..1        |
                 +--------------+---------+-------------+

7.1.10.  Usage Example

     module acme-system {
         namespace "http://acme.example.com/system";
         prefix "acme";

         import ietf-yang-types {
             prefix "yang";
         }

         include acme-types;

         organization "ACME Inc.";
         contact
             "Joe L. User

              ACME, Inc.
              42 Anywhere Drive
              Nowhere, CA 95134
              USA

              Phone: +1 800 555 0100
              EMail: joe@acme.example.com";

         description
             "The module for entities implementing the ACME protocol.";

         revision "2007-06-09" {
             description "Initial revision.";
         }

         // definitions follow...
     }

Top      Up      ToC       Page 46 
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 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 hold detailed submodule
   information.  The submodule name follows the rules for identifiers in
   Section 6.2.

   Names of submodules published in RFC streams [RFC4844] MUST be
   assigned by IANA, see Section 14.

   Private submodule names are assigned by the organization owning the
   submodule without a central registry.  It is RECOMMENDED to choose
   submodule names that will have a low probability of colliding with
   standard or other enterprise modules and submodules, e.g., by using
   the enterprise or organization name as a prefix for the submodule
   name.

Top      Up      ToC       Page 47 
   A submodule typically has the following layout:

     submodule <module-name> {

         <yang-version statement>

         // module identification
         <belongs-to statement>

         // linkage statements
         <import statements>
         <include statements>

         // meta information
         <organization statement>
         <contact statement>
         <description statement>
         <reference statement>

         // revision history
         <revision statements>

         // module definitions
         <other statements>
     }

Top      Up      ToC       Page 48 
7.2.1.  The submodule's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | anyxml       | 7.10    | 0..n        |
                 | augment      | 7.15    | 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.19.3  | 0..1        |
                 | deviation    | 7.18.3  | 0..n        |
                 | extension    | 7.17    | 0..n        |
                 | feature      | 7.18.1  | 0..n        |
                 | grouping     | 7.11    | 0..n        |
                 | identity     | 7.16    | 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.14    | 0..n        |
                 | organization | 7.1.7   | 0..1        |
                 | reference    | 7.19.4  | 0..1        |
                 | revision     | 7.1.9   | 0..n        |
                 | rpc          | 7.13    | 0..n        |
                 | typedef      | 7.3     | 0..n        |
                 | uses         | 7.12    | 0..n        |
                 | yang-version | 7.1.2   | 0..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 the module to which it belongs,
   or by 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 local
   submodule and any included submodules can be accessed by using the
   prefix.

Top      Up      ToC       Page 49 
                      The belongs-to's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | prefix       | 7.1.4   | 1           |
                 +--------------+---------+-------------+

7.2.3.  Usage Example

     submodule acme-types {

         belongs-to "acme-system" {
             prefix "acme";
         }

         import ietf-yang-types {
             prefix "yang";
         }

         organization "ACME Inc.";
         contact
             "Joe L. User

              ACME, Inc.
              42 Anywhere Drive
              Nowhere, CA 95134
              USA

              Phone: +1 800 555 0100
              EMail: joe@acme.example.com";

         description
             "This submodule defines common ACME types.";

         revision "2007-06-09" {
             description "Initial revision.";
         }

         // definitions follows...
     }

7.3.  The typedef Statement

   The "typedef" statement defines a new type that may be used locally
   in the module, in modules or submodules which include it, and by
   other modules that import from it, according to the rules in

Top      Up      ToC       Page 50 
   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.19.3  | 0..1        |
                 | reference    | 7.19.4  | 0..1        |
                 | status       | 7.19.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.

Top      Up      ToC       Page 51 
   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 are
   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 |
               +------------------+---------+-------------+
               | bit              | 9.7.4   | 0..n        |
               | enum             | 9.6.4   | 0..n        |
               | length           | 9.4.4   | 0..1        |
               | path             | 9.9.2   | 0..1        |
               | pattern          | 9.4.6   | 0..n        |
               | range            | 9.2.4   | 0..1        |
               | require-instance | 9.13.2  | 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.

Top      Up      ToC       Page 52 
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 configuration has an explicit meaning.

   In the first style, the container has no meaning of its own, existing
   only to contain child nodes.  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 is
   configuration data, representing a single bit of configuration data.
   The container acts as both a configuration knob and a means of
   organizing related configuration.  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 device using 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.

Top      Up      ToC       Page 53 
7.5.2.  The container's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | anyxml       | 7.10    | 0..n        |
                 | choice       | 7.9     | 0..n        |
                 | config       | 7.19.1  | 0..1        |
                 | container    | 7.5     | 0..n        |
                 | description  | 7.19.3  | 0..1        |
                 | grouping     | 7.11    | 0..n        |
                 | if-feature   | 7.18.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        |
                 | presence     | 7.5.5   | 0..1        |
                 | reference    | 7.19.4  | 0..1        |
                 | status       | 7.19.2  | 0..1        |
                 | typedef      | 7.3     | 0..n        |
                 | uses         | 7.12    | 0..n        |
                 | when         | 7.19.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 data node in the data tree, and
   for all leafs with default values in use (see Section 7.6.1).  If a
   data node does not exist in the data tree, and it does not have a
   default value, its "must" statements are not evaluated.

   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  The context node is the node in the data tree for which the "must"
      statement is defined.

   o  The accessible tree is made up of all nodes in the data tree, and
      all leafs with default values in use (see Section 7.6.1).

Top      Up      ToC       Page 54 
   The accessible tree depends on the context node:

   o  If the context node represents configuration, the tree is the data
      in the NETCONF datastore where the context node exists.  The XPath
      root node has all top-level configuration data nodes in all
      modules as children.

   o  If the context node represents state data, the tree is all state
      data on the device, and the <running/> datastore.  The XPath root
      node has all top-level data nodes in all modules as children.

   o  If the context node represents notification content, the tree is
      the notification XML instance document.  The XPath root node has
      the element representing the notification being defined as the
      only child.

   o  If the context node represents RPC input parameters, the tree is
      the RPC XML instance document.  The XPath root node has the
      element representing the RPC operation being defined as the only
      child.

   o  If the context node represents RPC output parameters, the tree is
      the RPC reply instance document.  The XPath root node has the
      elements representing the RPC output parameters as children.

   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 Sections 7.6 and 7.7), 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
   on the device.  How the evaluation is done in practice is an
   implementation decision.

Top      Up      ToC       Page 55 
7.5.4.  The must's Substatements

                 +---------------+---------+-------------+
                 | substatement  | section | cardinality |
                 +---------------+---------+-------------+
                 | description   | 7.19.3  | 0..1        |
                 | error-app-tag | 7.5.4.2 | 0..1        |
                 | error-message | 7.5.4.1 | 0..1        |
                 | reference     | 7.19.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>.

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

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 " +
              "(ifType = 'ethernet' and ifMTU = 1500)" {
             error-message "An ethernet MTU must be 1500";
         }
         must "ifType != 'atm' or " +
              "(ifType = 'atm' and ifMTU <= 17966 and ifMTU >= 64)" {
             error-message "An atm MTU must be  64 .. 17966";
         }
     }

Top      Up      ToC       Page 56 
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", and "anyxml" statements can be used to define child
   nodes to the container.

7.5.7.  XML Mapping 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 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.

   A NETCONF server that replies to a <get> or <get-config> request MAY
   choose not to send a container element if the container node does not
   have the "presence" statement and no child nodes exist.  Thus, a
   client that receives an <rpc-reply> for a <get> or <get-config>
   request, must be prepared to handle the case that a container node
   without a "presence" statement is not present in the XML.

7.5.8.  NETCONF <edit-config> Operations

   Containers can be created, deleted, replaced, and modified through
   <edit-config>, by using the "operation" attribute (see [RFC4741],
   Section 7.2) 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.

Top      Up      ToC       Page 57 
   When a NETCONF server processes an <edit-config> request, the
   elements of procedure for the container node are:

      If the operation is "merge" or "replace", the node is created if
      it does not exist.

      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.

      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>:

Top      Up      ToC       Page 58 
     <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="http://example.com/schema/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 instances 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:

   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 if
      the case node is the choice's default case, and no nodes from any
      other case exist in the data tree.

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

   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.19.1  | 0..1        |
                 | default      | 7.6.4   | 0..1        |
                 | description  | 7.19.3  | 0..1        |
                 | if-feature   | 7.18.2  | 0..n        |
                 | mandatory    | 7.6.5   | 0..1        |
                 | must         | 7.5.3   | 0..n        |
                 | reference    | 7.19.4  | 0..1        |
                 | status       | 7.19.2  | 0..1        |
                 | type         | 7.6.3   | 1           |
                 | units        | 7.3.3   | 0..1        |
                 | when         | 7.19.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.

Top      Up      ToC       Page 60 
   The "default" statement MUST NOT be present on nodes where
   "mandatory" is true.

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 Mapping 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 sent as character data in the element.

   A NETCONF server that replies to a <get> or <get-config> request MAY
   choose not to send the leaf element if its value is the default
   value.  Thus, a client that receives an <rpc-reply> for a <get> or
   <get-config> request, MUST be prepared to handle the case that a leaf
   node with a default value is not present in the XML.  In this case,
   the value used by the server is known to be the default value.

   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:

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

      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.

      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="http://example.com/schema/config">
             <services>
               <ssh>
                 <port>2022</port>
               </ssh>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>


Next RFC Part