When a YANG typedef or leaf derives from another typedef, how may it narrow range, length and pattern, and why can it never widen them?
answer
- derived means subset
- equally or more limiting
- patterns pile up
- XSD regex matches the whole value
- the default must survive
basics
~20 sA derivation may only shrink the value space: a new range or length must be equally or more limiting, every base pattern still applies with new ones ANDed, and an inherited default that no longer fits must be replaced.
solid answer
~50 sA `typedef` names a restricted type so every module reuses one definition. Deriving from it, in another typedef or directly under a leaf's `type`, can only narrow. RFC 7950 says a new `range` or `length` MUST be equally or more limiting: raise lower bounds, lower upper bounds, drop values, or split ranges with gaps. A value must also match every `pattern` of the base type plus any new ones. So an MTU type `uint16 { range "68..max"; }` can become `range "1280..max"` for IPv6 links, never `"0..max"`. Patterns are XML Schema regular expressions and match the whole value, so `[0-9\.]*` restricts all of it. Widening is forbidden because every value of the derived type must still be a valid value of its base. If the inherited `default` falls outside the narrowed space, the derived type or leaf MUST give a new one.
code
yang · 20 linestypedef mtu {
type uint16 {
range "68..max";
}
units "octets";
default "1500";
}
typedef ipv6-link-mtu {
type mtu {
range "1280..max"; // legal: lower bound raised
}
}
leaf jumbo-mtu {
type mtu {
range "9000..9216"; // legal: narrower still
}
default "9000"; // required: 1500 no longer fits
}go deeper
Recall that a typedef names a reusable type, that range limits numbers and length and pattern limit strings, and that derived types only narrow.
Explain the exact narrowing rule, that patterns are ANDed and anchored, and why a narrowed leaf may have to restate its default.
Show the difference between deriving a type, which can only narrow, and revising the owning module, which may widen but never shrink, and what each does to existing clients.
Decide where shared typedefs should live and how strict they should be, knowing that loosening later is a cheap revision while tightening later breaks deployed clients.
## Typedefs: one definition, many uses A **typedef** (RFC 7950 §7.3) gives a name to a type plus its restrictions. The type it is built from is its **base type**, the new one is the **derived type**, and every chain ends at a built-in type. A typedef carries exactly one `type` and may add `units`, `default`, `description`, `reference` and `status`. Its name MUST NOT be a built-in type name, and a top-level typedef name MUST be unique in its module. Restrictions can be added at two points: in another `typedef` that uses the first one as its base, or inline under a leaf's `type` statement. The rules are the same in both places. ## The narrowing rules | Restriction | Applies to | Rule when the base is already restricted | |---|---|---| | `range` | integer types and `decimal64` | equally or more limiting: raise lower bounds, reduce upper bounds, remove values, split into ranges with gaps | | `length` | `string` and `binary` | the same rule; counts Unicode characters for a string, octets for binary | | `pattern` | `string` | all base patterns still apply; new ones are ANDed with them | | `enum`, `bit` | `enumeration`, `bits` | the new type keeps a subset of names; values and positions MUST NOT change | Inside a `range` or `length`, several values or intervals are joined with `|` and MUST be disjoint and ascending. `min` and `max` mean the bounds of the type being restricted, not of the built-in type. ## Worked example: an MTU type RFC 791 requires every IPv4 module to forward a 68-octet datagram without further fragmentation, and RFC 8200 requires every IPv6 link to carry at least 1280 octets. A reusable MTU typedef and two derivations: 1. `typedef mtu { type uint16 { range "68..max"; } units "octets"; default "1500"; }`. Here `max` is 65535, the top of `uint16`. 2. A derived `ipv6-link-mtu` with `range "1280..max"` is legal: the lower bound rose. It inherits the default 1500, which still fits. 3. A leaf `jumbo-mtu` with `range "9000..9216"` is legal too, but the inherited default 1500 is now outside the value space, so §7.3.4 requires the leaf to state a new default, such as 9000. 4. `range "0..max"` is illegal because it lowers a bound, and `range "1280..70000"` is illegal because 70000 is not a `uint16` value at all. ## Patterns: dialect, anchoring and ANDing A `pattern` takes a regular expression in the **XML Schema** dialect (RFC 7950 §9.4.5 cites XSD-TYPES). Three facts follow: - **The whole value must match.** XML Schema expressions are implicitly anchored at head and tail; RFC 7950 states this when it defines `re-match()` (§10.2.1). There is no `^` or `$` to add, and a pattern written in another dialect with them does not mean what its author intended. - **Patterns are ANDed.** Several `pattern` statements on one type must all match, and a derived type's patterns are added to the base type's, never substituted for them. - **`modifier invert-match`** (new in YANG 1.1) restricts the type to values that do **not** match one pattern. The common types module shows all three. In RFC 9911 (which obsoletes RFC 6991), `inet:ipv4-address` is a string whose pattern allows an optional zone index after `%`. `inet:ipv4-address-no-zone` derives from it and adds one more pattern, `[0-9\.]*`. Because the match is anchored, that pattern says "the whole value is digits and dots", so `192.0.2.1` passes both types while `192.0.2.1%1` passes only the first. Unanchored, the same expression would match a zero-length piece of any string and restrict nothing. RFC 9907, the authoring guidelines, asks for patterns in **single quotes**: in a double-quoted YANG string a backslash starts an escape, and YANG 1.1 allows only `\n`, `\t`, `\"` and `\\`, so `\d` or `\.` would be illegal there. ## Defaults and units along the chain - A derived type with no `default` of its own inherits the base type's default. - If the inherited default is invalid under the new restrictions, the derived type or leaf MUST specify a compatible one. - A typedef's `default` MUST itself be valid for its type. ## Narrowing versus revising "Never widen" is a rule about **derivation**. The owner of a published module may still widen its own type in a later revision: RFC 7950 §11 allows a `range`, `length` or `pattern` to expand the allowed value space, because every value that was valid stays valid. What a revision may not do is shrink it, since a client's previously valid value would start failing. ## Mistakes that show up in review - Adding a wider `range` under a leaf to make room for one device's larger value. - Expecting a new pattern to replace the base pattern rather than adding to it. - Using `length` on an integer, or `range` on a string. - Narrowing a range and forgetting the default it inherited.
- If derivation can never widen a YANG range, how does a module's owner widen one?In a new revision of the module that defines the type. RFC 7950 §11 allows a `range`, `length` or `pattern` to expand the allowed value space in a published revision, because every value that was valid stays valid. Shrinking it in a revision is not allowed: a client's previously valid value would start failing.
- Why does RFC 9907 ask for YANG patterns in single quotes?A single-quoted YANG string preserves every character. In a double-quoted string a backslash introduces an escape, and YANG 1.1 allows only `\n`, `\t`, `\"` and `\\`, so a pattern such as `\d+` or `\.` would be illegal or altered. Single quotes keep the regular expression exactly as written.
- What does modifier invert-match add to a YANG pattern?Added in YANG 1.1 (RFC 7950 §9.4.6), it makes the type accept only values that do not match that pattern. Combined with an ordinary pattern, it expresses "an identifier, but not one starting with xml" without writing a complicated negative expression.
saying these in an interview costs you the question
- A leaf can loosen a typedef's range when one device needs a bigger value.
- A new pattern on a derived type replaces the base type's pattern.
- YANG patterns need ^ and $ or they match substrings.
- A string length restriction counts bytes, not characters.
- The inherited default always applies, even outside the new range.
- A published type can never be widened, even in a new revision.