diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index c75ff7b4cd..9abd3139fd 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -105,20 +105,6 @@ uint8_t nexthop_group_active_nexthop_num(const struct nexthop_group *nhg) return num; } -uint8_t -nexthop_group_active_nexthop_num_no_recurse(const struct nexthop_group *nhg) -{ - struct nexthop *nhop; - uint8_t num = 0; - - for (nhop = nhg->nexthop; nhop; nhop = nhop->next) { - if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_ACTIVE)) - num++; - } - - return num; -} - bool nexthop_group_has_label(const struct nexthop_group *nhg) { struct nexthop *nhop; @@ -1248,9 +1234,9 @@ void nexthop_group_disable_vrf(struct vrf *vrf) struct nexthop_hold *nhh; RB_FOREACH (nhgc, nhgc_entry_head, &nhgc_entries) { - struct listnode *node; + struct listnode *node, *nnode; - for (ALL_LIST_ELEMENTS_RO(nhgc->nhg_list, node, nhh)) { + for (ALL_LIST_ELEMENTS(nhgc->nhg_list, node, nnode, nhh)) { struct nexthop nhop; struct nexthop *nh; @@ -1271,6 +1257,8 @@ void nexthop_group_disable_vrf(struct vrf *vrf) nhg_hooks.del_nexthop(nhgc, nh); nexthop_free(nh); + + list_delete_node(nhgc->nhg_list, node); } } } diff --git a/lib/nexthop_group.h b/lib/nexthop_group.h index 78237e464f..88f9c62ccb 100644 --- a/lib/nexthop_group.h +++ b/lib/nexthop_group.h @@ -154,8 +154,6 @@ extern uint8_t nexthop_group_nexthop_num_no_recurse(const struct nexthop_group *nhg); extern uint8_t nexthop_group_active_nexthop_num(const struct nexthop_group *nhg); -extern uint8_t -nexthop_group_active_nexthop_num_no_recurse(const struct nexthop_group *nhg); extern bool nexthop_group_has_label(const struct nexthop_group *nhg); diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index aa720bacf2..9ff6ba99b6 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -563,9 +563,15 @@ void nhg_add(uint32_t id, const struct nexthop_group *nhg, } if (api_nhg.nexthop_num == 0) { - zlog_debug("%s: nhg %u not sent: no valid nexthops", __func__, - id); - is_valid = false; + if (sharp_nhgroup_id_is_installed(id)) { + zlog_debug("%s: nhg %u: no nexthops, deleting nexthop group", __func__, + id); + zclient_nhg_send(zclient, ZEBRA_NHG_DEL, &api_nhg); + } else { + zlog_debug("%s: nhg %u not sent: no valid nexthops", __func__, + id); + is_valid = false; + } goto done; } diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 477119d1ed..68b89454a5 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2624,7 +2624,7 @@ static bool _netlink_nexthop_build_group(struct nlmsghdr *n, size_t req_size, if (IS_ZEBRA_DEBUG_KERNEL) { if (i == 0) - snprintf(buf, sizeof(buf1), "group %u", + snprintf(buf, sizeof(buf), "group %u", grp[i].id); else { snprintf(buf1, sizeof(buf1), "/%u", diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 98268dafa6..f7293d8f0f 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1973,6 +1973,8 @@ static void zread_nhg_del(ZAPI_HANDLER_ARGS) zsend_nhg_notify(api_nhg.proto, client->instance, client->session_id, api_nhg.id, ZAPI_NHG_REMOVE_FAIL); + /* Stats */ + client->nhg_del_cnt++; } static void zread_nhg_add(ZAPI_HANDLER_ARGS) @@ -1981,7 +1983,7 @@ static void zread_nhg_add(ZAPI_HANDLER_ARGS) struct zapi_nhg api_nhg = {}; struct nexthop_group *nhg = NULL; struct nhg_backup_info *bnhg = NULL; - struct nhg_hash_entry *nhe; + struct nhg_hash_entry *nhe, *nhe_tmp; s = msg; if (zapi_nhg_decode(s, hdr->command, &api_nhg) < 0) { @@ -2039,6 +2041,12 @@ static void zread_nhg_add(ZAPI_HANDLER_ARGS) nexthop_group_delete(&nhg); zebra_nhg_backup_free(&bnhg); + /* Stats */ + nhe_tmp = zebra_nhg_lookup_id(api_nhg.id); + if (nhe_tmp) + client->nhg_upd8_cnt++; + else + client->nhg_add_cnt++; } static void zread_route_add(ZAPI_HANDLER_ARGS) diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index c38203df0f..c172f18cf1 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1526,7 +1526,13 @@ zebra_nhg_rib_find_nhe(struct nhg_hash_entry *rt_nhe, afi_t rt_afi) { struct nhg_hash_entry *nhe = NULL; - if (!(rt_nhe && rt_nhe->nhg.nexthop)) { + if (!rt_nhe) { + flog_err(EC_ZEBRA_TABLE_LOOKUP_FAILED, + "No nhg_hash_entry passed to %s", __func__); + return NULL; + } + + if (!rt_nhe->nhg.nexthop) { flog_err(EC_ZEBRA_TABLE_LOOKUP_FAILED, "No nexthop passed to %s", __func__); return NULL; diff --git a/zebra/zserv.c b/zebra/zserv.c index 2db228b158..1d3989dc73 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1061,6 +1061,8 @@ static void zebra_show_client_detail(struct vty *vty, struct zserv *client) 0, client->redist_v4_del_cnt); vty_out(vty, "Redist:v6 %-12u%-12u%-12u\n", client->redist_v6_add_cnt, 0, client->redist_v6_del_cnt); + vty_out(vty, "NHG %-12u%-12u%-12u\n", client->nhg_add_cnt, + client->nhg_upd8_cnt, client->nhg_del_cnt); vty_out(vty, "VRF %-12u%-12u%-12u\n", client->vrfadd_cnt, 0, client->vrfdel_cnt); vty_out(vty, "Connected %-12u%-12u%-12u\n", client->ifadd_cnt, 0, diff --git a/zebra/zserv.h b/zebra/zserv.h index 90aa4d53f4..631145e4fb 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -185,6 +185,9 @@ struct zserv { uint32_t local_es_evi_add_cnt; uint32_t local_es_evi_del_cnt; uint32_t error_cnt; + uint32_t nhg_add_cnt; + uint32_t nhg_upd8_cnt; + uint32_t nhg_del_cnt; time_t nh_reg_time; time_t nh_dereg_time;