From ac51cb02934c5a217e2cd59bfdb83235e72de62d Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Fri, 7 May 2021 13:07:34 +0200 Subject: [PATCH] * Fix: XPath:s used in netconf (eg get-config) did not correctly access default values --- CHANGELOG.md | 1 + apps/backend/backend_plugin.c | 6 +++--- lib/clixon/clixon_xml.h | 16 +++++++++------- lib/src/clixon_datastore_read.c | 29 ++++++++++++++++++++++------- lib/src/clixon_datastore_write.c | 6 +++--- lib/src/clixon_xml_map.c | 4 ++-- test/test_yang_deviation.sh | 4 +--- 7 files changed, 41 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d26b529d..b7438c64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ Users may have to change how they access the system ### Corrected Bugs +* Fix: XPath:s used in netconf (eg get-config) did not correctly access default values * [RESTCONF GET request of single-key list with empty string returns all elements #213](https://github.com/clicon/clixon/issues/213) * [RESTCONF GETof lists with empty string keys does not work #214](https://github.com/clicon/clixon/issues/214) * Fixed: [Multiple http requests in native restconf yields same reply #212](https://github.com/clicon/clixon/issues/212) diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index 83824eae..c4eecc9c 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -347,11 +347,11 @@ clixon_plugin_statedata_all(clicon_handle h, } if (xml_sort_recurse(x) < 0) goto done; - /* Mark non-presence containers as XML_FLAG_DEFAULT */ - if (xml_apply(x, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_DEFAULT) < 0) + /* Mark non-presence containers */ + if (xml_apply(x, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_TRANSIENT) < 0) goto done; /* Clear XML tree of defaults */ - if (xml_tree_prune_flagged(x, XML_FLAG_DEFAULT, 1) < 0) + if (xml_tree_prune_flagged(x, XML_FLAG_TRANSIENT, 1) < 0) goto done; /* clear mark and change */ xml_apply0(x, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, diff --git a/lib/clixon/clixon_xml.h b/lib/clixon/clixon_xml.h index 1c073767..d016613d 100644 --- a/lib/clixon/clixon_xml.h +++ b/lib/clixon/clixon_xml.h @@ -156,13 +156,15 @@ typedef struct clixon_xml_vec clixon_xvec; /* struct defined in clicon_xml_vec.c /* * xml_flag() flags: */ -#define XML_FLAG_MARK 0x01 /* Marker for dynamic algorithms, eg expand */ -#define XML_FLAG_ADD 0x02 /* Node is added (commits) or parent added rec*/ -#define XML_FLAG_DEL 0x04 /* Node is deleted (commits) or parent deleted rec */ -#define XML_FLAG_CHANGE 0x08 /* Node is changed (commits) or child changed rec */ -#define XML_FLAG_NONE 0x10 /* Node is added as NONE */ -#define XML_FLAG_DEFAULT 0x20 /* Added when a value is set as default @see xml_default */ -#define XML_FLAG_TOP 0x40 /* Top datastore symbol */ +#define XML_FLAG_MARK 0x01 /* General-purpose eg expand and xpath_vec selection and + * diffs between candidate and running */ +#define XML_FLAG_TRANSIENT 0x02 /* Marker for dynamic algorithms, unmark asap */ +#define XML_FLAG_ADD 0x04 /* Node is added (commits) or parent added rec*/ +#define XML_FLAG_DEL 0x08 /* Node is deleted (commits) or parent deleted rec */ +#define XML_FLAG_CHANGE 0x10 /* Node is changed (commits) or child changed rec */ +#define XML_FLAG_NONE 0x20 /* Node is added as NONE */ +#define XML_FLAG_DEFAULT 0x40 /* Added when a value is set as default @see xml_default */ +#define XML_FLAG_TOP 0x80 /* Top datastore symbol */ /* * Prototypes diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c index 7f57c144..0413d2c6 100644 --- a/lib/src/clixon_datastore_read.c +++ b/lib/src/clixon_datastore_read.c @@ -504,6 +504,11 @@ xmldb_readfile(clicon_handle h, if (singleconfigroot(x0, &x0) < 0) goto done; } + /* Purge all top-level body objects */ + x = NULL; + while ((x = xml_find_type(x0, NULL, "body", CX_BODY)) != NULL) + xml_purge(x); + xml_flag_set(x0, XML_FLAG_TOP); if (xml_child_nr(x0) == 0 && de) de->de_empty = 1; @@ -799,8 +804,15 @@ xmldb_get_cache(clicon_handle h, goto done; if (ret == 0) ; /* XXX */ + else { + /* Add default global values (to make xpath below include defaults) */ + if (xml_global_defaults(h, x0t, nsc, xpath, yspec, 0) < 0) + goto done; + /* Add default recursive values */ + if (xml_default_recurse(x0t, 0) < 0) + goto done; + } } - /* Here x0t looks like: ... */ /* Given the xpath, return a vector of matches in xvec * Can we do everything in one go? @@ -848,11 +860,14 @@ xmldb_get_cache(clicon_handle h, goto done; } /* Remove global defaults from cache - * Mark non-presence containers as XML_FLAG_DEFAULT */ - if (xml_apply(x0t, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_DEFAULT) < 0) + * Mark non-presence containers */ + if (xml_apply(x0t, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_TRANSIENT) < 0) + goto done; + /* clear XML tree of defaults */ + if (xml_tree_prune_flagged(x0t, XML_FLAG_DEFAULT, 1) < 0) goto done; /* Clear XML tree of defaults */ - if (xml_tree_prune_flagged(x0t, XML_FLAG_DEFAULT, 1) < 0) + if (xml_tree_prune_flagged(x0t, XML_FLAG_TRANSIENT, 1) < 0) goto done; if (yb != YB_NONE){ /* Add default global values */ @@ -1120,11 +1135,11 @@ xmldb_get0_clear(clicon_handle h, if (x == NULL) goto ok; - /* Mark non-presence containers as XML_FLAG_DEFAULT */ - if (xml_apply(x, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_DEFAULT) < 0) + /* Mark non-presence containers */ + if (xml_apply(x, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_TRANSIENT) < 0) goto done; /* Clear XML tree of defaults */ - if (xml_tree_prune_flagged(x, XML_FLAG_DEFAULT, 1) < 0) + if (xml_tree_prune_flagged(x, XML_FLAG_TRANSIENT, 1) < 0) goto done; /* clear mark and change */ diff --git a/lib/src/clixon_datastore_write.c b/lib/src/clixon_datastore_write.c index a4425258..5693f6c0 100644 --- a/lib/src/clixon_datastore_write.c +++ b/lib/src/clixon_datastore_write.c @@ -994,11 +994,11 @@ xmldb_put(clicon_handle h, if (xml_apply(x0, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)(XML_FLAG_NONE|XML_FLAG_MARK)) < 0) goto done; - /* Mark non-presence containers as XML_FLAG_DEFAULT */ - if (xml_apply(x0, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_DEFAULT) < 0) + /* Mark non-presence containers */ + if (xml_apply(x0, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_TRANSIENT) < 0) goto done; /* Clear XML tree of defaults */ - if (xml_tree_prune_flagged(x0, XML_FLAG_DEFAULT, 1) < 0) + if (xml_tree_prune_flagged(x0, XML_FLAG_TRANSIENT, 1) < 0) goto done; #if 0 /* debug */ if (xml_apply0(x0, -1, xml_sort_verify, NULL) < 0) diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index ca5fa16f..33d2a468 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -1409,9 +1409,9 @@ xml_nopresence_default(cxobj *xt) * @param[in] x * @param[in] arg (flag value) * @code - * if (xml_apply(xt, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_DEFAULT) < 0) + * if (xml_apply(xt, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_TRANSIENT) < 0) * err; - * if (xml_tree_prune_flagged(xt, XML_FLAG_DEFAULT, 1) < 0) + * if (xml_tree_prune_flagged(xt, XML_FLAG_TRANSIENT, 1) < 0) * goto done; * @endcode */ diff --git a/test/test_yang_deviation.sh b/test/test_yang_deviation.sh index 37ee3421..17a16be7 100755 --- a/test/test_yang_deviation.sh +++ b/test/test_yang_deviation.sh @@ -126,9 +126,7 @@ function testrun() if $admindefault; then # add rule new "Get type admin expected" - expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^bobadmin]]>]]>$" -# XXX Cannot select a default value?? - # expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" foo + expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^bobadmin]]>]]>$" else new "Get type none expected" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$"