* Fixed: [OpenConfig BGP afi-safi and when condition issues #249](https://github.com/clicon/clixon/issues/249)
* YANG when was not properly implemented for default values * Improved error message on leafref validation errors
This commit is contained in:
parent
0b08ba6ae5
commit
babdc6f496
10 changed files with 107 additions and 65 deletions
|
|
@ -114,6 +114,7 @@ validate_leafref(cxobj *xt,
|
|||
cvec *nsc = NULL;
|
||||
cbuf *cberr = NULL;
|
||||
char *path;
|
||||
yang_stmt *ymod;
|
||||
|
||||
if ((leafrefbody = xml_body(xt)) == NULL)
|
||||
goto ok;
|
||||
|
|
@ -140,7 +141,8 @@ validate_leafref(cxobj *xt,
|
|||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cberr, "Leafref validation failed: No leaf %s matching path %s", leafrefbody, path);
|
||||
ymod = ys_module(ys);
|
||||
cprintf(cberr, "Leafref validation failed: No leaf %s matching path %s in module %s", leafrefbody, path, yang_argument_get(ymod));
|
||||
if (xret && netconf_bad_element_xml(xret, "application", leafrefbody, cbuf_get(cberr)) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
|
|
@ -1136,6 +1138,7 @@ xml_yang_validate_all(clicon_handle h,
|
|||
char *ns = NULL;
|
||||
cbuf *cb = NULL;
|
||||
cvec *nsc = NULL;
|
||||
int hit = 0;
|
||||
|
||||
/* if not given by argument (overide) use default link
|
||||
and !Node has a config sub-statement and it is false */
|
||||
|
|
@ -1227,53 +1230,21 @@ xml_yang_validate_all(clicon_handle h,
|
|||
nsc = NULL;
|
||||
}
|
||||
}
|
||||
/* First variant of when, actual "when" sub-node RFC 7950 Sec 7.21.5. Can only be one. */
|
||||
if ((yc = yang_find(ys, Y_WHEN, NULL)) != NULL){
|
||||
xpath = yang_argument_get(yc); /* "when" has xpath argument */
|
||||
/* WHEN xpath needs namespace context */
|
||||
if (xml_nsctx_yang(ys, &nsc) < 0)
|
||||
if (yang_when_xpath(xt, xml_parent(xt), ys, &hit, &nr, &xpath) < 0)
|
||||
goto done;
|
||||
if (hit && nr == 0){
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
if ((nr = xpath_vec_bool(xt, nsc, "%s", xpath)) < 0)
|
||||
}
|
||||
cprintf(cb, "Failed WHEN condition of %s in module %s (WHEN xpath is %s)",
|
||||
xml_name(xt),
|
||||
yang_argument_get(ys_module(ys)),
|
||||
xpath);
|
||||
if (xret && netconf_operation_failed_xml(xret, "application",
|
||||
cbuf_get(cb)) < 0)
|
||||
goto done;
|
||||
if (nsc){
|
||||
xml_nsctx_free(nsc);
|
||||
nsc = NULL;
|
||||
}
|
||||
if (nr == 0){
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cb, "Failed WHEN condition of %s in module %s",
|
||||
xml_name(xt),
|
||||
yang_argument_get(ys_module(ys)));
|
||||
if (xret && netconf_operation_failed_xml(xret, "application",
|
||||
cbuf_get(cb)) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
/* Second variants of WHEN:
|
||||
* Augmented and uses when using special info in node
|
||||
*/
|
||||
if ((xpath = yang_when_xpath_get(ys)) != NULL){
|
||||
if ((nr = xpath_vec_bool(xml_parent(xt), yang_when_nsc_get(ys),
|
||||
"%s", xpath)) < 0)
|
||||
goto done;
|
||||
if (nr == 0){
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cb, "Failed augmented 'when' condition '%s' of node '%s' in module '%s'",
|
||||
xpath,
|
||||
xml_name(xt),
|
||||
yang_argument_get(ys_module(ys)));
|
||||
if (xret && netconf_operation_failed_xml(xret, "application",
|
||||
cbuf_get(cb)) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
x = NULL;
|
||||
|
|
|
|||
|
|
@ -1139,10 +1139,11 @@ xml_default1(yang_stmt *yt,
|
|||
int retval = -1;
|
||||
yang_stmt *yc;
|
||||
cxobj *xc;
|
||||
int top=0; /* Top symbol (set default namespace) */
|
||||
int top = 0; /* Top symbol (set default namespace) */
|
||||
int create = 0;
|
||||
char *xpath;
|
||||
int nr;
|
||||
int nr = 0;
|
||||
int hit = 0;
|
||||
|
||||
if (xt == NULL){ /* No xml */
|
||||
clicon_err(OE_XML, EINVAL, "No XML argument");
|
||||
|
|
@ -1181,12 +1182,10 @@ xml_default1(yang_stmt *yt,
|
|||
case Y_CONTAINER:
|
||||
if (yang_find(yc, Y_PRESENCE, NULL) == NULL){
|
||||
/* Check when statement from uses or augment */
|
||||
if ((xpath = yang_when_xpath_get(yc)) != NULL){
|
||||
if ((nr = xpath_vec_bool(xt, yang_when_nsc_get(yc), "%s", xpath)) < 0)
|
||||
goto done;
|
||||
if (nr == 0)
|
||||
break; /* Do not create default if xpath fails */
|
||||
}
|
||||
if (yang_when_xpath(NULL, xt, yc, &hit, &nr, &xpath) < 0)
|
||||
goto done;
|
||||
if (hit && nr == 0)
|
||||
break; /* Do not create default if xpath fails */
|
||||
/* If this is non-presence, (and it does not exist in xt) call
|
||||
* recursively and create nodes if any default value exist first.
|
||||
* Then continue and populate?
|
||||
|
|
@ -2257,3 +2256,70 @@ xml_copy_marked(cxobj *x0,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Check when condition
|
||||
*
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] xn XML node, can be NULL, in which case it is added as dummy under xp
|
||||
* @param[in] xp XML parent
|
||||
* @param[in] ys Yang node
|
||||
* First variants of WHEN: Augmented and uses when using special info in node
|
||||
* Second variant of when, actual "when" sub-node RFC 7950 Sec 7.21.5. Can only be one.
|
||||
*/
|
||||
int
|
||||
yang_when_xpath(cxobj *xn,
|
||||
cxobj *xp,
|
||||
yang_stmt *yn,
|
||||
int *hit,
|
||||
int *nrp,
|
||||
char **xpathp)
|
||||
{
|
||||
int retval = 1;
|
||||
yang_stmt *yc;
|
||||
char *xpath = NULL;
|
||||
cxobj *x = NULL;
|
||||
int nr = 0;
|
||||
cvec *nsc = NULL;
|
||||
int xmalloc = 0; /* ugly help variable to clean temporary object */
|
||||
int nscmalloc = 0; /* ugly help variable to remove */
|
||||
|
||||
/* First variant */
|
||||
if ((xpath = yang_when_xpath_get(yn)) != NULL){
|
||||
x = xp;
|
||||
nsc = yang_when_nsc_get(yn);
|
||||
*hit = 1;
|
||||
}
|
||||
/* Second variant */
|
||||
else if ((yc = yang_find(yn, Y_WHEN, NULL)) != NULL){
|
||||
xpath = yang_argument_get(yc); /* "when" has xpath argument */
|
||||
/* Create dummy */
|
||||
if (xn == NULL){
|
||||
if ((x = xml_new(yang_argument_get(yn), xp, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
xml_spec_set(x, yn);
|
||||
xmalloc++;
|
||||
}
|
||||
else
|
||||
x = xn;
|
||||
if (xml_nsctx_yang(yn, &nsc) < 0)
|
||||
goto done;
|
||||
nscmalloc++;
|
||||
*hit = 1;
|
||||
}
|
||||
else
|
||||
*hit = 0;
|
||||
if (x && xpath){
|
||||
if ((nr = xpath_vec_bool(x, nsc, "%s", xpath)) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (nrp)
|
||||
*nrp = nr;
|
||||
if (xpathp)
|
||||
*xpathp = xpath;
|
||||
retval = 0;
|
||||
done:
|
||||
if (xmalloc)
|
||||
xml_purge(x);
|
||||
if (nsc && nscmalloc)
|
||||
xml_nsctx_free(nsc);
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -340,11 +340,13 @@ yang_flag_reset(yang_stmt *ys,
|
|||
* @param[in] ys Yang statement
|
||||
* @retval xpath xpath should evaluate to true at validation
|
||||
* @retval NULL Not set
|
||||
* Note xpath context is PARENT which is different from when actual when child which is
|
||||
* child itself
|
||||
*/
|
||||
char*
|
||||
yang_when_xpath_get(yang_stmt *ys)
|
||||
{
|
||||
return ys->ys_when_xpath;
|
||||
return ys->ys_when_xpath;
|
||||
}
|
||||
|
||||
/*! Set yang xpath and namespace context for "when"-associated augment
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue