diff options
Diffstat (limited to 'zebra/zserv.c')
| -rw-r--r-- | zebra/zserv.c | 134 |
1 files changed, 127 insertions, 7 deletions
diff --git a/zebra/zserv.c b/zebra/zserv.c index cca926f3b0..2a5352a1da 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -557,6 +557,9 @@ DEFINE_KOOH(zserv_client_close, (struct zserv *client), (client)); */ static void zserv_client_free(struct zserv *client) { + if (client == NULL) + return; + hook_call(zserv_client_close, client); /* Close file descriptor. */ @@ -565,11 +568,14 @@ static void zserv_client_free(struct zserv *client) close(client->sock); - nroutes = rib_score_proto(client->proto, client->instance); - zlog_notice( - "client %d disconnected. %lu %s routes removed from the rib", - client->sock, nroutes, - zebra_route_string(client->proto)); + if (!client->gr_instance_count) { + nroutes = rib_score_proto(client->proto, + client->instance); + zlog_notice( + "client %d disconnected %lu %s routes removed from the rib", + client->sock, nroutes, + zebra_route_string(client->proto)); + } client->sock = -1; } @@ -600,7 +606,25 @@ static void zserv_client_free(struct zserv *client) } vrf_bitmap_free(client->ridinfo); - XFREE(MTYPE_TMP, client); + /* + * If any instance are graceful restart enabled, + * client is not deleted + */ + if (!client->gr_instance_count) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s: Deleting client %s", __func__, + zebra_route_string(client->proto)); + XFREE(MTYPE_TMP, client); + } else { + /* Handle cases where client has GR instance. */ + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s: client %s restart enabled", __func__, + zebra_route_string(client->proto)); + if (zebra_gr_client_disconnect(client) < 0) + zlog_err( + "%s: GR enabled but could not handle disconnect event", + __func__); + } } void zserv_close_client(struct zserv *client) @@ -670,6 +694,7 @@ static struct zserv *zserv_client_create(int sock) pthread_mutex_init(&client->ibuf_mtx, NULL); pthread_mutex_init(&client->obuf_mtx, NULL); client->wb = buffer_new(0); + TAILQ_INIT(&(client->gr_info_queue)); atomic_store_explicit(&client->connect_time, (uint32_t) monotime(NULL), memory_order_relaxed); @@ -861,12 +886,14 @@ static char *zserv_time_buf(time_t *time1, char *buf, int buflen) return buf; } +/* Display client info details */ static void zebra_show_client_detail(struct vty *vty, struct zserv *client) { char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF]; char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF]; time_t connect_time, last_read_time, last_write_time; uint32_t last_read_cmd, last_write_cmd; + struct client_gr_info *info = NULL; vty_out(vty, "Client: %s", zebra_route_string(client->proto)); if (client->instance) @@ -945,12 +972,100 @@ static void zebra_show_client_detail(struct vty *vty, struct zserv *client) vty_out(vty, "MAC-IP add notifications: %d\n", client->macipadd_cnt); vty_out(vty, "MAC-IP delete notifications: %d\n", client->macipdel_cnt); + TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) { + vty_out(vty, "VRF : %s\n", vrf_id_to_name(info->vrf_id)); + vty_out(vty, "Capabilities : "); + switch (info->capabilities) { + case ZEBRA_CLIENT_GR_CAPABILITIES: + vty_out(vty, "Graceful Restart\n"); + break; + case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE: + case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING: + case ZEBRA_CLIENT_GR_DISABLE: + case ZEBRA_CLIENT_RIB_STALE_TIME: + vty_out(vty, "None\n"); + break; + } + } + #if defined DEV_BUILD vty_out(vty, "Input Fifo: %zu:%zu Output Fifo: %zu:%zu\n", client->ibuf_fifo->count, client->ibuf_fifo->max_count, client->obuf_fifo->count, client->obuf_fifo->max_count); #endif vty_out(vty, "\n"); +} + +/* Display stale client information */ +static void zebra_show_stale_client_detail(struct vty *vty, + struct zserv *client) +{ + char buf[PREFIX2STR_BUFFER]; + struct tm *tm; + struct timeval tv; + time_t uptime; + struct client_gr_info *info = NULL; + struct zserv *s = NULL; + + if (client->instance) + vty_out(vty, " Instance: %d", client->instance); + + TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) { + vty_out(vty, "VRF : %s\n", vrf_id_to_name(info->vrf_id)); + vty_out(vty, "Capabilities : "); + switch (info->capabilities) { + case ZEBRA_CLIENT_GR_CAPABILITIES: + vty_out(vty, "Graceful Restart\n"); + break; + case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE: + case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING: + case ZEBRA_CLIENT_GR_DISABLE: + case ZEBRA_CLIENT_RIB_STALE_TIME: + vty_out(vty, "None\n"); + break; + } + + if (ZEBRA_CLIENT_GR_ENABLED(info->capabilities)) { + if (info->stale_client_ptr) { + s = (struct zserv *)(info->stale_client_ptr); + uptime = monotime(&tv); + uptime -= s->restart_time; + tm = gmtime(&uptime); + vty_out(vty, "Last restart time : "); + if (uptime < ONE_DAY_SECOND) + vty_out(vty, "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, + tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) + vty_out(vty, "%dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, + tm->tm_min); + else + vty_out(vty, "%02dw%dd%02dh", + tm->tm_yday / 7, + tm->tm_yday - ((tm->tm_yday / 7) + * 7), + tm->tm_hour); + vty_out(vty, " ago\n"); + + vty_out(vty, "Stalepath removal time: %d sec\n", + info->stale_removal_time); + if (info->t_stale_removal) { + vty_out(vty, + "Stale delete timer: %ld sec\n", + thread_timer_remain_second( + info->t_stale_removal)); + } + } + vty_out(vty, "Current AFI : %d\n", info->current_afi); + if (info->current_prefix) { + prefix2str(info->current_prefix, buf, + sizeof(buf)); + vty_out(vty, "Current prefix : %s\n", buf); + } + } + } + vty_out(vty, "\n"); return; } @@ -1002,8 +1117,12 @@ DEFUN (show_zebra_client, struct listnode *node; struct zserv *client; - for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) { zebra_show_client_detail(vty, client); + vty_out(vty, "Stale Client Information\n"); + vty_out(vty, "------------------------\n"); + zebra_show_stale_client_detail(vty, client); + } return CMD_SUCCESS; } @@ -1047,6 +1166,7 @@ void zserv_init(void) { /* Client list init. */ zrouter.client_list = list_new(); + zrouter.stale_client_list = list_new(); /* Misc init. */ zsock = -1; |
