Subject: Re: [netmod] duplicate leaf names in augments

From: David Reid <[email-masked]>
Date: Wed, 18 Mar 2009 09:16:07 -0400

I don't think the issue discussed in this thread has been addressed in the
current document. Or maybe it was addressed in a different way and I'm just
missing it.

-David Reid

-------- Original Thread:

David> If I have 2 different augments in the same module, do the leaf 
David> identifiers have to be unique? Below is an example, where ChannelNumber 
David> is used twice. I don't think that is legal, but I'm not sure what 
David> rule tells me it is not.
David> 
David>     module if {
David>         namespace "http://example.com/schema/interfaces"
David>         prefix "if";
David> 
David>         container interfaces {
David>             list ifEntry {
David>                 key "ifIndex";
David> 
David>                 leaf ifIndex { type uint32; }
David>                 leaf ifDescr { type string; }
David>                 leaf ifType { type iana:IfType; }
David>                 leaf ifMtu { type int32; }
David>             }
David>         }
David> 
David>         augment "/if:interfaces/if:ifEntry" {
David>             when "if:ifType='ds0'";
David>             leaf ChannelNumber {
David>                  type ChannelNumber;
David>             }
David>         }
David> 
David>         augment "/if:interfaces/if:ifEntry" {
David>             when "if:ifDescr='xyz'";
David>             leaf ChannelNumber {
David>                  type ChannelNumber;
David>             }
David>         }
David>     }
David> 
David> -David Reid

Andy> good question.
Andy> It applies to any usage of thew 'when' statement, not just augment.
Andy> IMO, no -- otherwise you can end up with an invalid schema
Andy> based on the value of arbitrary leaf value.  All QName siblings
Andy> need to be unique, regardless of when and if-feature values.
Andy> 
Andy> Andy

Martin> You're right that it is not supposed to be legal and also that some
Martin> text is missing.  I think we need a new rule in 6.2.1.

---

From: Andy Bierman <[email-masked]>
Date: Wed, 18 Mar 2009 06:40:08 -0700

> current document. Or maybe it was addressed in a different way and I'm just

This is not legal.
At YANG-compile-time, all the sibling nodes in
the same namespace must be unique.  The when-stmt
is evaluated at agent-run-time.  You can have
as many augment-stmts pointing at the same target
as you want.  Just use different names.
(e.g., leaf ChannelNumber is declared twice).

> -David Reid

Andy

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

---

From: David Reid <[email-masked]>
Date: Wed, 18 Mar 2009 09:57:33 -0400

> the same namespace must be unique.  

I agree that this should not be legal, I just can't find the text in the
document that tells me it is not legal. From section 6.2.1, it looks like
my 2 leafs named ChannelNumber are in different namespaces, therefore legal.

My yang compiler does not report this as an error (which I think is wrong).

-David Reid

---

From: Andy Bierman <[email-masked]>
Date: Wed, 18 Mar 2009 07:13:24 -0700

> my 2 leafs named ChannelNumber are in different namespaces, therefore legal.

which bullet in 6.2.1 makes you think these leafs are in
different namespaces.  Both augment-stmts are in the
same namespace.

> My yang compiler does not report this as an error (which I think is wrong).

which compiler?
which version of YANG?

Both augment-stmts are in the same module, and
they both have the same target.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 18 Mar 2009 15:25:53 +0100

> (e.g., leaf ChannelNumber is declared twice).

I agree, except that such intra-module augments are not allowed anymore.

Sec. 7.15:
The "augment" statement allows a module or submodule to add to the
schema tree defined in another module or submodule, and to add to the
nodes from a grouping in a "uses" statement.

The intended effect can be achieved simply this way:

container interfaces {
    list ifEntry {
        key "ifIndex";
        leaf ifIndex { type uint32; }
        leaf ifDescr { type string; }
        leaf ifType { type iana:IfType; }
        leaf ifMtu { type int32; }
        leaf ChannelNumber {
            when "../if:ifType='ds0' or ../if:ifDescr='xyz'";
            type ChannelNumber;
        }
    }
}

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: David Reid <[email-masked]>
Date: Wed, 18 Mar 2009 10:32:14 -0400

> different namespaces.  Both augment-stmts are in the

   o  All leafs, leaf-lists, lists, containers, choices, rpcs, and
      notifications defined within a parent node or at the top-level of
      the module or its submodules share the same identifier namespace.
      This namespace is scoped to the parent node or module, unless the
      parent node is a case node.  In that case, the namespace is scoped
      to the parent node of the case node's parent choice node.

>From the statement above, I though that my 2 ChannelNumber leafs had different
parents, therefore different namespaces. I think you are telling me that since
they augment the same list, they really have the same parent and therefore
share a namespace. Did I understand that correctly?

> > My yang compiler does not report this as an error (which I think is wrong).

It is the compiler I am developing, which is not yet complete. It was 
originally written for draft-ietf-netmod-yang-01.txt, and has been updated
some since then. The reason I'm asking the question is that I don't think
my compiler is doing the right thing, but I'm not seeing a rule in the spec
that tells me why.

-David Reid

---

From: Andy Bierman <[email-masked]>
Date: Wed, 18 Mar 2009 07:48:16 -0700

> share a namespace. Did I understand that correctly?

yes. what matters is the conceptual 'composite' object tree
that is built from all the uses/refine/augment/deviations details.
This applies to any sibling nodes (could be top-level).

> my compiler is doing the right thing, but I'm not seeing a rule in the spec

Wow!
Where can I get one of those spec-reading-code-writing machines? :-)

(yang-01 is so ancient...
One hopes that YANG will eventually stabilize.
It is mostly pointless to implement tools now.)

Andy

---

From: David Reid <[email-masked]>
Date: Wed, 18 Mar 2009 10:55:32 -0400

> I agree, except that such intra-module augments are not allowed anymore.

Good point. I missed that.

> nodes from a grouping in a "uses" statement.

This causes me another problem. I'm trying to make SNMP MIB data available over
netconf with yang. If I can't augment a list in the same module, I'm not sure
what to do with SNMP MIBs that augment tables in the same module. For example,
in IF-MIB, ifXEntry augments ifEntry.

-David Reid

---

From: David Reid <[email-masked]>
Date: Wed, 18 Mar 2009 11:30:06 -0400

> I agree, except that such intra-module augments are not allowed anymore.

Let me change my example slightly and put the augments in different submodules.
Now I don't have an intra-module augments. If I understand Andy correctly, my
compiler should still flag this as an error because I can know at compile time
that ifEntry would end up with 2 leafs named ChannelNumber. Is that right?

    module if {
        namespace "http://example.com/schema/interfaces";
        prefix "if";
        include A;
        include B;

        container interfaces {
            list ifEntry {
                key "ifIndex";

    submodule A {
        belongs-to if { prefix if; }

        augment "/if:interfaces/if:ifEntry" {
            when "if:ifType='ds0'";
            leaf ChannelNumber {
                 type int32;
            }
        }
    }

    submodule B {
        belongs-to if { prefix if; }

        augment "/if:interfaces/if:ifEntry" {
            when "if:Descr='xyz'";
            leaf ChannelNumber {
                 type int32;
            }
        }
    }

-David Reid

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 18 Mar 2009 16:43:55 +0100

> that ifEntry would end up with 2 leafs named ChannelNumber. Is that right?

I think so, and also if the augments were in stand-alone modules, but
probably only if all three modules were compiled together - I assume an
import statement by itself doesn't apply the augment from the imported
module.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 18 Mar 2009 17:01:10 +0100

> in IF-MIB, ifXEntry augments ifEntry.

One option is to rewrite the original table definition and another to
put the list in a grouping and then augment it inside "uses".

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: David Reid <[email-masked]>
Date: Wed, 18 Mar 2009 12:04:13 -0400

> import statement by itself doesn't apply the augment from the imported

Let me change the example one more time and put the 2 augments in stand-alone
modules. I think this example is legal and should not generate a compile
error. 

    module if {

        container interfaces {
            list ifEntry {
                key "ifIndex";

    module A {
        namespace "http://example.com/schema/A";
        import if { prefix if; }

    module B {
        namespace "http://example.com/schema/B";
        import if { prefix if; }

-David Reid

---

From: Balazs Lengyel <[email-masked]>
Date: Wed, 18 Mar 2009 17:16:34 +0100

You can't include a module, only a submodule, so it should be import. After that is should be 
legal.
Balazs

-- 
Balazs Lengyel                       Ericsson Hungary Ltd.
TSP System Manager
ECN: 831 7320                        Fax: +36 1 4377792
Tel: +36-1-437-7320     email: [email-masked]

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 18 Mar 2009 17:24:16 +0100

> You can't include a module, only a submodule, so it should be import. After that is should be 

Hmm, I probably don't understand what "compile" precisely means, but if
an agent advertised all three modules in <hello>, then it looks like a
problem.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Wed, 18 Mar 2009 09:27:34 -0700

Balazs Lengyel wrote:
> You can't include a module, only a submodule, so it should be import. 
> After that is should be legal.

I disagree.
One of the 2 submodules (A or B) is going
to go first, and add leaf channelNumber.
Then the other submodule (which does not know about
the first one) will also try to add a leaf
named channelNumber. But this time there will
already be one present.  It is no different
than if channelNumber were part of the original
ifEntry list.

The correct solution is the one Lada suggested.

Andy

---

From: David Reid <[email-masked]>
Date: Wed, 18 Mar 2009 13:12:32 -0400

> than if channelNumber were part of the original

In the case where the augments are in different yang modules, the 2 
ChannelNumbers will be in different XML namespaces, which is why I thought 
it would be legal.

> The correct solution is the one Lada suggested.

I agree that my example is a bit contrived. My goal is to make sure that
the spec is clear and that my implementation is correct.

-David Reid

---

From: David Reid <[email-masked]>
Date: Wed, 18 Mar 2009 13:54:39 -0400

Why would it be a problem to advertise all three?

-David Reid

> Balazs Lengyel:

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 18 Mar 2009 21:02:57 +0100

> Why would it be a problem to advertise all three?

Oh yes, I forgot about the difference in namespaces, sorry for the
confusion.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Wed, 18 Mar 2009 13:04:27 -0700

> the spec is clear and that my implementation is correct.

I tested your files with a new version of
yangdump to see what would happen.

I attached the (really short) files:

   if.yang == top level module
    A.yang == submodule A
    B.yang == submodule B
    C.orig.yang == guts of if.yang moved to a submodule, with 'iana' bug
                  (A submodule cannot access stuff in the main module.)
    C.yang == guts of if.yang moved to a submodule, with 'iana' bug
    logfile_AB == yangdump results with C.orig.yang,
                  with include A before include B
    logfile_BA == yangdump results with C.orig.yang,
                  with include B before include A
    logfile_AB2 == yangdump results with C.yang,
                  with include A before include B
    logfile_BA2 == yangdump results with C.yang,
                  with include B before include A

Notes:
   1) logfile_AB, logfile_BA:
      the Xpath 'when' target 'if:ifType' is not found in yangdump
      because the 'ifType' leaf had an invalid data type,
      and was not added to 'ifEntry' for further error reporting
   2) logfile_AB2:
      since 'include A' is first, its 'channelNumber' gets
      added to ifEntry just fine.  No when-stmt bug in this one.
      The channelNumber in submodule 'B' does not get checked
      further, after the duplicate is found.
   3) logfile_BA2:
      since 'include B' is first, its version of channelNumber
      is used, and its when-stmt is tested, and the 'if:Descr'
      error is reported

Andy

    module if {
        include C;

    submodule B {
        include C;

    submodule C {

        container interfaces {
            list ifEntry {
                key "ifIndex";

    submodule C {

        container interfaces {
            list ifEntry {
                key "ifIndex";

                leaf ifIndex { type uint32; }
                leaf ifDescr { type string; }
                leaf ifType { type string; }
                leaf ifMtu { type int32; }
            }
        }
    }

*** Generated by yangdump 0.9.4 at 2009-03-18T11:48:06.000-07:00

Warning: no revision statements for submodule 'C'
Error: import for prefix 'iana' not found
C.yang:10.36: error(331): undefined prefix

Warning: no revision statements for submodule 'A'
Warning: no revision statements for submodule 'B'
Error: object 'ChannelNumber' already defined in submodule 'A' at line 7
B.yang:8.13: error(224): duplicate entry

Warning: no revision statements for module 'if'
Warning: no child nodes found in XPath expr 'if:ifType='ds0''
C.yang:6.33: warning(432): no child node available

*** if.yang: 2 Errors, 5 Warnings

*** Generated by yangdump 0.9.4 at 2009-03-18T11:48:35.000-07:00

Warning: no revision statements for submodule 'C'
Error: import for prefix 'iana' not found
C.yang:10.36: error(331): undefined prefix

Warning: no revision statements for submodule 'B'
Warning: no revision statements for submodule 'A'
Error: object 'ChannelNumber' already defined in submodule 'B' at line 8
A.yang:7.13: error(224): duplicate entry

Warning: no revision statements for module 'if'
Warning: no child nodes found in XPath expr 'if:Descr='xyz''
C.yang:7.32: warning(432): no child node available

*** if.yang: 2 Errors, 5 Warnings

*** Generated by yangdump 0.9.4 at 2009-03-18T12:42:12.000-07:00

Warning: no revision statements for submodule 'C'
Warning: no revision statements for submodule 'A'
Warning: no revision statements for submodule 'B'
Error: object 'ChannelNumber' already defined in submodule 'A' at line 7
B.yang:8.13: error(224): duplicate entry

Warning: no revision statements for module 'if'
*** if.yang: 1 Errors, 4 Warnings

*** Generated by yangdump 0.9.4 at 2009-03-18T12:41:47.000-07:00

Warning: no revision statements for submodule 'C'
Warning: no revision statements for submodule 'B'
Warning: no revision statements for submodule 'A'
Error: object 'ChannelNumber' already defined in submodule 'B' at line 8
A.yang:7.13: error(224): duplicate entry

Warning: no revision statements for module 'if'
Warning: no child nodes found in XPath expr 'if:Descr='xyz''
C.yang:7.32: warning(432): no child node available

*** if.yang: 1 Errors, 5 Warnings

---

From: Martin Bjorklund <[email-masked]>
Date: Mon, 23 Mar 2009 11:32:18 -0700 (PDT)

David Reid <[email-masked]> wrote:
> current document.

How about adding this to the section "7.15  The augment statement":

  The augment statement MUST NOT add multiple nodes with the same name
  from the same module to the target node.

/martin

---

From: David Reid <[email-masked]>
Date: Tue, 24 Mar 2009 11:46:11 -0400

>   from the same module to the target node.

Yes, that solves the problem.

-David Reid