In YANG, how do feature and if-feature make part of a module optional, and what happens when a client configures an unsupported part?
answer
- the server decides, not the client
- a named optional capability
- boolean expression since YANG 1.1
- an error-tag, not silent acceptance
basics
~20 sA feature statement names an optional capability and if-feature ties schema nodes to it. Where a server does not support the feature those nodes are absent from its schema, and a NETCONF server must reject data for them with unknown-element.
solid answer
~40 s`feature` declares a named, optional capability of a module: RFC 7950's own example is `local-storage` in a syslog model, and `ietf-interfaces` (RFC 8343) defines `arbitrary-names`, `pre-provisioning` and `if-mib`. `if-feature` on a statement makes it exist only on servers where its expression is true; since YANG 1.1 the argument is a boolean expression with `not`, `and`, `or` and parentheses, where YANG 1.0 took a single feature name. The server decides which features it supports, not the client. If a client sends data for a node whose `if-feature` evaluates false, RFC 7950 §8.3.1 requires a NETCONF server to reply with an `unknown-element` `<rpc-error>`, so the gap fails loudly. A disabled node's default is not in use, and a feature that carries its own `if-feature` can only be supported together with the features it names.
go deeper
Remember that a YANG feature names an optional capability and that if-feature attaches parts of a module to it. The server, not the client, decides which features it supports.
Explain the YANG 1.1 expression syntax and precedence, and say exactly what a NETCONF server does with data for a disabled node: an unknown-element error, with the node's default no longer in use.
Show how supported features shape the schema an automation system must target per device, and why loud rejection of unsupported data is what keeps pushed intent and device state from drifting apart unnoticed.
Weigh features against separate modules when designing a model family: fine-grained features multiply the combinations clients must handle, while extra modules keep the base stable but are harder to discover.
## Why a YANG module needs optional parts A YANG module is a contract between a management client and a server: every node it defines is something the client may read or write. Real devices differ, though. RFC 7950 §5.6.2 gives the canonical example: a syslog model can offer to store logs locally, but a box without local storage cannot honour that. Rather than publish two modules, YANG lets the **modeler** mark sections as conditional and lets the **server** say which conditions hold for it. That mechanism is the pair of statements `feature` and `if-feature`, one of three conformance tools RFC 7950 lists alongside the basic behaviour of the model and deviations. ## Declaring a feature and conditioning nodes - `feature <name>` defines a label for a capability. It may carry `description`, `reference`, `status` and its own `if-feature` substatements (§7.20.1.1). - `if-feature <expr>` makes its parent statement conditional. It may sit in data nodes, `choice` and `case`, `uses`, `rpc`, `action`, `notification`, `augment`, `identity` and `feature`, and since YANG 1.1 also in `enum`, `bit` and `refine`. - A real example: `ietf-interfaces` (RFC 8343) defines the feature `if-mib`, and the leaf `link-up-down-trap-enable` carries `if-feature if-mib`, so it exists only on servers that also implement the Interfaces Group MIB. ```yang feature local-storage { description "The server can store syslog messages locally."; } container syslog { leaf local-storage-limit { if-feature local-storage; type uint64; units "kilobyte"; config false; } } ``` Note that the conditional leaf here is `config false`: features apply to state data just as much as to configuration. ## The if-feature expression | | YANG 1.0 (RFC 6020) | YANG 1.1 (RFC 7950) | |---|---|---| | Argument | one feature name | a boolean expression over feature names | | Operators | none | `not`, `and`, `or`, parentheses | | Precedence | n/a | parentheses, then `not`, then `and`, then `or` | | Allowed on enum, bit, identity, refine | no | yes | So `if-feature "not foo or bar and baz"` means `(not foo) or (bar and baz)`. A prefixed name refers to a feature in an imported module; an unprefixed one must be defined in the current module or one of its submodules. ## What the server does with a disabled node When an expression evaluates false on a server, the conditioned schema nodes are simply not part of that server's schema. Three consequences follow: 1. **Edits are rejected.** RFC 7950 §8.3.1: if data for a node tagged `if-feature` arrives and the expression is false, a NETCONF server MUST reply with an `<rpc-error>` whose `error-tag` is `unknown-element`. Accepting and dropping the data is not an option the standard offers. 2. **Defaults go quiet.** A default value is not in use when the leaf or any ancestor has an `if-feature` that evaluates false (§7.6.1), so the server must not behave as if the default applied. 3. **The schema shrinks for every datastore that lacks the feature.** RFC 8342 defines a datastore schema as the modules supported by that datastore, taking deviations and enabled features into account, so a feature can be enabled in one datastore and not in another. Which features a server supports is reported through the YANG library, a mechanism of its own; what matters here is that the support set comes from the server. ## Rules that trip module authors - **No if-feature on a list key.** §7.20.2 forbids it outright, and §1.1 lists this as a backward-incompatible change from YANG 1.0. Put the condition on the list itself. - **A default must not depend on a feature.** §7.6.4 calls `default blue` illegal when `enum blue` carries `if-feature blue`. - **Dependent features travel together.** If a feature has `if-feature` substatements, a server supporting it MUST support the features they name (§7.20.1). - **No cycles.** A feature MUST NOT reference itself, directly or through a chain. ## Feature or separate module? RFC 9907 (BCP 216, which obsoletes RFC 8407) adds authoring guidance in §4.17. Very fine-grained features raise interoperability complexity and should be avoided; tagging individual counters with separate features is its named example of misuse. When a large set of objects hangs off one capability, a separate module is often better, partly for stability: adding a feature means republishing the base module, while a new module leaves the base untouched. The trade is discoverability: a module's features are easy to read, the set of related modules is not.
- Why may a YANG 1.1 list key leaf not carry its own if-feature statement?RFC 7950 §7.20.2 forbids it, a backward-incompatible change from YANG 1.0. A list entry is identified by its key, so a key that exists on some servers and not others would leave entries without an identity. To make keyed data optional, put `if-feature` on the list; the condition then covers the whole entry, and RFC 9907 §4.5 says conditions on a list must apply equally to its keys.
- When should a YANG module author use a separate module rather than a feature for optional functionality?RFC 9907 §4.17: when a large set of objects hangs off the capability, or when the base module should stay stable. A new feature means republishing the base module; a separate module does not. Very fine-grained features, such as one per counter, add interoperability complexity and should be avoided. The cost of separate modules is that readers must discover the related set themselves.
saying these in an interview costs you the question
- if-feature is evaluated against settings the client chooses per request
- A server should accept and quietly drop data for a feature it lacks
- if-feature on a list key leaf makes that key optional
- YANG 1.1 if-feature still accepts only a single feature name
- A disabled node's default value still applies on the device