1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Zebra GR related helper functions.
6 * Copyright (C) 2019 VMware, Inc.
13 #include "lib/prefix.h"
14 #include "lib/command.h"
16 #include "lib/thread.h"
17 #include "lib/stream.h"
18 #include "lib/memory.h"
19 #include "lib/table.h"
20 #include "lib/network.h"
21 #include "lib/sockunion.h"
23 #include "lib/zclient.h"
24 #include "lib/privs.h"
25 #include "lib/network.h"
26 #include "lib/buffer.h"
27 #include "lib/nexthop.h"
29 #include "lib/libfrr.h"
30 #include "lib/sockopt.h"
32 #include "zebra/zebra_router.h"
33 #include "zebra/debug.h"
34 #include "zebra/zapi_msg.h"
36 DEFINE_MTYPE_STATIC(ZEBRA
, ZEBRA_GR
, "GR");
39 * Forward declaration.
41 static struct zserv
*zebra_gr_find_stale_client(struct zserv
*client
);
42 static void zebra_gr_route_stale_delete_timer_expiry(struct thread
*thread
);
43 static int32_t zebra_gr_delete_stale_routes(struct client_gr_info
*info
);
44 static void zebra_gr_process_client_stale_routes(struct zserv
*client
,
50 #define LOG_GR(msg, ...) \
52 if (IS_ZEBRA_DEBUG_EVENT) \
53 zlog_debug(msg, ##__VA_ARGS__); \
58 * Client connection functions
62 * Function to clean all the stale clients,
63 * function will also clean up all per instance
64 * capabilities that are exchanged.
66 void zebra_gr_stale_client_cleanup(struct list
*client_list
)
68 struct listnode
*node
, *nnode
;
69 struct zserv
*s_client
= NULL
;
70 struct client_gr_info
*info
, *ninfo
;
72 /* Find the stale client */
73 for (ALL_LIST_ELEMENTS(client_list
, node
, nnode
, s_client
)) {
75 LOG_GR("%s: Stale client %s is being deleted", __func__
,
76 zebra_route_string(s_client
->proto
));
78 TAILQ_FOREACH_SAFE (info
, &s_client
->gr_info_queue
, gr_info
,
81 /* Cancel the stale timer */
82 if (info
->t_stale_removal
!= NULL
) {
83 THREAD_OFF(info
->t_stale_removal
);
84 info
->t_stale_removal
= NULL
;
85 /* Process the stale routes */
88 zebra_gr_route_stale_delete_timer_expiry
,
96 * A helper function to create client info.
98 static struct client_gr_info
*zebra_gr_client_info_create(struct zserv
*client
)
100 struct client_gr_info
*info
;
102 info
= XCALLOC(MTYPE_ZEBRA_GR
, sizeof(struct client_gr_info
));
104 TAILQ_INSERT_TAIL(&(client
->gr_info_queue
), info
, gr_info
);
109 * A helper function to delete and destroy client info.
111 static void zebra_gr_client_info_delte(struct zserv
*client
,
112 struct client_gr_info
*info
)
114 TAILQ_REMOVE(&(client
->gr_info_queue
), info
, gr_info
);
116 THREAD_OFF(info
->t_stale_removal
);
118 XFREE(MTYPE_ZEBRA_GR
, info
->current_prefix
);
120 LOG_GR("%s: Instance info is being deleted for client %s", __func__
,
121 zebra_route_string(client
->proto
));
123 /* Delete all the stale routes. */
124 info
->do_delete
= true;
125 zebra_gr_delete_stale_routes(info
);
127 XFREE(MTYPE_ZEBRA_GR
, info
);
131 * Function to handle client when it disconnect.
133 int32_t zebra_gr_client_disconnect(struct zserv
*client
)
135 struct zserv
*stale_client
;
137 struct client_gr_info
*info
= NULL
;
139 /* Find the stale client */
140 stale_client
= zebra_gr_find_stale_client(client
);
143 * We should never be here.
146 LOG_GR("%s: Stale client %s exist, we should not be here!",
147 __func__
, zebra_route_string(client
->proto
));
151 client
->restart_time
= monotime(&tv
);
153 /* For all the GR instance start the stale removal timer. */
154 TAILQ_FOREACH (info
, &client
->gr_info_queue
, gr_info
) {
155 if (ZEBRA_CLIENT_GR_ENABLED(info
->capabilities
)
156 && (info
->t_stale_removal
== NULL
)) {
159 zebra_gr_route_stale_delete_timer_expiry
, info
,
160 info
->stale_removal_time
,
161 &info
->t_stale_removal
);
162 info
->current_afi
= AFI_IP
;
163 info
->stale_client_ptr
= client
;
164 info
->stale_client
= true;
165 LOG_GR("%s: Client %s Stale timer update to %d",
166 __func__
, zebra_route_string(client
->proto
),
167 info
->stale_removal_time
);
171 listnode_add(zrouter
.stale_client_list
, client
);
177 * Function to delete stale client
179 static void zebra_gr_delete_stale_client(struct client_gr_info
*info
)
181 struct client_gr_info
*bgp_info
;
182 struct zserv
*s_client
= NULL
;
184 s_client
= info
->stale_client_ptr
;
186 if (!s_client
|| !info
->stale_client
)
190 * If there are bgp instances with the stale delete timer pending
191 * then stale client is not deleted
193 if ((s_client
->gr_instance_count
> 0) && info
->gr_enable
)
194 s_client
->gr_instance_count
--;
196 TAILQ_REMOVE(&(s_client
->gr_info_queue
), info
, gr_info
);
198 LOG_GR("%s: Client %s gr count %d", __func__
,
199 zebra_route_string(s_client
->proto
),
200 s_client
->gr_instance_count
);
202 TAILQ_FOREACH (bgp_info
, &s_client
->gr_info_queue
, gr_info
) {
203 if (bgp_info
->t_stale_removal
!= NULL
)
207 LOG_GR("%s: Client %s is being deleted", __func__
,
208 zebra_route_string(s_client
->proto
));
210 TAILQ_INIT(&(s_client
->gr_info_queue
));
211 listnode_delete(zrouter
.stale_client_list
, s_client
);
212 if (info
->stale_client
)
213 zserv_client_delete(s_client
);
214 XFREE(MTYPE_ZEBRA_GR
, info
);
218 * Function to find stale client.
220 static struct zserv
*zebra_gr_find_stale_client(struct zserv
*client
)
222 struct listnode
*node
, *nnode
;
223 struct zserv
*stale_client
;
225 /* Find the stale client */
226 for (ALL_LIST_ELEMENTS(zrouter
.stale_client_list
, node
, nnode
,
228 if (client
->proto
== stale_client
->proto
229 && client
->instance
== stale_client
->instance
) {
238 * Function to handle reconnect of client post restart.
240 void zebra_gr_client_reconnect(struct zserv
*client
)
242 struct listnode
*node
, *nnode
;
243 struct zserv
*old_client
= NULL
;
244 struct client_gr_info
*info
= NULL
;
246 /* Find the stale client */
247 for (ALL_LIST_ELEMENTS(zrouter
.stale_client_list
, node
, nnode
,
249 if (client
->proto
== old_client
->proto
250 && client
->instance
== old_client
->instance
)
254 /* Copy the timers */
258 client
->gr_instance_count
= old_client
->gr_instance_count
;
259 client
->restart_time
= old_client
->restart_time
;
261 LOG_GR("%s : old client %s, gr_instance_count %d", __func__
,
262 zebra_route_string(old_client
->proto
),
263 old_client
->gr_instance_count
);
265 if (TAILQ_FIRST(&old_client
->gr_info_queue
)) {
266 TAILQ_CONCAT(&client
->gr_info_queue
, &old_client
->gr_info_queue
,
268 TAILQ_INIT(&old_client
->gr_info_queue
);
271 TAILQ_FOREACH (info
, &client
->gr_info_queue
, gr_info
) {
272 info
->stale_client_ptr
= client
;
273 info
->stale_client
= false;
276 /* Delete the stale client */
277 listnode_delete(zrouter
.stale_client_list
, old_client
);
278 /* Delete old client */
279 zserv_client_delete(old_client
);
283 * Functions to deal with capabilities
287 * Update the graceful restart information
288 * for the client instance.
289 * This function handles all the capabilities that are received.
291 static void zebra_client_update_info(struct zserv
*client
, struct zapi_cap
*api
)
293 struct client_gr_info
*info
= NULL
;
295 /* Find the bgp information for the specified vrf id */
296 TAILQ_FOREACH (info
, &client
->gr_info_queue
, gr_info
) {
297 if (info
->vrf_id
== api
->vrf_id
)
303 * If the command is delete, then cancel the stale timer and
304 * delete the bgp info
307 case ZEBRA_CLIENT_GR_DISABLE
:
311 LOG_GR("%s: Client %s instance GR disabled count %d", __func__
,
312 zebra_route_string(client
->proto
),
313 client
->gr_instance_count
);
315 if ((info
->gr_enable
) && (client
->gr_instance_count
> 0))
316 client
->gr_instance_count
--;
318 zebra_gr_client_info_delte(client
, info
);
320 case ZEBRA_CLIENT_GR_CAPABILITIES
:
321 /* Allocate bgp info */
323 info
= zebra_gr_client_info_create(client
);
325 /* Update other parameters */
326 if (!info
->gr_enable
) {
327 client
->gr_instance_count
++;
329 LOG_GR("%s: Cient %s GR enabled count %d", __func__
,
330 zebra_route_string(client
->proto
),
331 client
->gr_instance_count
);
333 info
->capabilities
= api
->cap
;
334 info
->stale_removal_time
= api
->stale_removal_time
;
335 info
->vrf_id
= api
->vrf_id
;
336 info
->gr_enable
= true;
339 case ZEBRA_CLIENT_RIB_STALE_TIME
:
340 LOG_GR("%s: Client %s stale time update event", __func__
,
341 zebra_route_string(client
->proto
));
343 /* Update the stale removal timer */
344 if (info
&& info
->t_stale_removal
== NULL
) {
346 LOG_GR("%s: Stale time: %d is now update to: %d",
347 __func__
, info
->stale_removal_time
,
348 api
->stale_removal_time
);
350 info
->stale_removal_time
= api
->stale_removal_time
;
354 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE
:
356 "%s: Client %s route update complete for AFI %d, SAFI %d",
357 __func__
, zebra_route_string(client
->proto
), api
->afi
,
360 info
->route_sync
[api
->afi
][api
->safi
] = true;
362 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING
:
363 LOG_GR("%s: Client %s route update pending for AFI %d, SAFI %d",
364 __func__
, zebra_route_string(client
->proto
), api
->afi
,
367 info
->af_enabled
[api
->afi
][api
->safi
] = true;
373 * Handler for capabilities that are received from client.
375 static void zebra_client_capabilities_handler(struct zserv
*client
,
376 struct zapi_cap
*api
)
379 case ZEBRA_CLIENT_GR_CAPABILITIES
:
380 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING
:
381 case ZEBRA_CLIENT_GR_DISABLE
:
382 case ZEBRA_CLIENT_RIB_STALE_TIME
:
384 * For all the cases we need to update the client info.
386 zebra_client_update_info(client
, api
);
388 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE
:
390 * After client info has been updated delete all
393 zebra_client_update_info(client
, api
);
394 zebra_gr_process_client_stale_routes(client
, api
->vrf_id
);
400 * Function to decode and call appropriate functions
401 * to handle client capabilities.
403 void zread_client_capabilities(ZAPI_HANDLER_ARGS
)
410 if (zapi_capabilities_decode(s
, &api
)) {
411 LOG_GR("%s: Error in reading capabilities for client %s",
412 __func__
, zebra_route_string(client
->proto
));
416 /* GR only for dynamic clients */
417 if (client
->proto
<= ZEBRA_ROUTE_CONNECT
) {
418 LOG_GR("%s: GR capabilities for client %s not supported",
419 __func__
, zebra_route_string(client
->proto
));
422 /* Call the capabilities handler */
423 zebra_client_capabilities_handler(client
, &api
);
428 * Stale route handling
432 * Delete all the stale routes that have not been refreshed
435 static void zebra_gr_route_stale_delete_timer_expiry(struct thread
*thread
)
437 struct client_gr_info
*info
;
439 struct zserv
*client
;
441 info
= THREAD_ARG(thread
);
442 info
->t_stale_removal
= NULL
;
443 client
= (struct zserv
*)info
->stale_client_ptr
;
445 /* Set the flag to indicate all stale route deletion */
446 if (thread
->u
.val
== 1)
447 info
->do_delete
= true;
449 cnt
= zebra_gr_delete_stale_routes(info
);
451 /* Restart the timer */
453 LOG_GR("%s: Client %s processed %d routes. Start timer again",
454 __func__
, zebra_route_string(client
->proto
), cnt
);
456 thread_add_timer(zrouter
.master
,
457 zebra_gr_route_stale_delete_timer_expiry
, info
,
458 ZEBRA_DEFAULT_STALE_UPDATE_DELAY
,
459 &info
->t_stale_removal
);
461 /* No routes to delete for the VRF */
462 LOG_GR("%s: Client %s all stale routes processed", __func__
,
463 zebra_route_string(client
->proto
));
465 XFREE(MTYPE_ZEBRA_GR
, info
->current_prefix
);
466 info
->current_afi
= 0;
467 zebra_gr_delete_stale_client(info
);
473 * Function to process to check if route entry is stale
474 * or has been updated.
476 static void zebra_gr_process_route_entry(struct zserv
*client
,
477 struct route_node
*rn
,
478 struct route_entry
*re
)
480 if ((client
== NULL
) || (rn
== NULL
) || (re
== NULL
))
483 /* If the route is not refreshed after restart, delete the entry */
484 if (re
->uptime
< client
->restart_time
) {
485 if (IS_ZEBRA_DEBUG_RIB
)
486 zlog_debug("%s: Client %s stale route %pFX is deleted",
487 __func__
, zebra_route_string(client
->proto
),
494 * This function walks through the route table for all vrf and deletes
495 * the stale routes for the restarted client specified by the protocol
498 static int32_t zebra_gr_delete_stale_route(struct client_gr_info
*info
,
499 struct zebra_vrf
*zvrf
)
501 struct route_node
*rn
, *curr
;
502 struct route_entry
*re
;
503 struct route_entry
*next
;
504 struct route_table
*table
;
509 struct zserv
*s_client
;
511 if ((info
== NULL
) || (zvrf
== NULL
))
514 s_client
= info
->stale_client_ptr
;
515 if (s_client
== NULL
) {
516 LOG_GR("%s: Stale client not present", __func__
);
520 proto
= s_client
->proto
;
521 instance
= s_client
->instance
;
522 curr_afi
= info
->current_afi
;
524 LOG_GR("%s: Client %s stale routes are being deleted", __func__
,
525 zebra_route_string(proto
));
527 /* Process routes for all AFI */
528 for (afi
= curr_afi
; afi
< AFI_MAX
; afi
++) {
529 table
= zvrf
->table
[afi
][SAFI_UNICAST
];
533 * If the current prefix is NULL then get the first
534 * route entry in the table
536 if (info
->current_prefix
== NULL
) {
537 rn
= route_top(table
);
542 /* Get the next route entry */
543 curr
= route_table_get_next(
544 table
, info
->current_prefix
);
546 for (rn
= curr
; rn
; rn
= srcdest_route_next(rn
)) {
547 RNODE_FOREACH_RE_SAFE (rn
, re
, next
) {
548 if (CHECK_FLAG(re
->status
,
549 ROUTE_ENTRY_REMOVED
))
551 /* If the route refresh is received
552 * after restart then do not delete
555 if (re
->type
== proto
556 && re
->instance
== instance
) {
557 zebra_gr_process_route_entry(
562 /* If the max route count is reached
563 * then timer thread will be restarted
564 * Store the current prefix and afi
566 if ((n
>= ZEBRA_MAX_STALE_ROUTE_COUNT
)
567 && (info
->do_delete
== false)) {
568 info
->current_afi
= afi
;
569 info
->current_prefix
= XCALLOC(
571 sizeof(struct prefix
));
573 info
->current_prefix
,
581 * Reset the current prefix to indicate processing completion
584 XFREE(MTYPE_ZEBRA_GR
, info
->current_prefix
);
590 * Delete the stale routes when client is restarted and routes are not
591 * refreshed within the stale timeout
593 static int32_t zebra_gr_delete_stale_routes(struct client_gr_info
*info
)
596 struct zebra_vrf
*zvrf
;
602 /* Get the current VRF */
603 vrf
= vrf_lookup_by_id(info
->vrf_id
);
605 LOG_GR("%s: Invalid VRF %d", __func__
, info
->vrf_id
);
611 LOG_GR("%s: Invalid VRF entry %d", __func__
, info
->vrf_id
);
615 cnt
= zebra_gr_delete_stale_route(info
, zvrf
);
620 * This function checks if route update for all AFI, SAFI is completed
621 * and cancels the stale timer
623 static void zebra_gr_process_client_stale_routes(struct zserv
*client
,
626 struct client_gr_info
*info
= NULL
;
630 TAILQ_FOREACH (info
, &client
->gr_info_queue
, gr_info
) {
631 if (info
->vrf_id
== vrf_id
)
638 /* Check if route update completed for all AFI, SAFI */
639 FOREACH_AFI_SAFI_NSF (afi
, safi
) {
640 if (info
->af_enabled
[afi
][safi
]) {
641 if (!info
->route_sync
[afi
][safi
]) {
642 LOG_GR("%s: Client %s route update not completed for AFI %d, SAFI %d",
644 zebra_route_string(client
->proto
), afi
,
652 * Route update completed for all AFI, SAFI
653 * Cancel the stale timer and process the routes
655 if (info
->t_stale_removal
) {
656 LOG_GR("%s: Client %s canceled stale delete timer vrf %d",
657 __func__
, zebra_route_string(client
->proto
),
659 THREAD_OFF(info
->t_stale_removal
);
660 thread_execute(zrouter
.master
,
661 zebra_gr_route_stale_delete_timer_expiry
, info
,