summaryrefslogtreecommitdiff
path: root/zebra/redistribute.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/redistribute.c')
-rw-r--r--zebra/redistribute.c164
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);
+ }
}