Subject: [netmod] Y18: fix "when" expression context node problem

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 24 Mar 2014 11:05:22 +0100

Hi,

I think the solution Y18-01 is just hand-waving that raises other questions: If the context node is tentatively added to the instance document, then with what content? Are mandatory descendants supposed to be added as well, do contained defaults apply?

This can lead to nasty race conditions, for example:

leaf foo {
    when "../bar/baz" = 42";
    type uint8;
}
container bar {
    when "not(../foo = 1)";
    leaf baz {
        type uint8;
        default 42;
    }
}

Then, is the data tree fragment

<foo>1</foo>

valid or not?

The thing is, XPath evaluation needs a fixed XML document that has to be properly defined (as it is done, e.g., for "must"). Without it, standard XPath tools will never work.

My example also shows that it is not sufficient to forbid "when" expressions to refer to nodes below the context node - similar pathological situations can arise if two nodes or subtrees refer to each other in their "when" expressions.

Here is an alternative solution:

====

** Solution Y18-02

For validation purposes, treat

when "<expression>";

as equivalent to

must "<expression> or not(.)";

This is essentially how RFC 6110 translates "when" to Schematron, because there is no other possibility.

What this means is that "when" expressions would not apply in any way if the context node is missing (after all defaults "in use" have been added).

====

Lada

-- 
Ladislav Lhotka, CZ.NIC Labs
PGP Key ID: E74E8C0C

---

From: Martin Bjorklund <[email-masked]>
Date: Mon, 24 Mar 2014 11:17:57 +0100 (CET)

Ladislav Lhotka <[email-masked]> wrote:
> Hi,
> 
> I think the solution Y18-01 is just hand-waving that raises other
> questions: If the context node is tentatively added to the instance
> document, then with what content? Are mandatory descendants supposed
> to be added as well, do contained defaults apply?

Y18-01 says:

  This node has no value and no children. 

It is only added in order to have a context node.

> The thing is, XPath evaluation needs a fixed XML document that has to
> be properly defined (as it is done, e.g., for "must"). Without it,
> standard XPath tools will never work.
> 
> My example also shows that it is not sufficient to forbid "when"
> expressions to refer to nodes below the context node - similar
> pathological situations can arise if two nodes or subtrees refer to
> each other in their "when" expressions.
> 

But must expressions are only evaluated if the node exists, so
"not(.)" will always evaluate to false.

This means that there would be no difference between must and when.

> What this means is that "when" expressions would not apply in any way
> if the context node is missing (after all defaults "in use" have been
> added).

This is not the intention of when!  Your example above is a good use
case of when:

  container foo {
    when ../enabled;
    leaf bar {
      mandatory true;
      ...
    }
  }

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 25 Mar 2014 10:03:37 +0100

Hi,

I think the problem of "when" definition is that it is inherently circular: it tries to decide about including a conditional node in the schema by evaluating an XPath expression whose context node is that conditional node.

Perhaps the correct solution would be to define the context node to be the closest ancestor data node.
And I'd also add another rule that the XPath expression must not involve any node that is directly or indirectly conditional (this also excludes the subtree of the conditional node that is being tested).

While this might solve the problem, it would break existing modules - the leading double-dot would have to be removed from all "when" expressions. On the other hand, it would be a correction of an error in the spec.

Lada

---

From: Andy Bierman <[email-masked]>
Date: Tue, 25 Mar 2014 05:29:19 -0700

On Tue, Mar 25, 2014 at 2:03 AM, Ladislav Lhotka <[email-masked]> wrote:

> Hi,
>
> I think the problem of "when" definition is that it is inherently
> circular: it tries to decide about including a conditional node in the
> schema by evaluating an XPath expression whose context node is that
> conditional node.
>
> And I'd also add another rule that the XPath expression must not involve
> any node that is directly or indirectly conditional (this also excludes the
> subtree of the conditional node that is being tested).
>
> While this might solve the problem, it would break existing modules - the
> leading double-dot would have to be removed from all "when" expressions. On
> the other hand, it would be a correction of an error in the spec.
>
>
I am against breaking all when-stmts and changing the way they work.
Implementation of the when-stmt in a real server is difficult.  So what's
your point?
It is not an error in the spec. It's just difficult code.

The priority for ease of use is readers, writers and lastly, tool
developers.
It seems you want to make YANG very difficult to write in order to
simplify tool development.

The when-stmt is worse than circular.  It is nested + circular.
Any modification to the datastore might cause a when-stmt to
change state.  Any deletion of a false when-stmt might cause
other nodes when-stmt value to change.  It is possible to construct
pathological cases that never resolve, no matter how you iterate
through the when-stmt tests.

Lada

Andy

> _______________________________________________
> netmod mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/netmod
>

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 25 Mar 2014 15:14:15 +0100

> It is not an error in the spec. It's just difficult code.

I disagree, of course. Issue Y18 is real, and it describes an error in the spec.

> simplify tool development.

I want a precise specification that leaves no doubts about how tools are supposed to behave. We have seen already several times that vague formulations led to different results.

Moreover, my proposal would actually simplify the spec because the closest ancestor data node would now be the context node for all uses of "when" - in data nodes, choice, uses and augment.

> through the when-stmt tests.

That's why I also proposed that XPath expressions in "when" must not refer to any conditional nodes (that may or may not exist depending on another "when"). This should eliminate such ripple efects.

Lada

---

From: Andy Bierman <[email-masked]>
Date: Tue, 25 Mar 2014 07:41:27 -0700

On Tue, Mar 25, 2014 at 7:14 AM, Ladislav Lhotka <[email-masked]> wrote:

> >> Perhaps the correct solution would be to define the context node to be
> the
> >> closest ancestor data node.

I think the text is clear.  The when expression is obviously processed
before
the context node exists.  It is the test to determine if the node should
exist or not.
Otherwise it would be identical to the must-stmt.

The pathological cases are probably unimplementable.
It would require that all the when-stmts be processed simultaneously
instead of 1 at a time.  Fortunately the pathological loops are not
operationally useful, so they do not really show up.

> I want a precise specification that leaves no doubts about how tools are
> supposed to behave. We have seen already several times that vague
> formulations led to different results.
>
>
I want a data modeling language that is easy to use for readers and writers.
Changing the context node would be non-intuitive.  It also prevents
when-stmt
from being used inside groupings where the parent node has not been set.

> Moreover, my proposal would actually simplify the spec because the closest
> ancestor data node would now be the context node for all uses of "when" -
> in data nodes, choice, uses and augment.
>
>
It would make it very difficult to write modular and reusable data
definitions.
A when-stmt can point at a conditional node.  It would be a problem if there
were loops, but that is not how when-stmt gets used.

> That's why I also proposed that XPath expressions in "when" must not refer
> to any conditional nodes (that may or may not exist depending on another
> "when"). This should eliminate such ripple efects.
>

It would make YANG too difficult to use.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 25 Mar 2014 15:50:04 +0100

On 25 Mar 2014, at 15:41, Andy Bierman <[email-masked]> wrote:

> I think the text is clear.  The when expression is obviously processed before
> the context node exists.  It is the test to determine if the node should exist or not.

Xpath evaluation needs a context node, or else it is ill-defined.

> Otherwise it would be identical to the must-stmt.

Yes, this is what DSDL validation does - it has to because it relies on standard XPath processors that cannot juggle with temporarily added nodes. 

> Changing the context node would be non-intuitive.  It also prevents when-stmt
> It would make it very difficult to write modular and reusable data definitions.

Why? I am pretty sure all uses of “when” in our core modules already follow these rules.

Lada

---

From: Andy Bierman <[email-masked]>
Date: Tue, 25 Mar 2014 08:09:40 -0700

On Tue, Mar 25, 2014 at 7:50 AM, Ladislav Lhotka <[email-masked]> wrote:

> > >> Perhaps the correct solution would be to define the context node to
> be the

It is defined.

> Yes, this is what DSDL validation does - it has to because it relies on
> standard XPath processors that cannot juggle with temporarily added nodes.
>
>
This is not correct though.
It is just an implementation detail to construct a new document with
the context node in that document. Then process the new document with
the standard XPath tool.

> > Moreover, my proposal would actually simplify the spec because the
> closest ancestor data node would now be the context node for all uses of
> "when" - in data nodes, choice, uses and augment.
> >
> >
> > That's why I also proposed that XPath expressions in "when" must not
> refer to any conditional nodes (that may or may not exist depending on
> another "when"). This should eliminate such ripple efects.
> >
> Why? I am pretty sure all uses of "when" in our core modules already
> follow these rules.
>
>

There is no implementation problem unless there are loops (A --> B --> C
--> A).
The normal case (A --> B --> C) is not a problem.  It can happen quite
easily.

Changing the context node to the ancestor breaks when-stmt for groupings:

   grouping foo {
       leaf X {
          when "../Y = 10";
          type string;
       }
       leaf Y {
          type int32;
       }
   }

This type of construct shows up often.
The context node cannot be changed to the parent or relative path
expressions would break.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 25 Mar 2014 16:28:11 +0100

> the context node in that document. Then process the new document with

If there are multiple nodes that have to be temporarily added in this way, do you add them all at once, and then start evaluating the XPath expressions? Or do you handle them one by one, and then in which order? Implementors may apply different answers to these questions, and arrive to different results. I don’t call this an implementation detail.

> There is no implementation problem unless there are loops (A --> B --> C --> A).
> The normal case (A --> B --> C) is not a problem.  It can happen quite easily.
> 

Why should it break? Every time this grouping is used, X and Y will have a common parent node that is the context node for the “when” expression. So only the when statement has to be changed to

    when "Y = 10";

and everything will work as expected.

Lada

> The context node cannot be changed to the parent or relative path expressions would break.
> 
>  
> Lada
> 
> 
> Andy
>

---

From: Andy Bierman <[email-masked]>
Date: Tue, 25 Mar 2014 08:38:06 -0700

....
> Why should it break? Every time this grouping is used, X and Y will have a
> common parent node that is the context node for the "when" expression. So
> only the when statement has to be changed to
>
>     when "Y = 10";
>

This is a massive change to YANG.
Not only that, the charter says that all YANG 1.0 modules MUST be
valid in YANG 1.1.  This change would not meet that constraint.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 25 Mar 2014 16:42:00 +0100

> valid in YANG 1.1.  This change would not meet that constraint.

That’s what I said. However, there is an error in YANG 1.0 and I seriously doubt the circular definition can be rectified.

Lada

---

From: Andy Bierman <[email-masked]>
Date: Tue, 25 Mar 2014 11:04:17 -0700

On Tue, Mar 25, 2014 at 8:42 AM, Ladislav Lhotka <[email-masked]> wrote:

> > Why should it break? Every time this grouping is used, X and Y will have
> a common parent node that is the context node for the "when" expression. So
> That's what I said. However, there is an error in YANG 1.0 and I seriously
> doubt the circular definition can be rectified.
>
>
I do not see the error.  Are you saying all the when-stmts that are in YANG
1.0
modules now are broken? Are you saying they are unimplementable?

YANG 1.0 when-stmts need to be unchanged in YANG 1.1.
The issue of evaluating a when-expr as if there was a context
node inserted is a completely different issue than the order that
multiple when-stmts are evaluated.  Changing the context node
to the parent does not alter the evaluation order problem.

The rules for what nodes can be accessed (directly or indirectly
via XPath mechanisms) cannot be changed because that would break
YANG 1.0 when statements.

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Tue, 25 Mar 2014 21:46:13 +0100 (CET)

Hi,

I fully agree with Andy.

I don't mind clarifying things, or make the pathological circular
cases illegal, if that can be done.

But in all real use cases, current "when" works just fine, and it is
being used and implemented all the time.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 25 Mar 2014 22:40:36 +0100

> modules now are broken? Are you saying they are unimplementable?

What I am saying is that data model fragments like

container foo {
    when "1 = 0";
    leaf bar {
        mandatory true;
        ...
    }
}

don't have a satisfactory interpretation. It is fully defensible if a validation tool flags datastore content as invalid if it doesn't contain the "foo" container and the mandatory "bar" leaf.

> to the parent does not alter the evaluation order problem.

That's true, but it does make a difference whether you insert all the temporary context nodes at once or one by one.

> YANG 1.0 when statements.

If you develop YANG modules for your customers, you can certainly make sure that everything works as expected because you are aware of the dark corners.

But if the plan is to offer YANG for general use, then the spec IMO must be rock solid. The idea that I can write a valid YANG module that will most likely blow up almost any tool around makes me nervous.

Lada

---

From: Andy Bierman <[email-masked]>
Date: Tue, 25 Mar 2014 16:03:43 -0700

On Tue, Mar 25, 2014 at 2:40 PM, Ladislav Lhotka <[email-masked]> wrote:

> don't have a satisfactory interpretation. It is fully defensible if a
> validation tool flags datastore content as invalid if it doesn't contain
> the "foo" container and the mandatory "bar" leaf.
>
>

Like I said, the pathological cases are operationally useless.
Nobody would ever write "when 1 = 0". We should avoid adding
CLRs to YANG that are intended from preventing people from doing things
they would not even try to do.  It is just busy work for compiler writers.

> That's true, but it does make a difference whether you insert all the
> temporary context nodes at once or one by one.
>
>
To be honest -- it doesn't.  Setting all the context nodes to random values
is just as arbitrarily incorrect as leaving them all out. Truth is, if
there are
dependency arcs then they have to be resolved in the correct order.

Our client code does not do that (yet).  If you are trying to test
when-stmts on
the client side in order to prevent showing the user false-when-nodes,
then it might be either order-dependent or impossible.  Unlike AJAX menus
where the conditional arcs are usually downward, the XPath arcs can go
anywhere.

Unlike "import" resolution, resolving arbitrary XPath could be impossible.
Any XPath expert could construct pathological expressions like "not(.)"
where the outcome makes YANG validation implementation-dependent or
impossible.

> If you develop YANG modules for your customers, you can certainly make
> sure that everything works as expected because you are aware of the dark
> corners.
>
> But if the plan is to offer YANG for general use, then the spec IMO must
> be rock solid. The idea that I can write a valid YANG module that will most
> likely blow up almost any tool around makes me nervous.
>
>

We can do something like mandatory top-level node -- write guidelines.
They are allowed in YANG but not in IETF modules.
The statement "while (1);" is allowed is C but it usually
is not a good thing to do.

Lada

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 26 Mar 2014 09:03:27 +0100 (CET)

Ladislav Lhotka <[email-masked]> wrote:
> don't have a satisfactory interpretation.

I think it is very clear.  The when expression is false, which means
that container foo can never exist, and thus bar can never exist.

> It is fully defensible if a
> validation tool flags datastore content as invalid if it doesn't
> contain the "foo" container and the mandatory "bar" leaf.

No.

/martin

---

From: Jernej Tuljak <[email-masked]>
Date: Wed, 26 Mar 2014 09:39:38 +0100

> that container foo can never exist, and thus bar can never exist.

I agree. This particular case is covered in section 8.2.

    Conditions on parent nodes affect constraints on child nodes as a
    natural consequence of the hierarchy of nodes. "must", "mandatory",
    "min-elements", and "max-elements" constraints are not enforced if
    the parent node has a "when" or "if-feature" property that is not
    satisfied on the current device.

>> contain the "foo" container and the mandatory "bar" leaf.

A smart compiler would flag this as a warning, since the module defines 
a data node subtree that is not instantiable. It could also prune this 
branch so it is never part of the schema tree and thus never a problem 
when validating content.

Jernej

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 26 Mar 2014 13:02:42 +0100

> I think it is very clear.  The when expression is false, which means

You cannot tell because you cannot evaluate the XPath expression, if you follow XPath rules. I guess it is why you put Y18 into the issue list, right? It is irrelevant what the XPath expression is, I used this trivial one to make my point.

And I also believe your proposed solution fails short. If you want something closer to "real use cases", here is one:

  container dhcp {
    when "not(../bootp)";
    leaf enabled {
      type boolean;
      default "true";
    }
    ...
  }
  container bootp {
    when "not(../dhcp)";
    leaf enabled {
      type boolean;
      default "true";
    }
    ...
  }
 
If neither bootp nor dhcp is explicitly configured, what is the device supposed to do? Run dhcp, bootp or neither?

Cases like this are bound to happen, especially if modules are developed in a distributed way.

Lada

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 26 Mar 2014 13:10:35 +0100

>     satisfied on the current device.

This is all fine but the point of this issue is that "when" expression cannot be evaluated without having a context node - and the context node must be in the data tree (in the instance document, in XML terms). So it is not possible to determine whether it is satisfied or not. 

> branch so it is never part of the schema tree and thus never a problem 

I wonder what a smart compiler would do with the example I just sent in my response to Martin.

Lada

---

From: Jernej Tuljak <[email-masked]>
Date: Wed, 26 Mar 2014 13:20:54 +0100

> It is only added in order to have a context node.

I don't see any solution in Y18 for the following problem?
http://www.ietf.org/mail-archive/web/netmod/current/msg08917.html
Is this a separate issue?

Jernej

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 26 Mar 2014 13:29:26 +0100 (CET)

> Is this a separate issue?

No I think it can be handled in the same issue.

Now fixed.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 26 Mar 2014 13:29:59 +0100

> Is this a separate issue?

It is a separate issue, and my understanding is the closest ancestor in this case is the Operations layer element, such as <nc:data> or <nc:config>. But you are right, it should be clarified.

Lada

---

From: Jernej Tuljak <[email-masked]>
Date: Wed, 26 Mar 2014 13:40:43 +0100

> I wonder what a smart compiler would do with the example I just sent in my response to Martin.

The optimization I hinted at would only work for your previous example 
(literals or if the compiler realizes that the equality expression is 
comparing the exact same node sets or anything else that does not 
require runtime expression evaluation). It's not applicable to your 
other example, since that requires "full" expression evaluation, and 
therefore an instance document.

Jernej

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 26 Mar 2014 13:34:59 +0100 (CET)

Ladislav Lhotka <[email-masked]> wrote:
> It is a separate issue, and my understanding is the closest ancestor
> in this case is the Operations layer element, such as <nc:data> or
> <nc:config>. But you are right, it should be clarified.

No, it doesn't make any sense to add the NETCONF message XML into the
mix.  As Jernej suggested in his original email, the context node
should be the root.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 26 Mar 2014 13:43:06 +0100

On 26 Mar 2014, at 13:40, Jernej Tuljak <[email-masked]> wrote:

> The optimization I hinted at would only work for your previous example (literals or if the compiler realizes that the equality expression is comparing the exact same node sets or anything else that does not require runtime expression evaluation). It's not applicable to your other example, since that requires "full" expression evaluation, and therefore an instance document.

The instance document is such that neither “dhcp” nor “bootp” container is present.

Lada

---

From: Jernej Tuljak <[email-masked]>
Date: Wed, 26 Mar 2014 14:35:18 +0100

Hi,

in Y18-01:

o If the "when" statement is a child of any other data definition 
statement, the context node is a node with the same name as the data 
definition node would have if it existed. This node has no value and no 
children.

Doesn't "data definition node" sound wrong? This term is used in section 
10 already and seems to refer to data definition statements/schema nodes.

    o  Any set of data definition nodes may be replaced with another set
       of syntactically and semantically equivalent nodes.  For example,
       a set of leafs may be replaced by a uses of a grouping with the
       same leafs.

A schema node always exists... What may not exist is an instance of a 
data node in the data tree.

Jernej

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 26 Mar 2014 14:40:52 +0100 (CET)

Jernej Tuljak <[email-masked]> wrote:
> definition node would have if it existed. This node has no value and
> no children.
> 
> Doesn't "data definition node" sound wrong?

Yes, it should be "data definition's node".

NEW2:

   o  If the "when" statement is a child of any other data definition
      statement, the context node is a node with the same name as the
      data definition's node would have if it existed in the tree.
      This node has no value and no children.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 26 Mar 2014 14:40:55 +0100

> Nobody would ever write "when 1 = 0". We should avoid adding

The XPath expression doesn't matter, the problem is the same whatever the expression is.

> To be honest -- it doesn't.  Setting all the context nodes to random values

It doesn't? So how do you proceed with inserting these dummy nodes in my recent dhcp/bootp example?

> is not a good thing to do.

YANG is not a programming language. If you have a valid XSD schema and an XML instance document, you probably don't expect an XSD validator to dump core.

Lada

---

From: Andy Bierman <[email-masked]>
Date: Wed, 26 Mar 2014 06:53:03 -0700

> recent dhcp/bootp example?
I would not allow that module to be published.
It would have to be rewritten so there was no dependency loop.

> YANG is not a programming language. If you have a valid XSD schema and an
> XML instance document, you probably don't expect an XSD validator to dump
> core.
>
> Lada
>
> >
> >
> > Lada
> >>
> >>
> >
> > Andy
> >
> >
> >
> >> >
> >> >
> >> >
> >> >> Lada
> >> >>
> >> >>
> >> >
> >> > Andy
> >>
> >> --

---

From: Jernej Tuljak <[email-masked]>
Date: Wed, 26 Mar 2014 14:53:39 +0100

> The instance document is such that neither “dhcp” nor “bootp” container is present.

I understand that. What I was talking about was a compile time 
optimization of the resulting schema tree. Your other example would not 
be a candidate for this optimization.

Jernej

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 26 Mar 2014 15:05:50 +0100

> It would have to be rewritten so there was no dependency loop.

Each container can be in a separate module maintained by a different party. Also, this is a very simple example - the dependency loop may be buried somewhere deep and span multiple hops.

Alternatively, it can be intentionally crafted by an attacker. 

IMO it is up to YANG spec to make sure this is not allowed, and compilers should do their best to eliminate it.

Lada

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 26 Mar 2014 15:09:35 +0100 (CET)

Ladislav Lhotka <[email-masked]> wrote:
> > >> contain
> Each container can be in a separate module maintained by a different
> party.

If I understand your concern this isn't possible, since you can't
refer to nodes from other module w/o importing the other module, and
cirular imports are not allowed.

> Alternatively, it can be intentionally crafted by an attacker. 

?

> IMO it is up to YANG spec to make sure this is not allowed, and
> compilers should do their best to eliminate it.

How can we state that there MUST NOT be any ciruclar references in
when expressions?

/martin

---

From: Andy Bierman <[email-masked]>
Date: Wed, 26 Mar 2014 07:17:09 -0700

On Wed, Mar 26, 2014 at 7:09 AM, Martin Bjorklund <[email-masked]> wrote:

> > > >> > I do not see the error.  Are you saying all the when-stmts that
> are in
> > > >> YANG
> > > >> > 1.0
This is way too difficult for a compiler to detect.
It takes somebody (like a YANG doctor) to spot the issue
and say "change this to a choice-stmt, or use must-stmt instead".

 We say say in the draft what bad things can happen if there are circular
references.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 26 Mar 2014 15:48:06 +0100

> cirular imports are not allowed.

Yes, you are right, it is not possible in this form (but see below).

>> Alternatively, it can be intentionally crafted by an attacker. 

Somebody can write a module that looks innocent and compiles properly but creates this when loop under some circumstances.

> How can we state that there MUST NOT be any ciruclar references in

I proposed a formulation earlier: 

"The XPath expression must not involve any node that is directly or indirectly conditional."

Checking it can be tricky, because the XPath expression may contain things like count(../*) whose result depends on the presence or absence of the context node.

I think XPath is too powerful for this purpose.

Lada

---

From: Andy Bierman <[email-masked]>
Date: Wed, 26 Mar 2014 07:57:12 -0700

On Wed, Mar 26, 2014 at 7:48 AM, Ladislav Lhotka <[email-masked]> wrote:

> >>>>>> I do not see the error.  Are you saying all the when-stmts that are
> in
> >>>>> YANG
> >>>>>> 1.0
> Somebody can write a module that looks innocent and compiles properly but
> creates this when loop under some circumstances.
>
> >
This is far too restrictive and not needed.

I strongly object to solutions that make valid YANG 1.0 modules invalid.
It violates the charter, so every proposal better meet this requirement.

Checking it can be tricky, because the XPath expression may contain things
> like count(../*) whose result depends on the presence or absence of the
> context node.
>
Andy

---

From: Jernej Tuljak <[email-masked]>
Date: Wed, 26 Mar 2014 16:02:26 +0100

> Checking it can be tricky, because the XPath expression may contain things like count(../*) whose result depends on the presence or absence of the context node.

I don't think you need the actual result of the evaluation though. All 
you need to know is what the expression is referencing; parent, self and 
siblings of the context node in your case.

Is there an example for the A->B->C->A loop case?

Jernej

---

From: Andy Bierman <[email-masked]>
Date: Wed, 26 Mar 2014 08:36:53 -0700

On Wed, Mar 26, 2014 at 8:02 AM, Jernej Tuljak <[email-masked]>wrote:

>> Checking it can be tricky, because the XPath expression may contain
>> things like count(../*) whose result depends on the presence or absence of
>> the context node.
>>
>
> I don't think you need the actual result of the evaluation though. All you
> need to know is what the expression is referencing; parent, self and
I think all the intermediate and final node-set results of every
must/when expression in order to know if any XPath expressions
access the same nodes.

Examining the schema tree instead of the value tree has some problems,
but ignoring that for the moment, it would be possible to detect that some
previous when-stmt accessed the same node as another when-stmt.

> Is there an example for the A->B->C->A loop case?

Simple loop:

  container foo {
     leaf A {
        when "../B = 10";
        type int32;
     }
     leaf B {
        when "../C = 10";
        type int32;
     }
     leaf C {
        when "../A != 10";
        type int32;
     }
  }

There are no real examples AFAIK.

Of course, it is more complicated. Nodes can inherit
multiple when-stmts, so even the order that when-stmts are processed
for a single node can affect the ability to detect these loops.
(You stop at the first false when-stmt).

If there are if-feature statements then it gets even more complicated.

It's fine to say when-stmt references MUST NOT create circular references,
but I doubt compilers will detect these errors very well.

Andy

---

From: Jernej Tuljak <[email-masked]>
Date: Thu, 27 Mar 2014 11:38:18 +0100

Dne 26.3.2014 16:36, piše Andy Bierman:
>
>
>
> On Wed, Mar 26, 2014 at 8:02 AM, Jernej Tuljak 
> <[email-masked] <mailto:[email-masked]>> wrote:
>
>         On 26 Mar 2014, at 15:09, Martin Bjorklund <[email-masked]
>         <mailto:[email-masked]>> wrote:
>
>             Ladislav Lhotka <[email-masked] <mailto:[email-masked]>> wrote:
>
>                 On 26 Mar 2014, at 14:53, Andy Bierman
>                 <[email-masked] <mailto:[email-masked]>> wrote:
>
>
>
>                     On Wed, Mar 26, 2014 at 6:40 AM, Ladislav Lhotka
>                     <[email-masked] <mailto:[email-masked]>>
>                     wrote:
>                     Andy Bierman <[email-masked]
>                     <mailto:[email-masked]>> writes:
>
>                         On Tue, Mar 25, 2014 at 2:40 PM, Ladislav
>                         Lhotka <[email-masked] <mailto:[email-masked]>>
>                         wrote:
>
>                             Andy Bierman <[email-masked]
>                             <mailto:[email-masked]>> writes:
>
>
>                                 I do not see the error.  Are you
>                                 saying all the when-stmts that are in
>
>                             YANG
>
>                                 1.0
>                     The XPath expression doesn't matter, the problem
>                     is the same whatever
>                     the expression is.
>
>                         CLRs to YANG that are intended from preventing
>                         people from doing
>                         things
>                         they would not even try to do.  It is just
>                         busy work for compiler
>                         writers.
>
>
>
>
>                         To be honest -- it doesn't.  Setting all the
>                         context nodes to random
>                         values
>
>                     It doesn't? So how do you proceed with inserting
>                     these dummy nodes in
>                     my recent dhcp/bootp example?
>
>
>         Somebody can write a module that looks innocent and compiles
>         properly but creates this when loop under some circumstances.
>
>         Checking it can be tricky, because the XPath expression may
>         contain things like count(../*) whose result depends on the
>         presence or absence of the context node.
>
>
>     I don't think you need the actual result of the evaluation though.
>     All you need to know is what the expression is referencing;
>     parent, self and siblings of the context node in your case.
>
>

What problems related to examining the schema tree were you referring to 
here?

> (You stop at the first false when-stmt).

There are no false when-stmts at compile time. If all you require from 
an XPath expression for loop detection is a set of data nodes upon which 
the expression relies, these can be determined at compile time, as long 
as there are no unknown XPath functions that return node sets. I don't 
think the order is relevant really - the analysis would be about what 
could potentially happen, not about what is happening in a given 
situation (compile time vs. runtime).

> If there are if-feature statements then it gets even more complicated.

If-features simply imply a conditional branch that relies on some 
condition which is only available at runtime. These conditions do not 
reference data nodes, so I don't think they are problematic. Two when 
statements that do not reference each other in any way are not an issue 
even if they are nested, right? An if-feature and a when is no 
different. Do you have an example that would demonstrate your concern? 
If leaf C had an if-feature that would not change the fact there's a 
potential loop in your example.

> but I doubt compilers will detect these errors very well.

I agree. Also agree that it would not be easy to implement.

Perhaps transforming the all data nodes of a schema tree (cooked YANG) 
into a directed graph, where edges are constructed as pairs of the 
initial context node and all subsequent context nodes for each 
expression and then applying an algorithm for finding cycles is enough 
to find all potential loops.

G=(V,E)
V= {foo, A, B, C}
E= {{A,foo}, {A,B}, {B,foo}, {B,C}, {C,foo}, {C,A}}

Just guessing though.

Jernej

>         [email-masked] <mailto:[email-masked]>
>     [email-masked] <mailto:[email-masked]>