Re: [vpp-dev] Static Route Data API Data Structures

2017-09-25 Thread Neale Ranns (nranns)
Hi Jon,

Some answers inline.

Thanks,
neale

-Original Message-
From: Jon Loeliger <j...@netgate.com>
Date: Thursday, 21 September 2017 at 16:42
To: "Neale Ranns (nranns)" <nra...@cisco.com>
Cc: vpp-dev <vpp-dev@lists.fd.io>
Subject: Re: [vpp-dev] Static Route Data API Data Structures

On Tue, Aug 29, 2017 at 9:37 AM, Neale Ranns (nranns) <nra...@cisco.com> 
wrote:
>
> Hi Jon,
>
> The new API does not function correctly in master at this time. If you 
want to ride on the bleeding edge with the new API, the code I intend to commit 
is (complete AFAICT) here:
>   https://gerrit.fd.io/r/#/c/7819/
>
> it’s not committed yet because I need to do an n-step dance with CSIT 
changes to make the verify jobs pass. This will take a few weeks (because 
vacations).
>
> Regards,
> neale


Hi Neale,

Hope your vacation went well!

Glad to see you are back at The Salt Mines, though!  Any chance for
a brief update on the progress of this whole Route Table re-work effort?

It’s committed and ready to go. 
I’m still working through some updates to CSIT to behave w.r.t. adding tables 
first before adding routes or binding interfaces. After that I will add the 
checks in VPP to enforce it.


Specifically, I have code poised to use the "add_del_table" API call, and
I *think* that I can do that now.  But can I remove the soon-to-be-obsolete
create_table_if_needed flag yet?

You can remove that flag. I mistakenly left the flag in the API, but it has no 
effect in VPP. Too late to remove it now we are in the API Freeze, I’ll do it 
in the next iteration.

Also, I read a comment about the need to ensure that an interface does
not have addresses on it when the IF is bound to a route table.  I get
the "why" behind that, but I'd like a small clarification:  Is that per-AF?
Or is that "across the board"?

Per-AF. One could bind an interface to a new IPv4 tale whilst it had IPv6 
address.

The reason I ask is the potentially somewhat disconnected special case
API call intf_add_del_address which contains a flag "del_all".  And it
does as advertised -- it removes all IPv4 and IPv6 addresses in one shot.

But if the route table addition is per-AF, it might make sense to have
the two calls coordinated a bit better.  That is:

- Modify intf_add_del_address to del_all per AF, or all AFs
- Modify intf_sw_interface_set_table to accept and bind one or both AFs

It is all in an effort to avoid repeatedly removing and re-adding the
addresses that might be present in either or both AFs on an interface.

See where I am headed there?  Am I way off base?

I agree that is inconsistent. I would propose the del_all case becomes AF 
specific. But I would also suggest this in an API change, albeit semantic not 
syntactic, and so we should wait for the next release.

Regards,
neale

Thanks,
jdl


___
vpp-dev mailing list
vpp-dev@lists.fd.io
https://lists.fd.io/mailman/listinfo/vpp-dev

Re: [vpp-dev] Static Route Data API Data Structures

2017-09-21 Thread Jon Loeliger
On Tue, Aug 29, 2017 at 9:37 AM, Neale Ranns (nranns)  wrote:
>
> Hi Jon,
>
> The new API does not function correctly in master at this time. If you want 
> to ride on the bleeding edge with the new API, the code I intend to commit is 
> (complete AFAICT) here:
>   https://gerrit.fd.io/r/#/c/7819/
>
> it’s not committed yet because I need to do an n-step dance with CSIT changes 
> to make the verify jobs pass. This will take a few weeks (because vacations).
>
> Regards,
> neale


Hi Neale,

Hope your vacation went well!

Glad to see you are back at The Salt Mines, though!  Any chance for
a brief update on the progress of this whole Route Table re-work effort?
Specifically, I have code poised to use the "add_del_table" API call, and
I *think* that I can do that now.  But can I remove the soon-to-be-obsolete
create_table_if_needed flag yet?

Also, I read a comment about the need to ensure that an interface does
not have addresses on it when the IF is bound to a route table.  I get
the "why" behind that, but I'd like a small clarification:  Is that per-AF?
Or is that "across the board"?

The reason I ask is the potentially somewhat disconnected special case
API call intf_add_del_address which contains a flag "del_all".  And it
does as advertised -- it removes all IPv4 and IPv6 addresses in one shot.

But if the route table addition is per-AF, it might make sense to have
the two calls coordinated a bit better.  That is:

- Modify intf_add_del_address to del_all per AF, or all AFs
- Modify intf_sw_interface_set_table to accept and bind one or both AFs

It is all in an effort to avoid repeatedly removing and re-adding the
addresses that might be present in either or both AFs on an interface.

See where I am headed there?  Am I way off base?

Thanks,
jdl
___
vpp-dev mailing list
vpp-dev@lists.fd.io
https://lists.fd.io/mailman/listinfo/vpp-dev

Re: [vpp-dev] Static Route Data API Data Structures

2017-08-29 Thread Neale Ranns (nranns)


-Original Message-
From: Jon Loeliger <j...@netgate.com>
Date: Tuesday, 29 August 2017 at 21:23
To: "Neale Ranns (nranns)" <nra...@cisco.com>
Cc: vpp-dev <vpp-dev@lists.fd.io>
Subject: Re: [vpp-dev] Static Route Data API Data Structures

>> As with all things VPP the allocation of the data-structure that 
represents
>> the LPM-DB comes from a memory pool. This data-structure thus has an
>> associated pool index – this is the FIB index. So, there is a one to one
>> mapping between the externally visible and client assigned ‘table ID’ and
>> the internal use only ‘FIB index’. Both are a u32, neither are strictly 
typed…
>
> Ah, I see.  Mapping in one direction is pool index, and a hash table
> in the other direction?
>
> As some APIs appear to want the FIB index, is there an API to do
> the FIB Id lookup for a Table Id?  (I'd posit that either needs to be one,
> or the APIs that accept a FIB Id need to be converted to Table Id.)
> Or, are all those references to a FIB Id really *also* supposed to
> be a Table Id?
>
> (I'm not seeing this line up with the API call ip_fib_dump yet.  Does it?
> If it does, and I see that it has route details in the fib_path, the 
table id
> is lost.  So no client-side FIB-to-TableId mapping can be established.)

Neale,

My double bad.  I see (and understand!) this now:

/** \brief IP FIB table response
@param table_id - IP fib table id
@address_length - mask length
@address - ip4 prefix
@param count - the number of fib_paths in path
@param path  - array of of fib_path structures
*/
manual_endian manual_print define ip_fib_details
{
  u32 context;
  u32 table_id;
  u8  address_length;
  u8  address[4];
  u32 count;
  vl_api_fib_path_t path[count];
};

That table_id *is* the dump coming back with the mapping from
FIB index to Table Id, right?

That should be the client’s assigned table-ID (not VPP’s FIB index). There 
should be a table-Id in the vl_api_fib_path_t too, which is relevant for 
recursive paths (it would be the next_hop_table_id when the route was added)

S,   Will FIB index allocation always be dense?  If it is
coming from a pool allocation, it should be, right?  So FIB
indices are going to be reused after they are free'd up, right?

Yes, yes and yes,

And this dump/details response will be in dense-index order, right?

One would reasonably expect so. For v6 it would appear to be the case, but, 
reading code in:
  vl_api_ip_fib_dump_t_handler()
fib_entry_cmp_for_sort()
  fib_entry_cmp()
it does not compare the route’s FIB-index. So I expect the details to come 
prefix sorted.
We might want to change that loop code in the v4 dump handler to do one table 
at a time, like v6 does.

/neale

jdl


___
vpp-dev mailing list
vpp-dev@lists.fd.io
https://lists.fd.io/mailman/listinfo/vpp-dev

Re: [vpp-dev] Static Route Data API Data Structures

2017-08-29 Thread Neale Ranns (nranns)

Hi Jon,

Some answers inline.

Regards,
neale

-Original Message-
From: Jon Loeliger <j...@netgate.com>
Date: Tuesday, 29 August 2017 at 20:40
To: "Neale Ranns (nranns)" <nra...@cisco.com>
Cc: vpp-dev <vpp-dev@lists.fd.io>
Subject: Re: [vpp-dev] Static Route Data API Data Structures

On Tue, Aug 29, 2017 at 4:21 AM, Neale Ranns (nranns) <nra...@cisco.com> 
wrote:
> Hi Jon,
>

Neale,

> By ‘IP’ in this context we mean IPv4 and IPv6 and unicast and multicast
> (known as sub-address families or SAFIs). To provide this separation we
> therefore need 4 ‘tables’ per-VRF, one for each SAFI.

You say 4 here, but really we implement 2, one for IPv4 and one for IPv6.
So, an interface can be bound to multiple tables.  But is it limited to
one IPv4 and one IPv6 table?

Yes.
It was my choice to keep the unicast and multicast table-id the same within a 
given VRF. I thought that to be the simpler approach. It saves the interface 
being bound twice..

> A ‘table’ in this context is the well known longest-prefix matching DB.
> Tables are known by a unique per-AFI ID (note per-AFI not per-SAFI,
> so IPv4 unicast and multicast share the same table-id).

A table doesn't know its Address Family, except by the inspection of
the types of routes within it, right? (But both uni- and multi-cast routes
are possible in just one table, right?)

as you say, when you create a table you specify the AFI

Any checking done to prevent inter-family mixing in one table?

If you then add a route of the wrong AFI to that table one of two things will 
happen;
1) The route will be added to the table for that AFI that happens to have that 
same ID
2) You’ll get a no-such-table error

Or is that up to convention and enforcement by the API user?

GIGO

> It is the client’s responsibility to associate unique table IDs to tables
> within all of its VRFs.

Ah, there.  Only the external client (management agent) maintains
any notion of actual Virtual Routers.  To that end, multiple routing
tables are supplied for client use as it sees fit.

> The client is free to choose the table-ID from the full u32 range.
> So, bottom line, in the context of IP forwarding[,] a table (and its
> associated ID) refer to an instance of a LPM DB.

Right.  But prefix management is left up to something else (routing 
protocol).

Yes.

> Despite code comments and variable naming, VPP does not maintain
> the concept of a VRF, i.e. it does not maintain a grouping of ‘tables’.

This is an important observation.

> At the client interface VPP deals only with table IDs – i.e. an 
identifier that
> the client provided for a given LPM DB. All APIs that claim to accept a
> VRF index should be renamed to accept an IP table ID.

Would you (collectively) be receptive of patches to that end?

I (individually) would be ☺

And is "table id" the name?  Not anything more descriptive,
such as "Route Table Id"?

IMO if the context is clear that the API is related to IP, then table-id is 
descriptive. But, otherwise, or even if you think the context is clear, I’d be 
happy with ip_table_id.

> As with all things VPP the allocation of the data-structure that 
represents
> the LPM-DB comes from a memory pool. This data-structure thus has an
> associated pool index – this is the FIB index. So, there is a one to one
> mapping between the externally visible and client assigned ‘table ID’ and
> the internal use only ‘FIB index’. Both are a u32, neither are strictly 
typed…

Ah, I see.  Mapping in one direction is pool index, and a hash table
in the other direction?

Yes.

As some APIs appear to want the FIB index, is there an API to do
the FIB Id lookup for a Table Id?  (I'd posit that either needs to be one,
or the APIs that accept a FIB Id need to be converted to Table Id.)
Or, are all those references to a FIB Id really *also* supposed to
be a Table Id?

I’d hope they are really after a table-ID, given that there is no API for the 
conversion and know way I can think of that the client would learn a FIB-index.

(I'm not seeing this line up with the API call ip_fib_dump yet.  Does it?
If it does, and I see that it has route details in the fib_path, the table 
id
is lost.  So no client-side FIB-to-TableId mapping can be established.)

ip_fib_dump could probably use some TLC…

> With regards to the creation of tables, I’m currently working on the API
> you discovered – ip_table_add_del. With this API the client instructs VPP
> to add/delete a ‘table ID’ (as discussed above).

OK, good.

> The VPP FIB has the concept of ownership or ‘sourcing’

Re: [vpp-dev] Static Route Data API Data Structures

2017-08-29 Thread Jon Loeliger
On Tue, Aug 29, 2017 at 4:21 AM, Neale Ranns (nranns)  wrote:
> Hi Jon,
>

Neale,

> By ‘IP’ in this context we mean IPv4 and IPv6 and unicast and multicast
> (known as sub-address families or SAFIs). To provide this separation we
> therefore need 4 ‘tables’ per-VRF, one for each SAFI.

You say 4 here, but really we implement 2, one for IPv4 and one for IPv6.
So, an interface can be bound to multiple tables.  But is it limited to
one IPv4 and one IPv6 table?

> A ‘table’ in this context is the well known longest-prefix matching DB.
> Tables are known by a unique per-AFI ID (note per-AFI not per-SAFI,
> so IPv4 unicast and multicast share the same table-id).

A table doesn't know its Address Family, except by the inspection of
the types of routes within it, right? (But both uni- and multi-cast routes
are possible in just one table, right?)
Any checking done to prevent inter-family mixing in one table?
Or is that up to convention and enforcement by the API user?


> It is the client’s responsibility to associate unique table IDs to tables
> within all of its VRFs.

Ah, there.  Only the external client (management agent) maintains
any notion of actual Virtual Routers.  To that end, multiple routing
tables are supplied for client use as it sees fit.

> The client is free to choose the table-ID from the full u32 range.
> So, bottom line, in the context of IP forwarding[,] a table (and its
> associated ID) refer to an instance of a LPM DB.

Right.  But prefix management is left up to something else (routing protocol).

> Despite code comments and variable naming, VPP does not maintain
> the concept of a VRF, i.e. it does not maintain a grouping of ‘tables’.

This is an important observation.

> At the client interface VPP deals only with table IDs – i.e. an identifier 
> that
> the client provided for a given LPM DB. All APIs that claim to accept a
> VRF index should be renamed to accept an IP table ID.

Would you (collectively) be receptive of patches to that end?

And is "table id" the name?  Not anything more descriptive,
such as "Route Table Id"?

> As with all things VPP the allocation of the data-structure that represents
> the LPM-DB comes from a memory pool. This data-structure thus has an
> associated pool index – this is the FIB index. So, there is a one to one
> mapping between the externally visible and client assigned ‘table ID’ and
> the internal use only ‘FIB index’. Both are a u32, neither are strictly typed…

Ah, I see.  Mapping in one direction is pool index, and a hash table
in the other direction?

As some APIs appear to want the FIB index, is there an API to do
the FIB Id lookup for a Table Id?  (I'd posit that either needs to be one,
or the APIs that accept a FIB Id need to be converted to Table Id.)
Or, are all those references to a FIB Id really *also* supposed to
be a Table Id?

(I'm not seeing this line up with the API call ip_fib_dump yet.  Does it?
If it does, and I see that it has route details in the fib_path, the table id
is lost.  So no client-side FIB-to-TableId mapping can be established.)

> With regards to the creation of tables, I’m currently working on the API
> you discovered – ip_table_add_del. With this API the client instructs VPP
> to add/delete a ‘table ID’ (as discussed above).

OK, good.

> The VPP FIB has the concept of ownership or ‘sourcing’ of its resources.
> Sources can be external (i.e. the CLI or the API) or internal (e.g. LISP
> and DHCP).

Ah, "source" was confusing here.  We mean "origin" and not "route source".
How the FIB came to exist.

> FIB resources are only completely free’d was there are no more sources
> that are referencing it.

And that is internally managed, right?

> My intention with the table add/delete API is that the client can add the
> table then insert routes and bind interfaces.

Specifically in that order?  Does the table have to be fully route-populated
at the time it is IF-bound?  Or will a later route addition/deletion be
factored into that IF's forwarding properly?

> If the client then deletes the table its routes will be purged. The table will
> then be deleted iff it held the last reference.

Full table.  Good.  Individual route additions/removals to that table OK too?
Table continues to exist if last route is deleted or there were no routes
in the table from the onset, right?

> With the introduction of this API VPP will insist that it has been called
> to create the table before any routes or interfaces refer to it.

Seems like a correct behavior.

> The current behaviour is that tables can be created either by setting an
> interface into that table, or by setting the ‘create_vrf_if_needed’ flag in
> a route add. There is no means to delete it, hence my new API work.

I see.  OK, I'll help push to get your patches accepted. :-)

jdl
___
vpp-dev mailing list
vpp-dev@lists.fd.io
https://lists.fd.io/mailman/listinfo/vpp-dev

Re: [vpp-dev] Static Route Data API Data Structures

2017-08-29 Thread Neale Ranns (nranns)

Hi Jon,

The new API does not function correctly in master at this time. If you want to 
ride on the bleeding edge with the new API, the code I intend to commit is 
(complete AFAICT) here:
  https://gerrit.fd.io/r/#/c/7819/

it’s not committed yet because I need to do an n-step dance with CSIT changes 
to make the verify jobs pass. This will take a few weeks (because vacations).

Regards,
neale

-Original Message-
From: Jon Loeliger <j...@netgate.com>
Date: Tuesday, 29 August 2017 at 14:49
To: "Neale Ranns (nranns)" <nra...@cisco.com>
Cc: vpp-dev <vpp-dev@lists.fd.io>
Subject: Re: [vpp-dev] Static Route Data API Data Structures

On Tue, Aug 29, 2017 at 4:21 AM, Neale Ranns (nranns) <nra...@cisco.com> 
wrote:
> Hi Jon,
>
> (apologies for repeating some of what you already know, but from the top…)
>
> A VRF is virtualisation of a router’s *IP* routing and forwarding. VRFs 
are typically identified by a name (and again typically named to refer to the 
VPN customer they represent). IP packets in VRF RED must be separate from IP 
packets in VRF BLUE. By ‘IP’ in this context we mean IPv4 and IPv6 and unicast 
and multicast (known as sub-address families or SAFIs). To provide this 
separation we therefore need 4 ‘tables’ per-VRF, one for each SAFI. A ‘table’ 
in this context is the well known longest-prefix matching DB. Tables are known 
by a unique per-AFI ID (note per-AFI not per-SAFI, so IPv4 unicast and 
multicast share the same table-id). It is the client’s responsibility to 
associate unique table IDs to tables within all of its VRFs. The client is free 
to choose the table-ID from the full u32 range. So, bottom line, in the context 
of IP forwarding a table (and its associated ID) refer to an instance of a LPM 
DB.
>
> Despite code comments and variable naming, VPP does not maintain the 
concept of a VRF, i.e. it does not maintain a grouping of ‘tables’. At the 
client interface VPP deals only with table IDs – i.e. an identifier that the 
client provided for a given LPM DB. All APIs that claim to accept a VRF index 
should be renamed to accept an IP table ID.
> As with all things VPP the allocation of the data-structure that 
represents the LPM-DB comes from a memory pool. This data-structure thus has an 
associated pool index – this is the FIB index. So, there is a one to one 
mapping between the externally visible and client assigned ‘table ID’ and the 
internal use only ‘FIB index’. Both are a u32, neither are strictly typed…
>
> With regards to the creation of tables, I’m currently working on the API 
you discovered – ip_table_add_del. With this API the client instructs VPP to 
add/delete a ‘table ID’ (as discussed above). The VPP FIB has the concept of 
ownership or ‘sourcing’ of its resources. Sources can be external (i.e. the CLI 
or the API) or internal (e.g. LISP and DHCP). FIB resources are only completely 
free’d was there are no more sources that are referencing it.
> My intention with the table add/delete API is that the client can add the 
table then insert routes and bind interfaces. If the client then deletes the 
table its routes will be purged. The table will then be deleted iff it held the 
last reference. With the introduction of this API VPP will insist that it has 
been called to create the table before any routes or interfaces refer to it.
> The current behaviour is that tables can be created either by setting an 
interface into that table, or by setting the ‘create_vrf_if_needed’ flag in a 
route add. There is no means to delete it, hence my new API work.
>
> Hth,
> neale

Neale,

That helps tremendously!

I am poised to add a bunch of route-related API calls to our project.
Are the "new" IP Route APIs in place at this time?  Or shall I wait a bit
and watch for a bit still?

Thank you!

jdl


___
vpp-dev mailing list
vpp-dev@lists.fd.io
https://lists.fd.io/mailman/listinfo/vpp-dev

Re: [vpp-dev] Static Route Data API Data Structures

2017-08-29 Thread Neale Ranns (nranns)
Hi Jon,

(apologies for repeating some of what you already know, but from the top…)

A VRF is virtualisation of a router’s *IP* routing and forwarding. VRFs are 
typically identified by a name (and again typically named to refer to the VPN 
customer they represent). IP packets in VRF RED must be separate from IP 
packets in VRF BLUE. By ‘IP’ in this context we mean IPv4 and IPv6 and unicast 
and multicast (known as sub-address families or SAFIs). To provide this 
separation we therefore need 4 ‘tables’ per-VRF, one for each SAFI. A ‘table’ 
in this context is the well known longest-prefix matching DB. Tables are known 
by a unique per-AFI ID (note per-AFI not per-SAFI, so IPv4 unicast and 
multicast share the same table-id). It is the client’s responsibility to 
associate unique table IDs to tables within all of its VRFs. The client is free 
to choose the table-ID from the full u32 range. So, bottom line, in the context 
of IP forwarding a table (and its associated ID) refer to an instance of a LPM 
DB.

Despite code comments and variable naming, VPP does not maintain the concept of 
a VRF, i.e. it does not maintain a grouping of ‘tables’. At the client 
interface VPP deals only with table IDs – i.e. an identifier that the client 
provided for a given LPM DB. All APIs that claim to accept a VRF index should 
be renamed to accept an IP table ID.
As with all things VPP the allocation of the data-structure that represents the 
LPM-DB comes from a memory pool. This data-structure thus has an associated 
pool index – this is the FIB index. So, there is a one to one mapping between 
the externally visible and client assigned ‘table ID’ and the internal use only 
‘FIB index’. Both are a u32, neither are strictly typed…

With regards to the creation of tables, I’m currently working on the API you 
discovered – ip_table_add_del. With this API the client instructs VPP to 
add/delete a ‘table ID’ (as discussed above). The VPP FIB has the concept of 
ownership or ‘sourcing’ of its resources. Sources can be external (i.e. the CLI 
or the API) or internal (e.g. LISP and DHCP). FIB resources are only completely 
free’d was there are no more sources that are referencing it.
My intention with the table add/delete API is that the client can add the table 
then insert routes and bind interfaces. If the client then deletes the table 
its routes will be purged. The table will then be deleted iff it held the last 
reference. With the introduction of this API VPP will insist that it has been 
called to create the table before any routes or interfaces refer to it.
The current behaviour is that tables can be created either by setting an 
interface into that table, or by setting the ‘create_vrf_if_needed’ flag in a 
route add. There is no means to delete it, hence my new API work.

Hth,
neale


-Original Message-
From: <vpp-dev-boun...@lists.fd.io> on behalf of Jon Loeliger <j...@netgate.com>
Date: Monday, 28 August 2017 at 01:36
To: vpp-dev <vpp-dev@lists.fd.io>
Subject: [vpp-dev] Static Route Data API Data Structures

VPP-ites,

I am delving into the world of static routes.  I am clearly missing
some basic information and would like some help understanding
how static routes work.

For starters, I'm a little unclear on what exactly these items are,
or what they represent or hold, and their relationship to each other:

- VRF index / VRF id
- Table id
- FIB index  / FIB id

The only place I can find that even defines "VRF" is on this wiki page:

https://wiki.fd.io/view/VPP/What_is_VPP%3F

(Yeah, the final %3F is needed.)

And even that is in passing:

Some of the functionality that a routing application can create 
includes:

   o Virtual Routing and Forwarding (VRF) tables (in the thousands)


How is a VRF created/deleted/managed?  I don't see an obvious API call
that looks like it would create/delete one:

$ git grep -i vrf | grep add_del
src/plugins/nat/nat64.c:nat64_add_del_pool_addr (ip4_address_t * addr,
u32 vrf_id, u8 is_add)
src/plugins/nat/nat64.c:nat64_add_del_prefix (ip6_address_t * prefix,
u8 plen, u32 vrf_id, u8 is_add)
src/plugins/nat/nat64.h:int nat64_add_del_pool_addr (ip4_address_t *
addr, u32 vrf_id, u8 is_add);
src/plugins/nat/nat64.h:int nat64_add_del_prefix (ip6_address_t *
prefix, u8 plen, u32 vrf_id,
src/plugins/nat/nat64_cli.c:  rv = nat64_add_del_pool_addr
(_addr, vrf_id, is_add);
src/plugins/nat/nat64_cli.c:  rv = nat64_add_del_prefix (, (u8)
plen, vrf_id, is_add);
src/plugins/nat/nat_api.c:  if ((rv = nat64_add_del_pool_addr
(_addr, vrf_id, mp->is_add)))
src/plugins/nat/nat_api.c:  s = format (0, "SCRIPT:
nat64_add_del_prefix %U/%u vrf_id %u %s\n",
src/vat/api_format.c:_(oam_add_del, "src  dst
 [vrf ] [del]")   \
src/vat/a

[vpp-dev] Static Route Data API Data Structures

2017-08-27 Thread Jon Loeliger
VPP-ites,

I am delving into the world of static routes.  I am clearly missing
some basic information and would like some help understanding
how static routes work.

For starters, I'm a little unclear on what exactly these items are,
or what they represent or hold, and their relationship to each other:

- VRF index / VRF id
- Table id
- FIB index  / FIB id

The only place I can find that even defines "VRF" is on this wiki page:

https://wiki.fd.io/view/VPP/What_is_VPP%3F

(Yeah, the final %3F is needed.)

And even that is in passing:

Some of the functionality that a routing application can create includes:

   o Virtual Routing and Forwarding (VRF) tables (in the thousands)


How is a VRF created/deleted/managed?  I don't see an obvious API call
that looks like it would create/delete one:

$ git grep -i vrf | grep add_del
src/plugins/nat/nat64.c:nat64_add_del_pool_addr (ip4_address_t * addr,
u32 vrf_id, u8 is_add)
src/plugins/nat/nat64.c:nat64_add_del_prefix (ip6_address_t * prefix,
u8 plen, u32 vrf_id, u8 is_add)
src/plugins/nat/nat64.h:int nat64_add_del_pool_addr (ip4_address_t *
addr, u32 vrf_id, u8 is_add);
src/plugins/nat/nat64.h:int nat64_add_del_prefix (ip6_address_t *
prefix, u8 plen, u32 vrf_id,
src/plugins/nat/nat64_cli.c:  rv = nat64_add_del_pool_addr
(_addr, vrf_id, is_add);
src/plugins/nat/nat64_cli.c:  rv = nat64_add_del_prefix (, (u8)
plen, vrf_id, is_add);
src/plugins/nat/nat_api.c:  if ((rv = nat64_add_del_pool_addr
(_addr, vrf_id, mp->is_add)))
src/plugins/nat/nat_api.c:  s = format (0, "SCRIPT:
nat64_add_del_prefix %U/%u vrf_id %u %s\n",
src/vat/api_format.c:_(oam_add_del, "src  dst
 [vrf ] [del]")   \
src/vat/api_format.c:_(one_eid_table_add_del_map, "[del] vni  vrf
")   \
src/vat/api_format.c:_(lisp_eid_table_add_del_map, "[del] vni 
vrf ")  \
test/test_nat.py:
self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
test/test_nat.py:
self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
test/test_nat.py:self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
test/vpp_papi_provider.py:def nat64_add_del_prefix(self, prefix,
plen, vrf_id=0, is_add=1):


Tables, on the other hand, can be created/deleted:

src/vnet/ip/ip.api:autoreply define ip_table_add_del
src/vnet/ip/ip_api.c:_(IP_TABLE_ADD_DEL, ip_table_add_del)
  \
src/vnet/ip/ip_api.c:vl_api_ip_table_add_del_t_handler
(vl_api_ip_table_add_del_t * mp)

Is this the right "table"?

What is the lifetime management of a table?  When is it OK to delete one?
Does it have to come into existence before any thing references the Table Id?
Or is it OK to have a dangling Table Id pointer for a while?
What happens if you use the API to delete it and there are lingering referrers?

But let's face it "table" is very generic.  What kind of table is
that?  And there
is no better name for it than "table"?   Wait.  Don't answer yet.
Let's check at
the API definition first:

/** \brief Add / del table request
   A table can be added multiple times, but need be
deleted only once.
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param is_ipv6 - V4 or V6 table
@param table_id - table ID associated with the route
 This table ID will apply to both the unicast
  and mlticast FIBs.
*/
autoreply define ip_table_add_del
{
  u32 client_index;
  u32 context;
  u32 table_id;
  u8 is_ipv6;
  u8 is_add;
};

But still, no clue what the table is, what it manages, what it holds,
what abstraction
it provides.  Nothing.

Is it really an arbitrary "Table" of anything you want?  Are these
used for several (?)
unrelated items and a generic "Table" is really appropriate?

It appears that a "table id" can sometimes be a FIB table id:

/** \brief IP FIB table response
@param table_id - IP fib table id


But clearly they are not the same:

src/vnet/dhcp/dhcp_proxy.h: * @brief The FIB index (not the
external Table-ID) in which the server
src/vnet/dhcp/dhcp_proxy.h: * @brief The FIB index (not the
external Table-ID) in which the client

OK.  Let's turn to some commands for help or insight.

NAT wants VRF ids:

VLIB_CLI_COMMAND (add_address_command, static) = {
  .path = "nat44 add address",
  .short_help = "nat44 add addresses  [- ] "
"[tenant-vrf ] [del]",

VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
  .path = "nat44 add static mapping",
  .function = add_static_mapping_command_fn,
  .short_help =
"nat44 add static mapping local tcp|udp|icmp  []
external  [] [vrf ] [del]",
};

Ooo!  Look at that penultimate bit:  [vrf ]
So.  Is a "table id" the same thing as a "VRF id"?

I find no discussion or description of any of this in any of the wiki,
nor in the online docs.fd.io,
nor in