skip to content

In a NETCONF subtree filter, how do containment, selection and content-match nodes combine to return one interface's counters and nothing else?

level: middleimportance: must knowfreq 15%

answer

  1. state data needs the right retrieval
  2. the filter mirrors the data tree
  3. a leaf with text matches exactly
  4. an empty element selects a subtree

basics

~20 s

Send <get> (counters are state data, which <get-config> never returns) with a subtree filter: interfaces and interface as containment nodes, name with the text eth0 as a content-match node, and an empty statistics element as a selection node.

solid answer

~40 s

A subtree filter is an XML fragment shaped like the data. **Containment nodes** (`<interfaces>`, `<interface>`) have child elements and narrow the path. A **content-match node** (`<name>eth0</name>`) is a leaf with text; it is an exact-match test, and sibling content-match nodes are ANDed. A **selection node** (`<statistics/>`) is an empty element; its presence returns that subtree and suppresses the other siblings, so `description`, `type` and `oper-status` stay out. The reply holds the matched `name` and the `statistics` subtree. Drop `<statistics/>` and, with no selection or containment sibling, the whole `eth0` entry comes back. Use `<get>`, because counters are `config false`; `<get-config>` returns configuration only. No filter at all returns the entire data tree, which is the expensive mistake on a large device.

go deeper

for a junior

Remember that a subtree filter is an XML fragment shaped like the data, and that leaving it out returns the whole tree.

for a middle

Name the three node kinds, show how the selection node suppresses siblings, and explain why state counters need get rather than get-config.

for a senior

Show you filter every polling request, handle the deprecated interfaces-state tree on older servers, and read an empty reply as no match rather than as zero.

for a principal

Discuss what unfiltered polling costs a large fleet, and set the rule that collectors filter on the server side by default.

## The problem the filter solves A large device can hold thousands of interfaces, routes and sessions. A `<get>` without a filter returns **the entire data model**, configuration and state, to read one number. NETCONF's default filter type, the **subtree filter** (RFC 6241 section 6), lets the client say exactly which part of the tree it wants, and the server prunes everything else before replying. ## The five components RFC 6241 names five things that can appear in a subtree filter: - **Namespace selection**: an element matches only if its XML namespace matches the data model's. An element with an empty namespace (`xmlns=""`) is a wildcard: the server evaluates every namespace it supports for that node. - **Attribute match expressions**: XML attributes in the filter must match the data's attributes. YANG-modelled data rarely uses them. - **Containment nodes**: elements that contain child elements. They select instances along the path and pass the remaining criteria down. - **Selection nodes**: empty elements (`<foo/>`, or start and end tags with only whitespace). They select that node and its whole subtree, and their presence **suppresses** the automatic selection of the other siblings. - **Content-match nodes**: leaves with non-whitespace text. They are an **exact-match** test on that leaf's content. ## The worked filter The interfaces model (`ietf-interfaces`, RFC 8343) keeps per-interface counters in a `config false` container, `statistics`, under each `interface` list entry, keyed by `name`. ```xml <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <get> <filter type="subtree"> <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"> <interface> <name>eth0</name> <statistics/> </interface> </interfaces> </filter> </get> </rpc> ``` | Node | Kind | Effect | |---|---|---| | `interfaces` | containment | only this module's top container | | `interface` | containment | each list entry is tested with its children | | `name` = `eth0` | content match | the entry qualifies only if its name is exactly `eth0` | | `statistics` | selection | return this subtree; suppress the other siblings | ## How the server evaluates a sibling set RFC 6241 processes each **sibling set** (children of one parent) together: 1. Every content-match node in the set is tested. If **any** is false, the whole sibling set is pruned, so another interface contributes nothing. 2. If all are true, each content-match node is included in the output, so `name` comes back and identifies the entry. 3. Containment siblings are processed further and included if their nested criteria match. 4. Selection siblings are included with their full subtrees. 5. If there are **no** selection or containment siblings, every node at that level comes back, which is why `<interface><name>eth0</name></interface>` alone returns the entire `eth0` entry. The reply therefore holds `interfaces` / `interface` / `name` = `eth0` plus the whole `statistics` container (`in-octets`, `in-errors`, `discontinuity-time` and the rest): ```xml <rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <data> <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"> <interface> <name>eth0</name> <statistics> <discontinuity-time>2026-09-30T08:00:00Z</discontinuity-time> <in-octets>918273645</in-octets> <in-errors>0</in-errors> </statistics> </interface> </interfaces> </data> </rpc-reply> ``` (The reply is abridged; a real one carries every counter the device supports.) Nothing about `description`, `type`, `enabled` or `oper-status` appears, because the selection node suppressed those siblings. ## Edge cases worth knowing - **No filter** returns everything; an **empty** filter (`<filter type="subtree"></filter>`) returns an empty `<data>`, and that is not an error. - Several content-match siblings are **ANDed**: `<name>eth0</name><enabled>true</enabled>` needs both. To fetch two interfaces, repeat the `<interface>` fragment; the server does not duplicate data selected twice. - Matching is exact text equality, so there is no "greater than" and no pattern. That is the boundary where an XPath filter takes over. - On a server without the NMDA changes, the counters may live only in the older, now deprecated `/interfaces-state` tree; RFC 8343 moved them into `/interfaces` and obsoleted RFC 7223. Check the YANG library before writing the path. - `<get-config>` with the same filter returns no counters: they are `config false` state data. On an NMDA server, RFC 8526's `<get-data>` against the operational datastore accepts the same subtree filter. ## Why this matters operationally A poller that reads one interface's counters every few seconds without a filter forces the device to serialise its whole data tree each time, and the client to parse it. The filter costs nothing to write and moves the selection to the side that holds the data.

  • How do you fetch the counters of eth0 and eth1 in one NETCONF subtree-filtered request?
    Repeat the list-entry fragment: two `<interface>` elements under `<interfaces>`, each with its own `<name>` content-match node and a `<statistics/>` selection node. Content-match siblings inside one fragment are ANDed, so putting both names in one entry would match nothing; separate fragments act as alternatives, and RFC 6241 says data selected by several fragments is not duplicated in the reply.
  • What does a NETCONF subtree filter return if the name content-match node has no matching interface?
    A false content-match test prunes that whole sibling set, so no `interface` entry is selected. The reply is a valid `<data>` without that entry, not an `<rpc-error>`: a filter that selects nothing is not an error. A client must treat an empty result as "no such entry" rather than as a successful read of zero counters.

saying these in an interview costs you the question

  • A <get-config> with this filter returns the interface counters too.
  • An empty subtree filter returns everything, like leaving the filter out.
  • A content-match node on its own returns only that matched leaf.
  • Two content-match siblings select entries that match either of them.
  • Selecting one list entry by its key requires an XPath filter.