skip to content

When a YANG value set such as interface types must grow across modules and vendors, why choose identity and identityref over an enumeration?

level: seniorimportance: should knowfreq 10%

answer

  1. who may add a value
  2. an enum lives in one module
  3. identities derive from a base
  4. transitive, not reflexive
  5. test with derived-from-or-self

basics

~20 s

An enumeration's names belong to the one module that defines it, so only that module's next revision can add one; any module can derive a new identity from a published base, so an identityref accepts values its author never saw.

solid answer

~50 s

RFC 9907 §4.11.1 gives the rule: use `enumeration` when the set is fixed and controlled by one naming authority, and `identityref` when it needs distributed extensibility or a hierarchy. An enumeration grows only through a new revision of its own module (RFC 7950 §11), and a type derived from it may keep only a subset of names. An `identity` is derived from another with `base`, transitively and, in YANG 1.1, from several bases. A leaf typed `identityref { base if:interface-type; }` accepts any identity derived from that base in any module the server implements, which is how the interfaces module types its `type` leaf while the IANA-maintained iana-if-type module and others add values. The costs: values are qualified names, conditions should use `derived-from-or-self()` rather than string equality, and RFC 9907 notes identityref leaves are generally more expensive to process than enumerations.

code

yang · 17 lines
yang
// module example-tunnel, prefix tun
identity tunnel-encap {
  description "Base for tunnel encapsulations.";
}
identity gre {
  base tunnel-encap;
}
leaf encapsulation {
  type identityref {
    base tunnel-encap;
  }
}

// module example-tunnel-ext, prefix tx, imports example-tunnel
identity vxlan {
  base tun:tunnel-encap;
}

go deeper

for a junior

Recall that enumeration lists fixed names inside a type, while identityref accepts identities derived from a base that other modules can extend.

for a middle

Explain how enum values are assigned, why only a revision of the owning module can add an enum, and what transitive identity derivation means for valid values.

for a senior

Make the modelling call and defend it: who will extend the set, how clients learn the server's valid values, and why conditions must use derived-from-or-self.

for a principal

Plan value-set ownership across a multi-vendor estate: which sets IANA or your team owns, which partners extend, and what processing cost and per-server variation you accept.

## Two ways to model a set of names YANG offers two ways to say "this leaf holds one of a set of named values": - **`enumeration`** (RFC 7950 §9.6): the names are listed with `enum` statements inside the type itself. - **`identity` plus `identityref`** (§7.18 and §9.10): each name is a separate, globally unique `identity`, and a leaf of type `identityref` accepts identities derived from a named base. The difference that matters is **who may add a name, and where**. ## Enumeration mechanics - Each `enum` has an assigned name and an integer `value`. If no value is given, the first enum gets 0 and each later one gets one more than the highest value so far. - A type derived from an enumeration (allowed from YANG 1.1) may keep only a **subset** of the names and MUST NOT change their values. No other module can add a name. - The owning module may add enums in a new revision, provided existing values do not change. RFC 7950 §11 warns that inserting an enum before existing ones, or reordering them, renumbers every enum without an explicit value. - The wire carries the name, so XML and JSON stay readable; the integer matters to anything that maps the enum to numbers. ## Identity mechanics - An **identity** is abstract and untyped: its only purpose is to denote its name, semantics and existence. It carries no number. - `base` derives one identity from another. Derivation is **transitive** (if C derives from B and B from A, C derives from A) and **irreflexive** (no identity derives from itself). YANG 1.1 allows several `base` statements, and the identity then derives from all of them. - An `identityref` MUST name at least one `base`. Its valid values are identities derived from **all** its bases. On a particular server they are further limited to identities defined in modules the server **implements**. - Any module may define a new identity with a published base, without touching the module that defined the base. ## Choosing between them | Question | `enumeration` | `identityref` | |---|---|---| | Who adds a value? | only the owning module, in a new revision | any module that derives from the base | | Can values form a hierarchy? | no | yes, through `base` chains | | Can a value have several parents? | no | yes, in YANG 1.1 | | How does a client learn the valid set? | read the type | the implemented modules on that server | | Relative processing cost (RFC 9907 §4.24) | lower | generally higher | | RFC 9907 guidance | fixed set, single naming authority | distributed extensibility or hierarchy | ## The interface-type case RFC 8343's `ietf-interfaces` gives every interface a mandatory `type` leaf of `identityref` with base `interface-type`. The values come from the IANA-maintained `iana-if-type` module, which mirrors the ifType registry, and any other module can derive further types. Had `type` been an enumeration, every new interface kind would have needed a new revision of `ietf-interfaces` itself, and a vendor could not add its own kind without forking the module. The IANA case shows the guidance is not absolute: RFC 9907 notes that IANA-maintained modules use either approach, and even one authority may choose identities when it wants a hierarchy. ## Operating consequences 1. **Qualified names on the wire.** An identityref value names the identity together with where it is defined: an XML namespace prefix, or in JSON the defining module's name. Only an identity from the leaf's own module (or, in XML, the default namespace) may appear bare. 2. **Hierarchy-aware tests.** RFC 9907 §4.6.2 says a `when` or `must` expression should use `derived-from-or-self()` rather than comparing an identityref with a string, so a later, more specific identity still matches. Writing those expressions belongs to the constraint statements; the reason they are needed is the identity tree. 3. **Server-dependent value sets.** Two servers implementing different modules accept different identities for the same leaf, so a client must check which modules a server implements before sending a value defined in an optional module. 4. **Feature gating.** YANG 1.1 allows `if-feature` on an `enum`, a `bit` and an `identity`, so either form can switch values on per server. ## A short rule of thumb Choose `enumeration` for closed sets that one authority owns and that rarely change: an admin status, a direction, a duplex mode. Choose `identityref` for open sets that others will extend: interface types, encapsulations, crypto algorithms, address families.

  • What breaks if a YANG author inserts a new enum in the middle of an enumeration that has no explicit values?
    Implicit values are assigned in order, each one more than the highest so far, so every later enum is renumbered. RFC 7950 §11 calls this out: the names on the wire are unchanged, but anything relying on the integers, such as `enum-value()` in an expression or a mapping to numeric codes, silently changes meaning. Append new enums, or give values explicitly.
  • Which identities does a YANG identityref with base interface-type accept on a particular server?
    Identities derived from that base directly or transitively, but not the base itself, since derivation is irreflexive. RFC 7950 §9.10.2 further restricts them to identities defined in modules the server implements, so a value from a module the server does not implement is invalid there even though the schema allows it in principle.

saying these in an interview costs you the question

  • Any module can add a value to another module's enumeration by restricting it.
  • An identityref accepts only identities whose base is named directly.
  • Comparing an identityref with a string literal is the robust test.
  • Enumerations are obsolete; YANG models should always use identities.
  • An identity carries a numeric value, like an enum.