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,15 +257,19 @@ zebra_redistribute_add (int command, struct zserv *client, int length,
if (type == 0 || type >= ZEBRA_ROUTE_MAX)
return;
if (instance && !redist_check_instance(&client->mi_redist[afi][type], instance))
if (instance)
{
redist_add_instance(&client->mi_redist[afi][type], instance);
zebra_redistribute (client, type, instance, 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);
zebra_redistribute (client, type, 0, zvrf->vrf_id);
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);
}
} else {
if (! vrf_bitmap_check (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);
}
}
}
@ -284,12 +288,18 @@ zebra_redistribute_delete (int command, struct zserv *client, int length,
if (type == 0 || type >= ZEBRA_ROUTE_MAX)
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);
//Pending: why no reaction here?
if (redist_check_instance (&client->mi_redist[afi][type], instance))
redist_del_instance (&client->mi_redist[afi][type], instance);
}
vrf_bitmap_unset (client->redist[afi][type], zvrf->vrf_id);
else
vrf_bitmap_unset (client->redist[afi][type], zvrf->vrf_id);
}
void