summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Schoener <karen@voltanet.io>2020-12-07 18:01:01 -0500
committerKaren Schoener <karen@volta.io>2020-12-07 18:22:36 -0500
commit581e797e02d91cb1c5a7acfd9b2f8c8feb1cde56 (patch)
treed1ec08584f36686aa19986093d1d06b91687f102
parent6a684109aea0e8b314340a00d9c353df0b3daab4 (diff)
zebra: Adding zapi client close notification
When zebra detects a client close, send a zapi client close notification. Signed-off-by: Karen Schoener <karen@voltanet.io>
-rw-r--r--lib/log.c3
-rw-r--r--lib/zclient.c23
-rw-r--r--lib/zclient.h13
-rw-r--r--zebra/zapi_msg.c16
-rw-r--r--zebra/zapi_msg.h3
-rw-r--r--zebra/zserv.c17
6 files changed, 74 insertions, 1 deletions
diff --git a/lib/log.c b/lib/log.c
index 7b37ba7f27..03ed23a04b 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -456,7 +456,8 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_NHG_ADD),
DESC_ENTRY(ZEBRA_NHG_DEL),
DESC_ENTRY(ZEBRA_NHG_NOTIFY_OWNER),
- DESC_ENTRY(ZEBRA_ROUTE_NOTIFY_REQUEST)};
+ DESC_ENTRY(ZEBRA_ROUTE_NOTIFY_REQUEST),
+ DESC_ENTRY(ZEBRA_CLIENT_CLOSE_NOTIFY)};
#undef DESC_ENTRY
static const struct zebra_desc_table unknown = {0, "unknown", '?'};
diff --git a/lib/zclient.c b/lib/zclient.c
index 053014f86d..ba94b7fb99 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -3528,6 +3528,23 @@ stream_failure:
return -1;
}
+/* Utility to decode client close notify info */
+int zapi_client_close_notify_decode(struct stream *s,
+ struct zapi_client_close_info *info)
+{
+ memset(info, 0, sizeof(*info));
+
+ STREAM_GETC(s, info->proto);
+ STREAM_GETW(s, info->instance);
+ STREAM_GETL(s, info->session_id);
+
+ return 0;
+
+stream_failure:
+
+ return -1;
+}
+
/* Zebra client message read function. */
static int zclient_read(struct thread *thread)
{
@@ -3868,6 +3885,12 @@ static int zclient_read(struct thread *thread)
if (zclient->sr_policy_notify_status)
(*zclient->sr_policy_notify_status)(command, zclient,
length, vrf_id);
+ break;
+ case ZEBRA_CLIENT_CLOSE_NOTIFY:
+ if (zclient->zebra_client_close_notify)
+ (*zclient->zebra_client_close_notify)(command, zclient,
+ length, vrf_id);
+ break;
default:
break;
}
diff --git a/lib/zclient.h b/lib/zclient.h
index ae94237b76..33c1e732ee 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -220,6 +220,7 @@ typedef enum {
ZEBRA_OPAQUE_UNREGISTER,
ZEBRA_NEIGH_DISCOVER,
ZEBRA_ROUTE_NOTIFY_REQUEST,
+ ZEBRA_CLIENT_CLOSE_NOTIFY,
} zebra_message_types_t;
enum zebra_error_types {
@@ -377,6 +378,7 @@ struct zclient {
int (*opaque_register_handler)(ZAPI_CALLBACK_ARGS);
int (*opaque_unregister_handler)(ZAPI_CALLBACK_ARGS);
int (*sr_policy_notify_status)(ZAPI_CALLBACK_ARGS);
+ int (*zebra_client_close_notify)(ZAPI_CALLBACK_ARGS);
};
/* Zebra API message flag. */
@@ -1097,6 +1099,17 @@ zclient_send_neigh_discovery_req(struct zclient *zclient,
const struct interface *ifp,
const struct prefix *p);
+struct zapi_client_close_info {
+ /* Client session tuple */
+ uint8_t proto;
+ uint16_t instance;
+ uint32_t session_id;
+};
+
+/* Decode incoming client close notify */
+extern int zapi_client_close_notify_decode(struct stream *s,
+ struct zapi_client_close_info *info);
+
#ifdef __cplusplus
}
#endif
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index f7c123231e..c6210d14ac 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -2522,6 +2522,22 @@ int zsend_sr_policy_notify_status(uint32_t color, struct ipaddr *endpoint,
return zserv_send_message(client, s);
}
+/* Send client close notify to client */
+int zsend_client_close_notify(struct zserv *client, struct zserv *closed_client)
+{
+ struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+
+ zclient_create_header(s, ZEBRA_CLIENT_CLOSE_NOTIFY, VRF_DEFAULT);
+
+ stream_putc(s, closed_client->proto);
+ stream_putw(s, closed_client->instance);
+ stream_putl(s, closed_client->session_id);
+
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return zserv_send_message(client, s);
+}
+
/* Send response to a table manager connect request to client */
static void zread_table_manager_connect(struct zserv *client,
struct stream *msg, vrf_id_t vrf_id)
diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h
index efc52059b6..9822d72022 100644
--- a/zebra/zapi_msg.h
+++ b/zebra/zapi_msg.h
@@ -105,6 +105,9 @@ extern int zsend_sr_policy_notify_status(uint32_t color,
struct ipaddr *endpoint, char *name,
int status);
+extern int zsend_client_close_notify(struct zserv *client,
+ struct zserv *closed_client);
+
#ifdef __cplusplus
}
#endif
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 4b5791530d..c7b9433257 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -1300,6 +1300,21 @@ DEFUN (show_zebra_client_summary,
return CMD_SUCCESS;
}
+static int zserv_client_close_cb(struct zserv *closed_client)
+{
+ struct listnode *node, *nnode;
+ struct zserv *client = NULL;
+
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
+ if (client->proto == closed_client->proto)
+ continue;
+
+ zsend_client_close_notify(client, closed_client);
+ }
+
+ return 0;
+}
+
void zserv_init(void)
{
/* Client list init. */
@@ -1312,4 +1327,6 @@ void zserv_init(void)
install_element(ENABLE_NODE, &show_zebra_client_cmd);
install_element(ENABLE_NODE, &show_zebra_client_summary_cmd);
+
+ hook_register(zserv_client_close, zserv_client_close_cb);
}