summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_aspath.c4
-rw-r--r--bgpd/bgp_attr.c29
-rw-r--r--bgpd/bgp_community.c4
-rw-r--r--bgpd/bgp_community_alias.c6
-rw-r--r--bgpd/bgp_ecommunity.c4
-rw-r--r--bgpd/bgp_evpn.c28
-rw-r--r--bgpd/bgp_evpn_mh.c5
-rw-r--r--bgpd/bgp_keepalives.c7
-rw-r--r--bgpd/bgp_lcommunity.c4
-rw-r--r--bgpd/bgp_mac.c3
-rw-r--r--bgpd/bgp_nexthop.c12
-rw-r--r--bgpd/bgp_pbr.c22
-rw-r--r--bgpd/bgp_route.c43
-rw-r--r--bgpd/bgp_updgrp.c9
-rw-r--r--isisd/isis_spf.c9
-rw-r--r--isisd/isis_tx_queue.c3
-rw-r--r--lib/command.c4
-rw-r--r--lib/distribute.c15
-rw-r--r--lib/ferr.c4
-rw-r--r--lib/frrscript.c6
-rw-r--r--lib/hash.c10
-rw-r--r--lib/hash.h11
-rw-r--r--lib/if_rmap.c2
-rw-r--r--lib/northbound.c3
-rw-r--r--lib/thread.c4
-rw-r--r--lib/vrf.c6
-rw-r--r--nhrpd/nhrp_peer.c7
-rw-r--r--ospf6d/ospf6_asbr.c14
-rw-r--r--ospf6d/ospf6_gr_helper.c6
-rw-r--r--ospfd/ospf_asbr.c17
-rw-r--r--ospfd/ospf_gr_helper.c4
-rw-r--r--ospfd/ospf_sr.c5
-rw-r--r--pimd/pim_instance.c6
-rw-r--r--pimd/pim_msdp.c12
-rw-r--r--pimd/pim_rp.c4
-rw-r--r--pimd/pim_vxlan.c8
-rw-r--r--tests/lib/test_srcdest_table.c3
-rw-r--r--vrrpd/vrrp.c3
-rw-r--r--zebra/zebra_l2_bridge_if.c5
-rw-r--r--zebra/zebra_mpls.c6
-rw-r--r--zebra/zebra_router.c23
-rw-r--r--zebra/zebra_vxlan_if.c5
42 files changed, 125 insertions, 260 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 55be70c3ff..2c0de43c9b 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -2095,9 +2095,7 @@ void aspath_init(void)
void aspath_finish(void)
{
- hash_clean(ashash, (void (*)(void *))aspath_free);
- hash_free(ashash);
- ashash = NULL;
+ hash_clean_and_free(&ashash, (void (*)(void *))aspath_free);
if (snmp_stream)
stream_free(snmp_stream);
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 68be9675ca..c35e45275c 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -186,9 +186,7 @@ static void cluster_init(void)
static void cluster_finish(void)
{
- hash_clean(cluster_hash, (void (*)(void *))cluster_free);
- hash_free(cluster_hash);
- cluster_hash = NULL;
+ hash_clean_and_free(&cluster_hash, (void (*)(void *))cluster_free);
}
static struct hash *encap_hash = NULL;
@@ -372,13 +370,9 @@ static void encap_init(void)
static void encap_finish(void)
{
- hash_clean(encap_hash, (void (*)(void *))encap_free);
- hash_free(encap_hash);
- encap_hash = NULL;
+ hash_clean_and_free(&encap_hash, (void (*)(void *))encap_free);
#ifdef ENABLE_BGP_VNC
- hash_clean(vnc_hash, (void (*)(void *))encap_free);
- hash_free(vnc_hash);
- vnc_hash = NULL;
+ hash_clean_and_free(&vnc_hash, (void (*)(void *))encap_free);
#endif
}
@@ -694,12 +688,9 @@ static void srv6_init(void)
static void srv6_finish(void)
{
- hash_clean(srv6_l3vpn_hash, (void (*)(void *))srv6_l3vpn_free);
- hash_free(srv6_l3vpn_hash);
- srv6_l3vpn_hash = NULL;
- hash_clean(srv6_vpn_hash, (void (*)(void *))srv6_vpn_free);
- hash_free(srv6_vpn_hash);
- srv6_vpn_hash = NULL;
+ hash_clean_and_free(&srv6_l3vpn_hash,
+ (void (*)(void *))srv6_l3vpn_free);
+ hash_clean_and_free(&srv6_vpn_hash, (void (*)(void *))srv6_vpn_free);
}
static unsigned int transit_hash_key_make(const void *p)
@@ -726,9 +717,7 @@ static void transit_init(void)
static void transit_finish(void)
{
- hash_clean(transit_hash, (void (*)(void *))transit_free);
- hash_free(transit_hash);
- transit_hash = NULL;
+ hash_clean_and_free(&transit_hash, (void (*)(void *))transit_free);
}
/* Attribute hash routines. */
@@ -881,9 +870,7 @@ static void attr_vfree(void *attr)
static void attrhash_finish(void)
{
- hash_clean(attrhash, attr_vfree);
- hash_free(attrhash);
- attrhash = NULL;
+ hash_clean_and_free(&attrhash, attr_vfree);
}
static void attr_show_all_iterator(struct hash_bucket *bucket, struct vty *vty)
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index ff6e477355..f56bfc8bdc 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -919,9 +919,7 @@ static void community_hash_free(void *data)
void community_finish(void)
{
- hash_clean(comhash, community_hash_free);
- hash_free(comhash);
- comhash = NULL;
+ hash_clean_and_free(&comhash, community_hash_free);
}
static struct community *bgp_aggr_community_lookup(
diff --git a/bgpd/bgp_community_alias.c b/bgpd/bgp_community_alias.c
index 1ebe7c4c8c..96dc1ec8f9 100644
--- a/bgpd/bgp_community_alias.c
+++ b/bgpd/bgp_community_alias.c
@@ -74,10 +74,8 @@ static void bgp_ca_free(void *ca)
void bgp_community_alias_finish(void)
{
- hash_clean(bgp_ca_community_hash, bgp_ca_free);
- hash_free(bgp_ca_community_hash);
- hash_clean(bgp_ca_alias_hash, bgp_ca_free);
- hash_free(bgp_ca_alias_hash);
+ hash_clean_and_free(&bgp_ca_community_hash, bgp_ca_free);
+ hash_clean_and_free(&bgp_ca_alias_hash, bgp_ca_free);
}
static void bgp_community_alias_show_iterator(struct hash_bucket *hb,
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index 0a4ebc5130..541da9ecd6 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -364,9 +364,7 @@ void ecommunity_init(void)
void ecommunity_finish(void)
{
- hash_clean(ecomhash, (void (*)(void *))ecommunity_hash_free);
- hash_free(ecomhash);
- ecomhash = NULL;
+ hash_clean_and_free(&ecomhash, (void (*)(void *))ecommunity_hash_free);
}
/* Extended Communities token enum. */
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 6968558681..78e96d130c 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -6650,20 +6650,20 @@ void bgp_evpn_cleanup(struct bgp *bgp)
(void (*)(struct hash_bucket *, void *))free_vni_entry,
bgp);
- hash_clean(bgp->import_rt_hash, (void (*)(void *))hash_import_rt_free);
- hash_free(bgp->import_rt_hash);
- bgp->import_rt_hash = NULL;
-
- hash_clean(bgp->vrf_import_rt_hash,
- (void (*)(void *))hash_vrf_import_rt_free);
- hash_free(bgp->vrf_import_rt_hash);
- bgp->vrf_import_rt_hash = NULL;
-
- hash_clean(bgp->vni_svi_hash, (void (*)(void *))hash_evpn_free);
- hash_free(bgp->vni_svi_hash);
- bgp->vni_svi_hash = NULL;
- hash_free(bgp->vnihash);
- bgp->vnihash = NULL;
+ hash_clean_and_free(&bgp->import_rt_hash,
+ (void (*)(void *))hash_import_rt_free);
+
+ hash_clean_and_free(&bgp->vrf_import_rt_hash,
+ (void (*)(void *))hash_vrf_import_rt_free);
+
+ hash_clean_and_free(&bgp->vni_svi_hash,
+ (void (*)(void *))hash_evpn_free);
+
+ /*
+ * Why is the vnihash freed at the top of this function and
+ * then deleted here?
+ */
+ hash_clean_and_free(&bgp->vnihash, NULL);
list_delete(&bgp->vrf_import_rtl);
list_delete(&bgp->vrf_export_rtl);
diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c
index 826793be1d..1f3dfd656e 100644
--- a/bgpd/bgp_evpn_mh.c
+++ b/bgpd/bgp_evpn_mh.c
@@ -4595,9 +4595,8 @@ void bgp_evpn_nh_finish(struct bgp *bgp_vrf)
bgp_vrf->evpn_nh_table,
(void (*)(struct hash_bucket *, void *))bgp_evpn_nh_flush_cb,
NULL);
- hash_clean(bgp_vrf->evpn_nh_table, (void (*)(void *))hash_evpn_nh_free);
- hash_free(bgp_vrf->evpn_nh_table);
- bgp_vrf->evpn_nh_table = NULL;
+ hash_clean_and_free(&bgp_vrf->evpn_nh_table,
+ (void (*)(void *))hash_evpn_nh_free);
}
static void bgp_evpn_nh_update_ref_pi(struct bgp_evpn_nh *nh)
diff --git a/bgpd/bgp_keepalives.c b/bgpd/bgp_keepalives.c
index b9e4d7c4c2..4e58773645 100644
--- a/bgpd/bgp_keepalives.c
+++ b/bgpd/bgp_keepalives.c
@@ -136,12 +136,7 @@ static unsigned int peer_hash_key(const void *arg)
/* Cleanup handler / deinitializer. */
static void bgp_keepalives_finish(void *arg)
{
- if (peerhash) {
- hash_clean(peerhash, pkat_del);
- hash_free(peerhash);
- }
-
- peerhash = NULL;
+ hash_clean_and_free(&peerhash, pkat_del);
pthread_mutex_unlock(peerhash_mtx);
pthread_mutex_destroy(peerhash_mtx);
diff --git a/bgpd/bgp_lcommunity.c b/bgpd/bgp_lcommunity.c
index 2329bcb6c6..15bf419868 100644
--- a/bgpd/bgp_lcommunity.c
+++ b/bgpd/bgp_lcommunity.c
@@ -334,9 +334,7 @@ void lcommunity_init(void)
void lcommunity_finish(void)
{
- hash_clean(lcomhash, (void (*)(void *))lcommunity_hash_free);
- hash_free(lcomhash);
- lcomhash = NULL;
+ hash_clean_and_free(&lcomhash, (void (*)(void *))lcommunity_hash_free);
}
/* Get next Large Communities token from the string.
diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c
index 5d49175e43..980f351303 100644
--- a/bgpd/bgp_mac.c
+++ b/bgpd/bgp_mac.c
@@ -64,8 +64,7 @@ static void bgp_mac_hash_free(void *data)
void bgp_mac_finish(void)
{
- hash_clean(bm->self_mac_hash, bgp_mac_hash_free);
- hash_free(bm->self_mac_hash);
+ hash_clean_and_free(&bm->self_mac_hash, bgp_mac_hash_free);
}
static void bgp_mac_hash_interface_string_del(void *val)
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 00a0bc8402..f1f6b031a9 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -166,11 +166,7 @@ void bgp_tip_hash_init(struct bgp *bgp)
void bgp_tip_hash_destroy(struct bgp *bgp)
{
- if (bgp->tip_hash == NULL)
- return;
- hash_clean(bgp->tip_hash, bgp_tip_hash_free);
- hash_free(bgp->tip_hash);
- bgp->tip_hash = NULL;
+ hash_clean_and_free(&bgp->tip_hash, bgp_tip_hash_free);
}
/* Add/Update Tunnel-IP entry of bgp martian next-hop table.
@@ -305,11 +301,7 @@ void bgp_address_init(struct bgp *bgp)
void bgp_address_destroy(struct bgp *bgp)
{
- if (bgp->address_hash == NULL)
- return;
- hash_clean(bgp->address_hash, bgp_address_hash_free);
- hash_free(bgp->address_hash);
- bgp->address_hash = NULL;
+ hash_clean_and_free(&bgp->address_hash, bgp_address_hash_free);
}
static void bgp_address_add(struct bgp *bgp, struct connected *ifc,
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index 7bced6cd33..bc9ecff7d9 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -1014,7 +1014,7 @@ static void bgp_pbr_match_free(void *arg)
bpm->action = NULL;
}
}
- hash_free(bpm->entry_hash);
+ hash_clean_and_free(&bpm->entry_hash, NULL);
XFREE(MTYPE_PBR_MATCH, bpm);
}
@@ -1386,23 +1386,13 @@ struct bgp_pbr_match *bgp_pbr_match_iptable_lookup(vrf_id_t vrf_id,
void bgp_pbr_cleanup(struct bgp *bgp)
{
- if (bgp->pbr_match_hash) {
- hash_clean(bgp->pbr_match_hash, bgp_pbr_match_free);
- hash_free(bgp->pbr_match_hash);
- bgp->pbr_match_hash = NULL;
- }
- if (bgp->pbr_rule_hash) {
- hash_clean(bgp->pbr_rule_hash, bgp_pbr_rule_free);
- hash_free(bgp->pbr_rule_hash);
- bgp->pbr_rule_hash = NULL;
- }
- if (bgp->pbr_action_hash) {
- hash_clean(bgp->pbr_action_hash, bgp_pbr_action_free);
- hash_free(bgp->pbr_action_hash);
- bgp->pbr_action_hash = NULL;
- }
+ hash_clean_and_free(&bgp->pbr_match_hash, bgp_pbr_match_free);
+ hash_clean_and_free(&bgp->pbr_rule_hash, bgp_pbr_rule_free);
+ hash_clean_and_free(&bgp->pbr_action_hash, bgp_pbr_action_free);
+
if (bgp->bgp_pbr_cfg == NULL)
return;
+
bgp_pbr_reset(bgp, AFI_IP);
bgp_pbr_reset(bgp, AFI_IP6);
XFREE(MTYPE_PBR, bgp->bgp_pbr_cfg);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 7365d53212..069aa5b923 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -8341,54 +8341,25 @@ static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
if (aggregate->community)
community_free(&aggregate->community);
- if (aggregate->community_hash) {
- /* Delete all communities in the hash.
- */
- hash_clean(aggregate->community_hash,
- bgp_aggr_community_remove);
- /* Free up the community_hash.
- */
- hash_free(aggregate->community_hash);
- }
+ hash_clean_and_free(&aggregate->community_hash,
+ bgp_aggr_community_remove);
if (aggregate->ecommunity)
ecommunity_free(&aggregate->ecommunity);
- if (aggregate->ecommunity_hash) {
- /* Delete all ecommunities in the hash.
- */
- hash_clean(aggregate->ecommunity_hash,
- bgp_aggr_ecommunity_remove);
- /* Free up the ecommunity_hash.
- */
- hash_free(aggregate->ecommunity_hash);
- }
+ hash_clean_and_free(&aggregate->ecommunity_hash,
+ bgp_aggr_ecommunity_remove);
if (aggregate->lcommunity)
lcommunity_free(&aggregate->lcommunity);
- if (aggregate->lcommunity_hash) {
- /* Delete all lcommunities in the hash.
- */
- hash_clean(aggregate->lcommunity_hash,
- bgp_aggr_lcommunity_remove);
- /* Free up the lcommunity_hash.
- */
- hash_free(aggregate->lcommunity_hash);
- }
+ hash_clean_and_free(&aggregate->lcommunity_hash,
+ bgp_aggr_lcommunity_remove);
if (aggregate->aspath)
aspath_free(aggregate->aspath);
- if (aggregate->aspath_hash) {
- /* Delete all as-paths in the hash.
- */
- hash_clean(aggregate->aspath_hash,
- bgp_aggr_aspath_remove);
- /* Free up the aspath_hash.
- */
- hash_free(aggregate->aspath_hash);
- }
+ hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
bgp_aggregate_free(aggregate);
bgp_dest_unlock_node(dest);
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index 962783b21f..204b8092e5 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -101,12 +101,9 @@ static void sync_init(struct update_subgroup *subgrp,
static void sync_delete(struct update_subgroup *subgrp)
{
XFREE(MTYPE_BGP_SYNCHRONISE, subgrp->sync);
- if (subgrp->hash) {
- hash_clean(subgrp->hash,
- (void (*)(void *))bgp_advertise_attr_free);
- hash_free(subgrp->hash);
- }
- subgrp->hash = NULL;
+ hash_clean_and_free(&subgrp->hash,
+ (void (*)(void *))bgp_advertise_attr_free);
+
if (subgrp->work)
stream_free(subgrp->work);
subgrp->work = NULL;
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index e1aec683d8..9229f0a77d 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -241,11 +241,7 @@ void isis_vertex_del(struct isis_vertex *vertex)
{
list_delete(&vertex->Adj_N);
list_delete(&vertex->parents);
- if (vertex->firsthops) {
- hash_clean(vertex->firsthops, NULL);
- hash_free(vertex->firsthops);
- vertex->firsthops = NULL;
- }
+ hash_clean_and_free(&vertex->firsthops, NULL);
memset(vertex, 0, sizeof(struct isis_vertex));
XFREE(MTYPE_ISIS_VERTEX, vertex);
@@ -371,8 +367,7 @@ struct isis_spftree *isis_spftree_new(struct isis_area *area,
void isis_spftree_del(struct isis_spftree *spftree)
{
- hash_clean(spftree->prefix_sids, NULL);
- hash_free(spftree->prefix_sids);
+ hash_clean_and_free(&spftree->prefix_sids, NULL);
isis_zebra_rlfa_unregister_all(spftree);
isis_rlfa_list_clear(spftree);
list_delete(&spftree->lfa.remote.pc_spftrees);
diff --git a/isisd/isis_tx_queue.c b/isisd/isis_tx_queue.c
index ad91059766..eada0d5521 100644
--- a/isisd/isis_tx_queue.c
+++ b/isisd/isis_tx_queue.c
@@ -86,8 +86,7 @@ static void tx_queue_element_free(void *element)
void isis_tx_queue_free(struct isis_tx_queue *queue)
{
- hash_clean(queue->hash, tx_queue_element_free);
- hash_free(queue->hash);
+ hash_clean_and_free(&queue->hash, tx_queue_element_free);
XFREE(MTYPE_TX_QUEUE, queue);
}
diff --git a/lib/command.c b/lib/command.c
index ee5a3889e8..196d73d46a 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -2596,9 +2596,7 @@ void cmd_terminate(void)
// well
graph_delete_graph(cmd_node->cmdgraph);
vector_free(cmd_node->cmd_vector);
- hash_clean(cmd_node->cmd_hash, NULL);
- hash_free(cmd_node->cmd_hash);
- cmd_node->cmd_hash = NULL;
+ hash_clean_and_free(&cmd_node->cmd_hash, NULL);
}
vector_free(cmdvec);
diff --git a/lib/distribute.c b/lib/distribute.c
index 4cfdcc7840..65487676d6 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -445,14 +445,15 @@ int config_write_distribute(struct vty *vty,
void distribute_list_delete(struct distribute_ctx **ctx)
{
- if ((*ctx)->disthash) {
- hash_clean((*ctx)->disthash, (void (*)(void *))distribute_free);
+ hash_clean_and_free(&(*ctx)->disthash,
+ (void (*)(void *))distribute_free);
+
+ if (dist_ctx_list) {
+ listnode_delete(dist_ctx_list, *ctx);
+ if (list_isempty(dist_ctx_list))
+ list_delete(&dist_ctx_list);
}
- if (!dist_ctx_list)
- dist_ctx_list = list_new();
- listnode_delete(dist_ctx_list, *ctx);
- if (list_isempty(dist_ctx_list))
- list_delete(&dist_ctx_list);
+
XFREE(MTYPE_DISTRIBUTE_CTX, (*ctx));
}
diff --git a/lib/ferr.c b/lib/ferr.c
index 5998befec2..33bcb075fa 100644
--- a/lib/ferr.c
+++ b/lib/ferr.c
@@ -180,9 +180,7 @@ void log_ref_init(void)
void log_ref_fini(void)
{
frr_with_mutex (&refs_mtx) {
- hash_clean(refs, NULL);
- hash_free(refs);
- refs = NULL;
+ hash_clean_and_free(&refs, NULL);
}
}
diff --git a/lib/frrscript.c b/lib/frrscript.c
index 4248a45002..1b99c7e2c6 100644
--- a/lib/frrscript.c
+++ b/lib/frrscript.c
@@ -398,8 +398,7 @@ fail:
void frrscript_delete(struct frrscript *fs)
{
- hash_clean(fs->lua_function_hash, lua_function_free);
- hash_free(fs->lua_function_hash);
+ hash_clean_and_free(&fs->lua_function_hash, lua_function_free);
XFREE(MTYPE_SCRIPT, fs->name);
XFREE(MTYPE_SCRIPT, fs);
}
@@ -417,8 +416,7 @@ void frrscript_init(const char *sd)
void frrscript_fini(void)
{
- hash_clean(codec_hash, codec_free);
- hash_free(codec_hash);
+ hash_clean_and_free(&codec_hash, codec_free);
frrscript_names_destroy();
}
diff --git a/lib/hash.c b/lib/hash.c
index 97a77a2b9a..df56243985 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -297,6 +297,16 @@ void hash_clean(struct hash *hash, void (*free_func)(void *))
hash->stats.empty = hash->size;
}
+void hash_clean_and_free(struct hash **hash, void (*free_func)(void *))
+{
+ if (!*hash)
+ return;
+
+ hash_clean(*hash, free_func);
+ hash_free(*hash);
+ *hash = NULL;
+}
+
static void hash_to_list_iter(struct hash_bucket *hb, void *arg)
{
struct list *list = arg;
diff --git a/lib/hash.h b/lib/hash.h
index f32309d804..810faf9030 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -278,6 +278,17 @@ extern void hash_walk(struct hash *hash,
extern void hash_clean(struct hash *hash, void (*free_func)(void *));
/*
+ * Remove all elements from a hash table and free the table,
+ * setting the pointer to NULL.
+ *
+ * hash
+ * hash table to operate on
+ * free_func
+ * function to call with each removed item, intended to free the data
+ */
+extern void hash_clean_and_free(struct hash **hash, void (*free_func)(void *));
+
+/*
* Delete a hash table.
*
* This function assumes the table is empty. Call hash_clean to delete the
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index fa8899e9f8..27c41aaa27 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -276,7 +276,7 @@ int config_write_if_rmap(struct vty *vty,
void if_rmap_ctx_delete(struct if_rmap_ctx *ctx)
{
listnode_delete(if_rmap_ctx_list, ctx);
- hash_clean(ctx->ifrmaphash, (void (*)(void *))if_rmap_free);
+ hash_clean_and_free(&ctx->ifrmaphash, (void (*)(void *))if_rmap_free);
if (ctx->name)
XFREE(MTYPE_IF_RMAP_CTX_NAME, ctx);
XFREE(MTYPE_IF_RMAP_CTX, ctx);
diff --git a/lib/northbound.c b/lib/northbound.c
index 6f2c522a29..b208e45d62 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -2498,8 +2498,7 @@ void nb_terminate(void)
nb_nodes_delete();
/* Delete the running configuration. */
- hash_clean(running_config_entries, running_config_entry_free);
- hash_free(running_config_entries);
+ hash_clean_and_free(&running_config_entries, running_config_entry_free);
nb_config_free(running_config);
pthread_mutex_destroy(&running_config_mgmt_lock.mtx);
}
diff --git a/lib/thread.c b/lib/thread.c
index 8324783a7b..87ad3d8823 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -724,9 +724,7 @@ void thread_master_free(struct thread_master *m)
list_delete(&m->cancel_req);
m->cancel_req = NULL;
- hash_clean(m->cpu_record, cpu_record_hash_free);
- hash_free(m->cpu_record);
- m->cpu_record = NULL;
+ hash_clean_and_free(&m->cpu_record, cpu_record_hash_free);
XFREE(MTYPE_THREAD_MASTER, m->name);
XFREE(MTYPE_THREAD_MASTER, m->handler.pfds);
diff --git a/lib/vrf.c b/lib/vrf.c
index a60f532f41..73f5d8ff72 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -394,11 +394,7 @@ void vrf_bitmap_free(vrf_bitmap_t bmap)
{
struct hash *vrf_hash = bmap;
- if (vrf_hash == NULL)
- return;
-
- hash_clean(vrf_hash, vrf_hash_bitmap_free);
- hash_free(vrf_hash);
+ hash_clean_and_free(&vrf_hash, vrf_hash_bitmap_free);
}
void vrf_bitmap_set(vrf_bitmap_t bmap, vrf_id_t vrf_id)
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index 0c9d5ade37..9b92cdffc3 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -201,12 +201,7 @@ void nhrp_peer_interface_del(struct interface *ifp)
debugf(NHRP_DEBUG_COMMON, "Cleaning up undeleted peer entries (%lu)",
nifp->peer_hash ? nifp->peer_hash->count : 0);
- if (nifp->peer_hash) {
- hash_clean(nifp->peer_hash, do_peer_hash_free);
- assert(nifp->peer_hash->count == 0);
- hash_free(nifp->peer_hash);
- nifp->peer_hash = NULL;
- }
+ hash_clean_and_free(&nifp->peer_hash, do_peer_hash_free);
}
struct nhrp_peer *nhrp_peer_get(struct interface *ifp,
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index b2cdbc9b57..57c873b53b 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -3133,11 +3133,9 @@ static void ospf6_handle_external_aggr_update(struct ospf6 *ospf6)
aggr->action = OSPF6_ROUTE_AGGR_NONE;
ospf6_asbr_summary_config_delete(ospf6, rn);
- if (OSPF6_EXTERNAL_RT_COUNT(aggr))
- hash_clean(aggr->match_extnl_hash,
- ospf6_aggr_handle_external_info);
+ hash_clean_and_free(&aggr->match_extnl_hash,
+ ospf6_aggr_handle_external_info);
- hash_free(aggr->match_extnl_hash);
XFREE(MTYPE_OSPF6_EXTERNAL_RT_AGGR, aggr);
} else if (aggr->action == OSPF6_ROUTE_AGGR_MODIFY) {
@@ -3175,18 +3173,14 @@ static void ospf6_aggr_unlink_external_info(void *data)
void ospf6_external_aggregator_free(struct ospf6_external_aggr_rt *aggr)
{
- if (OSPF6_EXTERNAL_RT_COUNT(aggr))
- hash_clean(aggr->match_extnl_hash,
- ospf6_aggr_unlink_external_info);
+ hash_clean_and_free(&aggr->match_extnl_hash,
+ ospf6_aggr_unlink_external_info);
if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: Release the aggregator Address(%pFX)",
__func__,
&aggr->p);
- hash_free(aggr->match_extnl_hash);
- aggr->match_extnl_hash = NULL;
-
XFREE(MTYPE_OSPF6_EXTERNAL_RT_AGGR, aggr);
}
diff --git a/ospf6d/ospf6_gr_helper.c b/ospf6d/ospf6_gr_helper.c
index bf570a0b2d..3df0580fcd 100644
--- a/ospf6d/ospf6_gr_helper.c
+++ b/ospf6d/ospf6_gr_helper.c
@@ -110,10 +110,8 @@ static void ospf6_enable_rtr_hash_destroy(struct ospf6 *ospf6)
if (ospf6->ospf6_helper_cfg.enable_rtr_list == NULL)
return;
- hash_clean(ospf6->ospf6_helper_cfg.enable_rtr_list,
- ospf6_disable_rtr_hash_free);
- hash_free(ospf6->ospf6_helper_cfg.enable_rtr_list);
- ospf6->ospf6_helper_cfg.enable_rtr_list = NULL;
+ hash_clean_and_free(&ospf6->ospf6_helper_cfg.enable_rtr_list,
+ ospf6_disable_rtr_hash_free);
}
/*
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index 5b5367811b..6eada0b1a4 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -450,15 +450,12 @@ static void ospf_aggr_unlink_external_info(void *data)
void ospf_external_aggregator_free(struct ospf_external_aggr_rt *aggr)
{
- if (OSPF_EXTERNAL_RT_COUNT(aggr))
- hash_clean(aggr->match_extnl_hash,
- (void *)ospf_aggr_unlink_external_info);
+ hash_clean_and_free(&aggr->match_extnl_hash,
+ (void *)ospf_aggr_unlink_external_info);
if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
zlog_debug("%s: Release the aggregator Address(%pI4/%d)",
__func__, &aggr->p.prefix, aggr->p.prefixlen);
- hash_free(aggr->match_extnl_hash);
- aggr->match_extnl_hash = NULL;
XFREE(MTYPE_OSPF_EXTERNAL_RT_AGGR, aggr);
}
@@ -983,13 +980,9 @@ static void ospf_handle_external_aggr_update(struct ospf *ospf)
aggr->action = OSPF_ROUTE_AGGR_NONE;
ospf_external_aggr_delete(ospf, rn);
- if (OSPF_EXTERNAL_RT_COUNT(aggr))
- hash_clean(
- aggr->match_extnl_hash,
- (void *)ospf_aggr_handle_external_info);
-
- hash_free(aggr->match_extnl_hash);
- XFREE(MTYPE_OSPF_EXTERNAL_RT_AGGR, aggr);
+ hash_clean_and_free(
+ &aggr->match_extnl_hash,
+ (void *)ospf_aggr_handle_external_info);
} else if (aggr->action == OSPF_ROUTE_AGGR_MODIFY) {
diff --git a/ospfd/ospf_gr_helper.c b/ospfd/ospf_gr_helper.c
index 0263df48c5..07ce0d66ea 100644
--- a/ospfd/ospf_gr_helper.c
+++ b/ospfd/ospf_gr_helper.c
@@ -99,9 +99,7 @@ static void ospf_enable_rtr_hash_destroy(struct ospf *ospf)
if (ospf->enable_rtr_list == NULL)
return;
- hash_clean(ospf->enable_rtr_list, ospf_disable_rtr_hash_free);
- hash_free(ospf->enable_rtr_list);
- ospf->enable_rtr_list = NULL;
+ hash_clean_and_free(&ospf->enable_rtr_list, ospf_disable_rtr_hash_free);
}
/*
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index adb14ec6b1..d1af08c652 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -639,10 +639,7 @@ void ospf_sr_term(void)
/* Stop Segment Routing */
ospf_sr_stop();
- /* Clear SR Node Table */
- if (OspfSR.neighbors)
- hash_free(OspfSR.neighbors);
-
+ hash_clean_and_free(&OspfSR.neighbors, (void *)sr_node_del);
}
/*
diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c
index b50d9954f7..6f33af0601 100644
--- a/pimd/pim_instance.c
+++ b/pimd/pim_instance.c
@@ -45,11 +45,7 @@ static void pim_instance_terminate(struct pim_instance *pim)
pim_bsm_proc_free(pim);
/* Traverse and cleanup rpf_hash */
- if (pim->rpf_hash) {
- hash_clean(pim->rpf_hash, (void *)pim_rp_list_hash_clean);
- hash_free(pim->rpf_hash);
- pim->rpf_hash = NULL;
- }
+ hash_clean_and_free(&pim->rpf_hash, (void *)pim_rp_list_hash_clean);
pim_if_terminate(pim);
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index dfa5ffeeec..9d29a33a52 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -1367,21 +1367,13 @@ void pim_msdp_exit(struct pim_instance *pim)
while ((mg = SLIST_FIRST(&pim->msdp.mglist)) != NULL)
pim_msdp_mg_free(pim, &mg);
- if (pim->msdp.peer_hash) {
- hash_clean(pim->msdp.peer_hash, NULL);
- hash_free(pim->msdp.peer_hash);
- pim->msdp.peer_hash = NULL;
- }
+ hash_clean_and_free(&pim->msdp.peer_hash, NULL);
if (pim->msdp.peer_list) {
list_delete(&pim->msdp.peer_list);
}
- if (pim->msdp.sa_hash) {
- hash_clean(pim->msdp.sa_hash, NULL);
- hash_free(pim->msdp.sa_hash);
- pim->msdp.sa_hash = NULL;
- }
+ hash_clean_and_free(&pim->msdp.sa_hash, NULL);
if (pim->msdp.sa_list) {
list_delete(&pim->msdp.sa_list);
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index e2ee6656d1..c7516242f5 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -47,9 +47,7 @@ void pim_rp_list_hash_clean(void *data)
list_delete(&pnc->rp_list);
- hash_clean(pnc->upstream_hash, NULL);
- hash_free(pnc->upstream_hash);
- pnc->upstream_hash = NULL;
+ hash_clean_and_free(&pnc->upstream_hash, NULL);
if (pnc->nexthop)
nexthops_free(pnc->nexthop);
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c
index 4c317a2546..91ec9d69a2 100644
--- a/pimd/pim_vxlan.c
+++ b/pimd/pim_vxlan.c
@@ -1172,12 +1172,8 @@ void pim_vxlan_init(struct pim_instance *pim)
void pim_vxlan_exit(struct pim_instance *pim)
{
- if (pim->vxlan.sg_hash) {
- hash_clean(pim->vxlan.sg_hash,
- (void (*)(void *))pim_vxlan_sg_del_item);
- hash_free(pim->vxlan.sg_hash);
- pim->vxlan.sg_hash = NULL;
- }
+ hash_clean_and_free(&pim->vxlan.sg_hash,
+ (void (*)(void *))pim_vxlan_sg_del_item);
}
void pim_vxlan_terminate(void)
diff --git a/tests/lib/test_srcdest_table.c b/tests/lib/test_srcdest_table.c
index de0482d694..c1235fe857 100644
--- a/tests/lib/test_srcdest_table.c
+++ b/tests/lib/test_srcdest_table.c
@@ -121,8 +121,7 @@ static struct test_state *test_state_new(void)
static void test_state_free(struct test_state *test)
{
route_table_finish(test->table);
- hash_clean(test->log, log_free);
- hash_free(test->log);
+ hash_clean_and_free(&test->log, log_free);
XFREE(MTYPE_TMP, test);
}
diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c
index 5bb1d6911c..1d934f616b 100644
--- a/vrrpd/vrrp.c
+++ b/vrrpd/vrrp.c
@@ -2411,6 +2411,5 @@ void vrrp_fini(void)
list_delete(&vrs);
- hash_clean(vrrp_vrouters_hash, NULL);
- hash_free(vrrp_vrouters_hash);
+ hash_clean_and_free(&vrrp_vrouters_hash, NULL);
}
diff --git a/zebra/zebra_l2_bridge_if.c b/zebra/zebra_l2_bridge_if.c
index b85d39bcd6..00450ddd36 100644
--- a/zebra/zebra_l2_bridge_if.c
+++ b/zebra/zebra_l2_bridge_if.c
@@ -142,10 +142,7 @@ static void *zebra_l2_bridge_vlan_alloc(void *p)
static void zebra_l2_bridge_vlan_table_destroy(struct hash *vlan_table)
{
- if (vlan_table) {
- hash_clean(vlan_table, zebra_l2_bridge_vlan_free);
- hash_free(vlan_table);
- }
+ hash_clean_and_free(&vlan_table, zebra_l2_bridge_vlan_free);
}
static struct hash *zebra_l2_bridge_vlan_table_create(void)
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 4c2d546126..4aaf6f25af 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -4058,10 +4058,8 @@ static void lsp_table_free(void *p)
void zebra_mpls_close_tables(struct zebra_vrf *zvrf)
{
hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL);
- hash_clean(zvrf->lsp_table, lsp_table_free);
- hash_free(zvrf->lsp_table);
- hash_clean(zvrf->slsp_table, lsp_table_free);
- hash_free(zvrf->slsp_table);
+ hash_clean_and_free(&zvrf->lsp_table, lsp_table_free);
+ hash_clean_and_free(&zvrf->slsp_table, lsp_table_free);
route_table_finish(zvrf->fec_table[AFI_IP]);
route_table_finish(zvrf->fec_table[AFI_IP6]);
}
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index 21e09a81f7..787442f5c8 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -232,20 +232,15 @@ void zebra_router_terminate(void)
/* Free NHE in ID table only since it has unhashable entries as well */
hash_iterate(zrouter.nhgs_id, zebra_nhg_hash_free_zero_id, NULL);
- hash_clean(zrouter.nhgs_id, zebra_nhg_hash_free);
- hash_free(zrouter.nhgs_id);
- hash_clean(zrouter.nhgs, NULL);
- hash_free(zrouter.nhgs);
-
- hash_clean(zrouter.rules_hash, zebra_pbr_rules_free);
- hash_free(zrouter.rules_hash);
-
- hash_clean(zrouter.ipset_entry_hash, zebra_pbr_ipset_entry_free),
- hash_clean(zrouter.ipset_hash, zebra_pbr_ipset_free);
- hash_free(zrouter.ipset_hash);
- hash_free(zrouter.ipset_entry_hash);
- hash_clean(zrouter.iptable_hash, zebra_pbr_iptable_free);
- hash_free(zrouter.iptable_hash);
+ hash_clean_and_free(&zrouter.nhgs_id, zebra_nhg_hash_free);
+ hash_clean_and_free(&zrouter.nhgs, NULL);
+
+ hash_clean_and_free(&zrouter.rules_hash, zebra_pbr_rules_free);
+
+ hash_clean_and_free(&zrouter.ipset_entry_hash,
+ zebra_pbr_ipset_entry_free);
+ hash_clean_and_free(&zrouter.ipset_hash, zebra_pbr_ipset_free);
+ hash_clean_and_free(&zrouter.iptable_hash, zebra_pbr_iptable_free);
#ifdef HAVE_SCRIPTING
zebra_script_destroy();
diff --git a/zebra/zebra_vxlan_if.c b/zebra/zebra_vxlan_if.c
index 08e07b60a2..3cc7e499bf 100644
--- a/zebra/zebra_vxlan_if.c
+++ b/zebra/zebra_vxlan_if.c
@@ -610,10 +610,7 @@ struct hash *zebra_vxlan_vni_table_create(void)
void zebra_vxlan_vni_table_destroy(struct hash *vni_table)
{
- if (vni_table) {
- hash_clean(vni_table, zebra_vxlan_vni_free);
- hash_free(vni_table);
- }
+ hash_clean_and_free(&vni_table, zebra_vxlan_vni_free);
}
int zebra_vxlan_if_vni_table_destroy(struct zebra_if *zif)