tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Gloss.     Arch.     IMS     UICC    |    Misc.    |    search     info

RFC 7950

 
 
 

The YANG 1.1 Data Modeling Language

Part 7 of 9, p. 138 to 163
Prev Section       Next Section

 


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