* Fixed: YANG uses statements in sub-modules did not search for grouping statements in other submodules of the module it belongs to.

This commit is contained in:
Olof hagsand 2020-09-04 16:23:18 +02:00
parent b8955c81d8
commit f524a89b2d
2 changed files with 63 additions and 13 deletions

View file

@ -60,6 +60,7 @@ Developers may need to change their code
### Corrected Bugs ### Corrected Bugs
* Fixed: YANG `uses` statements in sub-modules did not search for `grouping` statements in other submodules of the module it belongs to.
* Fixed: [CLI crash if error-info is empty #134](https://github.com/clicon/clixon/issues/134) * Fixed: [CLI crash if error-info is empty #134](https://github.com/clicon/clixon/issues/134)
* Fixed: [copy-config's RPC cxobj parameter does not contain namespace #131](https://github.com/clicon/clixon/issues/131) * Fixed: [copy-config's RPC cxobj parameter does not contain namespace #131](https://github.com/clicon/clixon/issues/131)
* See also "Netconf as default namespace has been disabled by default" above * See also "Netconf as default namespace has been disabled by default" above

View file

@ -101,6 +101,47 @@
/* Size of json read buffer when reading from file*/ /* Size of json read buffer when reading from file*/
#define BUFLEN 1024 #define BUFLEN 1024
/*! Resolve a grouping name from a module, includes looking in submodules
*/
static yang_stmt *
ys_grouping_module_resolve(yang_stmt *ymod,
yang_stmt *yspec,
char *name)
{
yang_stmt *yinc;
yang_stmt *ysubm;
yang_stmt *yrealmod = NULL;
yang_stmt *ygrouping = NULL;
char *submname;
/* Find grouping from own sub/module */
if ((ygrouping = yang_find(ymod, Y_GROUPING, name)) != NULL)
goto done;
/* Find top-level module */
if (ys_real_module(ymod, &yrealmod) < 0)
goto done;
if (yrealmod == ymod) /* skip if module, continue if submodule */
goto done;
/* Find grouping from real module */
if ((ygrouping = yang_find(yrealmod, Y_GROUPING, name)) != NULL)
goto done;
/* Find grouping from sub-modules */
yinc = NULL;
while ((yinc = yn_each(yrealmod, yinc)) != NULL){
if (yang_keyword_get(yinc) != Y_INCLUDE)
continue;
submname = yang_argument_get(yinc);
if ((ysubm = yang_find_module_by_name(yspec, submname)) == NULL)
continue;
if (ysubm == ymod)
continue;
if ((ygrouping = yang_find(ysubm, Y_GROUPING, name)) != NULL)
break;
}
done:
return ygrouping;
}
/*! Resolve a grouping name from a point in the yang tree /*! Resolve a grouping name from a point in the yang tree
* @param[in] ys Yang statement of "uses" statement doing the lookup * @param[in] ys Yang statement of "uses" statement doing the lookup
* @param[in] prefix Prefix of grouping to look for * @param[in] prefix Prefix of grouping to look for
@ -110,31 +151,40 @@
* @retval -1 Error, with clicon_err called * @retval -1 Error, with clicon_err called
*/ */
static int static int
ys_grouping_resolve(yang_stmt *ys, ys_grouping_resolve(yang_stmt *yuses,
char *prefix, char *prefix,
char *name, char *name,
yang_stmt **ygrouping0) yang_stmt **ygrouping0)
{ {
int retval = -1; int retval = -1;
yang_stmt *ymodule; yang_stmt *ymod;
yang_stmt *ygrouping = NULL; yang_stmt *ygrouping = NULL;
yang_stmt *yn; yang_stmt *yp;
yang_stmt *ys;
yang_stmt *yspec;
enum rfc_6020 keyw;
yspec = ys_spec(yuses);
/* find the grouping associated with argument and expand(?) */ /* find the grouping associated with argument and expand(?) */
if (prefix){ /* Go to top and find import that matches */ if (prefix){ /* Go to top and find import that matches */
if ((ymodule = yang_find_module_by_prefix(ys, prefix)) != NULL) if ((ymod = yang_find_module_by_prefix(yuses, prefix)) != NULL)
ygrouping = yang_find(ymodule, Y_GROUPING, name); ygrouping = ys_grouping_module_resolve(ymod, yspec, name);
} }
else else {
ys = yuses; /* Check upwards in hierarchy for matching groupings */
while (1){ while (1){
/* Check upwards in hierarchy for matching groupings */ if ((yp = yang_parent_get(ys)) == NULL)
if ((yn = yang_parent_get(ys)) == NULL || yang_keyword_get(yn) == Y_SPEC)
break; break;
/* Here find grouping */ if ((keyw = yang_keyword_get(yp)) == Y_SPEC)
if ((ygrouping = yang_find(yn, Y_GROUPING, name)) != NULL)
break; break;
/* Proceed to next level */ else if (keyw == Y_MODULE || keyw == Y_SUBMODULE){ /* Try submodules */
ys = (yang_stmt*)yn; ygrouping = ys_grouping_module_resolve(yp, yspec, name);
break;
}
else if ((ygrouping = yang_find(yp, Y_GROUPING, name)) != NULL) /* Here find grouping */
break;
ys = (yang_stmt*)yp; /* Proceed to next level */
}
} }
*ygrouping0 = ygrouping; *ygrouping0 = ygrouping;
retval = 0; retval = 0;
@ -352,7 +402,6 @@ yang_expand_grouping(yang_stmt *yn)
yp = yn; yp = yn;
do { do {
if (yp == ygrouping){ if (yp == ygrouping){
clicon_err(OE_YANG, EFAULT, "Yang use of grouping %s in module %s is defined inside the grouping (recursion), see RFC 7950 Sec 7.12: A grouping MUST NOT reference itself", clicon_err(OE_YANG, EFAULT, "Yang use of grouping %s in module %s is defined inside the grouping (recursion), see RFC 7950 Sec 7.12: A grouping MUST NOT reference itself",
yang_argument_get(ys), yang_argument_get(ys),
yang_argument_get(ys_module(yn)) yang_argument_get(ys_module(yn))