Subject: Re: [netmod] mbj review of draft-ietf-netmod-routing-cfg-04

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 14 Aug 2012 14:48:28 +0200

Hi Martin,

thank you for the review, see my replies inline.

Martin Bjorklund <[email-masked]> writes:

>
> o  4.  bullet 1 (after Figure 2)
>
>    o  Along with the main routing table, which must always be present,
>       an additional routing table is configured.
>
>   What does "must always be present mean"?  This needs to be
>   clarified.  In my world, it should not be necessary to configure
>   this, so I assume it means that it always exists operationally, even
>   if it is not explicitly configured.

My idea is that an implementation will preconfigure the main table and will not allow the client to delete it.

A cleaner solution - given the current state of affairs - would be to have routing tables in two places, as state data and as configuration. But that would sort of defeat the proposed approach for state data that we discussed in Vancouver. Any suggestion?

>
>
> o  4.1.
>
>   It would be useful with a paragraph that explains that an
>   implementation doesn't have to support more than a single router
>   (i.e., no logical routers).

OK. BTW, I will probably drop the term "logical router" entirely and use only.

>
>   It would also be useful to include the text you wrote in 
>   http://www.ietf.org/mail-archive/web/netmod/current/msg06845.html.

OK.

>
>
> o  4.3.
>
>   Why is the main routing table's name only a SHOULD?  If it not a
>   MUST, how will a client know which table is main?

Some implementations may not have one "main" table, and may therefore want to adjust the naming.

>
>
> o  4.3.
>
>    The naming scheme for additional routing tables, as well as
>    restrictions on the number and configurability of routing tables are
>    implementation-specific.
>
>   What does "restrictions on configurability" mean?

It means, for example, that an implementation may not accept user-configured tables at all, or may limit their number.

>
>
> o  4.4
>
>    Each routing protocol instance is connected to exactly one routing
>    table for each address family that the routing protocol instance
>    supports.
>
>   How do I know which address families a routing protocol instance
>   supports?

This is protocol-specific. For instance, in the static protocol it is implicitly indicated by the presence of the list of static routes within the corresponding container ("ipv4" or "ipv6").

>
>
> o  4.4.1
>
>   OLD:
>
>    Every router instance MUST contain exactly one instance of the
>    "direct" pseudo-protocol type.   The name of this instance MUST
>    also be "direct". 
>
>
>   NEW:
>
>    Every router instance MUST contain exactly one "routing-protocol"
>    instance of the "direct" pseudo-protocol type.   The name of this
>    instance MUST also be "direct".
>
>   What does this MUST mean?  Do I have to configure this
>   routing-protocol instance?  What happens if I try to delete it?
>

I assume that the "direct" protocol will not have any configuration - direct routes are configured as a result of IP configuration on an interface. In fact, the only place where the direct protocol may explicitly appear is the "source-protocol" attribute of routes.
 
>   Why is the name important?

It is not important but since there is always exactly one instance it would only be confusing if the name was arbitrary.

>
>   Isn't it better to state that if no routing-protocol instance of
>   type "direct" is configured, then all routes are sent to the main
>   routing table.

Such routes will have the "source-protocol" attribute set to "direct".

>
>
> o  4.4.1
>
>    A pseudo-protocol of the type "static" allows for specifying routes
>    manually.  It MAY be configured in zero or multiple instances,
>    although a typical implementation will have exactly one instance per
>    logical router.
>
>   Do you mean "typical configuration"?

Yes, I will change it.

>
>
> o  4.5
>
>    The default value for the route
>    filter type is the identity "deny-all-route-filter".
>
>   I still think this is confusing and not necessary.  If I define a
>   filter and leave out the type, the filter will block everything.  I
>   think the result will be much more clear if the type is mandatory.
>   I.e., when a filter is defined, the type must also be specified.

OK.

>
>
> o  4.6.
>
>   I think we should stop using the semi-formal notation of specifying
>   new rpcs.  The YANG definition is supposed to capture all this
>   information in a more strict way.  This only leads to duplicate text
>   and the opportunity for errors.  In fact, the text, but not the YANG
>   module, was updated with the "error-tag" fix.
>
>   I suggest you remove 4.6.1 and 4.6.2, and just provide a short
>   descrioption of these operations in 4.6. (and fix the text in the
>   YANG module).

OK, will do.

>
>   You also use the term "FIB" here, but "forwarding table" earlier.
>   Also, the rpc active-route says that is reads the route from the
>   FIB, but earlier you wrote that the FIB was optional.  So this
>   should probably be rephrased.

The acronym FIB is meant more dynamically here. Every IP box must be able to do routing, i.e. to find the active route for a given destination. However, it needn't be a simple lookup in a forwarding table - Linux, for example, has the "fib_lookup" function for this purpose.

In the mean time, we had an interesting discussion about the definition of RIB and FIB. It seems it will be wise to avoid them entirely.
  
>
>
> o  5.2  identity direct
>
>   Move text from 4.4.1 to the description.  Same for "static".

OK.

>
>
> o  5.2  identity deny-all-route-filter
>
>   Should it be called "deny-all-routes"?
>

I don't know, but for an identity name I subjectively prefer "deny-all-route-filter".

>
> o  5.2.  grouping afn-safi
>
>         leaf address-family {
>          type ianaaf:address-family;
>          default "ipv4";
>    
>   Is this default really appropriate?  Isn't it better w/ no default?

The advantage of having a default is that this info needn't be present in the configuration. It is not a big deal but I think it will prove practical though maybe not politically correct.
>
>
> o  5.2.
>
>   There are some single-qouted strings in descriptions that should be
>   changed to double-quoted strings (in all three modules).

Why and where? I used single quotes for all quoting purposes in descriptions (which are enclosed in double quotes).

>
>
> o  5.2. 
>
>          leaf name {
>            type string;
>            description
>              "The unique router name.";
>          }
>   
>    NEW:
>
>      "An arbitrary name of the router instance.";

OK.

>
>
> o  5.2
>
>              leaf name {
>                type string;
>                description
>                  "The name of the routing protocol instance.";
>              }
>
>   NEW:
>
>     "An arbitrary name of the routing protocol instance.";
>

OK.

>   OR: state that an implementation MAY restrict the allowed values of
>   this name (if this is what you meant).

Not really, it's supposed to be an arbitrary name.

>
>
> o  5.2.
>
>   Currently you have:
>
>        +--rw connected-routing-tables
>        |  +--rw routing-table [name]
>       
>   Should the latter list be called "connected-routing-table" for
>   consistency with the rest of the model?

IMO this way it also conveys the information that it is a reference to an existing routing table (leafref).

>
>   The impressive "must" expression in this list uses a "rt:" prefix on
>   some nodes, but not all.  I suggest you remove it from all nodes for
>   consistency.

OK.

>
>
> o  5.2.
>
>              container static-routes {
>                must "../type='rt:static'" {
>
>   This should be "when", not "must".  See also 4.4.2 bullet 4!

Apart from my reservations towards 'when', in this case I don't really see any benefit of doing so. The 'must' expression guarantees that "static-routes" are only configured for a "static" protocol. Why would somebody ever want to change the protocol type to something else than "static" and let the server delete the container? IMO this could only happen by mistake and therefore is not desirable. Am I missing something?

Following Yi Yang's suggestion, I will add the "enabled" switch under "routing-protocol", so disabling a protocol instance can be easily done by setting this switch to "false".

Regarding the fourth bullet in 4.4.2, it talks about an augment, so 'when' is the only option.
   
>
>
> o  5.2.
>
>            list routing-table {
>              key "name";
>              description
>                "Each entry represents a routing table identified by the
>                 'name' key. All routes in a routing table must have the
>                 same AFN and SAFI.";
>
>   The last sentence has a "must" that doesn't make much sense, since
>   a route doesn't "uses afn-safi".

The address family is implicit in every route - it follows from the address format.
This description means that e.g. IPv4 and IPv6 routes cannot appear in the same table.
    
>
>     NEW:
>
>                 'name' key. All routes in a routing table have the
>                 same AFN and SAFI.";

OK, this is possible.

>
>
> o  5.2
>
>                list route {
>                  description
>                    "A routing table entry. This data node must augmented
>
>   s/must augmented/must be augmented/

OK.

>
>
> o  5.2.
>
>                  leaf source-protocol {
>                    type leafref {
>                      path "/routing/router/routing-protocols/"
>                         + "routing-protocol/name";
>                    }
>
>   I think the leafref should be relative - otherwise you can point to
>   protocols in other logical routers.

It was relative in a previous revision but now router instances needn't be isolated, so the possibility of a "foreign" source protocol is indeed open. Hmm, but we have no guarantee that the names of protocol instances are unique accross router instances - I have to think about it.

>
>   The text says:
>
>                       This routing protocol must
>                       be configured (automatically or manually) in the
>                       device."
>
>   so what happens if the routing protocol instance is removed?  Will
>   all its routes be removed?

Good question. I have to check the existing implementations but I think the routes should also be removed if their source disappears.

>
>
> o  5.2
>
>                list recipient-routing-table {
>                  ...
>                  leaf name {
>                    type leafref {
>                      path "/routing/router/routing-tables/"
>                         + "routing-table/name";
>                    }
>
>   This should also be a relative path.

It is the same as with "source-protocol".

>
>
> o  7
>
>         Every implementation must preconfigure a routing table with the
>         name 'main-ipv4-unicast', which is the main routing table for
>         IPv4 unicast.
>
>   This contraditcs the SHOULD on page 12.

Right, the description has to say the same thing.

>
>
> o  7
>
>          list route {
>            ...
>            leaf id {
>              type uint32 {
>                range "1..max";
>              }
>
>   Why do you have a numeric id if it is arbitrary?  Why not a string?

Why is a string better?

>
>
> o  8
>
>             NOTE: Parameter 'is-router' is not included, it is expected
>             that it will be implemented by the 'ietf-ip' module.
>
>   Remove this sentence, or rephrase.

OK.

>
>
> o  8
>
>          leaf min-rtr-adv-interval {
>            ...
>            description
>              "The minimum time allowed between sending unsolicited
>               multicast Router Advertisements from the interface.
>
>               Must be no greater than 0.75 * max-rtr-adv-interval.
>
>  
>   Make a "must" statement out if this constraint.

OK.

>
>
> o  8
>
>          leaf cur-hop-limit {
>            default "64";
>            description
>               ...
>               The default should be set to the value specified in IANA
>               Assigned Numbers that was in effect at the time of
>               implementation.
>
>   Either remove the default statement, or change the text.

I would keep the default, the "Internet diameter" doesn't change that often.

>
>
> o  8
>
>          leaf default-lifetime {
>            ...
>               The default value is dynamic and should be set to 3 *
>               max-rtr-adv-interval.
>
>   I prefer to not use the term "dynamic default".  I suggest this:
>
>         If this leaf is not configured, the server uses the value
>         3 * max-rtr-adv-interval.

OK.

Lada

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

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

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 16 Aug 2012 09:47:33 +0200 (CEST)

Ladislav Lhotka <[email-masked]> wrote:
> A cleaner solution - given the current state of affairs - would be to
> have routing tables in two places, as state data and as
> configuration. But that would sort of defeat the proposed approach for
> state data that we discussed in Vancouver. Any suggestion?

I think the data model should not be duplicated, and it should not be
necessary to configure the main routing table.  If it is not
explicitly configured, it operationally exists within the system.
Once configured, it can be referenced in leafrefs etc.

> It means, for example, that an implementation may not accept
> user-configured tables at all, or may limit their number.

This should be clarified.

> I assume that the "direct" protocol will not have any configuration -
> direct routes are configured as a result of IP configuration on an
> interface. In fact, the only place where the direct protocol may
> explicitly appear is the "source-protocol" attribute of routes.

If it doesn't have any configuration, why is it a MUST to configure
it?

> It is not important but since there is always exactly one instance it
> would only be confusing if the name was arbitrary.

Ok, but this seems to be a CLR...

> Such routes will have the "source-protocol" attribute set to "direct".

Ok, so you mean that since source-protocol is a leafref it must be
configured?  Hmm - this might work better with the introduction of
"operational state"...

> The advantage of having a default is that this info needn't be present
> in the configuration.

Sure, but it is not configured in "many" places, and w/o a default the
config is more explict.  Also, if you don't look at the data model, it
is not obvious if the default is ipv4 or ipv6.

> Why and where? I used single quotes for all quoting purposes in
> descriptions (which are enclosed in double quotes).

[grep "';" *.yang]

/routing/router/description:

      description
        'Each list entry is a container for configuration and

ipv4/route/id

          description
            'Numeric identifier of the route.

ipv6/route/id

          description
            'Numeric identifier of the route.

> Apart from my reservations towards 'when', in this case I don't really
> see any benefit of doing so. The 'must' expression guarantees that
> "static-routes" are only configured for a "static" protocol. Why would
> somebody ever want to change the protocol type to something else than
> "static"

This is why "when" is better.  The container is valid only when the
type is static.  So if the type is not static, it should not even be
possible to configure static routes.  Imagine a client application
with drop-down menus for these additional per-type containers.  With
"when" statements, the client application can adjust the available
choices to what makes sense for the specific type.

> 'when' is the only option.

You have chosen to inline the definition of static routes, but it
could as well have been done in a separate module, and if so, you
would have used "when" - so it makes sense to use "when" even though
you inline the definition.

> It was relative in a previous revision but now router instances
> needn't be isolated, so the possibility of a "foreign" source protocol
> is indeed open. Hmm, but we have no guarantee that the names of
> protocol instances are unique accross router instances

Exactly.  So you would have to have a second leafref to the router
name as well.

> >   Why do you have a numeric id if it is arbitrary?  Why not a string?

It gives the user more flexibility in finding a unique and maybe
descriptive name.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Thu, 16 Aug 2012 18:34:22 +0200

> Once configured, it can be referenced in leafrefs etc.

Do you mean the draft should state that the main table always exists as operational state data but these state data are not present in the data model?

It would be actually more logical to let the leafrefs point to tables within state data because routing protocols are connected to routing tables, not to their configuration. 

> This should be clarified.

OK, will try.

> If it doesn't have any configuration, why is it a MUST to configure

The text doesn't say that it MUST be configured (by a client) but rather that it MUST exist - it is the same as with the main routing table. We badly need a better model for the dual character of such objects that essentially exist as operational state data but may also be configured.

> Ok, but this seems to be a CLR...

Well, I think it is better to be able to immediately identify direct routes in routing tables by the value of "source-protocol" (= "direct"). I see no sane reason why an implementor might want another name.

> configured?  Hmm - this might work better with the introduction of

Exactly, the same story again.

> is not obvious if the default is ipv4 or ipv6.

It will usually be quite obvious, e.g. from the format of addresses. But I have no strong opinion on this, so I'd like to hear other voices, if somebody else has read this far. :-)
  
>             'Numeric identifier of the route.

OK, I thought you meant single-quoted strings *inside* descriptions. I will fix it.

> possible to configure static routes.  Imagine a client application

It won't be possible with "must" either.

> choices to what makes sense for the specific type.

But it can do so even with "must", can't it?

As far as I can tell, the real difference between "must" and "when" is in the server behaviour if a client tries to change the value of "../type" from "static" to something else (which IMO could only happen by mistake). With "must", the server will reject this change, whereas with "when" it will accept it and, as a side effect, also delete the "static-routes" container with all its contents. I don't like the latter scenario at all, however improbable it may be.

Randy Presuhn advocated "when" as a means for enabling hot-swap or hot-insertion of components and subsystems, but I don't think it can really be used for this: A hot-inserted component may induce some changes in operational state data which are however not accessible for "when" statements within the config=true tree.

Moreover, I don't think it is generally desirable to remove *configuration* of a component that has been removed. It is OK to remove operational state data owned by that component, but not necessarily configuration.

So I guess we are back to the issue of operational state data versus configuration, surprise, surprise ... 

> you inline the definition.

For me it makes sense to take advantage of the fact that it is inline and completely eliminate the auto-deletion scenario.

> Exactly.  So you would have to have a second leafref to the router

Or I could re-introduce my esoteric "unique" statement that stirred such a lively discussion few months ago. :-)

> It gives the user more flexibility in finding a unique and maybe

Hmm, imagine you have a list of a few thousand routes - finding a fresh key might be a challenge, no matter what the datatype. It would be neat if we could leave the assigment of such keys to the server.

Lada