Mailing List Archive

multitable in zebra 0.94-pre5 (fwd)
Hello,

OK, since the same problem exists in Quagga 0.96.2 I decided to send
this bug report also to this list. Espacially, that I'm not a member of
zebra@zebra.org and my mail has to be verified by moderator which takes
much time. ;-)


---------- Forwarded message ----------
Date: Tue, 23 Sep 2003 15:22:33 +0200 (CEST)
From: Krzysztof Olêdzki <ole@ans.pl>
To: zebra@zebra.org, Kunihiro Ishiguro <kunihiro@ipinfusion.com>
Subject: multitable in zebra 0.94-pre5

Hello.

It seems there is something wrong with multitable support in zebra
0.94-pre5 and Linux 2.4.x.

I have Linux router with 3 links - 2 to one ISP (lets call this
ISP0) one one to other one (ISP1). I exchange RIP2 routing with ISP0
so when one of the links goes down my router immediately switches
default routing to other link. Since both ISPs do source validation
I decided to use source routing. Let's assume that 192.168.0.0/24
belongs to ISP0 and 192.168.1.0/24 belongs to ISP1. My configuration
looks something like this:

rule add from 192.168.1.0/24 table 5
ip route add 0/0 dev isp1 table 5

Default routing for default table is set up by zebra&ripd.

Unfortunately, zebra refuses to install default route (or
any other route) if it detects that this route exist and
is set by kernel. I think that it should check if existed
route is in current table and if not process route insertion.


It also seems that there is something wrong with "table" command.
With following zebra.conf file:
----------
hostname zebra
password zebra

table 5
ip route 0.0.0.0/0 192.168.0.240
----------

zebra inserts "0.0.0.0/0 via 192.168.0.240" route to default
table. According to manual zebra should install static routes to table 5!
Anyway, "show ip route" shows empty routing table until I started ripd -
then it shows RIP routes marked as "inactive" which are not inserted to
any kernel table. Strange - manual (main.texi) says that only static
routes defined after this command go to the specified table.

Zebra was build with:
./configure --prefix=/usr --sysconfdir=/etc/zebra \
--enable-netlink --enable-multipath=0 --enable-tcp-zebra \
--enable-vtysh --enable-snmp

Tested on kernels 2.4.21, 2.4.23-pre4.

Best Regards,


Krzysztof Olêdzki
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
Hi krystof,

The table command isnt really useful, partly because its behaviour is
so inconsistent. I

On Mon, 29 Sep 2003, Krzysztof OlÄ^Ydzki wrote:

> zebra inserts "0.0.0.0/0 via 192.168.0.240" route to default
> table. According to manual zebra should install static routes to table 5!
> Anyway, "show ip route" shows empty routing table until I started ripd -
> then it shows RIP routes marked as "inactive" which are not inserted to
> any kernel table. Strange - manual (main.texi) says that only static
> routes defined after this command go to the specified table.

try inserting routes into table 5 with 'ip route' - zebra should see
them iirc, and you can redistribute them into protocol daemons. I'm
not sure about insertion into the table. I do know that zebra also
reads the main table, regardless (either because zebra does that
explicitely, or because it reads routes from the kernel before
processing the conf file (and hence the table command)). Anyway, that
table command is generally not very useful.

regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
warning: do not ever send email to spam@dishone.st
Fortune:
The difference between reality and unreality is that reality has so
little to recommend it.
-- Allan Sherman
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
On Wed, 1 Oct 2003, Paul Jakma wrote:

> Hi krystof,
Hi :)

> The table command isnt really useful, partly because its behaviour is
> so inconsistent. I
>
> On Mon, 29 Sep 2003, Krzysztof OlÄ^Ydzki wrote:
>
> > zebra inserts "0.0.0.0/0 via 192.168.0.240" route to default
> > table. According to manual zebra should install static routes to table 5!
> > Anyway, "show ip route" shows empty routing table until I started ripd -
> > then it shows RIP routes marked as "inactive" which are not inserted to
> > any kernel table. Strange - manual (main.texi) says that only static
> > routes defined after this command go to the specified table.
>
> try inserting routes into table 5 with 'ip route' - zebra should see
> them iirc, and you can redistribute them into protocol daemons.
Yes, unfortunately it does. Like I wrote in my previous mail:

--previous mail--
rule add from 192.168.1.0/24 table 5
ip route add 0/0 dev isp1 table 5

Default routing for default table is set up by zebra&ripd.

Unfortunately, zebra refuses to install default route (or
any other route) if it detects that this route exist and
is set by kernel. I think that it should check if existed
route is in current table and if not process route insertion.
--end--


> I'm not sure about insertion into the table. I do know that zebra also
> reads the main table
No - new zebra (0.94-pre) and quagga reads table 0 (unspec) so it gets all
routes. Old zebra (0.93b) reads only main table AFAIK, since I'm able to
use statically selected default gw for table 5 and dynamically assigned
for table "main". So it is no longer possible to set policy routing.

Best regards,


Krzysztof Oledzki
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
On Wed, 1 Oct 2003, Krzysztof OlÄ^Ydzki wrote:

> > them iirc, and you can redistribute them into protocol daemons.

> Yes, unfortunately it does. Like I wrote in my previous mail:
>
> --previous mail--
> rule add from 192.168.1.0/24 table 5
> ip route add 0/0 dev isp1 table 5
>
> Default routing for default table is set up by zebra&ripd.
>
> Unfortunately, zebra refuses to install default route (or
> any other route) if it detects that this route exist and
> is set by kernel. I think that it should check if existed
> route is in current table and if not process route insertion.

hmmm...

> --end--
>
>
> > I'm not sure about insertion into the table. I do know that zebra also
> > reads the main table

> No - new zebra (0.94-pre) and quagga reads table 0 (unspec) so it
> gets all routes.

ah yes.

> Old zebra (0.93b) reads only main table AFAIK, since I'm able to
> use statically selected default gw for table 5 and dynamically
> assigned for table "main". So it is no longer possible to set
> policy routing.

reverting to reading only table main would fix your problem? snarf
the diff from 0.93b->0.94 and provided Gilad doesnt howl i might
apply it. Reading all routes without being able to deal with tables
fully is a bit silly, i guess.

> Best regards,
>
> Krzysztof Oledzki

regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
warning: do not ever send email to spam@dishone.st
Fortune:
Porsche: there simply is no substitute.
-- Risky Business
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
On Wed, 1 Oct 2003, Paul Jakma wrote:
> On Wed, 1 Oct 2003, Krzysztof OlÄ^Ydzki wrote:
<CIACH>

> > > I'm not sure about insertion into the table. I do know that zebra also
> > > reads the main table
>
> > No - new zebra (0.94-pre) and quagga reads table 0 (unspec) so it
> > gets all routes.
>
> ah yes.
>
> > Old zebra (0.93b) reads only main table AFAIK, since I'm able to
> > use statically selected default gw for table 5 and dynamically
> > assigned for table "main". So it is no longer possible to set
> > policy routing.
>
> reverting to reading only table main would fix your problem?
IMHO Yes. I think only routes from table main should be announced by rip,
bgp, etc. We can also read all routes and ignore ones from other tables.

> snarf the diff from 0.93b->0.94 and provided Gilad doesnt howl i might
> apply it.
Eh. I was trying to find where it was changed but without success.

Best regards,

Krzysztof Oledzki
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
On Thu, 2 Oct 2003, Krzysztof Oledzki wrote:
> On Wed, 1 Oct 2003, Paul Jakma wrote:
> > On Wed, 1 Oct 2003, Krzysztof OlÄ^Ydzki wrote:
<CIACH>
> > reverting to reading only table main would fix your problem?
> IMHO Yes. I think only routes from table main should be announced by rip,
> bgp, etc. We can also read all routes and ignore ones from other tables.
>
> > snarf the diff from 0.93b->0.94 and provided Gilad doesnt howl i might
> > apply it.

OK. Multitable support in zebra/quagga sees to be very, very broken. I'm
going to check the code and propose some solutions. Are there any ideas how to make
multitable usefull?

Here is the diff:
diff -Nur quagga-0.96.4-orig/zebra/zebra_rib.c quagga-0.96.4/zebra/zebra_rib.c
--- quagga-0.96.4-orig/zebra/zebra_rib.c 2003-09-29 22:06:13.000000000 +0200
+++ quagga-0.96.4/zebra/zebra_rib.c 2003-10-16 13:39:37.000000000 +0200
@@ -1032,6 +1032,7 @@
rib->distance = distance;
rib->flags = flags;
rib->metric = metric;
+ rib->table = vrf_id;
rib->nexthop_num = 0;
rib->uptime = time (NULL);

@@ -1676,6 +1677,7 @@
rib->distance = distance;
rib->flags = flags;
rib->metric = metric;
+ rib->table = vrf_id;
rib->nexthop_num = 0;
rib->uptime = time (NULL);

With this patch quagga should work more or less like the old zebra v0.93b.

Best Regards,


Krzysztof Olêdzki
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
Krzysztof Oledzki wrote:

>>>snarf the diff from 0.93b->0.94 and provided Gilad doesnt howl i might
>>>apply it.
>
>
> OK. Multitable support in zebra/quagga sees to be very, very broken. I'm
> going to check the code and propose some solutions. Are there any ideas how to make
> multitable usefull?
>
> Here is the diff:
...

I'm not sure what you're trying to do, but bear in mind that zebra's RIB
is single layered wrt table id: your can't have two routes to the same
destination prefix active at the same time, even if they're associated
with different "table id" values. Generally speaking, I'm not sure the
'table' command is applicable to anything with quagga, and I'd gladly
give it up completely... (and go for a real multi-context implementation
;->)

Gilad
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
On Sun, 19 Oct 2003, Gilad Arnold wrote:

>
> Krzysztof Oledzki wrote:
>
> >>>snarf the diff from 0.93b->0.94 and provided Gilad doesnt howl i might
> >>>apply it.
> >
> >
> > OK. Multitable support in zebra/quagga sees to be very, very broken. I'm
> > going to check the code and propose some solutions. Are there any ideas how to make
> > multitable usefull?
> >
> > Here is the diff:
> ...
>
> I'm not sure what you're trying to do, but bear in mind that zebra's RIB
> is single layered wrt table id: your can't have two routes to the same
> destination prefix active at the same time, even if they're associated
> with different "table id" values. Generally speaking, I'm not sure the
> 'table' command is applicable to anything with quagga, and I'd gladly
> give it up completely... (and go for a real multi-context implementation
> ;->)

No. I'm not trying to fix the "table" command. My fix (AFAIK) just allows
to put routes to the same destinations into different tables (using
iproute2). With zebra-0.93b it was possibe. When new zebra (0.94-pre) and
quagga reads routing table both ignore "table id" so it is no longer
possible to use policy routing based on IP src address. Anyway, please
read my first mail.

Best regards,

Krzysztof Olêdzki
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
Krzysztof Oledzki wrote:

>>I'm not sure what you're trying to do, but bear in mind that zebra's RIB
>>is single layered wrt table id: your can't have two routes to the same
>>destination prefix active at the same time, even if they're associated
>>with different "table id" values. Generally speaking, I'm not sure the
>>'table' command is applicable to anything with quagga, and I'd gladly
>>give it up completely... (and go for a real multi-context implementation
>>;->)
>
>
> No. I'm not trying to fix the "table" command. My fix (AFAIK) just allows
> to put routes to the same destinations into different tables (using
> iproute2). With zebra-0.93b it was possibe. When new zebra (0.94-pre) and
> quagga reads routing table both ignore "table id" so it is no longer
> possible to use policy routing based on IP src address. Anyway, please
> read my first mail.

I read your first mail (again). AFAIU, what you essentially need is for
zebra to ignore routes from non-RT_TABLE_MAIN table (eg, table 5 in your
example, which is used for source-based policy routing). IMO, storing
the table id in each route won't bring you much benefit, since RIB
selection process still allows at most one route per destination prefix
to be installed into FIB, so I'd say you should patch something around
your kernel API layer (normally zebra/rt_netlink.c) to not import route
belonging to foreign kernel tables.

(Alongside, I keep promoting my concepts of well-defined,
fully-independent routing contexts with zebra, to replace the legacy
patch in the form of 'table' command -- as you can see, this command
doesn't really do what it is claimed to be doing... ;-> )

Gilad
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
On Sun, 19 Oct 2003, Gilad Arnold wrote:

>
> Krzysztof Oledzki wrote:
>
> >>I'm not sure what you're trying to do, but bear in mind that zebra's RIB
> >>is single layered wrt table id: your can't have two routes to the same
> >>destination prefix active at the same time, even if they're associated
> >>with different "table id" values. Generally speaking, I'm not sure the
> >>'table' command is applicable to anything with quagga, and I'd gladly
> >>give it up completely... (and go for a real multi-context implementation
> >>;->)
> >
> >
> > No. I'm not trying to fix the "table" command. My fix (AFAIK) just allows
> > to put routes to the same destinations into different tables (using
> > iproute2). With zebra-0.93b it was possibe. When new zebra (0.94-pre) and
> > quagga reads routing table both ignore "table id" so it is no longer
> > possible to use policy routing based on IP src address. Anyway, please
> > read my first mail.
>
> I read your first mail (again). AFAIU, what you essentially need is for
> zebra to ignore routes from non-RT_TABLE_MAIN table (eg, table 5 in your
> example, which is used for source-based policy routing).

OK. Longer version:

Zebra 0.93b has rib.c file with
"int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
struct in_addr *gate, unsigned int ifindex, int table,
u_int32_t metric, u_char distance)"
{
(...)
/* Allocate new rib structure. */
rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
memset (rib, 0, sizeof (struct rib));
rib->type = type;
rib->distance = distance;
rib->flags = flags;
rib->metric = metric;
rib->table = table;
rib->nexthop_num = 0;
rib->uptime = time (NULL);
(...)
}

function. This function is being called in rt_netlink.c while reading
kernel routing table shortly after startup:
/* Looking up routing table by netlink interface. */
int
netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
{
(...)
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, 0, 0);
(...)
}

Zebra 0.94-pre and quagga has little different organization - the file
"rib.c" was moved to zebra_rib.c. The file contains very simmilar
function:
int
rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
u_int32_t metric, u_char distance)
{
(...)
/* Allocate new rib structure. */
rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
memset (rib, 0, sizeof (struct rib));
rib->type = type;
rib->distance = distance;
rib->flags = flags;
rib->metric = metric;
rib->nexthop_num = 0;
rib->uptime = time (NULL);
(...)
}

Like you can see "int table" was renamed to "u_int32_t vrf_id" and now
rib->table is left unchanged.

Call to this function from the netlink_routing_table wasn't changed:
(...)
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, 0, 0);
(...)

After this strange modification this very important function does
nothing:

/* Remove all routes which comes from non main table. */
void
rib_weed_table (struct route_table *table)
{
struct route_node *rn;
struct rib *rib;
struct rib *next;

if (table)
for (rn = route_top (table); rn; rn = route_next (rn))
for (rib = rn->info; rib; rib = next)
{
next = rib->next;

if (rib->table != zebrad.rtm_table_default &&
rib->table != RT_TABLE_MAIN)
{
rib_delnode (rn, rib);
newrib_free (rib);
route_unlock_node (rn);
}
}
}

So like you said:

> IMO, storing the table id in each route won't bring you much benefit,
> since RIB selection process still allows at most one route per
> destination prefix to be installed into FIB, so I'd say you should patch
> something around your kernel API layer (normally zebra/rt_netlink.c) to
> not import route belonging to foreign kernel tables.

And that's what my patch realy does. It fix thing which works in
zebra-0.93b and now is broken. I know there should be much better
solution, but IMHO it should be enough for now.

Best Regards,

Krzysztof Olêdzki
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
Krzysztof Oledzki wrote:

>>IMO, storing the table id in each route won't bring you much benefit,
>>since RIB selection process still allows at most one route per
>>destination prefix to be installed into FIB, so I'd say you should patch
>>something around your kernel API layer (normally zebra/rt_netlink.c) to
>>not import route belonging to foreign kernel tables.
>
>
> And that's what my patch realy does. It fix thing which works in
> zebra-0.93b and now is broken. I know there should be much better
> solution, but IMHO it should be enough for now.

I believe your patch works for you, nonetheless I'd suggest -- for the
sake of future development wrt forwarding contexts in quagga -- to keep
it outside the repository: it seems that zebra (and quagga as well) are
making some very slow steps towards a more abstract approach, eg VRF
contexts (you can see it in the prototype you were citing,
zebra/zebra_rib.c/rib_add_ipv4()), and applying you patch, which
essentially converts an kernel-specific table id into a presumably
abstract VRF ID (and back) -- instead of, for example, managing several
routing contexts based on that VRF ID -- is rowing against the flow.

Of course, if Paul considers it helpful, then I won't object. I don't
use the table command as-is anyway... ;->

Gilad
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
On Mon, 20 Oct 2003, Gilad Arnold wrote:
<CIACH>
> I believe your patch works for you, nonetheless I'd suggest -- for the
> sake of future development wrt forwarding contexts in quagga -- to keep
> it outside the repository: it seems that zebra (and quagga as well) are
> making some very slow steps towards a more abstract approach, eg VRF
> contexts (you can see it in the prototype you were citing,
> zebra/zebra_rib.c/rib_add_ipv4()), and applying you patch, which
> essentially converts an kernel-specific table id into a presumably
> abstract VRF ID (and back) -- instead of, for example, managing several
> routing contexts based on that VRF ID -- is rowing against the flow.

My patch fix something which used to work but now it is broken. It does
not break anything, AFAIK. If someone fix (finish) VRF then it can be
easly removed. Currently both things does not work.

> Of course, if Paul considers it helpful, then I won't object.
OK. Paul?

> I don't use the table command as-is anyway... ;->
It does not touch the table command. This is a different problem. :)

Best Regards,

Krzysztof Olêdzki
Re: multitable in zebra 0.94-pre5 (fwd) [ In reply to ]
I take it the end result of the discussion on the below patch was
that in lieu of some kind of real VRF support, the below change migth
as well be made (yes, table is fairly useless, but at least with
below change its useful to someone?)?

On Thu, 16 Oct 2003, Krzysztof Oledzki wrote:

> OK. Multitable support in zebra/quagga sees to be very, very broken. I'm
> going to check the code and propose some solutions. Are there any ideas how to make
> multitable usefull?
>
> Here is the diff:
> diff -Nur quagga-0.96.4-orig/zebra/zebra_rib.c quagga-0.96.4/zebra/zebra_rib.c
> --- quagga-0.96.4-orig/zebra/zebra_rib.c 2003-09-29 22:06:13.000000000 +0200
> +++ quagga-0.96.4/zebra/zebra_rib.c 2003-10-16 13:39:37.000000000 +0200
> @@ -1032,6 +1032,7 @@
> rib->distance = distance;
> rib->flags = flags;
> rib->metric = metric;
> + rib->table = vrf_id;
> rib->nexthop_num = 0;
> rib->uptime = time (NULL);
>
> @@ -1676,6 +1677,7 @@
> rib->distance = distance;
> rib->flags = flags;
> rib->metric = metric;
> + rib->table = vrf_id;
> rib->nexthop_num = 0;
> rib->uptime = time (NULL);
>
> With this patch quagga should work more or less like the old zebra v0.93b.
>
> Best Regards,
>
>
> Krzysztof Olędzki

regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
warning: do not ever send email to spam@dishone.st
Fortune:
You've been Berkeley'ed!