back to topotato report
topotato coverage report
Current view: top level - zebra - zebra_gr.c (source / functions) Hit Total Coverage
Test: test_exabgp_demo.py::ExaBGPDemo Lines: 40 243 16.5 %
Date: 2023-02-24 18:37:55 Functions: 8 17 47.1 %

          Line data    Source code
       1             : /*
       2             :  * Zebra GR related helper functions.
       3             :  *
       4             :  * Portions:
       5             :  *      Copyright (C) 2019 VMware, Inc.
       6             :  *      et al.
       7             :  *
       8             :  * This program is free software; you can redistribute it and/or modify it
       9             :  * under the terms of the GNU General Public License as published by the Free
      10             :  * Software Foundation; either version 2 of the License, or (at your option)
      11             :  * any later version.
      12             :  *
      13             :  * This program is distributed in the hope that it will be useful, but WITHOUT
      14             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15             :  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
      16             :  * more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License along
      19             :  * with this program; see the file COPYING; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #include <zebra.h>
      24             : #include <libgen.h>
      25             : 
      26             : #include "lib/prefix.h"
      27             : #include "lib/command.h"
      28             : #include "lib/if.h"
      29             : #include "lib/thread.h"
      30             : #include "lib/stream.h"
      31             : #include "lib/memory.h"
      32             : #include "lib/table.h"
      33             : #include "lib/network.h"
      34             : #include "lib/sockunion.h"
      35             : #include "lib/log.h"
      36             : #include "lib/zclient.h"
      37             : #include "lib/privs.h"
      38             : #include "lib/network.h"
      39             : #include "lib/buffer.h"
      40             : #include "lib/nexthop.h"
      41             : #include "lib/vrf.h"
      42             : #include "lib/libfrr.h"
      43             : #include "lib/sockopt.h"
      44             : 
      45             : #include "zebra/zebra_router.h"
      46             : #include "zebra/debug.h"
      47             : #include "zebra/zapi_msg.h"
      48             : 
      49           9 : DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_GR, "GR");
      50             : 
      51             : /*
      52             :  * Forward declaration.
      53             :  */
      54             : static struct zserv *zebra_gr_find_stale_client(struct zserv *client);
      55             : static void zebra_gr_route_stale_delete_timer_expiry(struct thread *thread);
      56             : static int32_t zebra_gr_delete_stale_routes(struct client_gr_info *info);
      57             : static void zebra_gr_process_client_stale_routes(struct zserv *client,
      58             :                                                  vrf_id_t vrf_id);
      59             : 
      60             : /*
      61             :  * Debug macros.
      62             :  */
      63             : #define LOG_GR(msg, ...)                                                       \
      64             :         do {                                                                   \
      65             :                 if (IS_ZEBRA_DEBUG_EVENT)                                      \
      66             :                         zlog_debug(msg, ##__VA_ARGS__);                        \
      67             :         } while (0)
      68             : 
      69             : 
      70             : /*
      71             :  * Client connection functions
      72             :  */
      73             : 
      74             : /*
      75             :  * Function to clean all the stale clients,
      76             :  * function will also clean up all per instance
      77             :  * capabilities that are exchanged.
      78             :  */
      79           3 : void zebra_gr_stale_client_cleanup(struct list *client_list)
      80             : {
      81           3 :         struct listnode *node, *nnode;
      82           3 :         struct zserv *s_client = NULL;
      83           3 :         struct client_gr_info *info, *ninfo;
      84             : 
      85             :         /* Find the stale client */
      86           6 :         for (ALL_LIST_ELEMENTS(client_list, node, nnode, s_client)) {
      87             : 
      88           0 :                 LOG_GR("%s: Stale client %s is being deleted", __func__,
      89             :                        zebra_route_string(s_client->proto));
      90             : 
      91           0 :                 TAILQ_FOREACH_SAFE (info, &s_client->gr_info_queue, gr_info,
      92             :                                     ninfo) {
      93             : 
      94             :                         /* Cancel the stale timer */
      95           0 :                         if (info->t_stale_removal != NULL) {
      96           0 :                                 THREAD_OFF(info->t_stale_removal);
      97           0 :                                 info->t_stale_removal = NULL;
      98             :                                 /* Process the stale routes */
      99           0 :                                 thread_execute(
     100             :                                     zrouter.master,
     101             :                                     zebra_gr_route_stale_delete_timer_expiry,
     102             :                                     info, 1);
     103             :                         }
     104             :                 }
     105             :         }
     106           3 : }
     107             : 
     108             : /*
     109             :  * A helper function to create client info.
     110             :  */
     111           0 : static struct client_gr_info *zebra_gr_client_info_create(struct zserv *client)
     112             : {
     113           0 :         struct client_gr_info *info;
     114             : 
     115           0 :         info = XCALLOC(MTYPE_ZEBRA_GR, sizeof(struct client_gr_info));
     116             : 
     117           0 :         TAILQ_INSERT_TAIL(&(client->gr_info_queue), info, gr_info);
     118           0 :         return info;
     119             : }
     120             : 
     121             : /*
     122             :  * A helper function to delete and destroy client info.
     123             :  */
     124           0 : static void zebra_gr_client_info_delte(struct zserv *client,
     125             :                                        struct client_gr_info *info)
     126             : {
     127           0 :         TAILQ_REMOVE(&(client->gr_info_queue), info, gr_info);
     128             : 
     129           0 :         THREAD_OFF(info->t_stale_removal);
     130             : 
     131           0 :         XFREE(MTYPE_ZEBRA_GR, info->current_prefix);
     132             : 
     133           0 :         LOG_GR("%s: Instance info is being deleted for client %s", __func__,
     134             :                zebra_route_string(client->proto));
     135             : 
     136             :         /* Delete all the stale routes. */
     137           0 :         info->do_delete = true;
     138           0 :         zebra_gr_delete_stale_routes(info);
     139             : 
     140           0 :         XFREE(MTYPE_ZEBRA_GR, info);
     141           0 : }
     142             : 
     143             : /*
     144             :  * Function to handle client when it disconnect.
     145             :  */
     146           0 : int32_t zebra_gr_client_disconnect(struct zserv *client)
     147             : {
     148           0 :         struct zserv *stale_client;
     149           0 :         struct timeval tv;
     150           0 :         struct client_gr_info *info = NULL;
     151             : 
     152             :         /* Find the stale client */
     153           0 :         stale_client = zebra_gr_find_stale_client(client);
     154             : 
     155             :         /*
     156             :          * We should never be here.
     157             :          */
     158           0 :         if (stale_client) {
     159           0 :                 LOG_GR("%s: Stale client %s exist, we should not be here!",
     160             :                        __func__, zebra_route_string(client->proto));
     161           0 :                 assert(0);
     162             :         }
     163             : 
     164           0 :         client->restart_time = monotime(&tv);
     165             : 
     166             :         /* For all the GR instance start the stale removal timer. */
     167           0 :         TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) {
     168           0 :                 if (ZEBRA_CLIENT_GR_ENABLED(info->capabilities)
     169           0 :                     && (info->t_stale_removal == NULL)) {
     170           0 :                         thread_add_timer(
     171             :                                 zrouter.master,
     172             :                                 zebra_gr_route_stale_delete_timer_expiry, info,
     173             :                                 info->stale_removal_time,
     174             :                                 &info->t_stale_removal);
     175           0 :                         info->current_afi = AFI_IP;
     176           0 :                         info->stale_client_ptr = client;
     177           0 :                         info->stale_client = true;
     178           0 :                         LOG_GR("%s: Client %s Stale timer update to %d",
     179             :                                __func__, zebra_route_string(client->proto),
     180             :                                info->stale_removal_time);
     181             :                 }
     182             :         }
     183             : 
     184           0 :         listnode_add(zrouter.stale_client_list, client);
     185             : 
     186           0 :         return 0;
     187             : }
     188             : 
     189             : /*
     190             :  * Function to delete stale client
     191             :  */
     192           0 : static void zebra_gr_delete_stale_client(struct client_gr_info *info)
     193             : {
     194           0 :         struct client_gr_info *bgp_info;
     195           0 :         struct zserv *s_client = NULL;
     196             : 
     197           0 :         s_client = info->stale_client_ptr;
     198             : 
     199           0 :         if (!s_client || !info->stale_client)
     200             :                 return;
     201             : 
     202             :         /*
     203             :          * If there are bgp instances with the stale delete timer pending
     204             :          * then stale client is not deleted
     205             :          */
     206           0 :         if ((s_client->gr_instance_count > 0) && info->gr_enable)
     207           0 :                 s_client->gr_instance_count--;
     208             : 
     209           0 :         TAILQ_REMOVE(&(s_client->gr_info_queue), info, gr_info);
     210             : 
     211           0 :         LOG_GR("%s: Client %s gr count %d", __func__,
     212             :                zebra_route_string(s_client->proto),
     213             :                s_client->gr_instance_count);
     214             : 
     215           0 :         TAILQ_FOREACH (bgp_info, &s_client->gr_info_queue, gr_info) {
     216           0 :                 if (bgp_info->t_stale_removal != NULL)
     217             :                         return;
     218             :         }
     219             : 
     220           0 :         LOG_GR("%s: Client %s is being deleted", __func__,
     221             :                zebra_route_string(s_client->proto));
     222             : 
     223           0 :         TAILQ_INIT(&(s_client->gr_info_queue));
     224           0 :         listnode_delete(zrouter.stale_client_list, s_client);
     225           0 :         if (info->stale_client)
     226           0 :                 zserv_client_delete(s_client);
     227           0 :         XFREE(MTYPE_ZEBRA_GR, info);
     228             : }
     229             : 
     230             : /*
     231             :  * Function to find stale client.
     232             :  */
     233           0 : static struct zserv *zebra_gr_find_stale_client(struct zserv *client)
     234             : {
     235           0 :         struct listnode *node, *nnode;
     236           0 :         struct zserv *stale_client;
     237             : 
     238             :         /* Find the stale client */
     239           0 :         for (ALL_LIST_ELEMENTS(zrouter.stale_client_list, node, nnode,
     240             :                                stale_client)) {
     241           0 :                 if (client->proto == stale_client->proto
     242           0 :                     && client->instance == stale_client->instance) {
     243           0 :                         return stale_client;
     244             :                 }
     245             :         }
     246             : 
     247             :         return NULL;
     248             : }
     249             : 
     250             : /*
     251             :  * Function to handle reconnect of client post restart.
     252             :  */
     253           6 : void zebra_gr_client_reconnect(struct zserv *client)
     254             : {
     255           6 :         struct listnode *node, *nnode;
     256           6 :         struct zserv *old_client = NULL;
     257           6 :         struct client_gr_info *info = NULL;
     258             : 
     259             :         /* Find the stale client */
     260          12 :         for (ALL_LIST_ELEMENTS(zrouter.stale_client_list, node, nnode,
     261             :                                old_client)) {
     262           0 :                 if (client->proto == old_client->proto
     263           0 :                     && client->instance == old_client->instance)
     264             :                         break;
     265             :         }
     266             : 
     267             :         /* Copy the timers */
     268           6 :         if (!old_client)
     269             :                 return;
     270             : 
     271           0 :         client->gr_instance_count = old_client->gr_instance_count;
     272           0 :         client->restart_time = old_client->restart_time;
     273             : 
     274           0 :         LOG_GR("%s : old client %s, gr_instance_count %d", __func__,
     275             :                zebra_route_string(old_client->proto),
     276             :                old_client->gr_instance_count);
     277             : 
     278           0 :         if (TAILQ_FIRST(&old_client->gr_info_queue)) {
     279           0 :                 TAILQ_CONCAT(&client->gr_info_queue, &old_client->gr_info_queue,
     280             :                              gr_info);
     281           0 :                 TAILQ_INIT(&old_client->gr_info_queue);
     282             :         }
     283             : 
     284           0 :         TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) {
     285           0 :                 info->stale_client_ptr = client;
     286           0 :                 info->stale_client = false;
     287             :         }
     288             : 
     289             :         /* Delete the stale client */
     290           0 :         listnode_delete(zrouter.stale_client_list, old_client);
     291             :         /* Delete old client */
     292           0 :         zserv_client_delete(old_client);
     293             : }
     294             : 
     295             : /*
     296             :  * Functions to deal with capabilities
     297             :  */
     298             : 
     299             : /*
     300             :  * Update the graceful restart information
     301             :  * for the client instance.
     302             :  * This function handles all the capabilities that are received.
     303             :  */
     304           2 : static void zebra_client_update_info(struct zserv *client, struct zapi_cap *api)
     305             : {
     306           2 :         struct client_gr_info *info = NULL;
     307             : 
     308             :         /* Find the bgp information for the specified vrf id */
     309           2 :         TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) {
     310           0 :                 if (info->vrf_id == api->vrf_id)
     311             :                         break;
     312             :         }
     313             : 
     314             : 
     315             :         /*
     316             :          * If the command is delete, then cancel the stale timer and
     317             :          * delete the bgp info
     318             :          */
     319           2 :         switch (api->cap) {
     320           0 :         case ZEBRA_CLIENT_GR_DISABLE:
     321           0 :                 if (!info)
     322             :                         return;
     323             : 
     324           0 :                 LOG_GR("%s: Client %s instance GR disabled count %d", __func__,
     325             :                        zebra_route_string(client->proto),
     326             :                        client->gr_instance_count);
     327             : 
     328           0 :                 if ((info->gr_enable) && (client->gr_instance_count > 0))
     329           0 :                         client->gr_instance_count--;
     330             : 
     331           0 :                 zebra_gr_client_info_delte(client, info);
     332           0 :                 break;
     333           0 :         case ZEBRA_CLIENT_GR_CAPABILITIES:
     334             :                 /* Allocate bgp info */
     335           0 :                 if (!info)
     336           0 :                         info = zebra_gr_client_info_create(client);
     337             : 
     338             :                 /* Update other parameters */
     339           0 :                 if (!info->gr_enable) {
     340           0 :                         client->gr_instance_count++;
     341             : 
     342           0 :                         LOG_GR("%s: Cient %s GR enabled count %d", __func__,
     343             :                                zebra_route_string(client->proto),
     344             :                                client->gr_instance_count);
     345             : 
     346           0 :                         info->capabilities = api->cap;
     347           0 :                         info->stale_removal_time = api->stale_removal_time;
     348           0 :                         info->vrf_id = api->vrf_id;
     349           0 :                         info->gr_enable = true;
     350             :                 }
     351             :                 break;
     352           0 :         case ZEBRA_CLIENT_RIB_STALE_TIME:
     353           0 :                 LOG_GR("%s: Client %s stale time update event", __func__,
     354             :                        zebra_route_string(client->proto));
     355             : 
     356             :                 /* Update the stale removal timer */
     357           0 :                 if (info && info->t_stale_removal == NULL) {
     358             : 
     359           0 :                         LOG_GR("%s: Stale time: %d is now update to: %d",
     360             :                                __func__, info->stale_removal_time,
     361             :                                api->stale_removal_time);
     362             : 
     363           0 :                         info->stale_removal_time = api->stale_removal_time;
     364             :                 }
     365             : 
     366             :                 break;
     367           2 :         case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
     368           2 :                 LOG_GR(
     369             :                    "%s: Client %s route update complete for AFI %d, SAFI %d",
     370             :                    __func__, zebra_route_string(client->proto), api->afi,
     371             :                    api->safi);
     372           2 :                 if (info)
     373           0 :                         info->route_sync[api->afi][api->safi] = true;
     374             :                 break;
     375           0 :         case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
     376           0 :                 LOG_GR("%s: Client %s route update pending for AFI %d, SAFI %d",
     377             :                        __func__, zebra_route_string(client->proto), api->afi,
     378             :                        api->safi);
     379           0 :                 if (info)
     380           0 :                         info->af_enabled[api->afi][api->safi] = true;
     381             :                 break;
     382             :         }
     383             : }
     384             : 
     385             : /*
     386             :  * Handler for capabilities that are received from client.
     387             :  */
     388           2 : static void zebra_client_capabilities_handler(struct zserv *client,
     389             :                                               struct zapi_cap *api)
     390             : {
     391           2 :         switch (api->cap) {
     392           0 :         case ZEBRA_CLIENT_GR_CAPABILITIES:
     393             :         case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
     394             :         case ZEBRA_CLIENT_GR_DISABLE:
     395             :         case ZEBRA_CLIENT_RIB_STALE_TIME:
     396             :                 /*
     397             :                  * For all the cases we need to update the client info.
     398             :                  */
     399           0 :                 zebra_client_update_info(client, api);
     400           0 :                 break;
     401           2 :         case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
     402             :                 /*
     403             :                  * After client info has been updated delete all
     404             :                  * stale routes
     405             :                  */
     406           2 :                 zebra_client_update_info(client, api);
     407           2 :                 zebra_gr_process_client_stale_routes(client, api->vrf_id);
     408           2 :                 break;
     409             :         }
     410           2 : }
     411             : 
     412             : /*
     413             :  * Function to decode and call appropriate functions
     414             :  * to handle client capabilities.
     415             :  */
     416           2 : void zread_client_capabilities(ZAPI_HANDLER_ARGS)
     417             : {
     418           2 :         struct zapi_cap api;
     419           2 :         struct stream *s;
     420             : 
     421           2 :         s = msg;
     422             : 
     423           2 :         if (zapi_capabilities_decode(s, &api)) {
     424           0 :                 LOG_GR("%s: Error in reading capabilities for client %s",
     425             :                        __func__, zebra_route_string(client->proto));
     426           0 :                 return;
     427             :         }
     428             : 
     429             :         /* GR only for dynamic clients */
     430           2 :         if (client->proto <= ZEBRA_ROUTE_CONNECT) {
     431           0 :                 LOG_GR("%s: GR capabilities for client %s not supported",
     432             :                        __func__, zebra_route_string(client->proto));
     433           0 :                 return;
     434             :         }
     435             :         /* Call the capabilities handler */
     436           2 :         zebra_client_capabilities_handler(client, &api);
     437             : }
     438             : 
     439             : 
     440             : /*
     441             :  * Stale route handling
     442             :  */
     443             : 
     444             : /*
     445             :  * Delete all the stale routes that have not been refreshed
     446             :  * post restart.
     447             :  */
     448           0 : static void zebra_gr_route_stale_delete_timer_expiry(struct thread *thread)
     449             : {
     450           0 :         struct client_gr_info *info;
     451           0 :         int32_t cnt = 0;
     452           0 :         struct zserv *client;
     453             : 
     454           0 :         info = THREAD_ARG(thread);
     455           0 :         info->t_stale_removal = NULL;
     456           0 :         client = (struct zserv *)info->stale_client_ptr;
     457             : 
     458             :         /* Set the flag to indicate all stale route deletion */
     459           0 :         if (thread->u.val == 1)
     460           0 :                 info->do_delete = true;
     461             : 
     462           0 :         cnt = zebra_gr_delete_stale_routes(info);
     463             : 
     464             :         /* Restart the timer */
     465           0 :         if (cnt > 0) {
     466           0 :                 LOG_GR("%s: Client %s processed %d routes. Start timer again",
     467             :                        __func__, zebra_route_string(client->proto), cnt);
     468             : 
     469           0 :                 thread_add_timer(zrouter.master,
     470             :                                  zebra_gr_route_stale_delete_timer_expiry, info,
     471             :                                  ZEBRA_DEFAULT_STALE_UPDATE_DELAY,
     472             :                                  &info->t_stale_removal);
     473             :         } else {
     474             :                 /* No routes to delete for the VRF */
     475           0 :                 LOG_GR("%s: Client %s all stale routes processed", __func__,
     476             :                        zebra_route_string(client->proto));
     477             : 
     478           0 :                 XFREE(MTYPE_ZEBRA_GR, info->current_prefix);
     479           0 :                 info->current_afi = 0;
     480           0 :                 zebra_gr_delete_stale_client(info);
     481             :         }
     482           0 : }
     483             : 
     484             : 
     485             : /*
     486             :  * Function to process to check if route entry is stale
     487             :  * or has been updated.
     488             :  */
     489           0 : static void zebra_gr_process_route_entry(struct zserv *client,
     490             :                                          struct route_node *rn,
     491             :                                          struct route_entry *re)
     492             : {
     493           0 :         if ((client == NULL) || (rn == NULL) || (re == NULL))
     494             :                 return;
     495             : 
     496             :         /* If the route is not refreshed after restart, delete the entry */
     497           0 :         if (re->uptime < client->restart_time) {
     498           0 :                 if (IS_ZEBRA_DEBUG_RIB)
     499           0 :                         zlog_debug("%s: Client %s stale route %pFX is deleted",
     500             :                                    __func__, zebra_route_string(client->proto),
     501             :                                    &rn->p);
     502           0 :                 rib_delnode(rn, re);
     503             :         }
     504             : }
     505             : 
     506             : /*
     507             :  * This function walks through the route table for all vrf and deletes
     508             :  * the stale routes for the restarted client specified by the protocol
     509             :  * type
     510             :  */
     511           0 : static int32_t zebra_gr_delete_stale_route(struct client_gr_info *info,
     512             :                                            struct zebra_vrf *zvrf)
     513             : {
     514           0 :         struct route_node *rn, *curr;
     515           0 :         struct route_entry *re;
     516           0 :         struct route_entry *next;
     517           0 :         struct route_table *table;
     518           0 :         int32_t n = 0;
     519           0 :         afi_t afi, curr_afi;
     520           0 :         uint8_t proto;
     521           0 :         uint16_t instance;
     522           0 :         struct zserv *s_client;
     523             : 
     524           0 :         if ((info == NULL) || (zvrf == NULL))
     525             :                 return -1;
     526             : 
     527           0 :         s_client = info->stale_client_ptr;
     528           0 :         if (s_client == NULL) {
     529           0 :                 LOG_GR("%s: Stale client not present", __func__);
     530           0 :                 return -1;
     531             :         }
     532             : 
     533           0 :         proto = s_client->proto;
     534           0 :         instance = s_client->instance;
     535           0 :         curr_afi = info->current_afi;
     536             : 
     537           0 :         LOG_GR("%s: Client %s stale routes are being deleted", __func__,
     538             :                zebra_route_string(proto));
     539             : 
     540             :         /* Process routes for all AFI */
     541           0 :         for (afi = curr_afi; afi < AFI_MAX; afi++) {
     542           0 :                 table = zvrf->table[afi][SAFI_UNICAST];
     543             : 
     544           0 :                 if (table) {
     545             :                         /*
     546             :                          * If the current prefix is NULL then get the first
     547             :                          * route entry in the table
     548             :                          */
     549           0 :                         if (info->current_prefix == NULL) {
     550           0 :                                 rn = route_top(table);
     551           0 :                                 if (rn == NULL)
     552           0 :                                         continue;
     553             :                                 curr = rn;
     554             :                         } else
     555             :                                 /* Get the next route entry */
     556           0 :                                 curr = route_table_get_next(
     557             :                                         table, info->current_prefix);
     558             : 
     559           0 :                         for (rn = curr; rn; rn = srcdest_route_next(rn)) {
     560           0 :                                 RNODE_FOREACH_RE_SAFE (rn, re, next) {
     561           0 :                                         if (CHECK_FLAG(re->status,
     562             :                                                        ROUTE_ENTRY_REMOVED))
     563           0 :                                                 continue;
     564             :                                         /* If the route refresh is received
     565             :                                          * after restart then do not delete
     566             :                                          * the route
     567             :                                          */
     568           0 :                                         if (re->type == proto
     569           0 :                                             && re->instance == instance) {
     570           0 :                                                 zebra_gr_process_route_entry(
     571             :                                                         s_client, rn, re);
     572           0 :                                                 n++;
     573             :                                         }
     574             : 
     575             :                                         /* If the max route count is reached
     576             :                                          * then timer thread will be restarted
     577             :                                          * Store the current prefix and afi
     578             :                                          */
     579           0 :                                         if ((n >= ZEBRA_MAX_STALE_ROUTE_COUNT)
     580           0 :                                             && (info->do_delete == false)) {
     581           0 :                                                 info->current_afi = afi;
     582           0 :                                                 info->current_prefix = XCALLOC(
     583             :                                                         MTYPE_ZEBRA_GR,
     584             :                                                         sizeof(struct prefix));
     585           0 :                                                 prefix_copy(
     586             :                                                         info->current_prefix,
     587           0 :                                                         &rn->p);
     588           0 :                                                 return n;
     589             :                                         }
     590             :                                 }
     591             :                         }
     592             :                 }
     593             :                 /*
     594             :                  * Reset the current prefix to indicate processing completion
     595             :                  * of the current AFI
     596             :                  */
     597           0 :                 XFREE(MTYPE_ZEBRA_GR, info->current_prefix);
     598             :         }
     599             :         return 0;
     600             : }
     601             : 
     602             : /*
     603             :  * Delete the stale routes when client is restarted and routes are not
     604             :  * refreshed within the stale timeout
     605             :  */
     606           0 : static int32_t zebra_gr_delete_stale_routes(struct client_gr_info *info)
     607             : {
     608           0 :         struct vrf *vrf;
     609           0 :         struct zebra_vrf *zvrf;
     610           0 :         uint64_t cnt = 0;
     611             : 
     612           0 :         if (info == NULL)
     613             :                 return -1;
     614             : 
     615             :         /* Get the current VRF */
     616           0 :         vrf = vrf_lookup_by_id(info->vrf_id);
     617           0 :         if (vrf == NULL) {
     618           0 :                 LOG_GR("%s: Invalid VRF %d", __func__, info->vrf_id);
     619           0 :                 return -1;
     620             :         }
     621             : 
     622           0 :         zvrf = vrf->info;
     623           0 :         if (zvrf == NULL) {
     624           0 :                 LOG_GR("%s: Invalid VRF entry %d", __func__, info->vrf_id);
     625           0 :                 return -1;
     626             :         }
     627             : 
     628           0 :         cnt = zebra_gr_delete_stale_route(info, zvrf);
     629           0 :         return cnt;
     630             : }
     631             : 
     632             : /*
     633             :  * This function checks if route update for all AFI, SAFI is completed
     634             :  * and cancels the stale timer
     635             :  */
     636           2 : static void zebra_gr_process_client_stale_routes(struct zserv *client,
     637             :                                                  vrf_id_t vrf_id)
     638             : {
     639           2 :         struct client_gr_info *info = NULL;
     640           2 :         afi_t afi;
     641           2 :         safi_t safi;
     642             : 
     643           2 :         TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) {
     644           0 :                 if (info->vrf_id == vrf_id)
     645             :                         break;
     646             :         }
     647             : 
     648           2 :         if (info == NULL)
     649             :                 return;
     650             : 
     651             :         /* Check if route update completed for all AFI, SAFI */
     652           0 :         FOREACH_AFI_SAFI_NSF (afi, safi) {
     653           0 :                 if (info->af_enabled[afi][safi]) {
     654           0 :                         if (!info->route_sync[afi][safi]) {
     655           0 :                                 LOG_GR("%s: Client %s route update not completed for AFI %d, SAFI %d",
     656             :                                        __func__,
     657             :                                        zebra_route_string(client->proto), afi,
     658             :                                        safi);
     659           0 :                                 return;
     660             :                         }
     661             :                 }
     662             :         }
     663             : 
     664             :         /*
     665             :          * Route update completed for all AFI, SAFI
     666             :          * Cancel the stale timer and process the routes
     667             :          */
     668           0 :         if (info->t_stale_removal) {
     669           0 :                 LOG_GR("%s: Client %s canceled stale delete timer vrf %d",
     670             :                        __func__, zebra_route_string(client->proto),
     671             :                        info->vrf_id);
     672           0 :                 THREAD_OFF(info->t_stale_removal);
     673           0 :                 thread_execute(zrouter.master,
     674             :                                zebra_gr_route_stale_delete_timer_expiry, info,
     675             :                                0);
     676             :         }
     677             : }

Generated by: LCOV version v1.16-topotato