From 4e1cadf011e484ff865e0e54ce51adc32d1590e3 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 6 Oct 2016 10:38:55 -0300 Subject: [PATCH] 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 --- zebra/redistribute.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 9c835bf2d6..061224461e 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -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 -- 2.39.5