From 0e5223e7a0366d6c61b1baf609c81d4d59199853 Mon Sep 17 00:00:00 2001 From: vivek Date: Fri, 12 Feb 2016 11:37:33 -0800 Subject: [PATCH] Quagga: Support VRF unregister for clients Clients (BGP, OSPF etc.) register with Zebra for information about a VRF such as Router ID, interfaces and redistribution. Add API to support unregister also which is required for the non-default VRF. Signed-off-by: Vivek Venkatraman Reviewed-by: Donald Sharp Ticket: CM-9128 Reviewed By: CCR-4098 Testing Done: Manual testing --- bgpd/bgp_zebra.c | 6 ++--- isisd/isis_zebra.c | 2 +- lib/zclient.c | 61 +++++++++++++++++++++++++++++++++++++++++--- lib/zclient.h | 3 ++- ospf6d/ospf6_zebra.c | 2 +- ospfd/ospf_zebra.c | 2 +- ripd/rip_zebra.c | 2 +- ripngd/ripng_zebra.c | 2 +- 8 files changed, 68 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 4b80bbeafc..9ffe44f267 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -239,9 +239,9 @@ bgp_vrf_add (int command, struct zclient *zclient, zebra_size_t length, bgp->vrf_id = vrf_id; if (BGP_DEBUG (zebra, ZEBRA) && vrf) - zlog_debug("zclient_send_requests %u", vrf_id); + zlog_debug("zclient_send_reg_requests %u", vrf_id); - zclient_send_requests (zclient, vrf_id); + zclient_send_reg_requests (zclient, vrf_id); bgp_instance_up (bgp); //Pending: See if the following can be moved inside bgp_instance_up () @@ -264,7 +264,7 @@ bgp_vrf_update (struct bgp *bgp) bgp->vrf_id = vrf->vrf_id; } - zclient_send_requests (zclient, bgp->vrf_id); + zclient_send_reg_requests (zclient, bgp->vrf_id); bgp_nht_register_all (bgp->vrf_id); } diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 86e6692e15..e02de129ac 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -603,7 +603,7 @@ isis_redistribute_default_set (int routetype, int metric_type, static void isis_zebra_connected (struct zclient *zclient) { - zclient_send_requests (zclient, VRF_DEFAULT); + zclient_send_reg_requests (zclient, VRF_DEFAULT); } void diff --git a/lib/zclient.c b/lib/zclient.c index 21d9253067..82f0c26e59 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -371,9 +371,9 @@ zebra_hello_send (struct zclient *zclient) return 0; } -/* Send requests to zebra daemon for the information in a VRF. */ +/* Send register requests to zebra daemon for the information in a VRF. */ void -zclient_send_requests (struct zclient *zclient, vrf_id_t vrf_id) +zclient_send_reg_requests (struct zclient *zclient, vrf_id_t vrf_id) { int i; afi_t afi; @@ -387,7 +387,7 @@ zclient_send_requests (struct zclient *zclient, vrf_id_t vrf_id) return; if (zclient_debug) - zlog_debug ("%s: send messages for VRF %u", __func__, vrf_id); + zlog_debug ("%s: send register messages for VRF %u", __func__, vrf_id); /* We need router-id information. */ zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD, vrf_id); @@ -426,6 +426,61 @@ zclient_send_requests (struct zclient *zclient, vrf_id_t vrf_id) zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD, vrf_id); } +/* Send unregister requests to zebra daemon for the information in a VRF. */ +void +zclient_send_dereg_requests (struct zclient *zclient, vrf_id_t vrf_id) +{ + int i; + afi_t afi; + + /* zclient is disabled. */ + if (! zclient->enable) + return; + + /* If not connected to the zebra yet. */ + if (zclient->sock < 0) + return; + + if (zclient_debug) + zlog_debug ("%s: send deregister messages for VRF %u", __func__, vrf_id); + + /* We need router-id information. */ + zebra_message_send (zclient, ZEBRA_ROUTER_ID_DELETE, vrf_id); + + /* We need interface information. */ + zebra_message_send (zclient, ZEBRA_INTERFACE_DELETE, vrf_id); + + /* Set unwanted redistribute route. */ + for (afi = AFI_IP; afi < AFI_MAX; afi++) + vrf_bitmap_set (zclient->redist[afi][zclient->redist_default], vrf_id); + + /* Flush all redistribute request. */ + if (vrf_id == VRF_DEFAULT) + for (afi = AFI_IP; afi < AFI_MAX; afi++) + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) + if (zclient->mi_redist[afi][i].enabled) + { + struct listnode *node; + u_short *id; + + for (ALL_LIST_ELEMENTS_RO(zclient->mi_redist[afi][i].instances, node, id)) + if (!(i == zclient->redist_default && *id == zclient->instance)) + zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, i, + *id, VRF_DEFAULT); + } + + /* Flush all redistribute request. */ + for (afi = AFI_IP; afi < AFI_MAX; afi++) + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) + if (i != zclient->redist_default && + vrf_bitmap_check (zclient->redist[afi][i], vrf_id)) + zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, i, 0, vrf_id); + + /* If default information is needed. */ + if (vrf_bitmap_check (zclient->default_information, VRF_DEFAULT)) + zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, vrf_id); +} + /* Make connection to zebra daemon. */ int zclient_start (struct zclient *zclient) diff --git a/lib/zclient.h b/lib/zclient.h index 22cd0410e0..e58870828b 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -173,7 +173,8 @@ extern int redist_check_instance (struct redist_proto *, u_short); extern void redist_add_instance (struct redist_proto *, u_short); extern void redist_del_instance (struct redist_proto *, u_short); -extern void zclient_send_requests (struct zclient *, vrf_id_t); +extern void zclient_send_reg_requests (struct zclient *, vrf_id_t); +extern void zclient_send_dereg_requests (struct zclient *, vrf_id_t); /* Send redistribute command to zebra daemon. Do not update zclient state. */ extern int zebra_redistribute_send (int command, struct zclient *, afi_t, int type, u_short instance, vrf_id_t vrf_id); diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 3fbc4d9c8d..a40b3d5f0f 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -651,7 +651,7 @@ DEFUN (no_redistribute_ospf6, static void ospf6_zebra_connected (struct zclient *zclient) { - zclient_send_requests (zclient, VRF_DEFAULT); + zclient_send_reg_requests (zclient, VRF_DEFAULT); } void diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index b5980072a0..543740c67e 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -1557,7 +1557,7 @@ ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or) static void ospf_zebra_connected (struct zclient *zclient) { - zclient_send_requests (zclient, VRF_DEFAULT); + zclient_send_reg_requests (zclient, VRF_DEFAULT); } void diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index a5f7bda6df..e4b9ae330c 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -679,7 +679,7 @@ static struct cmd_node zebra_node = static void rip_zebra_connected (struct zclient *zclient) { - zclient_send_requests (zclient, VRF_DEFAULT); + zclient_send_reg_requests (zclient, VRF_DEFAULT); } void diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index d894bfcd60..e404e0f37c 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -500,7 +500,7 @@ static struct cmd_node zebra_node = static void ripng_zebra_connected (struct zclient *zclient) { - zclient_send_requests (zclient, VRF_DEFAULT); + zclient_send_reg_requests (zclient, VRF_DEFAULT); } /* Initialize zebra structure and it's commands. */ -- 2.39.5