diff --git a/CHANGELOG.md b/CHANGELOG.md index 13ff9628..315d996a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Expected: January 2025 * Changed: `CLICON_NETCONF_DUPLICATE_ALLOW` to not only check but remove duplicates * Added: `CLICON_CLI_PIPE_DIR` * Added: `CLICON_XMLDB_SYSTEM_ONLY_CONFIG` + * Deprecated: `CLICON_YANG_SCHEMA_MOUNT_SHARE` ### C/CLI-API changes on existing features diff --git a/lib/clixon/clixon_xml_bind.h b/lib/clixon/clixon_xml_bind.h index 9b02c96a..ff0ea542 100644 --- a/lib/clixon/clixon_xml_bind.h +++ b/lib/clixon/clixon_xml_bind.h @@ -45,10 +45,10 @@ */ int xml_bind_yang_unknown_anydata(int val); int xml_bind_netconf_message_id_optional(int val); +int xml_bind_yang(clixon_handle h, cxobj *xt, yang_bind yb, yang_stmt *yspec, cxobj **xerr); +int xml_bind_yang0(clixon_handle h, cxobj *xt, yang_bind yb, yang_stmt *yspec, cxobj **xerr); int xml_bind_yang_rpc(clixon_handle h, cxobj *xrpc, yang_stmt *yspec, cxobj **xerr); int xml_bind_yang_rpc_reply(clixon_handle h, cxobj *xrpc, char *name, yang_stmt *yspec, cxobj **xerr); -int xml_bind_yang0(clixon_handle h, cxobj *xt, yang_bind yb, yang_stmt *yspec, cxobj **xerr); -int xml_bind_yang(clixon_handle h, cxobj *xt, yang_bind yb, yang_stmt *yspec, cxobj **xerr); int xml_bind_special(cxobj *xd, yang_stmt *yspec, char *schema_nodeid); #endif /* _CLIXON_XML_BIND_H_ */ diff --git a/lib/clixon/clixon_yang_schema_mount.h b/lib/clixon/clixon_yang_schema_mount.h index 9f8fe0d7..0067b900 100644 --- a/lib/clixon/clixon_yang_schema_mount.h +++ b/lib/clixon/clixon_yang_schema_mount.h @@ -63,7 +63,8 @@ int xml_yang_mount_get(clixon_handle h, cxobj *x, validate_level *vl, char **xpa int xml_yang_mount_set(clixon_handle h, cxobj *x, yang_stmt *yspec); int yang_mount_xtop2xmnt(cxobj *xtop, cvec **cvvp); int yang_schema_mount_statedata(clixon_handle h, yang_stmt *yspec, char *xpath, cvec *nsc, cxobj **xret, cxobj **xerr); -int yang_schema_yanglib_parse_mount(clixon_handle h, cxobj *xt); +int yang_schema_yanglib_mount_parse(clixon_handle h, cxobj *xt, cxobj *xyanglib, yang_stmt **yspecp); +int yang_schema_yanglib_get_mount_parse(clixon_handle h, cxobj *xt); int yang_schema_get_child(clixon_handle h, cxobj *x1, cxobj *x1c, yang_stmt **yc); int yang_schema_yspec_rm(clixon_handle h, cxobj *xmnt); diff --git a/lib/src/clixon_xml_bind.c b/lib/src/clixon_xml_bind.c index 807abae2..51fb936f 100644 --- a/lib/src/clixon_xml_bind.c +++ b/lib/src/clixon_xml_bind.c @@ -142,7 +142,6 @@ strip_body_objects(cxobj *xt) * @param[in] h Clixon handle * @param[in] xt XML tree node * @param[in] xsibling - * @param[in] yspec Top-level YANG spec / mount-point * @param[out] xerr Reason for failure, or NULL * @retval 2 OK Yang assignment not made because yang parent is anyxml or anydata * @retval 1 OK Yang assignment made @@ -155,7 +154,6 @@ static int populate_self_parent(clixon_handle h, cxobj *xt, cxobj *xsibling, - yang_stmt *yspec, cxobj **xerr) { int retval = -1; @@ -448,7 +446,7 @@ xml_bind_yang0_opt(clixon_handle h, goto done; break; case YB_PARENT: - if ((ret = populate_self_parent(h, xt, xsibling, yspec, xerr)) < 0) + if ((ret = populate_self_parent(h, xt, xsibling, xerr)) < 0) goto done; break; default: @@ -474,7 +472,7 @@ xml_bind_yang0_opt(clixon_handle h, else if (h == NULL) goto ok; /* treat as anydata */ else{ - if ((ret = yang_schema_yanglib_parse_mount(h, xt)) < 0) // XXX malloc + freed här + if ((ret = yang_schema_yanglib_get_mount_parse(h, xt)) < 0) goto done; if (ret == 0){ /* Special flag if mount-point but no yanglib */ xml_flag_set(xt, XML_FLAG_ANYDATA); @@ -557,7 +555,7 @@ xml_bind_yang0(clixon_handle h, goto done; break; case YB_PARENT: - if ((ret = populate_self_parent(h, xt, NULL, yspec, xerr)) < 0) + if ((ret = populate_self_parent(h, xt, NULL, xerr)) < 0) goto done; break; case YB_NONE: diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index e83fc61f..99070fdd 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -48,7 +48,7 @@ * such as . An xml with (or ) will NOT match EVEN IF they have the * same namespace given by xmlns settings. * 2) RFC6241 8.9.1 - * In the scope of get-.config, the set of namespace declarations are those in scope on the + * In the scope of get-config, the set of namespace declarations are those in scope on the * element. * * diff --git a/lib/src/clixon_yang_module.c b/lib/src/clixon_yang_module.c index e9e6f928..d550559c 100644 --- a/lib/src/clixon_yang_module.c +++ b/lib/src/clixon_yang_module.c @@ -851,10 +851,10 @@ yang_metadata_init(clixon_handle h) * This function is used where a yang-lib module-set is available to populate * an XML mount-point. * @param[in] h Clixon handle - * @param[in] xyanglib XML tree on the form ... - * @param[in] mntpnt Name of mount-point for logs + * @param[in] xyanglib XML tree on the form * + * @param[in] mntpnt Name of mount-point for logs (debug) * @param[in] domain YANG domain (NULL is default) - * @param[in] yspec Will be populated with YANGs, is consumed + * @param[in] yspec Will be populated with YANGs * @retval 1 OK * @retval 0 Parse error * @retval -1 Error diff --git a/lib/src/clixon_yang_schema_mount.c b/lib/src/clixon_yang_schema_mount.c index 245c20eb..d49c3fc0 100644 --- a/lib/src/clixon_yang_schema_mount.c +++ b/lib/src/clixon_yang_schema_mount.c @@ -53,6 +53,10 @@ * The API handles the relation between yext -->* ymnt -->* xmnt * Structure: * + * ymounts(top) + * | + * ydomain* + * | * yspec0(1) xtop(1) * | | (xpath) * ymnt(*) <-- xmnt(*) @@ -64,11 +68,11 @@ * The calls in this code are: * - yang_schema_mount_point(): Is ymnt a yang mount-point? (ymnt) * - yang_mount_get(): ymnt + xpath -> yspec + * XXXX - yang_mount_get(): ymnt + xpath -> yspec * - yang_mount_set(): ymnt * - xml_yang_mount_get(): xmnt-> yspec * - xml_yang_mount_set(): xmnt -> yspec * - yang_mount_get_yspec_any(): ymnt -> yspec - * - yang_mounto_freeall(): ymnt-> free cvec * - yang_mount_xmnt2ymnt_xpath(): xmnt -> ymnt + xpath * - yang_mount_xtop2xmnt(): top-level xml -> xmnt vector * - yang_mount_yspec2ymnt(): top-level yspec -> ymnt vector NOTUSED @@ -183,11 +187,13 @@ yang_schema_mount_point(yang_stmt *y) /*! Get yangspec mount-point * - * @param[in] y Yang container/list containing unknown node + * @param[in] ys Yang container/list containing unknown node * @param[in] xpath Key for yspec on y * @param[out] yspec YANG stmt spec * @retval 0 OK * @retval -1 Error + * With domains it is assumed an xpath is unique across domains, which is true if the xpath + * has eg a list name which is unique. But there could be cases where this is not true. */ int yang_mount_get(yang_stmt *ys, @@ -721,7 +727,7 @@ yang_schema_find_share(clixon_handle h, cg_var *cv; cxobj *xroot; cxobj *xmnt; - cxobj *xylib; + cxobj *xylib = NULL; int config = 1; int ret; @@ -735,7 +741,10 @@ yang_schema_find_share(clixon_handle h, xmnt = cv_void_get(cv); if (xmnt == xt) continue; - xylib = NULL; + if (xylib){ + xml_free(xylib); + xylib = NULL; + } /* Get xyanglib */ if (clixon_plugin_yang_mount_all(h, xmnt, &config, NULL, &xylib) < 0) goto done; @@ -753,44 +762,41 @@ yang_schema_find_share(clixon_handle h, } retval = 0; done: + if (xylib) + xml_free(xylib); if (cvv) cvec_free(cvv); return retval; } -/*! Get yanglib from user plugin callback, parse it and mount it +/*! Given yanglib, mount it, potentially create a new yspec, and parse all its yangs * * Optionally check for shared yspec - * @param[in] h Clixon handle - * @param[in] xt XML tree node - * @retval 1 OK - * @retval 0 No yanglib or problem when parsing yanglib - * @retval -1 Error + * @param[in] h Clixon handle + * @param[in] xt XML tree node + * @param[in] xyanglib XML yang-lib + * @retval 1 OK + * @retval 0 No yanglib or problem when parsing yanglib + * @retval -1 Error */ int -yang_schema_yanglib_parse_mount(clixon_handle h, - cxobj *xt) +yang_schema_yanglib_mount_parse(clixon_handle h, + cxobj *xt, + cxobj *xyanglib, + yang_stmt **yspecp) { int retval = -1; - cxobj *xyanglib = NULL; cxobj *xb; + char *domain = NULL; yang_stmt *ymounts; yang_stmt *ydomain; yang_stmt *yspec0 = NULL; yang_stmt *yspec1 = NULL; char *xpath = NULL; - char *domain = NULL; cbuf *cb = NULL; int ret; static unsigned int nr = 0; - /* 1. Get modstate (xyanglib) of node: xyanglib, by querying backend state (via callback) - * XXX this xyanglib is not proper RFC8525, submodules appear as modules WHY? - */ - if (clixon_plugin_yang_mount_all(h, xt, NULL, NULL, &xyanglib) < 0) - goto done; - if (xyanglib == NULL) - goto anydata; if ((xb = xpath_first(xyanglib, NULL, "module-set/name")) != NULL) domain = xml_body(xb); if (domain == NULL){ @@ -813,10 +819,8 @@ yang_schema_yanglib_parse_mount(clixon_handle h, goto done; } /* Optimization: find equal yspec from other mount-point */ - if (clicon_option_bool(h, "CLICON_YANG_SCHEMA_MOUNT_SHARE")) { - if (yang_schema_find_share(h, xt, xyanglib, &yspec0) < 0) - goto done; - } + if (yang_schema_find_share(h, xt, xyanglib, &yspec0) < 0) + goto done; if ((cb = cbuf_new()) == NULL){ clixon_err(OE_YANG, errno, "cbuf_new"); goto done; @@ -835,15 +839,54 @@ yang_schema_yanglib_parse_mount(clixon_handle h, } if (xml_yang_mount_set(h, xt, yspec1) < 0) goto done; + if (yspecp) + *yspecp = yspec1; yspec1 = NULL; retval = 1; done: + if (yspec1) + ys_free(yspec1); if (cb) cbuf_free(cb); if (xpath) free(xpath); - if (yspec1) - ys_free(yspec1); + return retval; + anydata: + retval = 0; + goto done; +} + +/*! Get yanglib from user plugin callback, create yspec, mount it and parse all yangs + * + * Optionally check for shared yspec + * @param[in] h Clixon handle + * @param[in] xt XML tree node + * @retval 1 OK + * @retval 0 No yanglib or problem when parsing yanglib + * @retval -1 Error + */ +int +yang_schema_yanglib_get_mount_parse(clixon_handle h, + cxobj *xt) +{ + int retval = -1; + cxobj *xyanglib = NULL; + int ret; + + clixon_debug(CLIXON_DBG_APP, ""); + /* 1. Get modstate (xyanglib) of node: xyanglib, by querying backend state (via callback) + * XXX this xyanglib is not proper RFC8525, submodules appear as modules WHY? + */ + if (clixon_plugin_yang_mount_all(h, xt, NULL, NULL, &xyanglib) < 0) + goto done; + if (xyanglib == NULL) + goto anydata; + if ((ret = yang_schema_yanglib_mount_parse(h, xt, xyanglib, NULL)) < 0) + goto done; + if (ret == 0) + goto anydata; + retval = 1; + done: if (xyanglib) xml_free(xyanglib); return retval; diff --git a/yang/clixon/clixon-config@2024-11-01.yang b/yang/clixon/clixon-config@2024-11-01.yang index 88c3584c..39aba110 100644 --- a/yang/clixon/clixon-config@2024-11-01.yang +++ b/yang/clixon/clixon-config@2024-11-01.yang @@ -55,6 +55,7 @@ module clixon-config { CLICON_XMLDB_SYSTEM_ONLY_CONFIG CLICON_CLI_PIPE_DIR Changed: CLICON_NETCONF_DUPLICATE_ALLOW to not only check but remove duplicates + Deprecated: CLICON_YANG_SCHEMA_MOUNT_SHARE Released in Clixon 7.3"; } revision 2024-08-01 { @@ -618,8 +619,10 @@ module clixon-config { (yangmnt:mount-point is on same node). A comparison is made between yang modules and revision and must match exactly. If so, a new yang-spec is not created, instead the other is used. - Only if CLICON_YANG_SCHEMA_MOUNT is enabled"; - default false; + Only if CLICON_YANG_SCHEMA_MOUNT is enabled + Enabled permanently and deprecated when yang domains introduced"; + status deprecated; + default true; } leaf CLICON_YANG_AUGMENT_ACCEPT_BROKEN { type boolean;