Skip to content

Commit 7ae5c7d

Browse files
lePicimichalvasko
authored andcommitted
yang parser BUGFIX inheriting the "config" value
Inheriting the "config" value due to "deviate" now fixes #1429.
1 parent 6a98575 commit 7ae5c7d

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

src/parser_yang.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4499,6 +4499,9 @@ yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct
44994499
}
45004500

45014501
if ((deviate->flags & LYS_CONFIG_MASK)) {
4502+
struct lys_node *parent;
4503+
const struct lys_node_list *node_list;
4504+
45024505
/* cannot add if it was explicitly set */
45034506
if ((deviate->mod == LY_DEVIATE_ADD) && (dev_target->flags & LYS_CONFIG_SET)) {
45044507
LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "config");
@@ -4516,6 +4519,60 @@ yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct
45164519

45174520
/* ... and replace it with the value specified in deviation */
45184521
dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
4522+
4523+
/* "config" is explicitely set in the node */
4524+
dev_target->flags |= LYS_CONFIG_SET;
4525+
4526+
/* "config" must be set to either "yes" or "no" */
4527+
assert(dev_target->flags ^ LYS_CONFIG_MASK);
4528+
4529+
/* from rfc7950#page-86: All key leafs in a list MUST have the same value
4530+
* for their "config" as the list itself.
4531+
*/
4532+
if ((node_list = lys_is_key((const struct lys_node_leaf *)dev_target, NULL))) {
4533+
if ((node_list->flags & LYS_CONFIG_MASK) != (dev_target->flags & LYS_CONFIG_MASK)) {
4534+
LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "config");
4535+
LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
4536+
"The deviate statement causes a violation of \"config\" rules in a key leaf. "
4537+
"The \"config\" value in the key leaf must be the same as in the list to which belongs.");
4538+
goto error;
4539+
}
4540+
}
4541+
4542+
/* from rfc7950#page-135: If the parent node is a case node,
4543+
* the value is the same as the case node's parent choice node.
4544+
*/
4545+
if (dev_target->nodetype == LYS_CASE) {
4546+
parent = lys_parent(dev_target);
4547+
assert(parent && parent->nodetype == LYS_CHOICE);
4548+
if ((parent->flags & LYS_CONFIG_MASK) != (dev_target->flags & LYS_CONFIG_MASK)) {
4549+
LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "config");
4550+
LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
4551+
"The deviate statement causes a violation of \"config\" rules in a case node. "
4552+
"The \"config\" value in the case must be the same as in the choice to which belongs.");
4553+
goto error;
4554+
}
4555+
}
4556+
4557+
/* from rfc7950#page-135: If a node has "config" set to "false",
4558+
* no node underneath it can have "config" set to "true".
4559+
*/
4560+
if (dev_target->flags & LYS_CONFIG_R) {
4561+
struct lys_node *next, *elem;
4562+
LY_TREE_DFS_BEGIN(dev_target->child, next, elem) {
4563+
if (elem->flags & LYS_CONFIG_W) {
4564+
/* Remove current config value of the elem including LYS_CONFIG_SET.
4565+
* Note that LYS_CONFIG_SET is cleared. The point is that if the config was explicitly set to yes in the node,
4566+
* and at the same time the inheritance from the ancestor was projected, then the config is switched to no,
4567+
* so such a config does not have the value set explicitly, but rather implicitly. Therefore, the flag is deleted.
4568+
*/
4569+
elem->flags &= ~(LYS_CONFIG_MASK | LYS_CONFIG_SET) ;
4570+
/* set "config" to "no" */
4571+
elem->flags |= LYS_CONFIG_R;
4572+
}
4573+
LY_TREE_DFS_END(dev_target->child, next, elem);
4574+
}
4575+
}
45194576
}
45204577

45214578
if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {

0 commit comments

Comments
 (0)