Zebra: Zebra gr dynamic client handling.

When a client connects to zebra with GR capabilities and
then restarts, it might disconnect again even before hello is
sent leading zebra cores.

GR should be supported only for dynamic neighbor who are capable
of restarting.

Signed-off-by: Santosh P K <sapk@vmware.com>
This commit is contained in:
Santosh P K 2020-02-20 10:50:14 -08:00
parent f294fac22d
commit 6f4aee61a2
4 changed files with 36 additions and 24 deletions

View File

@ -1773,10 +1773,11 @@ static void zread_hello(ZAPI_HANDLER_ARGS)
client->proto = proto; client->proto = proto;
client->instance = instance; client->instance = instance;
}
/* Graceful restart processing for client connect */ /* Graceful restart processing for client connect */
zebra_gr_client_reconnect(client); zebra_gr_client_reconnect(client);
}
zsend_capabilities(client, zvrf); zsend_capabilities(client, zvrf);
zebra_vrf_update_all(client); zebra_vrf_update_all(client);
stream_failure: stream_failure:

View File

@ -265,7 +265,9 @@ void zebra_gr_client_reconnect(struct zserv *client)
} }
/* Copy the timers */ /* Copy the timers */
if (old_client) { if (!old_client)
return;
client->gr_instance_count = old_client->gr_instance_count; client->gr_instance_count = old_client->gr_instance_count;
client->restart_time = old_client->restart_time; client->restart_time = old_client->restart_time;
@ -274,8 +276,8 @@ void zebra_gr_client_reconnect(struct zserv *client)
old_client->gr_instance_count); old_client->gr_instance_count);
if (TAILQ_FIRST(&old_client->gr_info_queue)) { if (TAILQ_FIRST(&old_client->gr_info_queue)) {
TAILQ_CONCAT(&client->gr_info_queue, TAILQ_CONCAT(&client->gr_info_queue, &old_client->gr_info_queue,
&old_client->gr_info_queue, gr_info); gr_info);
TAILQ_INIT(&old_client->gr_info_queue); TAILQ_INIT(&old_client->gr_info_queue);
} }
@ -288,7 +290,6 @@ void zebra_gr_client_reconnect(struct zserv *client)
listnode_delete(zrouter.stale_client_list, old_client); listnode_delete(zrouter.stale_client_list, old_client);
/* Delete old client */ /* Delete old client */
XFREE(MTYPE_TMP, old_client); XFREE(MTYPE_TMP, old_client);
}
} }
/* /*
@ -425,6 +426,12 @@ void zread_client_capabilities(ZAPI_HANDLER_ARGS)
return; return;
} }
/* GR only for dynamic clients */
if (client->proto <= ZEBRA_ROUTE_CONNECT) {
LOG_GR("%s: GR capabilities for client %s not supported",
__func__, zebra_route_string(client->proto));
return;
}
/* Call the capabilities handler */ /* Call the capabilities handler */
zebra_client_capabilities_handler(client, &api); zebra_client_capabilities_handler(client, &api);
} }

View File

@ -568,7 +568,7 @@ static void zserv_client_free(struct zserv *client)
close(client->sock); close(client->sock);
if (!client->gr_instance_count) { if (DYNAMIC_CLIENT_GR_DISABLED(client)) {
nroutes = rib_score_proto(client->proto, nroutes = rib_score_proto(client->proto,
client->instance); client->instance);
zlog_notice( zlog_notice(
@ -610,7 +610,7 @@ static void zserv_client_free(struct zserv *client)
* If any instance are graceful restart enabled, * If any instance are graceful restart enabled,
* client is not deleted * client is not deleted
*/ */
if (!client->gr_instance_count) { if (DYNAMIC_CLIENT_GR_DISABLED(client)) {
if (IS_ZEBRA_DEBUG_EVENT) if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("%s: Deleting client %s", __func__, zlog_debug("%s: Deleting client %s", __func__,
zebra_route_string(client->proto)); zebra_route_string(client->proto));

View File

@ -229,6 +229,10 @@ struct zserv {
DECLARE_HOOK(zserv_client_connect, (struct zserv *client), (client)); DECLARE_HOOK(zserv_client_connect, (struct zserv *client), (client));
DECLARE_KOOH(zserv_client_close, (struct zserv *client), (client)); DECLARE_KOOH(zserv_client_close, (struct zserv *client), (client));
#define DYNAMIC_CLIENT_GR_DISABLED(_client) \
((_client->proto <= ZEBRA_ROUTE_CONNECT) \
|| !(_client->gr_instance_count))
/* /*
* Initialize Zebra API server. * Initialize Zebra API server.
* *