]> git.puffer.fish Git - mirror/frr.git/commitdiff
Zebra: Zebra gr dynamic client handling. 5850/head
authorSantosh P K <sapk@vmware.com>
Thu, 20 Feb 2020 18:50:14 +0000 (10:50 -0800)
committerSantosh P K <sapk@vmware.com>
Fri, 21 Feb 2020 14:26:48 +0000 (06:26 -0800)
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>
zebra/zapi_msg.c
zebra/zebra_gr.c
zebra/zserv.c
zebra/zserv.h

index 6012962b1c4155712caf812895706edd2eb77fa9..9d9d5ea8f76e428fad886f017ec7c205fb638095 100644 (file)
@@ -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:
index e8c7304f44b1f1bed706bf2c10ebca32e4caad50..6d3829110ea3be70beb8cf7db03c70b502799e6a 100644 (file)
@@ -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);
 }
index 2a5352a1da26e063a00748c07cb77bab5fd24c4b..299c079df1831e7e48d54f8af333cbfb01dee56b 100644 (file)
@@ -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));
index 77ea19202f334ba43e6fa6fcdee7a18768c42932..6a075cc9a738a99d7f53a1ae5d45d97591cf1163 100644 (file)
@@ -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.
  *