Replaced YANG find share algorithm, use direct yanglib diff
This commit is contained in:
parent
803da7b76a
commit
419e8312f9
2 changed files with 47 additions and 174 deletions
|
|
@ -212,10 +212,6 @@
|
||||||
*/
|
*/
|
||||||
#undef USE_SHA256
|
#undef USE_SHA256
|
||||||
|
|
||||||
/*! Temporary comparison of xyanglibs, should be removed asap
|
|
||||||
*/
|
|
||||||
#define YANG_SCHEMA_CMP_KLUDGE
|
|
||||||
|
|
||||||
/*! Force add ietf-yang-library@2019-01-04 on all mount-points
|
/*! Force add ietf-yang-library@2019-01-04 on all mount-points
|
||||||
*
|
*
|
||||||
* This is a limitation of of the current implementation
|
* This is a limitation of of the current implementation
|
||||||
|
|
|
||||||
|
|
@ -339,14 +339,14 @@ yang_mount_xmnt2ymnt_xpath(clixon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Get yangspec mount-point
|
/*! Given XML mount-point get yangspec mount-point
|
||||||
*
|
*
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] xmnt XML mount-point
|
* @param[in] xmnt XML mount-point
|
||||||
* @param[out] vallevel Do or dont do full RFC 7950 validation if given
|
* @param[out] vallevel Do or dont do full RFC 7950 validation if given
|
||||||
* @param[out] yspec YANG stmt spec of mount-point (if ret is 1)
|
* @param[out] yspec YANG stmt spec of mount-point (if ret is 1)
|
||||||
* @retval 1 x is a mount-point: yspec may be set
|
* @retval 1 x is a mount-point: yspec may be set
|
||||||
* @retval 0 x is not a mount point
|
* @retval 0 x is not a mount-point
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|
@ -818,123 +818,14 @@ yang_schema_mount_statistics(clixon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef YANG_SCHEMA_CMP_KLUDGE
|
/*! Given xml mount-point and yanglib, find existing yspec
|
||||||
/*! XXX: This comparison is kludgy since xyanglib is not proper RFC8525
|
|
||||||
* XXX: it should be enough to compare xyanglib with xmodst
|
|
||||||
* XXX openconfig xy2 have submodules but in xy1 they are modules and the counting is wrong
|
|
||||||
* @param[in] h CLixon handle
|
|
||||||
* @param[in] xyanglib Only modules
|
|
||||||
* @param[in] xmodst Has submodules
|
|
||||||
* @retval 1 Equal
|
|
||||||
* @retval 0 Found
|
|
||||||
* @retval -1 Error
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
yang_schema_cmp_kludge(clixon_handle h,
|
|
||||||
cxobj *xyanglib,
|
|
||||||
cxobj *xmodst)
|
|
||||||
{
|
|
||||||
int retval = -1;
|
|
||||||
cxobj *xy1;
|
|
||||||
cxobj *xy2;
|
|
||||||
cxobj *x1;
|
|
||||||
cxobj *x2;
|
|
||||||
char *name;
|
|
||||||
char *revision1;
|
|
||||||
char *revision2;
|
|
||||||
int nr1;
|
|
||||||
int nr2;
|
|
||||||
|
|
||||||
if ((xy1 = xml_find_type(xyanglib, NULL, "module-set", CX_ELMNT)) == NULL ||
|
|
||||||
(xy2 = xml_find_type(xmodst, NULL, "module-set", CX_ELMNT)) == NULL)
|
|
||||||
goto noteq;
|
|
||||||
nr1 = 0;
|
|
||||||
x1 = NULL;
|
|
||||||
while ((x1 = xml_child_each(xy1, x1, CX_ELMNT)) != NULL) {
|
|
||||||
if (strcmp(xml_name(x1), "module"))
|
|
||||||
continue;
|
|
||||||
if ((name = xml_find_body(x1, "name")) == NULL){
|
|
||||||
clixon_debug(CLIXON_DBG_YANG, "no name");
|
|
||||||
goto noteq;
|
|
||||||
}
|
|
||||||
revision1 = xml_find_body(x1, "revision");
|
|
||||||
if ((x2 = xpath_first(xy2, NULL, "module[name='%s']", name)) == NULL){
|
|
||||||
if ((x2 = xpath_first(xy2, NULL, "module/submodule[name='%s']", name)) == NULL){
|
|
||||||
clixon_debug(CLIXON_DBG_YANG, "name mismatch %s\n", name);
|
|
||||||
goto noteq;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
revision2 = xml_find_body(x2, "revision");
|
|
||||||
if (revision1 && revision2 && clicon_strcmp(revision1, revision2) != 0){
|
|
||||||
clixon_debug(CLIXON_DBG_YANG, "revision mismatch %s %s\n", revision1, revision2);
|
|
||||||
goto noteq;
|
|
||||||
}
|
|
||||||
nr1++;
|
|
||||||
}
|
|
||||||
nr2 = 0;
|
|
||||||
x2 = NULL;
|
|
||||||
while ((x2 = xml_child_each(xy2, x2, CX_ELMNT)) != NULL) {
|
|
||||||
if (strcmp(xml_name(x2), "module"))
|
|
||||||
continue;
|
|
||||||
if ((name = xml_find_body(x2, "name")) == NULL){
|
|
||||||
clixon_debug(CLIXON_DBG_YANG, "no name");
|
|
||||||
goto noteq;
|
|
||||||
}
|
|
||||||
revision2 = xml_find_body(x2, "revision");
|
|
||||||
if ((x1 = xpath_first(xy1, NULL, "module[name='%s']", name)) == NULL){
|
|
||||||
#ifdef YANG_SCHEMA_MOUNT_YANG_LIB_FORCE
|
|
||||||
/* Skip ietf-yang-library and imports since they are force-loaded in
|
|
||||||
* yang_lib2yspec
|
|
||||||
*/
|
|
||||||
if (strcmp(name, "ietf-yang-library") == 0 ||
|
|
||||||
strcmp(name, "ietf-yang-types") == 0 ||
|
|
||||||
strcmp(name, "ietf-inet-types") == 0 ||
|
|
||||||
strcmp(name, "ietf-datastores") == 0){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if ((x1 = xpath_first(xy1, NULL, "module/submodule[name='%s']", name)) == NULL){
|
|
||||||
clixon_debug(CLIXON_DBG_YANG, "name mismatch %s\n", name);
|
|
||||||
goto noteq;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
revision1 = xml_find_body(x1, "revision");
|
|
||||||
if (revision1 && revision2 && clicon_strcmp(revision1, revision2) != 0){
|
|
||||||
clixon_debug(CLIXON_DBG_YANG, "revision mismatch %s %s\n", revision1, revision2);
|
|
||||||
goto noteq;
|
|
||||||
}
|
|
||||||
nr2++;
|
|
||||||
}
|
|
||||||
/* kludge in kludge, does not work with submodules, eg openconfig:
|
|
||||||
* xy2 have submodules but in xy1 they are modules and the counting is wrong
|
|
||||||
*/
|
|
||||||
if (0 && nr1 != nr2){
|
|
||||||
clixon_debug(CLIXON_DBG_YANG, "nr mismatch %d %d", nr1, nr2);
|
|
||||||
goto noteq;
|
|
||||||
}
|
|
||||||
retval = 1;
|
|
||||||
done:
|
|
||||||
return retval;
|
|
||||||
noteq:
|
|
||||||
retval = 0;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
#endif // KLUDGE
|
|
||||||
|
|
||||||
/*! Given xml mount-point node, find existing mountpoint
|
|
||||||
*
|
*
|
||||||
* 1. Get modstate (xyanglib) of node: xyanglib, by querying backend state (via callback)
|
* Get and loop through all XML from xt mount-points.
|
||||||
* XXX this xyanglib is not proper RFC8525, submodules appear as modules WHY?
|
* Get xyanglib and if equal to xt, find and return yspec
|
||||||
* 2. Loop through other existing mountpoints of same YANG (dont consider other YANG mtpoints):
|
|
||||||
* 3. Get yspec of mountpoint.
|
|
||||||
* 4: Get RFC 8525 module-state of yspec (proper RFC 8525)
|
|
||||||
* 5: Compare to given modstate
|
|
||||||
* XXX: This comparison is kludgy since xyanglib is not proper RFC8525
|
|
||||||
* 6. If equal, then use existing yspec
|
|
||||||
* 7. Otherwise create new and parse yspec
|
|
||||||
* 8. set as new
|
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] xt XML tree node
|
* @param[in] xt XML tree node
|
||||||
|
* @param[in] xyanglib yanglib in XML
|
||||||
|
* @param[out] yspecp Yang spec
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
*/
|
*/
|
||||||
|
|
@ -945,58 +836,44 @@ yang_schema_find_share(clixon_handle h,
|
||||||
yang_stmt **yspecp)
|
yang_stmt **yspecp)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *yt;
|
cvec *cvv = NULL;
|
||||||
cvec *cvv;
|
|
||||||
cg_var *cv;
|
cg_var *cv;
|
||||||
yang_stmt *yspec1 = NULL;
|
cxobj *xroot;
|
||||||
cbuf *cb = NULL;
|
cxobj *xmnt;
|
||||||
cxobj *xmodst = NULL;
|
cxobj *xylib;
|
||||||
|
int config = 1;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
yt = xml_spec(xt);
|
xroot = xml_root(xt);
|
||||||
if ((cvv = yang_cvec_get(yt)) != NULL){
|
/* Get all XML mtpoints */
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if (yang_mount_xtop2xmnt(xroot, &cvv) < 0)
|
||||||
clixon_err(OE_UNIX, 0, "clicon buffer");
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
/* Loop through XML mount-points */
|
||||||
/* 2. Loop through other existing mountpoints of same YANG */
|
|
||||||
cv = NULL;
|
cv = NULL;
|
||||||
while ((cv = cvec_each(cvv, cv)) != NULL) {
|
while ((cv = cvec_each(cvv, cv)) != NULL) {
|
||||||
/* 3. Get yspec of mountpoint */
|
xmnt = cv_void_get(cv);
|
||||||
if ((yspec1 = cv_void_get(cv)) == NULL)
|
if (xmnt == xt)
|
||||||
continue;
|
continue;
|
||||||
/* 4: Get RFC 8525 module-state of yspec */
|
xylib = NULL;
|
||||||
cbuf_reset(cb);
|
/* Get xyanglib */
|
||||||
/* Build a cb string: <modules-state>... */
|
if (clixon_plugin_yang_mount_all(h, xmnt, &config, NULL, &xylib) < 0)
|
||||||
if (yang_modules_state_build(h, yspec1, "4242", 1, cb) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
/* Parse cb, x is on the form: <top><modules-state>...
|
if (xylib == NULL)
|
||||||
* Note, list is not sorted since it is state (should not be)
|
continue;
|
||||||
*/
|
/* Check if equal */
|
||||||
if (clixon_xml_parse_string(cbuf_get(cb), YB_MODULE, yspec1, &xmodst, NULL) < 0)
|
if (xml_tree_equal(xyanglib, xylib) == 1)
|
||||||
|
continue;
|
||||||
|
/* Find and return yspec */
|
||||||
|
*yspecp = NULL;
|
||||||
|
if ((ret = xml_yang_mount_get(h, xmnt, NULL, yspecp)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* 5: Compare to given modstate
|
if (ret == 1 && *yspecp != NULL)
|
||||||
*/
|
|
||||||
if (xml_rootchild(xmodst, 0, &xmodst) < 0)
|
|
||||||
goto done;
|
|
||||||
if ((ret = yang_schema_cmp_kludge(h, xyanglib, xmodst)) < 0)
|
|
||||||
goto done;
|
|
||||||
if (ret == 1){ /* equal */
|
|
||||||
*yspecp = yspec1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (xmodst){
|
|
||||||
xml_free(xmodst);
|
|
||||||
xmodst = NULL;
|
|
||||||
}
|
|
||||||
} /* while */
|
|
||||||
}
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (xmodst)
|
if (cvv)
|
||||||
xml_free(xmodst);
|
cvec_free(cvv);
|
||||||
if (cb)
|
|
||||||
cbuf_free(cb);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue