/* Cluster list related functions. */
static struct cluster_list *cluster_parse(struct in_addr *pnt, int length)
{
- struct cluster_list tmp;
+ struct cluster_list tmp = {};
struct cluster_list *cluster;
tmp.length = length;
- tmp.list = pnt;
+ tmp.list = length == 0 ? NULL : pnt;
cluster = hash_get(cluster_hash, &tmp, cluster_hash_alloc);
cluster->refcnt++;
return find;
}
-void cluster_unintern(struct cluster_list *cluster)
+static void cluster_unintern(struct cluster_list **cluster)
{
- if (cluster->refcnt)
- cluster->refcnt--;
+ if ((*cluster)->refcnt)
+ (*cluster)->refcnt--;
- if (cluster->refcnt == 0) {
- hash_release(cluster_hash, cluster);
- cluster_free(cluster);
+ if ((*cluster)->refcnt == 0) {
+ void *p = hash_release(cluster_hash, *cluster);
+ assert(p == *cluster);
+ cluster_free(*cluster);
+ *cluster = NULL;
}
}
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES));
if (attr->cluster)
- cluster_unintern(attr->cluster);
+ cluster_unintern(&attr->cluster);
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST));
if (attr->transit)
/* Cluster list prototypes. */
extern bool cluster_loop_check(struct cluster_list *, struct in_addr);
-extern void cluster_unintern(struct cluster_list *);
/* Below exported for unit-test purposes only */
struct bgp_attr_parser_args {