From: Donald Sharp Date: Tue, 21 Mar 2023 12:54:21 +0000 (-0400) Subject: *: Add a hash_clean_and_free() function X-Git-Tag: base_9.0~272^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=d8bc11a592110abdd14d11dfcb2ce623653ecab5;p=mirror%2Ffrr.git *: Add a hash_clean_and_free() function Add a hash_clean_and_free() function as well as convert the code to use it. This function also takes a double pointer to the hash to set it NULL. Also it cleanly does nothing if the pointer is NULL( as a bunch of code tested for ). Signed-off-by: Donald Sharp --- 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 @@ -277,6 +277,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. * 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)