zebra: fix processing of redistribute messages

We should not check/modify client->redist[] when the requested instance
is different than zero.

In the same way, we should not check/modify client->mi_redist[] when
the requested instance is zero.

Failure to respect these conditions can lead to unexpected behavior in
the client daemons.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
Renato Westphal 2016-10-06 10:38:55 -03:00 committed by Donald Sharp
parent fbf4aeaae6
commit 4e1cadf011

View File

@ -257,16 +257,20 @@ zebra_redistribute_add (int command, struct zserv *client, int length,
if (type == 0 || type >= ZEBRA_ROUTE_MAX) if (type == 0 || type >= ZEBRA_ROUTE_MAX)
return; return;
if (instance && !redist_check_instance(&client->mi_redist[afi][type], instance)) if (instance)
{ {
redist_add_instance(&client->mi_redist[afi][type], instance); if (! redist_check_instance (&client->mi_redist[afi][type], instance))
{
redist_add_instance (&client->mi_redist[afi][type], instance);
zebra_redistribute (client, type, instance, zvrf->vrf_id); zebra_redistribute (client, type, instance, zvrf->vrf_id);
} }
else if (! vrf_bitmap_check (client->redist[afi][type], zvrf->vrf_id)) } else {
if (! vrf_bitmap_check (client->redist[afi][type], zvrf->vrf_id))
{ {
vrf_bitmap_set (client->redist[afi][type], zvrf->vrf_id); vrf_bitmap_set (client->redist[afi][type], zvrf->vrf_id);
zebra_redistribute (client, type, 0, zvrf->vrf_id); zebra_redistribute (client, type, 0, zvrf->vrf_id);
} }
}
} }
void void
@ -284,11 +288,17 @@ zebra_redistribute_delete (int command, struct zserv *client, int length,
if (type == 0 || type >= ZEBRA_ROUTE_MAX) if (type == 0 || type >= ZEBRA_ROUTE_MAX)
return; return;
if (instance && redist_check_instance(&client->mi_redist[afi][type], instance)) /*
* NOTE: no need to withdraw the previously advertised routes. The clients
* themselves should keep track of the received routes from zebra and
* withdraw them when necessary.
*/
if (instance)
{ {
redist_del_instance(&client->mi_redist[afi][type], instance); if (redist_check_instance (&client->mi_redist[afi][type], instance))
//Pending: why no reaction here? redist_del_instance (&client->mi_redist[afi][type], instance);
} }
else
vrf_bitmap_unset (client->redist[afi][type], zvrf->vrf_id); vrf_bitmap_unset (client->redist[afi][type], zvrf->vrf_id);
} }