Subject: [netmod] keyref

From: Andy Bierman <[email-masked]>
Date: Tue, 08 Jul 2008 09:53:28 -0700

Hi,

I have some concerns about the keyref builtin data type.

8.8.  The keyref Built-in Type
------------------------------

    The keyref type is used to reference a particular list entry in the
    data tree.  Its value is constrained to be the same as the key of an
    existing list entry.

Randy already brought up the issue of hot-swap/provisioning
configuration.  It is insufficient to constrain the value of
a keyref to the set of existing instances.  This must be the set of
all possible instances instead.

It is also too restrictive to limit a keyref to a leaf used as a key.
A new list can be created with key leafs which happen to already be
defined as non-key leafs in other data structure (does not have to
be in a list).  Perhaps a separate 'leafref' would be better for this
purpose.  IMO, this is also needed to define notification content
properly.

    If the leaf with the keyref type represents configuration, the list
    entry it refers to MUST also represent configuration.  Such a leaf
    puts a constraint on a valid configuration.  In a valid
    configuration, all keyref nodes MUST reference existing list entries.

I do not agree with this paragraph.
smidump is already violating this rule by using keyref within
notifications to provide a pointer to the list entry associated
with the notification.  What is the purpose of this restriction?

8.8.2.  The path Statement
--------------------------

Why does keyref need to be made super-complicated by allowing
predicates in the path-stmt? (The ABNF for this is not correct BTW).

The example on pg 99 shows a path-stmt with a predicate:

   container default-address {
       leaf ifname {
           type keyref {
               path "../../interface/name";
           }
       }
       leaf address {
           type keyref {
               path "../../interface[name = $this/../ifname]/address/ip";
           }
       }
   }

IMO, this is really esoteric and hard to read.
How important is it to limit the keyref value range
to a subset of all instances?  Limiting instance
values will break provisioning applications anyway,
so this extra feature does not seem very important.

The examples of keyref in use (ipfix-psamp, smidump 'borrowed key'
and notification key) make sense to me, and do not need this
instance subsetting feature.

8.10 The union Built-in Type
----------------------------

   A member type can be of any built-in or derived type, except it MUST
   NOT be one of the built-in types "empty" or "keyref".

What is the purpose of excluding keyref from the list of
valid type-stmts within a union?  I am not saying this is wrong,
but some explanation would be helpful.

Other Issues (not in draft)
------------------------------------

What happens if a keyref points to another keyref object,
which happens to be a key defined as a keyref?  Is this
allowed?  So compilers must check for 'loops' in the
path-stmt to make sure the keyref chain eventually ends
at a leaf with a real data type?

What happens if node 'X' is deprecated or obsoleted in a new
version of module foo?  Does that automagically invalidate
all the modules that reference foo:X in keyref path-stmts?
What if the data type for leaf 'Y' changes over time?
Which version of 'Y' is referenced in keyrefs in other modules?

How are modules which use keyrefs that contain path-stmts
which reference nodes in other modules kept in synch (or not)
with each other?

Andy

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

---

From: Martin Bjorklund <[email-masked]>
Date: Tue, 08 Jul 2008 23:30:16 +0200 (CEST)

Hi,

> 8.8.  The keyref Built-in Type

If this is what you want, just use the same type as the corresponding
key.  For example, instead of:

      leaf if-name {
          type keyref {
              path "/interfaces/interface/name";
          }
      }

do:
   
      leaf if-name {
          type string;
      }

The whole point of using a keyref is to be able to have a reference to
an existing instance of some sort.

> purpose.  IMO, this is also needed to define notification content

Please make a proposal for what you want to do.  I don't understand
which problem 'leafref' solves.

> with the notification.  What is the purpose of this restriction?

Since a configuration is invalid if a keyref points to a non-existing
instance, the keyref cannot point to something that may change
dynamically.  A configuration cannot be valid at one point in time,
but invalid the next just b/c some operational state changed.

> predicates in the path-stmt?

It allows just one form of a predicate; equality.

The reason is that we need some way to refer to multiple keys.

> (The ABNF for this is not correct BTW).

Please let me know what the errors are.

> IMO, this is really esoteric and hard to read.

I agree with the hard to read part.  See below.

> so this extra feature does not seem very important.

The example shows how I can refer to an instance which have keys on
more than one level.  So given this:

  list interface {
    key "name";
    ...
    list address {
      key "ip";
      ...
    }
  }

the example shows how a specific ip address on a specific interface
can be referenced.

> instance subsetting feature.

Right.  In most cases, a simple keyref will do the job.  But the
current solution covers multiple hierarchies and multiple keys.

> 8.10 The union Built-in Type

The problem is the
interpretation of the following:

  leaf foo {
    type union {
      type keyref "/interface/ifIndex";
      type string;
    }
  }

Suppose ifIndexes 1, 2, and 3 exists, and I set foo to 1.  This is
fine.  Now suppse I remove ifIndex 1.  This is still fine, but foo
magically changed its underlying type from a uint32 into a string.

> allowed?

Sure.

> So compilers must check for 'loops' in the

Yes, a loop would be an error.

> all the modules that reference foo:X in keyref path-stmts?

No, the text says:

  If a definition is "current", it MUST NOT reference a "deprecated"
  or "obsolete" definition within the same module.

(not specific to keyref)

> Which version of 'Y' is referenced in keyrefs in other modules?

With the current import scheme (i.e. no import by revision), you will
not be allowed to change the data type unrestricted.

> which reference nodes in other modules kept in synch (or not)

I don't understand the question.  Just like augment paths maybe?

This being said, I would very much like to see a better solution for
the keyref problem.  What we have now is the best we have found so
far.  The problem is that we want simple references to object
instances.  If we just need any reference, we could use an
instance-identifier, but the syntax far from simple.  Compare with how
ifIndex is referenced in mibs; sometimes it's like
atmSvcVpCrossConnectLowIfIndex from the ATM2-MIB, and sometimes it's
references through an OBJECT IDENTIFIER.  The keyref constructs
formalizes the simple case of reference.

Compare:

      leaf if-name {
          type keyref {
              path "/interfaces/interface/name";
          }
      }

to:

      leaf if-name-2 {
          type instance-identifier;
      }

And the encodings:

  <if-name>eth0</ifname>

to:

  <if-name2 xmlns:if="urn:ietf:params:xml:ns:interface">
    /if:interfaces/if:interface[if:name="eth0"]
  </if-name2>

/martin

---

From: Balazs Lengyel <[email-masked]>
Date: Fri, 11 Jul 2008 16:56:23 +0200

Hello,
Please see below!

> but invalid the next just b/c some operational state changed.
[BALAZS]: What if someone pulls out an interface card? Can that make a configuration invalid?
A must statement can also reference a state variable, so a state change CAN invalidate a 
configuration.

>     /if:interfaces/if:interface[if:name="eth0"]
[BALAZS]: I think we need both the simple form and the free form (Instance Identifier). 
Instance identifiers can also point to leafs, to non-existing stuff, to different data-types ...

Balazs

---

From: Andy Bierman <[email-masked]>
Date: Fri, 11 Jul 2008 09:01:09 -0700

Balazs Lengyel wrote:
> A must statement can also reference a state variable, so a state change 
> CAN invalidate a configuration.
> 

I agree.  NE configuration must deal with hot-plug/hot-swap.
NETCONF has <edit-config> 'continue-on-error' to deal
will loading partially valid configurations.  However,
I would not want the agent generating errors because
some config exists for an empty slot.

> [BALAZS]: I think we need both the simple form and the free form 
> (Instance Identifier). Instance identifiers can also point to leafs, to 
> non-existing stuff, to different data-types ...
> 

The main use case for leafref is the use of secondary 'index-by-handle'
like RMON2 does with the protocolDirLocalIndex.  This is a plain
leaf in the config table where it is defined.  For performance
and simplicity, this uint32 is used in many other tables
for indexing, instead of the corresponding encoded OCTET STRING
identifier for a given protocol encapsulation.  This is not
currently supported in YANG.

The real topic of this thread should be 'Inter-Table Relationships'.
IMO, embedding table relationships into the built-in data types
is not well defined in YANG, and as a result, the 'keyref' and
'instance-identifier' types are over-loaded and confusing.

Andy