Fixed: [Error with submodules and feature Interaction](https://github.com/clicon/clixon-controller/issues/158)

This commit is contained in:
Olof hagsand 2024-11-08 16:37:31 +01:00
parent daaeaa0039
commit ca695ea386
7 changed files with 143 additions and 56 deletions

View file

@ -3613,7 +3613,7 @@ yang_features(clixon_handle h,
yang_stmt *ys = NULL;
yang_stmt *ymod;
const char *mainfile = NULL;
int ret;
int enabled;
i = 0;
while (i<yt->ys_len){
@ -3622,16 +3622,16 @@ yang_features(clixon_handle h,
/* Parse the if-feature-expr string using yang sub-parser */
if ((ymod = ys_module(ys)) != NULL)
mainfile = yang_filename_get(ymod);
ret = 0;
if (yang_subparse(yang_argument_get(ys), ys, YA_IF_FEATURE, mainfile, 1, &ret, h) < 0)
enabled = 0;
if (yang_subparse(h, yang_argument_get(ys), ys, YA_IF_FEATURE, mainfile, 1, &enabled) < 0)
goto done;
clixon_debug(CLIXON_DBG_YANG | CLIXON_DBG_DETAIL, "%s %d", yang_argument_get(ys), ret);
if (ret == 0)
clixon_debug(CLIXON_DBG_YANG | CLIXON_DBG_DETAIL, "%s %d", yang_argument_get(ys), enabled);
if (enabled == 0)
goto disabled;
}
else if (ys->ys_keyword == Y_FEATURE){
if (ys_populate_feature(h, ys) < 0)
goto done;
if (ys_populate_feature(h, ys) < 0)
goto done;
}
else
switch (yang_features(h, ys)){

View file

@ -2060,7 +2060,7 @@ ys_parse_sub(yang_stmt *ys,
* pass 1 is not yet resolved, only check syntax, actual feature check made in next pass
* @see yang_features
*/
if (yang_subparse(yang_argument_get(ys), ys, YA_IF_FEATURE, filename, yang_linenum_get(ys), NULL, NULL) < 0)
if (yang_subparse(NULL, yang_argument_get(ys), ys, YA_IF_FEATURE, filename, yang_linenum_get(ys), NULL) < 0)
goto done;
break;
case Y_AUGMENT: /* If parent is module/submodule: absolute-schema-nodeid

View file

@ -61,24 +61,24 @@
/*! Invoke yang sub-parser on string
*
* @param[in] str yang string
* @param[in] ys Yang statement
* @param[in] accept Sub-parse rule to accept
* @param[in] mainfile Name of main parse file
* @param[in] linenum Line number context in mainfile (assume parse module of ys)
* @param[in] h Clixon handle
* @param[out] enabled 0: Disabled, 1: Enabled (if present)
* @retval 0 OK
* @retval -1 Error
* @param[in] h Clixon handle (can be NULL)
* @param[in] str Yang string
* @param[in] ys Yang statement
* @param[in] accept Sub-parse rule to accept
* @param[in] mainfile Name of main parse file
* @param[in] linenum Line number context in mainfile (assume parse module of ys)
* @param[out] enabled 0: Disabled, 1: Enabled (if present)
* @retval 0 OK
* @retval -1 Error
*/
int
yang_subparse(char *str,
yang_subparse(clixon_handle h,
char *str,
yang_stmt *ys,
enum yang_sub_parse_accept accept,
const char *mainfile,
int linenum,
int *enabled,
clixon_handle h)
int *enabled)
{
int retval = -1;
clixon_yang_sub_parse_yacc ife = {0,};
@ -90,7 +90,7 @@ yang_subparse(char *str,
ife.if_ys = ys; /* Used as trigger to check if enabled */
ife.if_accept = accept;
ife.if_mainfile = mainfile;
ife.h = h;
ife.if_h = h;
if (clixon_yang_sub_parsel_init(&ife) < 0)
goto done;
if (clixon_yang_sub_parseparse(&ife) != 0) { /* yacc returns 1 on error */

View file

@ -49,14 +49,14 @@ enum yang_sub_parse_accept{
/*! XML parser yacc handler struct */
struct clixon_yang_sub_parse_yacc {
char *if_parse_string; /* original (copy of) parse string */
const char *if_mainfile; /* Original main-file (this is a sib-parser) */
int if_linenum; /* Number of \n in parsed buffer (in mainfile) */
void *if_lexbuf; /* Internal parse buffer from lex */
yang_stmt *if_ys; /* Yang statement, NULL if no check */
enum yang_sub_parse_accept if_accept; /* Which sub-parse rule to accept */
int if_enabled; /* Result: 0: feature disabled, 1: enabled */
clixon_handle h;
char *if_parse_string; /* original (copy of) parse string */
const char *if_mainfile; /* Original main-file (this is a sib-parser) */
int if_linenum; /* Number of \n in parsed buffer (in mainfile) */
void *if_lexbuf; /* Internal parse buffer from lex */
yang_stmt *if_ys; /* Yang statement, NULL if no check */
enum yang_sub_parse_accept if_accept; /* Which sub-parse rule to accept */
int if_enabled; /* Result: 0: feature disabled, 1: enabled */
clixon_handle if_h;
};
typedef struct clixon_yang_sub_parse_yacc clixon_yang_sub_parse_yacc;
@ -74,7 +74,7 @@ int clixon_yang_sub_parsel_linenr(void);
int clixon_yang_sub_parselex(void *);
int clixon_yang_sub_parseparse(void *);
int yang_subparse(char *str, yang_stmt *ys, enum yang_sub_parse_accept accept, const char *mainfile, int linenum, int *enabled, clixon_handle h);
int yang_subparse(clixon_handle h, char *str, yang_stmt *ys, enum yang_sub_parse_accept accept, const char *mainfile, int linenum, int *enabled);
int yang_schema_nodeid_subparse(char *str, enum yang_sub_parse_accept accept, const char *mainfile, int linenum);
#endif /* _CLIXON_YANG_SUB_PARSER_H_ */

View file

@ -86,6 +86,8 @@
#include <stdlib.h>
#include <sys/time.h>
#include <assert.h> // XXX
/* cligen */
#include <cligen/cligen.h>
@ -128,10 +130,11 @@ clixon_yang_sub_parseerror(void *arg,
/*! Check if feature "str" is enabled or not in context of yang node ys
*
* @param[in] ife If-feature struct
* @param[in] str feature str.
* @param[in] ys If-feature type yang node
* @retval 0 OK
* @retval -1 Error
* @note ife->if_ys is used as implicit flag to perform actual checks
*/
static int
if_feature_check(clixon_yang_sub_parse_yacc *ife,
@ -150,12 +153,19 @@ if_feature_check(clixon_yang_sub_parse_yacc *ife,
if (nodeid_split(str, &prefix, &feature) < 0)
goto done;
/* Specifically need to handle? strcmp(prefix, myprefix)) */
if (prefix == NULL)
ymod = ys_module(ys);
else
if (prefix != NULL){
ymod = yang_find_module_by_prefix(ys, prefix);
if (ymod == NULL)
if (ys_real_module(ymod, &ymod) < 0)
goto done;
}
else {
if (ys_real_module(ys, &ymod) < 0)
goto done;
}
if (ymod == NULL){
clixon_err(OE_YANG, 0, "Module not found: %s", str);
goto done;
}
/* Check if feature exists, and is set, otherwise remove */
if ((yfeat = yang_find(ymod, Y_FEATURE, feature)) == NULL){
clixon_err(OE_YANG, EINVAL, "Yang module %s has IF_FEATURE %s, but no such FEATURE statement exists",
@ -167,8 +177,8 @@ if_feature_check(clixon_yang_sub_parse_yacc *ife,
* Continue loop to catch unbound features and make verdict at end
*/
cv = yang_cv_get(yfeat);
if (cv == NULL && ife->h) {
ys_populate_feature(ife->h, yfeat);
if (cv == NULL && ife->if_h) {
ys_populate_feature(ife->if_h, yfeat);
}
cv = yang_cv_get(yfeat);