libyang
libyang copied to clipboard
must evaluated in empty container
For the following test.yang
module test {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:test";
prefix "test";
container foo {
leaf x {
type uint8;
}
container bar {
must "y < ../x";
leaf y {
type uint8;
}
}
}
}
and the following test.json
{
"test:foo": {
"x": 3
}
}
the output of yanglint test.yang test.json
is
libyang err : Must condition "y < ../x" not satisfied. (Data location "/test:foo/bar".)
YANGLINT[E]: Failed to parse input data file "test.json".
However, RFC 6020 writes If a data node does not exist in the data tree, and it does not have a default value, its "must" statements are not evaluated.
so I would expect the must
expression is not evaluated in this case.
I noticed that with the must statement in https://github.com/YangModels/yang/blob/3b369b8c147cf0242c0c311ed8fb17f71bdc3ab3/standard/ieee/draft/802.1/Qcw/ieee802-dot1q-sched.yang#L190 that is several layers deep, but is still evaluated. So for example, have a look at the following data:
{
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "eth0",
"type": "iana-if-type:ethernetCsmacd",
"ieee802-dot1q-bridge:bridge-port": {
"traffic-class": {
"traffic-class-table": {
"number-of-traffic-classes": 3,
"priority0": 2,
"priority1": 2,
"priority2": 1,
"priority3": 0,
"priority4": 2,
"priority5": 2,
"priority6": 2,
"priority7": 2
}
},
"ieee802-dot1q-sched-bridge:gate-parameter-table": {
"gate-enabled": true,
"config-change": true,
"supported-list-max": 3,
"supported-interval-max": 1000000,
"supported-cycle-max": {
"numerator": 1,
"denominator": 1
},
"admin-cycle-time": {
"numerator": 1,
"denominator": 1000
},
"admin-base-time": {
"seconds": "1",
"nanoseconds": 0
},
"admin-control-list": {
"gate-control-entry": [
{
"index": 0,
"operation-name": "ieee802-dot1q-sched:set-gate-states",
"time-interval-value": 300000,
"gate-states-value": 1
},
{
"index": 1,
"operation-name": "ieee802-dot1q-sched:set-gate-states",
"time-interval-value": 300000,
"gate-states-value": 3
},
{
"index": 2,
"operation-name": "ieee802-dot1q-sched:set-gate-states",
"time-interval-value": 400000,
"gate-states-value": 4
}
]
}
}
}
},
{
"name": "eth1",
"type": "iana-if-type:ethernetCsmacd"
}
]
}
}
where eth0
is considered valid, but eth1
fails with Number of elements in admin-control-list must not be greaterthan supported-list-max (Data location "/ietf-interfaces:interfaces/interface[name='eth1']/ieee802-dot1q-bridge:bridge-port/ieee802-dot1q-sched-bridge:gate-parameter-table/admin-control-list".)
However, RFC 6020 writes If a data node does not exist in the data tree, and it does not have a default value, its "must" statements are not evaluated. so I would expect the must expression is not evaluated in this case.
In the example YANG file, the node itself has no must
statement; it's a statement which belongs to the enclosing container. I do not think that the clause you quoted applies here.
I am not sure about the terminology here. However, as you see in the second example, the same problem exists several levels of containers deep.
So either there is a problem in the IEEE YANG model or in libyang. Due to the quoted statement I would tend to the latter (otherwise you need to fulfill "must" statements of branches you might not even be aware of just because a YANG model is loaded), but if you have a convincing argument why the YANG model is wrong, that would also be OK and I would forward it to the IEEE.
From RFC 7950:
In the first style, the container has no meaning of its own, existing
only to contain child nodes. In particular, the presence of the
container node with no child nodes is semantically equivalent to the
absence of the container node. YANG calls this style a "non-presence
container". This is the default style.
which pretty much contradicts what you quoted:
If a data node does not exist in the data tree, and it does not have a default value, its "must" statements are not evaluated.
because if a NP container has a must
, it has some meaning and yet it should not make a difference whether it exists or not. There was some discussion about this on the NETMOD mailing list and libyang behavior was accepted. In this particular case, the container is supposed to have presence
to signify that it actually has a meaning.
So, first of all, adding presence
statements to each container with must
actually leads to the must
statement not being evaluated if they do not appear in the data. So that is already good to know.
If I understand you correctly, you are saying that without a presence
statement it should not make a difference (i.e. it can not be decided) if a container node itself exists or is absent in the data tree, right?
But the relevant sentence for me in your quote is
In particular, the presence of the [NP] container node with no child nodes is semantically equivalent to the absence of the container node.
In my opinion that means also for a NP container it can be decided if it exists or not (and consequently if the must
statement should be evaluated), just the rules are different depending on the availability of the presence
statement:
presence
available: Container node exists in the data tree if and only if it is explicitly provided, regardless of the existence of child nodes.
presence
not available: Container node exists if and only if at least one child nodes exists, regardless of the container node itself being explicitly provided.
But there might have been other arguments on the NETMOD mailing list. Unfortunately, I was not able to find the post. The only ones that I found that could be slightly related were https://mailarchive.ietf.org/arch/msg/netmod/5sNvaTjijqcxojEIeb8ntLqKp8E/ https://mailarchive.ietf.org/arch/msg/netmod/fWJzQoTC9VgqSpEGXMG4xuo4uZ4/ but both do not seem to really apply to this scenario. Can you please share a link of that discussion?
Here is a discussion with links to all the relevant mailing discussions. Note that the current implementation is the result of several years of experience and while perhaps not immediately obvious, it is the most reasonable one. So, unless there is strong support of changing it, it will remain the way it is until at least a new YANG spec is standardized.