Repository navigation
Description
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".)
Activity
jktjkt commentedon Dec 11, 2023
In the example YANG file, the node itself has no
muststatement; it's a statement which belongs to the enclosing container. I do not think that the clause you quoted applies here.koalo commentedon Dec 11, 2023
michalvasko commentedon Dec 14, 2023
From RFC 7950:
which pretty much contradicts what you quoted:
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 havepresenceto signify that it actually has a meaning.koalo commentedon Dec 14, 2023
So, first of all, adding
presencestatements to each container withmustactually leads to themuststatement 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
presencestatement 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
muststatement should be evaluated), just the rules are different depending on the availability of thepresencestatement:presenceavailable: Container node exists in the data tree if and only if it is explicitly provided, regardless of the existence of child nodes.presencenot 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?
michalvasko commentedon Dec 15, 2023
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.
koalo commentedon Jun 18, 2024
Took some time for us to understand all the details, but now we fully agree that libyang is correct in this regard and the standard needs to be fixed.
See https://github.com/Linutronix/yang-validation/blob/main/qcw/README.md for details.
I opened #2256 that is a only remotely related and close this issue.