diff --git a/CHANGELOG.md b/CHANGELOG.md index ad2ebd7a..cbc70587 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,7 @@ * CLICON_YANG_MAIN_DIR Provides a directory where all yang modules should be loaded. ### API changes on existing features (you may need to change your code) +* CLICON_XML_SORT option (in clixon-config.yang) has been removed and set to true permanently since setting it to false is obsolete. * Strict namespace setting can be a problem when upgrading existing database files, such as startup-db or persistent running-db, or any other saved XML file. * For backward compatibility, load of startup and running set CLICON_XML_NS_STRICT to false temporarily. * Removed `delete-config` support for candidate db since it is not supported in RFC6241. diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index c9ea04ad..6a8b5943 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -482,7 +482,7 @@ from_client_edit_config(clicon_handle h, /* Cant do this earlier since we dont have a yang spec to * the upper part of the tree, until we get the "config" tree. */ - if (clicon_xml_sort(h) && xml_apply0(xc, CX_ELMNT, xml_sort, NULL) < 0) + if (xml_apply0(xc, CX_ELMNT, xml_sort, NULL) < 0) goto done; if ((ret = xmldb_put(h, target, operation, xc, cbret)) < 0){ clicon_debug(1, "%s ERROR PUT", __FUNCTION__); diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index 77d791cf..8e05c175 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -832,8 +832,6 @@ main(int argc, goto done; if (xmldb_setopt(h, "pretty", (void*)(intptr_t)clicon_option_bool(h, "CLICON_XMLDB_PRETTY")) < 0) goto done; - if (xmldb_setopt(h, "sort", (void*)(intptr_t)clicon_option_bool(h, "CLICON_XML_SORT")) < 0) - goto done; /* Startup mode needs to be defined, */ startup_mode = clicon_startup_mode(h); if (startup_mode == -1){ diff --git a/datastore/text/clixon_xmldb_text.c b/datastore/text/clixon_xmldb_text.c index d4160253..42210170 100644 --- a/datastore/text/clixon_xmldb_text.c +++ b/datastore/text/clixon_xmldb_text.c @@ -88,8 +88,6 @@ struct text_handle { Assumes single backend*/ char *th_format; /* Datastroe format: xml / json */ int th_pretty; /* Store xml/json pretty-printed. */ - int th_sort; /* Sort XML lists and leaf-lists alphabetically - (unless ordered-by user) */ }; /* Struct per database in hash */ @@ -241,8 +239,6 @@ text_getopt(xmldb_handle xh, *value = th->th_format; else if (strcmp(optname, "pretty") == 0) *value = &th->th_pretty; - else if (strcmp(optname, "sort") == 0) - *value = &th->th_sort; else{ clicon_err(OE_PLUGIN, 0, "Option %s not implemented by plugin", optname); goto done; @@ -292,9 +288,6 @@ text_setopt(xmldb_handle xh, else if (strcmp(optname, "pretty") == 0){ th->th_pretty = (intptr_t)value; } - else if (strcmp(optname, "sort") == 0){ - th->th_sort = (intptr_t)value; - } else{ clicon_err(OE_PLUGIN, 0, "Option %s not implemented by plugin", optname); goto done; @@ -551,14 +544,8 @@ text_get(xmldb_handle xh, /* Add default values (if not set) */ if (xml_apply(xt, CX_ELMNT, xml_default, NULL) < 0) goto done; - /* Order XML children according to YANG. - * XXX: should this be !th->th_sort? - */ - if (!th->th_sort) - if (xml_apply(xt, CX_ELMNT, xml_order, NULL) < 0) - goto done; #if 1 /* debug */ - if (th->th_sort && xml_apply0(xt, -1, xml_sort_verify, NULL) < 0) + if (xml_apply0(xt, -1, xml_sort_verify, NULL) < 0) clicon_log(LOG_NOTICE, "%s: sort verify failed #2", __FUNCTION__); #endif if (debug>1) @@ -741,7 +728,7 @@ text_modify(struct text_handle *th, } /* See if there is a corresponding node in the base tree */ x0c = NULL; - if (match_base_child(x0, x1c, &x0c, th->th_sort, yc) < 0) + if (match_base_child(x0, x1c, &x0c, yc) < 0) goto done; x0vec[i++] = x0c; } @@ -865,7 +852,7 @@ text_modify_top(struct text_handle *th, goto ok; } /* See if there is a corresponding node in the base tree */ - if (match_base_child(x0, x1c, &x0c, th->th_sort, yc) < 0) + if (match_base_child(x0, x1c, &x0c, yc) < 0) goto done; if (text_modify(th, x0c, (yang_node*)yc, x0, x1c, op, cbret) < 0) goto done; @@ -996,14 +983,8 @@ text_put(xmldb_handle xh, xml_name(x0)); goto done; } -#if 0 - /* Add yang specification backpointer to all XML nodes - * This is already done in from_client_edit_config() */ - if (xml_apply(x1, CX_ELMNT, xml_spec_populate, yspec) < 0) - goto done; -#endif #if 0 /* debug */ - if (th->th_sort && xml_apply0(x1, -1, xml_sort_verify, NULL) < 0) + if (xml_apply0(x1, -1, xml_sort_verify, NULL) < 0) clicon_log(LOG_NOTICE, "%s: verify failed #1", __FUNCTION__); #endif /* @@ -1029,7 +1010,7 @@ text_put(xmldb_handle xh, if (xml_tree_prune_flagged(x0, XML_FLAG_MARK, 1) < 0) goto done; #if 0 /* debug */ - if (th->th_sort && xml_apply0(x0, -1, xml_sort_verify, NULL) < 0) + if (xml_apply0(x0, -1, xml_sort_verify, NULL) < 0) clicon_log(LOG_NOTICE, "%s: verify failed #3", __FUNCTION__); #endif /* Write back to datastore cache if first time */ diff --git a/example/example_cli.c b/example/example_cli.c index 3aaf9259..bf24064d 100644 --- a/example/example_cli.c +++ b/example/example_cli.c @@ -110,7 +110,7 @@ fib_route_rpc(clicon_handle h, goto done; } /* Print result */ - xml2txt(stdout, xml_child_i(xret, 0), 1); + xml2txt(stdout, xml_child_i(xret, 0), 0); retval = 0; done: if (xret) diff --git a/lib/clixon/clixon_options.h b/lib/clixon/clixon_options.h index af92305c..04aae2e6 100644 --- a/lib/clixon/clixon_options.h +++ b/lib/clixon/clixon_options.h @@ -153,9 +153,6 @@ static inline char *clicon_xmldb_dir(clicon_handle h){ static inline char *clicon_xmldb_plugin(clicon_handle h){ return clicon_option_str(h, "CLICON_XMLDB_PLUGIN"); } -static inline int clicon_xml_sort(clicon_handle h){ - return clicon_option_bool(h, "CLICON_XML_SORT"); -} /*-- Specific option access functions for YANG options w type conversion--*/ int clicon_cli_genmodel(clicon_handle h); diff --git a/lib/clixon/clixon_xml_map.h b/lib/clixon/clixon_xml_map.h index 5148589a..2fa2afeb 100644 --- a/lib/clixon/clixon_xml_map.h +++ b/lib/clixon/clixon_xml_map.h @@ -62,7 +62,6 @@ int api_path_fmt2xpath(char *api_path_fmt, cvec *cvv, char **xpath); int xml_tree_prune_flagged_sub(cxobj *xt, int flag, int test, int *upmark); int xml_tree_prune_flagged(cxobj *xt, int flag, int test); int xml_default(cxobj *x, void *arg); -int xml_order(cxobj *x, void *arg); int xml_sanity(cxobj *x, void *arg); int xml_non_config_data(cxobj *xt, void *arg); int xml_spec_populate_rpc(clicon_handle h, cxobj *x, yang_spec *yspec); diff --git a/lib/clixon/clixon_xml_sort.h b/lib/clixon/clixon_xml_sort.h index 2a58472f..83f94f44 100644 --- a/lib/clixon/clixon_xml_sort.h +++ b/lib/clixon/clixon_xml_sort.h @@ -36,13 +36,6 @@ #ifndef _CLIXON_XML_SORT_H #define _CLIXON_XML_SORT_H -/* Sort and binary search of XML children - * XXX This variable is a kludge since low-level functions xml_merge/xml_diff calls - * match_base_child without handle - * @see clicon_xml_sort - */ -extern int xml_child_sort; - /* * Prototypes */ @@ -55,6 +48,6 @@ int xml_insert_pos(cxobj *x0, char *name, int yangi, enum rfc_6020 keyword, int upper); cxobj *xml_match(cxobj *x0, char *name, enum rfc_6020 keyword, int keynr, char **keyvec, char **keyval); int xml_sort_verify(cxobj *x, void *arg); -int match_base_child(cxobj *x0, cxobj *x1c, cxobj **x0cp, int xml_sort, yang_stmt *yc); +int match_base_child(cxobj *x0, cxobj *x1c, cxobj **x0cp, yang_stmt *yc); #endif /* _CLIXON_XML_SORT_H */ diff --git a/lib/src/clixon_options.c b/lib/src/clixon_options.c index 449b33ae..4fdb1dce 100644 --- a/lib/src/clixon_options.c +++ b/lib/src/clixon_options.c @@ -207,6 +207,8 @@ parse_configfile(clicon_handle h, *xconfig = xt; xt = NULL; done: + if (cbret) + cbuf_free(cbret); if (xt) xml_free(xt); if (f) @@ -275,11 +277,6 @@ clicon_options_main(clicon_handle h, goto done; /* Set clixon_conf pointer to handle */ clicon_conf_xml_set(h, xconfig); - /* Specific option handling */ - if (clicon_option_bool(h, "CLICON_XML_SORT") == 1) - xml_child_sort = 1; - else - xml_child_sort = 0; /* XXX Kludge to low-level functions to search for xml in all yang modules */ _CLICON_XML_NS_STRICT = clicon_option_bool(h, "CLICON_XML_NS_STRICT"); retval = 0; diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 5b4f513d..d3585ee4 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -988,8 +988,7 @@ xml_diff1(yang_stmt *ys, clicon_err(OE_UNIX, errno, "Unknown element: %s", xml_name(x1c)); goto done; } - /* XXX xml_child_sort is global */ - if (match_base_child(x2, x1c, &x2c, xml_child_sort, yc) < 0) + if (match_base_child(x2, x1c, &x2c, yc) < 0) goto done; if (x2c == NULL){ if (cxvec_append(x1c, x1vec, x1veclen) < 0) @@ -1025,8 +1024,7 @@ xml_diff1(yang_stmt *ys, clicon_err(OE_UNIX, errno, "Unknown element: %s", xml_name(x2c)); goto done; } - /* XXX xml_child_sort is global */ - if (match_base_child(x1, x2c, &x1c, xml_child_sort, yc) < 0) + if (match_base_child(x1, x2c, &x1c, yc) < 0) goto done; if (x1c == NULL) if (cxvec_append(x2c, x2vec, x2veclen) < 0) @@ -1550,70 +1548,6 @@ xml_default(cxobj *xt, return retval; } -/*! Order XML children according to YANG - * @param[in] xt XML top of tree - * @param[in] arg Dummy (so it can be called from xml_apply) - * @see xml_sort XXX: how do they relate? - * Called from text_get *only* - */ -int -xml_order(cxobj *xt, - void *arg) -{ - int retval = -1; - yang_stmt *y; - yang_stmt *yc; - int i; - int j0; - int j; - cxobj *xc; - cxobj *xj; - char *yname; /* yang child name */ - char *xname; /* xml child name */ - - if ((y = (yang_stmt*)xml_spec(xt)) == NULL){ - retval = 0; - goto done; - } - j0 = 0; - /* Go through yang node's children and ensure that the - * xml children follow this order. - * Do not order the list or leaf-list children (have same name). - */ - for (i=0; iys_len; i++){ - yc = y->ys_stmt[i]; - if (!yang_datanode(yc)) - continue; - yname = yc->ys_argument; - /* First go thru xml children with same name in rest of list */ - for (; j0ys_keyword, keynr, keyvec, keyval); + if (xml_child_nr(x0)==0 || xml_spec(xml_child_i(x0,0))!=NULL){ + yorder = yang_order(yc); + *x0cp = xml_search(x0, xml_name(x1c), yorder, yc->ys_keyword, keynr, keyvec, keyval); + } else{ - if (xml_child_nr(x0)==0 || xml_spec(xml_child_i(x0,0))!=NULL){ - yorder = yang_order(yc); - *x0cp = xml_search(x0, xml_name(x1c), yorder, yc->ys_keyword, keynr, keyvec, keyval); - } - else{ - *x0cp = xml_match(x0, xml_name(x1c), yc->ys_keyword, keynr, keyvec, keyval); - } + *x0cp = xml_match(x0, xml_name(x1c), yc->ys_keyword, keynr, keyvec, keyval); } ok: retval = 0; diff --git a/test/test_cli.sh b/test/test_cli.sh index b4005433..23fee546 100755 --- a/test/test_cli.sh +++ b/test/test_cli.sh @@ -115,7 +115,13 @@ expectfn "$clixon_cli -1 -f $cfg -l o debug level 1" 0 "^$" expectfn "$clixon_cli -1 -f $cfg -l o debug level 0" 0 "^$" new "cli rpc" -expectfn "$clixon_cli -1 -f $cfg -l o rpc ipv4" 0 "ipv4" "2.3.4.5" +expectfn "$clixon_cli -1 -f $cfg -l o rpc ipv4" 0 'rpc-reply { + route { + address-family ipv4; + next-hop { + next-hop-list 2.3.4.5; + } + source-protocol static;' if [ $BE -eq 0 ]; then exit # BE diff --git a/test/test_nacm_ext.sh b/test/test_nacm_ext.sh index b706b96f..b9cef0e1 100755 --- a/test/test_nacm_ext.sh +++ b/test/test_nacm_ext.sh @@ -209,7 +209,7 @@ new "cli show conf as guest" expectfn "$clixon_cli -1 -U guest -l o -f $cfg -y $fyang show conf" 255 "protocol access-denied" new "cli rpc as admin" -expectfn "$clixon_cli -1 -U andy -l o -f $cfg -y $fyang rpc ipv4" 0 "2.3.4.5" +expectfn "$clixon_cli -1 -U andy -l o -f $cfg -y $fyang rpc ipv4" 0 "next-hop-list 2.3.4.5;" new "cli rpc as limited" expectfn "$clixon_cli -1 -U wilma -l o -f $cfg -y $fyang rpc ipv4" 255 "protocol access-denied default deny" diff --git a/yang/clixon-config@2018-10-21.yang b/yang/clixon-config@2018-10-21.yang index d6b8c2c1..efa777e3 100644 --- a/yang/clixon-config@2018-10-21.yang +++ b/yang/clixon-config@2018-10-21.yang @@ -344,15 +344,6 @@ module clixon-config { If set, insert spaces and line-feeds making the XML/JSON human readable. If not set, make the XML/JSON more compact."; } - leaf CLICON_XML_SORT { - type boolean; - default true; - description - "If set, sort XML lists and leaf-lists alphabetically and uses binary - search. Unless ordered-by user is used. - Only works for Yang specified XML. - If not set, all lists accessed via linear search."; - } leaf CLICON_XML_NS_STRICT { type boolean; default true;