From 2f0f1ef5a727c09424913279d92dbee855310ef0 Mon Sep 17 00:00:00 2001 From: Jan-Olof Carlson Date: Wed, 17 Aug 2022 07:12:50 +0000 Subject: [PATCH] FC6243 with-defaults=report-all-tagged test cases and implementation added --- apps/backend/backend_get.c | 84 +++++++++++++++++++++++++++++-- lib/src/clixon_netconf_lib.c | 2 +- test/test_netconf_hello.sh | 2 +- test/test_netconf_ssh_callhome.sh | 2 +- test/test_yang_with_defaults.sh | 13 +++-- 5 files changed, 92 insertions(+), 11 deletions(-) diff --git a/apps/backend/backend_get.c b/apps/backend/backend_get.c index b71c54ae..78fe8a78 100644 --- a/apps/backend/backend_get.c +++ b/apps/backend/backend_get.c @@ -680,6 +680,68 @@ get_list_pagination(clicon_handle h, return retval; } +/*! Set flag on node having schema default value. + * @param[in] x XML node + * @param[in] flag Flag to be used + * @retval 0 OK + + */ +static int +xml_flag_default_value(cxobj *x, uint16_t flag) +{ + yang_stmt *y; + cg_var *cv; + char *yv; + char *xv; + + xml_flag_reset(x, flag); /* Assume not default value */ + if ((xv = xml_body(x)) == NULL) + goto done; + if ((y = xml_spec(x)) == NULL) + goto done; + if ((cv = yang_cv_get(y)) == NULL) + goto done; + if ((cv = yang_cv_get(y)) == NULL) + goto done; + if (cv_name_get(cv) == NULL) + goto done; + if ((yv = cv2str_dup(cv)) == NULL) + goto done; + if (strcmp(xv, yv) == 0) + xml_flag_set(x, flag); /* Actual value same as default value */ + free(yv); + + done: + return 0; +} + +/*! Add default attribute to node with default value. + * @param[in] x XML node + * @param[in] flags Flags indicatiing default nodes + * @retval 0 OK + * @retval -1 Error + */ +static int +xml_add_default_tag(cxobj *x, uint16_t flags) +{ + int retval = -1; + cxobj *xattr; + + if (xml_flag(x, flags)) { + /* set default attribute */ + if ((xattr = xml_new("default", x, CX_ATTR)) == NULL) + goto done; + if (xml_value_set(xattr, "true") < 0) + goto done; + if (xml_prefix_set(xattr, "wd") < 0) + goto done; + } + retval = 0; + done: + return retval; +} + + /*! Common get/get-config code for retrieving configuration and state information. * * @param[in] h Clicon handle @@ -846,23 +908,39 @@ get_common(clicon_handle h, /* rfc6243 Handle with-defaults. */ if ((xfind = xml_find(xe, "with-defaults")) != NULL) { if ((with_defaults = xml_find_value(xfind, "body")) != NULL) { + if (strcmp(with_defaults, "explicit") == 0) { /* Clear marked nodes */ if (xml_apply(xret, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)XML_FLAG_MARK) < 0) goto done; - /* Traverse XML and mark state nodes */ + /* Mark state nodes */ if (xml_non_config_data(xret, NULL) < 0) goto done; - /* Remove default configuration nodes from XML */ + /* Remove default configuration nodes*/ if (xml_tree_prune_flags(xret, XML_FLAG_DEFAULT, XML_FLAG_MARK|XML_FLAG_DEFAULT) < 0) goto done; + /* TODO. Remove empty containers */ } else if (strcmp(with_defaults, "trim") == 0) { /* Remove default nodes from XML */ if (xml_tree_prune_flags(xret, XML_FLAG_DEFAULT, XML_FLAG_DEFAULT) < 0) goto done; + /* Mark and remove nodes having schema default values */ + if (xml_apply(xret, CX_ELMNT, (xml_applyfn_t*)xml_flag_default_value, (void*)XML_FLAG_MARK) < 0) + goto done; + if (xml_tree_prune_flags(xret, XML_FLAG_MARK, XML_FLAG_MARK) < 0) + goto done; + /* TODO. Remove empty containers */ } - else if (strcmp(with_defaults, "report-all") == 0) { + else if (strcmp(with_defaults, "report-all-tagged") == 0) { + /* Mark nodes having default schema values */ + if (xml_apply(xret, CX_ELMNT, (xml_applyfn_t*)xml_flag_default_value, (void*)XML_FLAG_MARK) < 0) + goto done; + /* Add tag attributes to default nodes */ + if (xml_apply(xret, CX_ELMNT, (xml_applyfn_t*)xml_add_default_tag, (void*)(XML_FLAG_DEFAULT | XML_FLAG_MARK)) < 0) + goto done; + } + else if (strcmp(with_defaults, "report-all") == 0) { /* Accept mode, do nothing */ } else { diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c index c3ed587e..26f2f990 100644 --- a/lib/src/clixon_netconf_lib.c +++ b/lib/src/clixon_netconf_lib.c @@ -1725,7 +1725,7 @@ netconf_hello_server(clicon_handle h, cprintf(cb, "urn:ietf:params:netconf:capability:xpath:1.0"); cprintf(cb, "urn:ietf:params:netconf:capability:notification:1.0"); /* rfc6243 with-defaults capability modes */ - cprintf(cb, "urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all,trim"); + cprintf(cb, "urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all,trim,report-all-tagged"); cprintf(cb, ""); if (session_id) cprintf(cb, "%lu", (long unsigned int)session_id); diff --git a/test/test_netconf_hello.sh b/test/test_netconf_hello.sh index 319b3c28..4e90fcd1 100755 --- a/test/test_netconf_hello.sh +++ b/test/test_netconf_hello.sh @@ -106,7 +106,7 @@ new "Netconf snd hello with prefix" expecteof "$clixon_netconf -qef $cfg" 0 "urn:ietf:params:netconf:base:1.1]]>]]>" '^$' new "netconf snd + rcv hello" -expecteof "$clixon_netconf -f $cfg" 0 "urn:ietf:params:netconf:base:1.1]]>]]>" "^urn:ietf:params:netconf:base:1.1urn:ietf:params:netconf:base:1.0urn:ietf:params:netconf:capability:yang-library:1.0?revision=2019-01-04&module-set-id=42urn:ietf:params:netconf:capability:candidate:1.0urn:ietf:params:netconf:capability:validate:1.1urn:ietf:params:netconf:capability:startup:1.0urn:ietf:params:netconf:capability:xpath:1.0urn:ietf:params:netconf:capability:notification:1.0urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=report-all&also-supported=explicit,trim[0-9]*]]>]]>$" '^$' +expecteof "$clixon_netconf -f $cfg" 0 "urn:ietf:params:netconf:base:1.1]]>]]>" "^urn:ietf:params:netconf:base:1.1urn:ietf:params:netconf:base:1.0urn:ietf:params:netconf:capability:yang-library:1.0?revision=2019-01-04&module-set-id=42urn:ietf:params:netconf:capability:candidate:1.0urn:ietf:params:netconf:capability:validate:1.1urn:ietf:params:netconf:capability:startup:1.0urn:ietf:params:netconf:capability:xpath:1.0urn:ietf:params:netconf:capability:notification:1.0urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all,trim,report-all-tagged[0-9]*]]>]]>$" '^$' new "Netconf snd hello with extra element" expecteof "$clixon_netconf -qef $cfg" 0 "urn:ietf:params:netconf:base:1.1]]>]]>" '^protocolunknown-elementextra-elementerrorUnrecognized hello/capabilities element]]>]]>$' '^$' diff --git a/test/test_netconf_ssh_callhome.sh b/test/test_netconf_ssh_callhome.sh index 0144825a..43f7fb8d 100755 --- a/test/test_netconf_ssh_callhome.sh +++ b/test/test_netconf_ssh_callhome.sh @@ -132,7 +132,7 @@ EOF new "Start Listener client" echo "ssh -s -F $sshcfg -v -i $key -o ProxyUseFdpass=yes -o ProxyCommand=\"clixon_netconf_ssh_callhome_client -a 127.0.0.1\" . netconf" #-F $sshcfg -expectpart "$(ssh -s -F $sshcfg -v -i $key -o ProxyUseFdpass=yes -o ProxyCommand="${clixon_netconf_ssh_callhome_client} -a 127.0.0.1" . netconf < $rpccmd)" 0 "urn:ietf:params:netconf:base:1.1urn:ietf:params:netconf:base:1.0urn:ietf:params:netconf:capability:yang-library:1.0?revision=2019-01-04&module-set-id=42urn:ietf:params:netconf:capability:candidate:1.0urn:ietf:params:netconf:capability:validate:1.1urn:ietf:params:netconf:capability:startup:1.0urn:ietf:params:netconf:capability:xpath:1.0urn:ietf:params:netconf:capability:notification:1.0urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=report-all&also-supported=explicit,trim2" "" +expectpart "$(ssh -s -F $sshcfg -v -i $key -o ProxyUseFdpass=yes -o ProxyCommand="${clixon_netconf_ssh_callhome_client} -a 127.0.0.1" . netconf < $rpccmd)" 0 "urn:ietf:params:netconf:base:1.1urn:ietf:params:netconf:base:1.0urn:ietf:params:netconf:capability:yang-library:1.0?revision=2019-01-04&module-set-id=42urn:ietf:params:netconf:capability:candidate:1.0urn:ietf:params:netconf:capability:validate:1.1urn:ietf:params:netconf:capability:startup:1.0urn:ietf:params:netconf:capability:xpath:1.0urn:ietf:params:netconf:capability:notification:1.0urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all,trim,report-all-tagged2" "" # Wait wait diff --git a/test/test_yang_with_defaults.sh b/test/test_yang_with_defaults.sh index bef0921b..6d6125a0 100755 --- a/test/test_yang_with_defaults.sh +++ b/test/test_yang_with_defaults.sh @@ -172,7 +172,7 @@ wait_restconf new "rfc4243 4.3. Capability Identifier" expecteof "$clixon_netconf -ef $cfg" 0 "$DEFAULTHELLO" \ -"urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=report-all&also-supported=explicit,trim" +"urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all,trim,report-all-tagged" new "rfc6243 3.1. 'report-all' Retrieval Mode" expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" \ @@ -195,7 +195,7 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" \ eth08192\ eth1\ eth29000not feeling so good\ -eth31500waking up\ +eth3waking up\ " new "rfc6243 3.3. 'explicit' Retrieval Mode" @@ -215,9 +215,12 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" \ "\ report-all-tagged" \ "" \ -"applicationoperation-not-supported\ -error\ -with-defaults retrieval mode \"report-all-tagged\" is not supported" +"\ +eth08192ok\ +eth11500ok\ +eth29000not feeling so good\ +eth31500waking up\ +" new "rfc6243 2.3.1. 'explicit' Basic Mode Retrieval" expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" \