diff options
Diffstat (limited to 'zebra/redistribute.c')
| -rw-r--r-- | zebra/redistribute.c | 164 |
1 files changed, 96 insertions, 68 deletions
diff --git a/zebra/redistribute.c b/zebra/redistribute.c index d1148061b9..4d6346151a 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -150,6 +150,43 @@ static void zebra_redistribute(struct zserv *client, int type, } } +/* + * Function to check if prefix is candidate for + * redistribute. + */ +static bool zebra_redistribute_check(const struct route_entry *re, + struct zserv *client, + const struct prefix *p, int afi) +{ + /* Process only if there is valid re */ + if (!re) + return false; + + /* If default route and redistributed */ + if (is_default_prefix(p) + && vrf_bitmap_check(client->redist_default[afi], re->vrf_id)) + return true; + + /* If redistribute in enabled for zebra route all */ + if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL], re->vrf_id)) + return true; + + /* + * If multi-instance then check for route + * redistribution for given instance. + */ + if (re->instance + && redist_check_instance(&client->mi_redist[afi][re->type], + re->instance)) + return true; + + /* If redistribution is enabled for give route type. */ + if (vrf_bitmap_check(client->redist[afi][re->type], re->vrf_id)) + return true; + + return false; +} + /* Either advertise a route for redistribution to registered clients or */ /* withdraw redistribution if add cannot be done for client */ void redistribute_update(const struct prefix *p, const struct prefix *src_p, @@ -158,7 +195,6 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p, { struct listnode *node, *nnode; struct zserv *client; - int send_redistribute; int afi; char buf[PREFIX_STRLEN]; @@ -173,8 +209,7 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p, afi = family2afi(p->family); if (!afi) { flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF, - "%s: Unknown AFI/SAFI prefix received\n", - __FUNCTION__); + "%s: Unknown AFI/SAFI prefix received\n", __func__); return; } if (!zebra_check_addr(p)) { @@ -186,25 +221,7 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p, for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { - send_redistribute = 0; - - if (is_default_prefix(p) - && vrf_bitmap_check(client->redist_default[afi], - re->vrf_id)) - send_redistribute = 1; - else if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL], - re->vrf_id)) - send_redistribute = 1; - else if (re->instance - && redist_check_instance( - &client->mi_redist[afi][re->type], - re->instance)) - send_redistribute = 1; - else if (vrf_bitmap_check(client->redist[afi][re->type], - re->vrf_id)) - send_redistribute = 1; - - if (send_redistribute) { + if (zebra_redistribute_check(re, client, p, afi)) { if (IS_ZEBRA_DEBUG_RIB) { zlog_debug( "%s: client %s %s(%u), type=%d, distance=%d, metric=%d", @@ -216,18 +233,9 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p, } zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD, client, p, src_p, re); - } else if (prev_re - && ((re->instance - && redist_check_instance( - &client->mi_redist[afi] - [prev_re->type], - re->instance)) - || vrf_bitmap_check( - client->redist[afi][prev_re->type], - re->vrf_id))) { + } else if (zebra_redistribute_check(prev_re, client, p, afi)) zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL, client, p, src_p, prev_re); - } } } @@ -269,7 +277,7 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p, /* Add DISTANCE_INFINITY check. */ if (old_re && (old_re->distance == DISTANCE_INFINITY)) { if (IS_ZEBRA_DEBUG_RIB) - zlog_debug("\tSkipping due to Infinite Distance"); + zlog_debug(" Skipping due to Infinite Distance"); return; } @@ -292,45 +300,24 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p, } for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { - if (new_re) { - /* Skip this client if it will receive an update for the - * 'new' re - */ - if (is_default_prefix(p) - && vrf_bitmap_check(client->redist_default[afi], - new_re->vrf_id)) - continue; - else if (vrf_bitmap_check( - client->redist[afi][ZEBRA_ROUTE_ALL], - new_re->vrf_id)) - continue; - else if (new_re->instance - && redist_check_instance( - &client->mi_redist[afi][new_re->type], - new_re->instance)) - continue; - else if (vrf_bitmap_check( - client->redist[afi][new_re->type], - new_re->vrf_id)) - continue; - } + /* Do not send unsolicited messages to synchronous clients. */ + if (client->synchronous) + continue; + /* + * Skip this client if it will receive an update for the + * 'new' re + */ + if (zebra_redistribute_check(new_re, client, p, afi)) + continue; /* Send a delete for the 'old' re to any subscribed client. */ - if (old_re - && (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL], - old_re->vrf_id) - || (old_re->instance - && redist_check_instance( - &client->mi_redist[afi][old_re->type], - old_re->instance)) - || vrf_bitmap_check(client->redist[afi][old_re->type], - old_re->vrf_id))) { + if (zebra_redistribute_check(old_re, client, p, afi)) zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL, client, p, src_p, old_re); - } } } + void zebra_redistribute_add(ZAPI_HANDLER_ARGS) { afi_t afi = 0; @@ -473,6 +460,12 @@ void zebra_interface_up_update(struct interface *ifp) if (ifp->ptm_status || !ifp->ptm_enable) { for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + /* Do not send unsolicited messages to synchronous + * clients. + */ + if (client->synchronous) + continue; + zsend_interface_update(ZEBRA_INTERFACE_UP, client, ifp); zsend_interface_link_params(client, ifp); @@ -491,6 +484,10 @@ void zebra_interface_down_update(struct interface *ifp) ifp->name, ifp->vrf_id); for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + /* Do not send unsolicited messages to synchronous clients. */ + if (client->synchronous) + continue; + zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp); } } @@ -506,6 +503,10 @@ void zebra_interface_add_update(struct interface *ifp) ifp->vrf_id); for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + /* Do not send unsolicited messages to synchronous clients. */ + if (client->synchronous) + continue; + client->ifadd_cnt++; zsend_interface_add(client, ifp); zsend_interface_link_params(client, ifp); @@ -522,6 +523,10 @@ void zebra_interface_delete_update(struct interface *ifp) ifp->name, ifp->vrf_id); for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + /* Do not send unsolicited messages to synchronous clients. */ + if (client->synchronous) + continue; + client->ifdel_cnt++; zsend_interface_delete(client, ifp); } @@ -553,12 +558,17 @@ void zebra_interface_address_add_update(struct interface *ifp, router_id_add_address(ifc); - for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + /* Do not send unsolicited messages to synchronous clients. */ + if (client->synchronous) + continue; + if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) { client->connected_rt_add_cnt++; zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc); } + } } /* Interface address deletion. */ @@ -582,12 +592,17 @@ void zebra_interface_address_delete_update(struct interface *ifp, router_id_del_address(ifc); - for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + /* Do not send unsolicited messages to synchronous clients. */ + if (client->synchronous) + continue; + if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) { client->connected_rt_del_cnt++; zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc); } + } } /* Interface VRF change. May need to delete from clients not interested in @@ -604,6 +619,10 @@ void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id) ifp->name, ifp->vrf_id, new_vrf_id); for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + /* Do not send unsolicited messages to synchronous clients. */ + if (client->synchronous) + continue; + /* Need to delete if the client is not interested in the new * VRF. */ zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp); @@ -627,6 +646,10 @@ void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id) ifp->name, old_vrf_id, ifp->vrf_id); for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + /* Do not send unsolicited messages to synchronous clients. */ + if (client->synchronous) + continue; + /* Need to add if the client is interested in the new VRF. */ client->ifadd_cnt++; zsend_interface_add(client, ifp); @@ -914,6 +937,11 @@ void zebra_interface_parameters_update(struct interface *ifp) zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)", ifp->name, ifp->vrf_id); - for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + /* Do not send unsolicited messages to synchronous clients. */ + if (client->synchronous) + continue; + zsend_interface_link_params(client, ifp); + } } |
