summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSantosh P K <sapk@vmware.com>2020-02-20 19:50:14 +0100
committerSantosh P K <sapk@vmware.com>2020-02-21 15:26:48 +0100
commit6f4aee61a2e741b8ba6f91b5922ddafafda5b587 (patch)
tree464cda7f3595a74a51d91d8f38de47ea737caf29
parentMerge pull request #5842 from qlyoung/fix-test-then-xfree-again (diff)
downloadfrr-6f4aee61a2e741b8ba6f91b5922ddafafda5b587.tar.xz
frr-6f4aee61a2e741b8ba6f91b5922ddafafda5b587.zip
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>
-rw-r--r--zebra/zapi_msg.c5
-rw-r--r--zebra/zebra_gr.c49
-rw-r--r--zebra/zserv.c4
-rw-r--r--zebra/zserv.h4
4 files changed, 37 insertions, 25 deletions
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 6012962b1..9d9d5ea8f 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -1773,10 +1773,11 @@ static void zread_hello(ZAPI_HANDLER_ARGS)
client->proto = proto;
client->instance = instance;
+
+ /* Graceful restart processing for client connect */
+ zebra_gr_client_reconnect(client);
}
- /* Graceful restart processing for client connect */
- zebra_gr_client_reconnect(client);
zsend_capabilities(client, zvrf);
zebra_vrf_update_all(client);
stream_failure:
diff --git a/zebra/zebra_gr.c b/zebra/zebra_gr.c
index e8c7304f4..6d3829110 100644
--- a/zebra/zebra_gr.c
+++ b/zebra/zebra_gr.c
@@ -265,30 +265,31 @@ void zebra_gr_client_reconnect(struct zserv *client)
}
/* Copy the timers */
- if (old_client) {
- client->gr_instance_count = old_client->gr_instance_count;
- client->restart_time = old_client->restart_time;
-
- LOG_GR("%s : old client %s, gr_instance_count %d", __func__,
- zebra_route_string(old_client->proto),
- old_client->gr_instance_count);
-
- if (TAILQ_FIRST(&old_client->gr_info_queue)) {
- TAILQ_CONCAT(&client->gr_info_queue,
- &old_client->gr_info_queue, gr_info);
- TAILQ_INIT(&old_client->gr_info_queue);
- }
+ if (!old_client)
+ return;
- TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) {
- info->stale_client_ptr = client;
- info->stale_client = false;
- }
+ client->gr_instance_count = old_client->gr_instance_count;
+ client->restart_time = old_client->restart_time;
+
+ LOG_GR("%s : old client %s, gr_instance_count %d", __func__,
+ zebra_route_string(old_client->proto),
+ old_client->gr_instance_count);
+
+ if (TAILQ_FIRST(&old_client->gr_info_queue)) {
+ TAILQ_CONCAT(&client->gr_info_queue, &old_client->gr_info_queue,
+ gr_info);
+ TAILQ_INIT(&old_client->gr_info_queue);
+ }
- /* Delete the stale client */
- listnode_delete(zrouter.stale_client_list, old_client);
- /* Delete old client */
- XFREE(MTYPE_TMP, old_client);
+ TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) {
+ info->stale_client_ptr = client;
+ info->stale_client = false;
}
+
+ /* Delete the stale client */
+ listnode_delete(zrouter.stale_client_list, old_client);
+ /* Delete old client */
+ XFREE(MTYPE_TMP, old_client);
}
/*
@@ -425,6 +426,12 @@ void zread_client_capabilities(ZAPI_HANDLER_ARGS)
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 */
zebra_client_capabilities_handler(client, &api);
}
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 2a5352a1d..299c079df 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -568,7 +568,7 @@ static void zserv_client_free(struct zserv *client)
close(client->sock);
- if (!client->gr_instance_count) {
+ if (DYNAMIC_CLIENT_GR_DISABLED(client)) {
nroutes = rib_score_proto(client->proto,
client->instance);
zlog_notice(
@@ -610,7 +610,7 @@ static void zserv_client_free(struct zserv *client)
* If any instance are graceful restart enabled,
* client is not deleted
*/
- if (!client->gr_instance_count) {
+ if (DYNAMIC_CLIENT_GR_DISABLED(client)) {
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("%s: Deleting client %s", __func__,
zebra_route_string(client->proto));
diff --git a/zebra/zserv.h b/zebra/zserv.h
index 77ea19202..6a075cc9a 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -229,6 +229,10 @@ struct zserv {
DECLARE_HOOK(zserv_client_connect, (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.
*