Tech-invite  3GPPspecsRELsGlossariesSIPRFCs
8887868584838281807978777675747372717069686766656463626160595857565554535251504948474645444342414039383736353433323130292827262524232221201918171615141312111009080706050403020100

in Index   Prev   Next

RFC 7950

The YANG 1.1 Data Modeling Language

Pages: 217
Proposed Standard
Errata
Updated by:  8342
Part 7 of 9 – Pages 138 to 163
First   Prev   Next

Top   ToC   RFC7950 - Page 138   prevText

8. Constraints

8.1. Constraints on Data

Several YANG statements define constraints on valid data. These constraints are enforced in different ways, depending on what type of data the statement defines. o If the constraint is defined on configuration data, it MUST be true in a valid configuration data tree. o If the constraint is defined on state data, it MUST be true in a valid state data tree. o If the constraint is defined on notification content, it MUST be true in any notification data tree. o If the constraint is defined on RPC or action input parameters, it MUST be true in an invocation of the RPC or action operation. o If the constraint is defined on RPC or action output parameters, it MUST be true in the RPC or action reply. The following properties are true in all data trees: o All leaf data values MUST match the type constraints for the leaf, including those defined in the type's "range", "length", and "pattern" properties. o All key leafs MUST be present for all list entries. o Nodes MUST be present for at most one case branch in all choices. o There MUST be no nodes tagged with "if-feature" present if the "if-feature" expression evaluates to "false" in the server. o There MUST be no nodes tagged with "when" present if the "when" condition evaluates to "false" in the data tree. The following properties are true in a valid data tree: o All "must" constraints MUST evaluate to "true". o All referential integrity constraints defined via the "path" statement MUST be satisfied. o All "unique" constraints on lists MUST be satisfied.
Top   ToC   RFC7950 - Page 139
   o  The "mandatory" constraint is enforced for leafs and choices,
      unless the node or any of its ancestors has a "when" condition or
      "if-feature" expression that evaluates to "false".

   o  The "min-elements" and "max-elements" constraints are enforced for
      lists and leaf-lists, unless the node or any of its ancestors has
      a "when" condition or "if-feature" expression that evaluates to
      "false".

   The running configuration datastore MUST always be valid.

8.2. Configuration Data Modifications

o If a request creates configuration data nodes under a choice, any existing nodes from other case branches in the data tree are deleted by the server. o If a request modifies a configuration data node such that any node's "when" expression becomes false, then the node in the data tree with the "when" expression is deleted by the server.

8.3. NETCONF Constraint Enforcement Model

For configuration data, there are three windows when constraints MUST be enforced: o during parsing of RPC payloads o during processing of the <edit-config> operation o during validation Each of these scenarios is considered in the following sections.

8.3.1. Payload Parsing

When content arrives in RPC payloads, it MUST be well-formed XML, following the hierarchy and content rules defined by the set of models the server implements. o If a leaf data value does not match the type constraints for the leaf, including those defined in the type's "range", "length", and "pattern" properties, the server MUST reply with an "invalid-value" <error-tag> in the <rpc-error>, and with the error-app-tag (Section 7.5.4.2) and error-message (Section 7.5.4.1) associated with the constraint, if any exist.
Top   ToC   RFC7950 - Page 140
   o  If all keys of a list entry are not present, the server MUST reply
      with a "missing-element" <error-tag> in the <rpc-error>.

   o  If data for more than one case branch of a choice is present, the
      server MUST reply with a "bad-element" <error-tag> in the
      <rpc-error>.

   o  If data for a node tagged with "if-feature" is present and the
      "if-feature" expression evaluates to "false" in the server, the
      server MUST reply with an "unknown-element" <error-tag> in the
      <rpc-error>.

   o  If data for a node tagged with "when" is present and the "when"
      condition evaluates to "false", the server MUST reply with an
      "unknown-element" <error-tag> in the <rpc-error>.

   o  For insert handling, if the values for the attributes "before" and
      "after" are not valid for the type of the appropriate key leafs,
      the server MUST reply with a "bad-attribute" <error-tag> in the
      <rpc-error>.

   o  If the attributes "before" and "after" appear in any element that
      is not a list whose "ordered-by" property is "user", the server
      MUST reply with an "unknown-attribute" <error-tag> in the
      <rpc-error>.

8.3.2. NETCONF <edit-config> Processing

After the incoming data is parsed, the NETCONF server performs the <edit-config> operation by applying the data to the configuration datastore. During this processing, the following errors MUST be detected: o Delete requests for non-existent data. o Create requests for existent data. o Insert requests with "before" or "after" parameters that do not exist. o Modification requests for nodes tagged with "when", and the "when" condition evaluates to "false". In this case, the server MUST reply with an "unknown-element" <error-tag> in the <rpc-error>.
Top   ToC   RFC7950 - Page 141

8.3.3. Validation

When datastore processing is complete, the final contents MUST obey all validation constraints. This validation processing is performed at differing times according to the datastore. If the datastore is "running" or "startup", these constraints MUST be enforced at the end of the <edit-config> or <copy-config> operation. If the datastore is "candidate", the constraint enforcement is delayed until a <commit> or <validate> operation takes place.

9. Built-In Types

YANG has a set of built-in types, similar to those of many programming languages, but with some differences due to special requirements from the management information model. Additional types may be defined that are derived from those built-in types or from other derived types. Derived types may use subtyping to formally restrict the set of possible values. The different built-in types and their derived types allow different kinds of subtyping, namely length and regular expression restrictions of strings (Sections 9.4.4 and 9.4.5) and range restrictions of numeric types (Section 9.2.4). The lexical representation of a value of a certain type is used in the XML encoding and when specifying default values and numerical ranges in YANG modules.

9.1. Canonical Representation

For most types, there is a single canonical representation of the type's values. Some types allow multiple lexical representations of the same value; for example, the positive integer "17" can be represented as "+17" or "17". Implementations MUST support all lexical representations specified in this document. When a server sends XML-encoded data, it MUST use the canonical form defined in this section. Other encodings may introduce alternate representations. Note, however, that values in the data tree are conceptually stored in the canonical representation as defined in this section. In particular, any XPath expression evaluations are done using the canonical form if the data type has a canonical form. If the data type does not have a canonical form, the format of the value MUST match the data type's lexical representation, but the exact format is implementation dependent.
Top   ToC   RFC7950 - Page 142
   Some types have a lexical representation that depends on the
   encoding, e.g., the XML context in which they occur.  These types do
   not have a canonical form.

9.2. The Integer Built-In Types

The integer built-in types are int8, int16, int32, int64, uint8, uint16, uint32, and uint64. They represent signed and unsigned integers of different sizes: int8 represents integer values between -128 and 127, inclusively. int16 represents integer values between -32768 and 32767, inclusively. int32 represents integer values between -2147483648 and 2147483647, inclusively. int64 represents integer values between -9223372036854775808 and 9223372036854775807, inclusively. uint8 represents integer values between 0 and 255, inclusively. uint16 represents integer values between 0 and 65535, inclusively. uint32 represents integer values between 0 and 4294967295, inclusively. uint64 represents integer values between 0 and 18446744073709551615, inclusively.

9.2.1. Lexical Representation

An integer value is lexically represented as an optional sign ("+" or "-"), followed by a sequence of decimal digits. If no sign is specified, "+" is assumed. For convenience, when specifying a default value for an integer in a YANG module, an alternative lexical representation can be used that represents the value in a hexadecimal or octal notation. The hexadecimal notation consists of an optional sign ("+" or "-"), followed by the characters "0x", followed by a number of hexadecimal digits where letters may be uppercase or lowercase. The octal notation consists of an optional sign ("+" or "-"), followed by the character "0", followed by a number of octal digits.
Top   ToC   RFC7950 - Page 143
   Note that if a default value in a YANG module has a leading zero
   ("0"), it is interpreted as an octal number.  In the XML encoding, an
   integer is always interpreted as a decimal number, and leading zeros
   are allowed.

   Examples:

     // legal values
     +4711                       // legal positive value
     4711                        // legal positive value
     -123                        // legal negative value
     0xf00f                      // legal positive hexadecimal value
     -0xf                        // legal negative hexadecimal value
     052                         // legal positive octal value

     // illegal values
     - 1                         // illegal intermediate space

9.2.2. Canonical Form

The canonical form of a positive integer does not include the sign "+". Leading zeros are prohibited. The value zero is represented as "0".

9.2.3. Restrictions

All integer types can be restricted with the "range" statement (Section 9.2.4).

9.2.4. The "range" Statement

The "range" statement, which is an optional substatement to the "type" statement, takes as an argument a range expression string. It is used to restrict integer and decimal built-in types, or types derived from them. A range consists of an explicit value, or a lower-inclusive bound, two consecutive dots "..", and an upper-inclusive bound. Multiple values or ranges can be given, separated by "|". If multiple values or ranges are given, they all MUST be disjoint and MUST be in ascending order. If a range restriction is applied to a type that is already range-restricted, the new restriction MUST be equally limiting or more limiting, i.e., raising the lower bounds, reducing the upper bounds, removing explicit values or ranges, or splitting ranges into multiple ranges with intermediate gaps. Each explicit value and range boundary value given in the range expression MUST
Top   ToC   RFC7950 - Page 144
   match the type being restricted or be one of the special values "min"
   or "max".  "min" and "max" mean the minimum and maximum values
   accepted for the type being restricted, respectively.

   The range expression syntax is formally defined by the rule
   "range-arg" in Section 14.

9.2.4.1. The range'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 | +---------------+---------+-------------+

9.2.5. Usage Example

typedef my-base-int32-type { type int32 { range "1..4 | 10..20"; } } typedef my-type1 { type my-base-int32-type { // legal range restriction range "11..max"; // 11..20 } } typedef my-type2 { type my-base-int32-type { // illegal range restriction range "11..100"; } }

9.3. The decimal64 Built-In Type

The decimal64 built-in type represents a subset of the real numbers, which can be represented by decimal numerals. The value space of decimal64 is the set of numbers that can be obtained by multiplying a 64-bit signed integer by a negative power of ten, i.e., expressible as "i x 10^-n" where i is an integer64 and n is an integer between 1 and 18, inclusively.
Top   ToC   RFC7950 - Page 145

9.3.1. Lexical Representation

A decimal64 value is lexically represented as an optional sign ("+" or "-"), followed by a sequence of decimal digits, optionally followed by a period ('.') as a decimal indicator and a sequence of decimal digits. If no sign is specified, "+" is assumed.

9.3.2. Canonical Form

The canonical form of a positive decimal64 value does not include the sign "+". The decimal point is required. Leading and trailing zeros are prohibited, subject to the rule that there MUST be at least one digit before and after the decimal point. The value zero is represented as "0.0".

9.3.3. Restrictions

A decimal64 type can be restricted with the "range" statement (Section 9.2.4).

9.3.4. The "fraction-digits" Statement

The "fraction-digits" statement, which is a substatement to the "type" statement, MUST be present if the type is "decimal64". It takes as an argument an integer between 1 and 18, inclusively. It controls the size of the minimum difference between values of a decimal64 type by restricting the value space to numbers that are expressible as "i x 10^-n" where n is the fraction-digits argument.
Top   ToC   RFC7950 - Page 146
   The following table lists the minimum and maximum values for each
   fraction-digit value:

     +----------------+-----------------------+----------------------+
     | fraction-digit | min                   | max                  |
     +----------------+-----------------------+----------------------+
     | 1              | -922337203685477580.8 | 922337203685477580.7 |
     | 2              | -92233720368547758.08 | 92233720368547758.07 |
     | 3              | -9223372036854775.808 | 9223372036854775.807 |
     | 4              | -922337203685477.5808 | 922337203685477.5807 |
     | 5              | -92233720368547.75808 | 92233720368547.75807 |
     | 6              | -9223372036854.775808 | 9223372036854.775807 |
     | 7              | -922337203685.4775808 | 922337203685.4775807 |
     | 8              | -92233720368.54775808 | 92233720368.54775807 |
     | 9              | -9223372036.854775808 | 9223372036.854775807 |
     | 10             | -922337203.6854775808 | 922337203.6854775807 |
     | 11             | -92233720.36854775808 | 92233720.36854775807 |
     | 12             | -9223372.036854775808 | 9223372.036854775807 |
     | 13             | -922337.2036854775808 | 922337.2036854775807 |
     | 14             | -92233.72036854775808 | 92233.72036854775807 |
     | 15             | -9223.372036854775808 | 9223.372036854775807 |
     | 16             | -922.3372036854775808 | 922.3372036854775807 |
     | 17             | -92.23372036854775808 | 92.23372036854775807 |
     | 18             | -9.223372036854775808 | 9.223372036854775807 |
     +----------------+-----------------------+----------------------+

9.3.5. Usage Example

typedef my-decimal { type decimal64 { fraction-digits 2; range "1 .. 3.14 | 10 | 20..max"; } }

9.4. The string Built-In Type

The string built-in type represents human-readable strings in YANG. Legal characters are the Unicode and ISO/IEC 10646 [ISO.10646] characters, including tab, carriage return, and line feed but excluding the other C0 control characters, the surrogate blocks, and the noncharacters. The string syntax is formally defined by the rule "yang-string" in Section 14.

9.4.1. Lexical Representation

A string value is lexically represented as character data in the XML encoding.
Top   ToC   RFC7950 - Page 147

9.4.2. Canonical Form

The canonical form is the same as the lexical representation. No Unicode normalization of string values is performed.

9.4.3. Restrictions

A string can be restricted with the "length" (Section 9.4.4) and "pattern" (Section 9.4.5) statements.

9.4.4. The "length" Statement

The "length" statement, which is an optional substatement to the "type" statement, takes as an argument a length expression string. It is used to restrict the built-in types "string" and "binary" or types derived from them. A "length" statement restricts the number of Unicode characters in the string. A length range consists of an explicit value, or a lower bound, two consecutive dots "..", and an upper bound. Multiple values or ranges can be given, separated by "|". Length-restricting values MUST NOT be negative. If multiple values or ranges are given, they all MUST be disjoint and MUST be in ascending order. If a length restriction is applied to a type that is already length-restricted, the new restriction MUST be equally limiting or more limiting, i.e., raising the lower bounds, reducing the upper bounds, removing explicit length values or ranges, or splitting ranges into multiple ranges with intermediate gaps. A length value is a non-negative integer or one of the special values "min" or "max". "min" and "max" mean the minimum and maximum lengths accepted for the type being restricted, respectively. An implementation is not required to support a length value larger than 18446744073709551615. The length expression syntax is formally defined by the rule "length-arg" in Section 14.
9.4.4.1. The length'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 | +---------------+---------+-------------+
Top   ToC   RFC7950 - Page 148

9.4.5. The "pattern" Statement

The "pattern" statement, which is an optional substatement to the "type" statement, takes as an argument a regular expression string, as defined in [XSD-TYPES]. It is used to restrict the built-in type "string", or types derived from "string", to values that match the pattern. If the type has multiple "pattern" statements, the expressions are ANDed together, i.e., all such expressions have to match. If a pattern restriction is applied to a type that is already pattern-restricted, values must match all patterns in the base type, in addition to the new patterns.
9.4.5.1. The pattern'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 | | modifier | 9.4.6 | 0..1 | | reference | 7.21.4 | 0..1 | +---------------+---------+-------------+

9.4.6. The "modifier" Statement

The "modifier" statement, which is an optional substatement to the "pattern" statement, takes as an argument the string "invert-match". If a pattern has the "invert-match" modifier present, the type is restricted to values that do not match the pattern.
Top   ToC   RFC7950 - Page 149

9.4.7. Usage Example

With the following typedef: typedef my-base-str-type { type string { length "1..255"; } } the following refinement is legal: type my-base-str-type { // legal length refinement length "11 | 42..max"; // 11 | 42..255 } and the following refinement is illegal: type my-base-str-type { // illegal length refinement length "1..999"; } With the following type: type string { length "0..4"; pattern "[0-9a-fA-F]*"; } the following strings match: AB // legal 9A00 // legal and the following strings do not match: 00ABAB // illegal, too long xx00 // illegal, bad characters
Top   ToC   RFC7950 - Page 150
   With the following type:

     type string {
       length "1..max";
       pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*';
       pattern '[xX][mM][lL].*' {
         modifier invert-match;
       }
     }

   the following string matches:

     enabled     // legal

   and the following strings do not match:

     10-mbit     // illegal, starts with a number
     xml-element // illegal, starts with illegal sequence

9.5. The boolean Built-In Type

The boolean built-in type represents a boolean value.

9.5.1. Lexical Representation

The lexical representation of a boolean value is a string with a value of "true" or "false". These values MUST be in lowercase.

9.5.2. Canonical Form

The canonical form is the same as the lexical representation.

9.5.3. Restrictions

A boolean cannot be restricted.

9.6. The enumeration Built-In Type

The enumeration built-in type represents values from a set of assigned names.

9.6.1. Lexical Representation

The lexical representation of an enumeration value is the assigned name string.
Top   ToC   RFC7950 - Page 151

9.6.2. Canonical Form

The canonical form is the assigned name string.

9.6.3. Restrictions

An enumeration can be restricted with one or more "enum" (Section 9.6.4) statements, which enumerate a subset of the values for the base type.

9.6.4. The "enum" Statement

The "enum" statement, which is a substatement to the "type" statement, MUST be present if the type is "enumeration". It is repeatedly used to specify each assigned name of an enumeration type. It takes as an argument a string that is the assigned name. The string MUST NOT be zero-length and MUST NOT have any leading or trailing whitespace characters (any Unicode character with the "White_Space" property). The use of Unicode control codes SHOULD be avoided. The statement is optionally followed by a block of substatements that holds detailed enum information. All assigned names in an enumeration MUST be unique. When an existing enumeration type is restricted, the set of assigned names in the new type MUST be a subset of the base type's set of assigned names. The value of such an assigned name MUST NOT be changed.
9.6.4.1. The enum's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | description | 7.21.3 | 0..1 | | if-feature | 7.20.2 | 0..n | | reference | 7.21.4 | 0..1 | | status | 7.21.2 | 0..1 | | value | 9.6.4.2 | 0..1 | +--------------+---------+-------------+
Top   ToC   RFC7950 - Page 152
9.6.4.2. The "value" Statement
The "value" statement, which is optional, is used to associate an integer value with the assigned name for the enum. This integer value MUST be in the range -2147483648 to 2147483647, and it MUST be unique within the enumeration type. If a value is not specified, then one will be automatically assigned. If the "enum" substatement is the first one defined, the assigned value is zero (0); otherwise, the assigned value is one greater than the current highest enum value (i.e., the highest enum value, implicit or explicit, prior to the current "enum" substatement in the parent "type" statement). Note that the presence of an "if-feature" statement in an "enum" statement does not affect the automatically assigned value. If the current highest value is equal to 2147483647, then an enum value MUST be specified for "enum" substatements following the one with the current highest value. When an existing enumeration type is restricted, the "value" statement MUST either have the same value as in the base type or not be present, in which case the value is the same as in the base type.

9.6.5. Usage Example

leaf myenum { type enumeration { enum zero; enum one; enum seven { value 7; } } } The lexical representation of the leaf "myenum" with value "seven" is: <myenum>seven</myenum>
Top   ToC   RFC7950 - Page 153
   With the following typedef:

     typedef my-base-enumeration-type {
       type enumeration {
         enum white {
           value 1;
         }
         enum yellow {
           value 2;
         }
         enum red {
           value 3;
         }
       }
     }

   the following refinement is legal:

     type my-base-enumeration-type {
       // legal enum refinement
       enum yellow;
       enum red {
         value 3;
       }
     }

   and the following refinement is illegal:

     type my-base-enumeration-type {
       // illegal enum refinement
       enum yellow {
         value 4; // illegal value change
       }
       enum black; // illegal addition of new name
     }
Top   ToC   RFC7950 - Page 154
   The following example shows how an "enum" can be tagged with
   "if-feature", making the value legal only on servers that advertise
   the corresponding feature:

     type enumeration {
       enum tcp;
       enum ssh {
         if-feature ssh;
       }
       enum tls {
         if-feature tls;
       }
     }

9.7. The bits Built-In Type

The bits built-in type represents a bit set. That is, a bits value is a set of flags identified by small integer position numbers starting at 0. Each bit number has an assigned name. When an existing bits type is restricted, the set of assigned names in the new type MUST be a subset of the base type's set of assigned names. The bit position of such an assigned name MUST NOT be changed.

9.7.1. Restrictions

A bits type can be restricted with the "bit" (Section 9.7.4) statement.

9.7.2. Lexical Representation

The lexical representation of the bits type is a space-separated list of the names of the bits that are set. A zero-length string thus represents a value where no bits are set.

9.7.3. Canonical Form

In the canonical form, the bit values are separated by a single space character and they appear ordered by their position (see Section 9.7.4.2).
Top   ToC   RFC7950 - Page 155

9.7.4. The "bit" Statement

The "bit" statement, which is a substatement to the "type" statement, MUST be present if the type is "bits". It is repeatedly used to specify each assigned named bit of a bits type. It takes as an argument a string that is the assigned name of the bit. It is followed by a block of substatements that holds detailed bit information. The assigned name follows the same syntax rules as an identifier (see Section 6.2). All assigned names in a bits type MUST be unique.
9.7.4.1. The bit's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | description | 7.21.3 | 0..1 | | if-feature | 7.20.2 | 0..n | | position | 9.7.4.2 | 0..1 | | reference | 7.21.4 | 0..1 | | status | 7.21.2 | 0..1 | +--------------+---------+-------------+
9.7.4.2. The "position" Statement
The "position" statement, which is optional, takes as an argument a non-negative integer value that specifies the bit's position within a hypothetical bit field. The position value MUST be in the range 0 to 4294967295, and it MUST be unique within the bits type. If a bit position is not specified, then one will be automatically assigned. If the "bit" substatement is the first one defined, the assigned value is zero (0); otherwise, the assigned value is one greater than the current highest bit position (i.e., the highest bit position, implicit or explicit, prior to the current "bit" substatement in the parent "type" statement). Note that the presence of an "if-feature" statement in a "bit" statement does not affect the automatically assigned position. If the current highest bit position value is equal to 4294967295, then a position value MUST be specified for "bit" substatements following the one with the current highest position value. When an existing bits type is restricted, the "position" statement MUST either have the same value as in the base type or not be present, in which case the value is the same as in the base type.
Top   ToC   RFC7950 - Page 156

9.7.5. Usage Example

Given the following typedef and leaf: typedef mybits-type { type bits { bit disable-nagle { position 0; } bit auto-sense-speed { position 1; } bit ten-mb-only { position 2; } } } leaf mybits { type mybits-type; default "auto-sense-speed"; } The lexical representation of this leaf with bit values disable-nagle and ten-mb-only set would be: <mybits>disable-nagle ten-mb-only</mybits> The following example shows a legal refinement of this type: type mybits-type { // legal bit refinement bit disable-nagle { position 0; } bit auto-sense-speed { position 1; } }
Top   ToC   RFC7950 - Page 157
   and the following refinement is illegal:

     type mybits-type {
       // illegal bit refinement
       bit disable-nagle {
         position 2; // illegal position change
       }
       bit hundred-mb-only; // illegal addition of new name
     }

9.8. The binary Built-In Type

The binary built-in type represents any binary data, i.e., a sequence of octets.

9.8.1. Restrictions

A binary type can be restricted with the "length" (Section 9.4.4) statement. The length of a binary value is the number of octets it contains.

9.8.2. Lexical Representation

Binary values are encoded with the base64 encoding scheme (see Section 4 in [RFC4648]).

9.8.3. Canonical Form

The canonical form of a binary value follows the rules of "Base 64 Encoding" in [RFC4648].

9.9. The leafref Built-In Type

The leafref built-in type is restricted to the value space of some leaf or leaf-list node in the schema tree and optionally further restricted by corresponding instance nodes in the data tree. The "path" substatement (Section 9.9.2) is used to identify the referred leaf or leaf-list node in the schema tree. The value space of the referring node is the value space of the referred node. If the "require-instance" property (Section 9.9.3) is "true", there MUST exist a node in the data tree, or a node with a default value in use (see Sections 7.6.1 and 7.7.2), of the referred schema tree leaf or leaf-list node with the same value as the leafref value in a valid data tree.
Top   ToC   RFC7950 - Page 158
   If the referring node represents configuration data and the
   "require-instance" property (Section 9.9.3) is "true", the referred
   node MUST also represent configuration.

   There MUST NOT be any circular chains of leafrefs.

   If the leaf that the leafref refers to is conditional based on one or
   more features (see Section 7.20.2), then the leaf with the leafref
   type MUST also be conditional based on at least the same set of
   features.

9.9.1. Restrictions

A leafref can be restricted with the "require-instance" statement (Section 9.9.3).

9.9.2. The "path" Statement

The "path" statement, which is a substatement to the "type" statement, MUST be present if the type is "leafref". It takes as an argument a string that MUST refer to a leaf or leaf-list node. The syntax for a path argument is a subset of the XPath abbreviated syntax. Predicates are used only for constraining the values for the key nodes for list entries. Each predicate consists of exactly one equality test per key, and multiple adjacent predicates MAY be present if a list has multiple keys. The syntax is formally defined by the rule "path-arg" in Section 14. The predicates are only used when more than one key reference is needed to uniquely identify a leaf instance. This occurs if a list has multiple keys or a reference to a leaf other than the key in a list is needed. In these cases, multiple leafrefs are typically specified, and predicates are used to tie them together. The "path" expression evaluates to a node set consisting of zero, one, or more nodes. If the "require-instance" property is "true", this node set MUST be non-empty. The "path" XPath expression is conceptually evaluated in the following context, in addition to the definition in Section 6.4.1: o If the "path" statement is defined within a typedef, the context node is the leaf or leaf-list node in the data tree that references the typedef. o Otherwise, the context node is the node in the data tree for which the "path" statement is defined.
Top   ToC   RFC7950 - Page 159

9.9.3. The "require-instance" Statement

The "require-instance" statement, which is a substatement to the "type" statement, MAY be present if the type is "instance-identifier" or "leafref". It takes as an argument the string "true" or "false". If this statement is not present, it defaults to "true". If "require-instance" is "true", it means that the instance being referred to MUST exist for the data to be valid. This constraint is enforced according to the rules in Section 8. If "require-instance" is "false", it means that the instance being referred to MAY exist in valid data.

9.9.4. Lexical Representation

A leafref value is lexically represented the same way as the leaf it references represents its value.

9.9.5. Canonical Form

The canonical form of a leafref is the same as the canonical form of the leaf it references.

9.9.6. Usage Example

With the following list: list interface { key "name"; leaf name { type string; } leaf admin-status { type admin-status; } list address { key "ip"; leaf ip { type yang:ip-address; } } }
Top   ToC   RFC7950 - Page 160
   the following leafref refers to an existing interface:

     leaf mgmt-interface {
       type leafref {
         path "../interface/name";
       }
     }

   An example of a corresponding XML snippet:

     <interface>
       <name>eth0</name>
     </interface>
     <interface>
       <name>lo</name>
     </interface>

     <mgmt-interface>eth0</mgmt-interface>

   The following leafrefs refer to an existing address of an interface:

     container default-address {
       leaf ifname {
         type leafref {
           path "../../interface/name";
         }
       }
       leaf address {
         type leafref {
           path "../../interface[name = current()/../ifname]"
              + "/address/ip";
         }
       }
     }
Top   ToC   RFC7950 - Page 161
   An example of a corresponding XML snippet:

     <interface>
       <name>eth0</name>
       <admin-status>up</admin-status>
       <address>
         <ip>192.0.2.1</ip>
       </address>
       <address>
         <ip>192.0.2.2</ip>
       </address>
     </interface>
     <interface>
       <name>lo</name>
       <admin-status>up</admin-status>
       <address>
         <ip>127.0.0.1</ip>
       </address>
     </interface>

     <default-address>
       <ifname>eth0</ifname>
       <address>192.0.2.2</address>
     </default-address>

   The following list uses a leafref for one of its keys.  This is
   similar to a foreign key in a relational database.

     list packet-filter {
       key "if-name filter-id";
       leaf if-name {
         type leafref {
           path "/interface/name";
         }
       }
       leaf filter-id {
         type uint32;
       }
       ...
     }
Top   ToC   RFC7950 - Page 162
   An example of a corresponding XML snippet:

     <interface>
       <name>eth0</name>
       <admin-status>up</admin-status>
       <address>
         <ip>192.0.2.1</ip>
       </address>
       <address>
         <ip>192.0.2.2</ip>
       </address>
     </interface>

     <packet-filter>
       <if-name>eth0</if-name>
       <filter-id>1</filter-id>
       ...
     </packet-filter>
     <packet-filter>
       <if-name>eth0</if-name>
       <filter-id>2</filter-id>
       ...
     </packet-filter>

   The following notification defines two leafrefs to refer to an
   existing admin-status:

     notification link-failure {
       leaf if-name {
         type leafref {
           path "/interface/name";
         }
       }
       leaf admin-status {
         type leafref {
           path "/interface[name = current()/../if-name]"
              + "/admin-status";
         }
       }
     }
Top   ToC   RFC7950 - Page 163
   An example of a corresponding XML notification:

     <notification
       xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
       <eventTime>2008-04-01T00:01:00Z</eventTime>
       <link-failure xmlns="urn:example:system">
         <if-name>eth0</if-name>
         <admin-status>up</admin-status>
       </link-failure>
     </notification>



(page 163 continued on part 8)

Next Section