Subject: [netmod] choice's default case

From: Ladislav Lhotka <[email-masked]>
Date: Thu, 23 Apr 2009 08:16:14 +0200

Hi,

when substituting defaults with the following module, should the default
case "foo" be inserted if no case is present in the configuration?

module test {
    namespace "http://example.com/test";
    prefix test;
    choice foobar {
        default foo;
        container foo {
            presence "foo";
        }
        container bar {
            presence "bar";
        }
    }
}

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 23 Apr 2009 12:41:58 +0200 (CEST)

>     namespace "http://example.com/test";

I'm not sure I understand what you mean with "substituting defaults",
but 7.9.3 says:

   The default case is only important when considering the default
   values of nodes under the cases.  The default values for nodes under
   the default case are used if none of the nodes under any of the cases
   are present.

This means that if no case is present in your configuration, nothing
special happens, since there are no default values under the default
case.  Maybe our tools should give a warning about this...

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Thu, 23 Apr 2009 13:15:43 +0200

> I'm not sure I understand what you mean with "substituting defaults",

By this I mean the transformation of a configuration with suppressed
defaults to one with expressed defaults. I am trying to figure out how
the choice's default statement should be mapped to DSRL.

>    the default case are used if none of the nodes under any of the cases

Does "under" mean children or descendants here? For example, what will
happen if container foo in my example contained this leaf:

leaf greeting { type string; default "Hello"; }

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 23 Apr 2009 13:25:33 +0200 (CEST)

> leaf greeting { type string; default "Hello"; }

Nothing, since the foo container is a presence container.  If you
remove the presence statement, then greeting would have its default
value if no case was present.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Thu, 23 Apr 2009 14:24:07 +0200

> value if no case was present.

OK, so "under" means descendants, but then I think the cited paragraph
from 7.9.3 is a bit vague. One can understand the choice's default
statement as a way for selecting one case by default. This would IMO
make a perfect sense:

choice protocol {
  default ssh;
  container ssh {
    presence "secure shell";
    ...
  }
  container rsh {
    presence "remote shell";
    ...
  }
}

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Thu, 23 Apr 2009 12:42:19 -0700

> case.  Maybe our tools should give a warning about this...

I'm not sure I interpreted/implemented this correctly.
I probably create <foo/> because it is a P container.

Clearly, if 'foo' was an NP-container, it would not
be added as the default unless it had child nodes
that had defaults.

Lists and leaf-lists do not get entries created by default.
That is also clear.

But why not presence containers?

By definition, an empty P container has meaning,
so this sort of construct is valid:

  choice dhcp-or-static {
     default dhcp;

     container dhcp {
        presence
          "empty container means default DHCP parms are in effect.";
        ... optional leafs ...
     }
     container static {
        leaf address { type inet:ip-address; mandatory true; }
        leaf subnetmask { type inet:ip-address; mandatory true; }
        leaf gateway { type inet:ip-address; mandatory true; }
     }
   }

This is a valid config node:

   <dhcp/>

> /martin

Andy

---

From: WashamFan <[email-masked]>
Date: Fri, 24 Apr 2009 10:43:07 +0800

>  This is a valid config node:

I also prefer presence container is added as the default if it is stated
as the default in its ancestor choice.

washam

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

---

From: Ladislav Lhotka <[email-masked]>
Date: Fri, 24 Apr 2009 11:43:17 +0200

> so this sort of construct is valid:

Yes, this is the same as my ssh/rsh example and seems very natural, but
it is much less clear in this case:

choice dhcp-or-static {
    default dhcp;
    case dhcp {
        leaf someleaf { type string; default "Hi!"; }
        container dhcp {
            presence "...";
            ...
        }
    ...
}

I'd tend not to insert the P container by default here, but
from the point of view of the P container it is pretty much the same
situation as in your example.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Martin Bjorklund <[email-masked]>
Date: Fri, 24 Apr 2009 12:29:07 +0200 (CEST)

> But why not presence containers?

We want this to work with all flavors of :with-defaults.  In some
systems defaults are actually not stored in the data store.  If a leaf
does not exist in the data store, its default value is used.  If a P
container doesn't exist, with your suggestion above, the application
would treat it as if it existed.  But this means that there is no
difference to the application if it exists or not!  

Another way to understand this is that default values are not sent
unless with-defaults is "true" in the request.  So if a P container
would exist by default, it would not be sent if with-defaults is
false.  How can you differentiate this with the case that the P
container is explicitly removed?  In both cases it is not there.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Fri, 24 Apr 2009 12:52:06 +0200

> We want this to work with all flavors of :with-defaults.  In some

The fact that we don't have a clear model for dealing with defaults
leads to ambiguous formulations like in 7.9.3: "The default values for
nodes under the default case are used ...". What does this actually
mean? Apparently they are used only in some cases.

> container is explicitly removed?  In both cases it is not there.

The default statement in effect means that there is no way to suppress
all cases of the choice, so either one is specified explicitly or the
default one is assumed. This is no different from normal (leaf)
defaults: either an explicit value is specified or the default assumed.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Fri, 24 Apr 2009 04:16:35 -0700

> container is explicitly removed?  In both cases it is not there.

I don't agree with this logic at all.

The data modeler can decide if the default case makes sense
or not.  It makes no difference whether the default case
is a leaf or a P container.  In my perfectly valid use case,
there are semantics associated with the agent-selected default
of 'plain DCHP'.  If the <dhcp> node was a leaf of type 'empty'
then everything is fine.  A P container is no different,
if none of the optional leafs are filled in.  The <dhcp>
service is still running, and the config is clear and complete.

I really dislike P and NP containers.
I get comments all the time how strange it is
to make such a complicated mess out of a simple container.

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Mon, 27 Apr 2009 16:53:23 +0200 (CEST)

Andy Bierman <[email-masked]> wrote:
> > difference to the application if it exists or not!  Another way to understand
> > this is that default values are not sent
> then everything is fine.

No, that not how choice defaults work.  If I understand you correctly,
you mean that with this model:

  list foo {
      key name;
      leaf name { type string; }

      choice bar {
          default "tcp";
          case tcp {
              leaf tcp { type empty; }
          }
          case udp {
              leaf tcp { type empty; }
          }
      }
  }

If I create:

    <foo>
      <name>t1</name>
    </foo>

Then /foo/tcp gets automatically created by the agent?

And you suggest that the same happens if 'tcp' is a P container?

But the same does not happen if 'tcp' is a leaf of type boolean?

After my create in the example above, suppose I do:

  <foo>
    <name>t1</name>
    <tcp nc:operation="delete"/>
  </foo>

Is 'tcp' deleted or not?

/martin

---

From: Andy Bierman <[email-masked]>
Date: Mon, 27 Apr 2009 08:48:21 -0700

>     <tcp nc:operation="delete"/>

no -- just the same as any other time you
try to delete the default case.

  choice dhcp-or-static {
     default dhcp;

     container dhcp {
        presence
          "empty container means default DHCP parms are in effect.";
        leaf getDnsFromDhcp {
           description
             "If true, then the agent will use the DHCP provided
              DNS servers. Otherwise any pre-configured DNS servers
              will be used instead.";
           type boolean;
           default true;
        }
     }
     container static {
        leaf address { type inet:ip-address; mandatory true; }
        leaf subnetmask { type inet:ip-address; mandatory true; }
        leaf gateway { type inet:ip-address; mandatory true; }
     }
   }

This data model works fine wrt/ default case.
It does not make sense to simply delete /dhcp or its leaf.
The agent will create it back again, as intended.

I do not understand why YANG needs a CLR preventing this
sort of data model. What difference does it make what
child nodes are defined within 'dhcp'.  Because it is
a presence container, it is allowed to be an empty container.

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Mon, 27 Apr 2009 19:19:54 +0200 (CEST)

> try to delete the default case.

Ok, and would a P container behave like this only when it is a child
of a default case?  The rule would be that if a default case has a P
container or a leaf of type empty, then this node is automatically
created by the agent if no nodes from the choice is present?

A P container under a list would not behave like this?

> sort of data model.

In this case, you will get what you are looking for by making dhcp a
NP-container.

/martin

---

From: Andy Bierman <[email-masked]>
Date: Mon, 27 Apr 2009 10:33:47 -0700

> A P container under a list would not behave like this?

correct -- IMO this makes the default case consistent
with the leaf default.  It is the default-stmt causing
the automatic creation, not the P container itself.

> In this case, you will get what you are looking for by making dhcp a

true, but what about an empty P container that is defined
just so it can be augmented?  That might be rare, but maybe not.
What if some WG cannot agree on any of the exact DHCP parameters
to define, but they can agree on the concept of a flag <dhcp/>
to have some indication of which choice is made (dhcp-or-static)?

An empty NP container should be deleted by the agent,
so it is only an empty P container that would make sense
for the default case.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 28 Apr 2009 16:47:17 +0200

Hi,

how about this choice:

    choice one-or-two {
      default "one";
      container one {
        leaf leaf1 {
          type uint8;
          default "1";
        }
      }
      container two {
        leaf leaf2 {
          type uint8;
          default "2";
        }
      }
    }

Now, if the with-defaults=true document contains

    <two>
      <leaf2>2</leaf2>
    </two>

the corresponding with-defaults=false document should probably have just

    <two/>

However, in this case this empty NP container must not be removed,
contrary to what sec. 7.5.7 says.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Martin Bjorklund <[email-masked]>
Date: Tue, 28 Apr 2009 16:54:30 +0200 (CEST)

> the corresponding with-defaults=false document should probably have just

two wasn't the default case, so it must have been explicity created,
and thus with-defaults false would reply with the same as
with-defaults=true.

But if we change the model a bit:

   container x {
      presence "...";
       
      <your choice from above>
   }

and <x/> is created, a get with with-defaults=true would return:

  <x>
    <one>
      <leaf1>1</leaf1>
    </one>
  </x>

and get with with-defaults=false would return:

  <x/>

/martin

---

From: Andy Bierman <[email-masked]>
Date: Tue, 28 Apr 2009 07:58:29 -0700

> the corresponding with-defaults=false document should probably have just

You are mixing up the <rpc-reply> for a get operation
with the contents of a NETCONF configuration database.
The filtered contents within an <rpc-reply> do not
have anything to do with the requirements for a
valid configuration database.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 28 Apr 2009 17:03:38 +0200

> valid configuration database.

I don't think so. Both fragments above may be contained in get-reply
data, the first if with-defaults is true and the second if with-defaults
is false.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Tue, 28 Apr 2009 08:16:16 -0700

> data, the first if with-defaults is true and the second if with-defaults

I do not see any problem here.
Paragraph 3 of 7.5.7 says a manager needs to be aware
that an agent may return either form of <two>.
So what's the problem?

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 28 Apr 2009 17:19:15 +0200

> and thus with-defaults false would reply with the same as

Yes, but the client could have explicitly created just the empty
container <two/> and not the inner leaf2. Sec. 7.5.7 says:

A NETCONF server that replies to a <get> or <get-config> request MAY
choose not to send a container element if the container node does not
have the "presence" statement and no child nodes exist.

This is wrong here because removing <two/> switches to the default case "one".

The same problem could IMO also happen with full case "two" explicitly created like this:

<two><leaf2>2</leaf2></two>

If the server sends a get reply and applies the "trim" method for
suppressing defaults, it can

1. Remove leaf2, as its value equals to the default.
2. Following sec. 7.5.7, remove the empty NP container <two/>.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 28 Apr 2009 17:22:20 +0200

> that an agent may return either form of <two>.

The problem is that if the agent removes the empty container <two/>,
which it MAY do according to 7.5.7, the manager will interpret it as if
<one><leaf1>1</leaf1></one> was sent.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Tue, 28 Apr 2009 08:37:36 -0700

> This is wrong here because removing <two/> switches to the default case "one".

What does <get> or <get-config> have to do with deleting
nodes from the database?  That requires an <edit-config>
operation.

Andy

---

From: Andy Bierman <[email-masked]>
Date: Tue, 28 Apr 2009 08:42:30 -0700

> <one><leaf1>1</leaf1></one> was sent.

The results of an arbitrary subtree or XPath filtered
retrieval via <get> or <get-config> may need to be
interpreted with some knowledge of the original filter.
Arbitrary sub-trees may be missing, as requested by
the filter.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 28 Apr 2009 18:56:01 +0200

Andy Bierman píše v Út 28. 04. 2009 v 09:07 -0700:

> > It's not about removing anything from the database but about a NETCONF
> > server that replies to a <get> or <get-config> request and chooses not
> > to send the empty <two/> element.
> > 
> 
> then why do you say it switches the default case to <one>.
> It does not.  A get operation does not change the database.
> 

Because if the server doesn't send the empty <two/> container so that
nothing is present from any of the choice's cases, the manager should
use the default values for nodes under the default case - this is how I
interpret third paragraph of sec. 7.9.3.

Lada
 
-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Tue, 28 Apr 2009 10:05:18 -0700

> interpret third paragraph of sec. 7.9.3.

It depends on the filter.
The YANG draft does not consider the affects of
filtering on the <rpc-reply> contents.  Perhaps there
needs to be a sentence that says filtering mechanisms
such as those defined by <get>, <get-config>, and
the <with-defaults> extension may alter the reply contents.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 28 Apr 2009 20:15:22 +0200

> the <with-defaults> extension may alter the reply contents.

The behavior I am talking about may occur for replies to get/get-config
without any filters. The problem is that a non-presence container inside
a choice's case in fact does have a meaning even if it is empty - its
presence selects the case it is in, so it cannot be omitted at server's
discretion.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Martin Bjorklund <[email-masked]>
Date: Tue, 28 Apr 2009 21:23:20 +0200 (CEST)

> This is wrong here because removing <two/> switches to the default case "one".

The problem is in the data model.  An NP-container has no semantic
meaning, so the example can be simplified into:

    choice one-or-two {
      default "one";
      container one {
        leaf leaf1 {
          type uint8;
          default "1";
        }
      }
      case two {     // no container here!
        leaf leaf2 {
          type uint8;
          default "2";
        }
      }
    }

In order for a non-default case to make sense, you need to have some
nodes in the case where their presence make sense, i.e. a list,
leaf-list, leaf w/o default value, or a P-container.  The reason for
this is that the selected case is not explicitly present in the XML.

/martin

---

From: WashamFan <[email-masked]>
Date: Wed, 29 Apr 2009 10:15:10 +0800

>        case two {     // no container here!

Suppose case two has been chosen in the datastore, then I issue

  <get>
    <with-defaults>report-all</with-defaults>
  </get>

<leaf2>2</leaf2> would be returned, right?

But what if I issue

  <get>
    <with-defaults>trim</with-defaults>
  </get>

nothing about the choice content would be returned, right?

washam

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 29 Apr 2009 07:10:31 +0200

> meaning, so the example can be simplified into:

Well, there could be multiple leafs with default values in each
container, so an NP container can be used exactly what it is intended
for - organizing the data.

> this is that the selected case is not explicitly present in the XML.

I think the empty container <two/> makes sense in my example - it
selects the particular case and activates the default leaf values for
that case. I agree that the container then behaves more like a P
container but the example with NP containers is valid YANG, too, and can
lead to interoperability problems.

Lada
 
-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 29 Apr 2009 07:16:05 +0200

> nothing about the choice content would be returned, right?

If this happens, the manager should again assume the default case to be
present, so it leads to the same problem as in my example.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C