X-Git-Url: https://git.sommitrealweird.co.uk/quagga-debian.git/blobdiff_plain/191fe7a34582876de01d3e62c2a6587baf59a283..064d9c633233495319bcaa66335ea3d24c0bd7a1:/zebra/redistribute.c diff --git a/zebra/redistribute.c b/zebra/redistribute.c index a7a6b25..6d466ac 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -182,11 +182,11 @@ zebra_redistribute (struct zserv *client, int type, vrf_id_t vrf_id) } void -redistribute_add (struct prefix *p, struct rib *rib) +redistribute_add (struct prefix *p, struct rib *rib, struct rib *rib_old) { struct listnode *node, *nnode; struct zserv *client; - + for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) { if ((is_default (p) && @@ -204,6 +204,21 @@ redistribute_add (struct prefix *p, struct rib *rib) zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib); } } + else if (rib_old && vrf_bitmap_check (client->redist[rib_old->type], + rib_old->vrf_id)) + { + /* redistribute_add has implicit withdraw semantics, so there + * may be an old route already redistributed that is being updated. + * + * However, if the new route is of a type that is /not/ redistributed + * to the client, then we must ensure the old route is explicitly + * withdrawn. + */ + if (p->family == AF_INET) + zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib_old); + if (p->family == AF_INET6) + zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib_old); + } } }