Skip to content

fix(yang-push): resolve xpath-filter target modules by prefix - #43

Open
rodonile wants to merge 2 commits into
network-analytics:mainfrom
rodonile:xpath-namespace
Open

fix(yang-push): resolve xpath-filter target modules by prefix#43
rodonile wants to merge 2 commits into
network-analytics:mainfrom
rodonile:xpath-namespace

Conversation

@rodonile

@rodonile rodonile commented Aug 21, 2026

Copy link
Copy Markdown
Member

Summary

YANG-Push cache misses that fall back to fetch-by-subscription-id failed for
devices sending an inline datastore-xpath-filter without xmlns prefix
bindings (e.g. Cisco IOS-XR, where the path prefix is the YANG module name,
like Cisco-IOS-XR-procmem-oper:...). Module resolution only consulted
declared namespace prefixes, so the subscription's own target module was
never considered for the NETCONF get-schema set.

Devices that declare xmlns bindings on their filters (e.g. Huawei) were
unaffected.

Root cause

Per RFC 8641, the XPath context for datastore-xpath-filter is built by
combining two prefix-resolution mechanisms:

  1. Implicit: the prefix is the YANG module name for every module the
    server implements (no xmlns needed) — this is what Cisco IOS-XR uses.
  2. Additive: xmlns declarations on the leaf element, which override on
    conflict — this is what Huawei uses.

The fetcher only supported mechanism (2), so inline Cisco filters resolved to
zero modules and the fetch "succeeded" with an incomplete library.

Changes

  • Resolve xpath-filter modules per the full RFC 8641 context: try the
    declared xmlns binding first, then fall back to treating the path prefix
    as the YANG module name. Subtree and stream filters keep namespace-based
    lookup.
  • Hard-fail on empty resolution instead of caching an incomplete library
    that keeps failing validation forever.
  • Scope the prefix-as-module-name fallback by datastore: the implicit
    fallback now uses a datastore-scoped module lookup (mirroring the
    namespace-based one) instead of an unscoped search, so it can't return a
    module revision pinned in an unrelated datastore/module-set.
  • Improved logging and added unit tests covering the two resolution paths

Fetching a YANG Library by subscription id failed for devices that
send an inline datastore-xpath-filter without xmlns bindings (e.g.
Cisco IOS-XR), because module resolution only looked at declared
namespace prefixes. The target module was silently dropped and every
subsequent notification failed validation.

Resolve xpath-filter modules per the RFC 8641 XPath context: use a
declared xmlns binding when present (e.g. Huawei), otherwise treat the
path prefix as the YANG module name (e.g. Cisco IOS-XR). Both are
conformant. Subtree and stream filters keep namespace-based lookup.

An empty resolution result is now a hard error instead of silently
caching an incomplete library, and errors are now typed instead of
generic IO errors.

Add unit tests covering the two resolution cases, and
extra trace-level logging for debugging.
@rodonile rodonile self-assigned this Aug 21, 2026
@rodonile
rodonile enabled auto-merge (rebase) August 21, 2026 13:45
@rodonile
rodonile requested a balanced review from Copilot August 21, 2026 13:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes YANG-Push cache fallback by resolving inline XPath prefixes against device YANG libraries.

Changes:

  • Adds namespace and module-name prefix resolution.
  • Rejects empty or unresolved module sets.
  • Adds diagnostics and resolution tests.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
crates/yang-push/src/cache/storage.rs Adds resolution-specific errors.
crates/yang-push/src/cache/fetcher.rs Implements target-module resolution.
crates/netconf-proto/src/yang_push/tests.rs Tests XPath prefix extraction.
crates/netconf-proto/src/yang_push/filters.rs Exposes path prefixes.
crates/netconf-proto/src/xml_utils.rs Shares XPath prefix parsing.
crates/netconf-proto/src/client.rs Adds NETCONF diagnostics.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread crates/yang-push/src/cache/fetcher.rs Outdated
Comment thread crates/netconf-proto/src/xml_utils.rs
The Cisco-style xpath prefix fallback (prefix == module name) resolved
modules via YangLibrary::find_module, which searches every module set
in the library regardless of datastore. A module name can be pinned at
different revisions in different module sets (RFC 8525), so an
unscoped lookup could silently fetch and cache the wrong revision for
a subscription's target datastore.

Add YangLibrary::find_module_by_datastore_and_name, mirroring the
existing namespace-scoped lookup, and use it for the prefix-as-name
fallback so both resolution paths are scoped consistently. Add a
regression test with the same module name at two revisions in two
datastores.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (1)

crates/netconf-proto/src/yang_push/tests.rs:803

  • The Huawei-style XPath example has a likely typo in the path (devm:chassiss). It doesn’t affect the prefix-extraction assertion, but it makes the test fixture harder to read and can confuse future debugging (it looks like it’s meant to be devm:chassis).
        namespaces: Box::new([
            ("devm".into(), "urn:huawei:yang:huawei-devm".into()),
            ("driver".into(), "urn:huawei:yang:huawei-driver".into()),
        ]),
        path: "/devm:devm/devm:chassiss/devm:chassis/driver:power-supply-attribute".into(),
    };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants