From 335a18fecf1ac467f0b79b9d1b8e732212027b09 Mon Sep 17 00:00:00 2001 From: Vyacheslav Yamont Date: Sun, 25 Jan 2026 20:58:08 +0100 Subject: [PATCH] Fix identityref namespace binding in config-path-info XML Ensure identityref values with prefixed QNames get the correct xmlns binding --- lib/src/clixon_xml_map.c | 9 +- ...enconfig_spanning_tree_enabled_protocol.sh | 110 ++++++++++++++++++ 2 files changed, 117 insertions(+), 2 deletions(-) create mode 100755 test/test_openconfig_spanning_tree_enabled_protocol.sh diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index fe46f41e..4046c3b8 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -1878,11 +1878,15 @@ identityref_add_ns(cxobj *x, char *b; if ((y = xml_spec(x)) != NULL && - yang_keyword_get(y) == Y_LEAF){ + (yang_keyword_get(y) == Y_LEAF || + yang_keyword_get(y) == Y_LEAF_LIST)){ + if (yspec == NULL) + yspec = ys_spec(y); if (yang_type_get(y, &origtype, &yrestype, NULL, NULL, NULL, NULL, NULL) < 0) goto done; restype = yrestype?yang_argument_get(yrestype):NULL; - if (strcmp(restype, "identityref") == 0 && + if (restype && + strcmp(restype, "identityref") == 0 && (b = xml_body(x)) != NULL){ if (nodeid_split(b, &pf, NULL) < 0) goto done; @@ -1891,6 +1895,7 @@ identityref_add_ns(cxobj *x, if (xml2ns(x, pf, &ns) < 0) goto done; if (ns == NULL && + yspec && (yns = yang_find_module_by_prefix_yspec(yspec, pf)) != NULL){ if ((ns = yang_find_mynamespace(yns)) != NULL) if (xmlns_set(x, pf, ns) < 0) diff --git a/test/test_openconfig_spanning_tree_enabled_protocol.sh b/test/test_openconfig_spanning_tree_enabled_protocol.sh new file mode 100755 index 00000000..55dee6d1 --- /dev/null +++ b/test/test_openconfig_spanning_tree_enabled_protocol.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +# Verify openconfig-spanning-tree enabled-protocol identityref resolves oc-stp-types prefix. +# Reproduces CLI error: "prefix \"oc-stp-types\" has no associated namespace" + +# Magic line must be first in script (see README.md) +s="$_" +. ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi + +APPNAME=example + +new "openconfig" +if [ ! -d "$OPENCONFIG" ]; then + # err "Hmm Openconfig dir does not seem to exist, try git clone https://github.com/openconfig/public?" + echo "...skipped: OPENCONFIG not set" + rm -rf $dir + if [ "$s" = $0 ]; then exit 0; else return 0; fi +fi + +OCSTP=$OPENCONFIG/release/models/stp/openconfig-spanning-tree.yang +cfg=$dir/openconfig_spanning_tree_enabled_protocol.xml + +AUTOCLI=$(autocli_config "*" kw-nokey false) + +# Optional restconf config +RESTCONF_ENABLE=false +RESTCONF_FEATURE="" +RESTCONF_CFG="" +if [ $RC -ne 0 ]; then + RESTCONF_CFG=$(restconf_config none false) + if [ $? -eq 0 ]; then + RESTCONF_ENABLE=true + RESTCONF_FEATURE="clixon-restconf:allow-auth-none" + fi +fi + +cat <$cfg + + $cfg + $RESTCONF_FEATURE + ${OPENCONFIG} + ${YANG_INSTALLDIR} + $OCSTP + true + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/run/$APPNAME.sock + /usr/local/var/run/$APPNAME.pidfile + $dir + $AUTOCLI + $RESTCONF_CFG + +EOF + +if [ $BE -ne 0 ]; then + new "kill old backend" + sudo clixon_backend -zf $cfg + new "start backend -s init -f $cfg" + start_backend -s init -f $cfg +fi + +new "wait backend" +wait_backend + +new "cli set stp global enabled-protocol identityref" +expectpart "$($clixon_cli -1 -f $cfg set stp global config enabled-protocol oc-stp-types:MSTP 2>&1)" 0 "^$" + +new "netconf validate candidate" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "" "" + +if $RESTCONF_ENABLE; then + new "kill old restconf daemon" + stop_restconf_pre + + new "start restconf daemon" + start_restconf -f $cfg +fi + +if $RESTCONF_ENABLE; then + new "wait restconf" + wait_restconf + + new "restconf PATCH enabled-protocol identityref" + expectpart "$(curl $CURLOPTS -X PATCH -H "Content-Type: application/yang-data+json" -d '{"openconfig-spanning-tree:config":{"enabled-protocol":["openconfig-spanning-tree-types:MSTP"]}}' $RCPROTO://localhost/restconf/data/openconfig-spanning-tree:stp/global/config)" 0 "HTTP/$HVER 204" + + new "restconf GET enabled-protocol" + expectpart "$(curl $CURLOPTS -H "Accept: application/yang-data+json" -X GET $RCPROTO://localhost/restconf/data/openconfig-spanning-tree:stp/global/config/enabled-protocol)" 0 "HTTP/$HVER 200" "openconfig-spanning-tree-types:MSTP" + + new "Kill restconf daemon" + stop_restconf +else + echo "...skipped: restconf not enabled" +fi + +new "discard-changes" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "" "" + +if [ $BE -ne 0 ]; then + new "Kill backend" + pid=$(pgrep -u root -f clixon_backend) + if [ -z "$pid" ]; then + err "backend already dead" + fi + stop_backend -f $cfg +fi + +rm -rf $dir + +new "endtest" +endtest