mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-01 17:59:27 +00:00
zebra: plug more memory leaks
Try to free all memory explicitly on exit. This should help to detect new memory leaks in the future with tools like valgrind. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
2414ffe50c
commit
5a8dfcd891
18
zebra/main.c
18
zebra/main.c
@ -182,17 +182,27 @@ sighup (void)
|
||||
static void
|
||||
sigint (void)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
struct zebra_ns *zns;
|
||||
|
||||
zlog_notice ("Terminating on signal");
|
||||
|
||||
if (!retain_mode)
|
||||
rib_close ();
|
||||
#ifdef HAVE_IRDP
|
||||
irdp_finish();
|
||||
#endif
|
||||
|
||||
zebra_ptm_finish();
|
||||
list_delete_all_node (zebrad.client_list);
|
||||
|
||||
if (retain_mode)
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
zvrf = vrf->info;
|
||||
if (zvrf)
|
||||
SET_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN);
|
||||
}
|
||||
vrf_terminate ();
|
||||
|
||||
zns = zebra_ns_lookup (NS_DEFAULT);
|
||||
zebra_ns_disable (0, (void **)&zns);
|
||||
@ -204,6 +214,10 @@ sigint (void)
|
||||
vty_terminate ();
|
||||
zprivs_terminate (&zserv_privs);
|
||||
list_delete (zebrad.client_list);
|
||||
work_queue_free (zebrad.ribq);
|
||||
if (zebrad.lsp_process_q)
|
||||
work_queue_free (zebrad.lsp_process_q);
|
||||
meta_queue_free (zebrad.mq);
|
||||
thread_master_free (zebrad.master);
|
||||
if (zlog_default)
|
||||
closezlog (zlog_default);
|
||||
|
@ -366,13 +366,14 @@ extern void rib_update (vrf_id_t, rib_update_event_t);
|
||||
extern void rib_weed_tables (void);
|
||||
extern void rib_sweep_route (void);
|
||||
extern void rib_close_table (struct route_table *);
|
||||
extern void rib_close (void);
|
||||
extern void rib_init (void);
|
||||
extern unsigned long rib_score_proto (u_char proto, u_short instance);
|
||||
extern void rib_queue_add (struct route_node *rn);
|
||||
extern void meta_queue_free (struct meta_queue *mq);
|
||||
|
||||
extern struct route_table *rib_table_ipv6;
|
||||
|
||||
extern void rib_unlink (struct route_node *, struct rib *);
|
||||
extern int rib_gc_dest (struct route_node *rn);
|
||||
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);
|
||||
|
||||
|
@ -1304,8 +1304,6 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
|
||||
}
|
||||
}
|
||||
|
||||
static void rib_unlink (struct route_node *, struct rib *);
|
||||
|
||||
/*
|
||||
* rib_can_delete_dest
|
||||
*
|
||||
@ -2216,6 +2214,17 @@ meta_queue_new (void)
|
||||
return new;
|
||||
}
|
||||
|
||||
void
|
||||
meta_queue_free (struct meta_queue *mq)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < MQ_SIZE; i++)
|
||||
list_delete (mq->subq[i]);
|
||||
|
||||
XFREE (MTYPE_WORK_QUEUE, mq);
|
||||
}
|
||||
|
||||
/* initialise zebra rib work queue */
|
||||
static void
|
||||
rib_queue_init (struct zebra_t *zebra)
|
||||
@ -2351,7 +2360,7 @@ rib_addnode (struct route_node *rn, struct rib *rib, int process)
|
||||
* rib_gc_dest() at some point. This allows a rib_dest_t that is no
|
||||
* longer required to be deleted.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
rib_unlink (struct route_node *rn, struct rib *rib)
|
||||
{
|
||||
rib_dest_t *dest;
|
||||
@ -3153,43 +3162,6 @@ rib_close_table (struct route_table *table)
|
||||
}
|
||||
}
|
||||
|
||||
/* Close all RIB tables. */
|
||||
void
|
||||
rib_close (void)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
struct listnode *node;
|
||||
struct interface *ifp;
|
||||
u_int32_t table_id;
|
||||
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
{
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
{
|
||||
rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||
rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||
}
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
|
||||
}
|
||||
|
||||
/* If we do multiple tables per vrf, need to move this to loop above */
|
||||
zvrf = vrf_info_lookup (VRF_DEFAULT);
|
||||
|
||||
for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
|
||||
{
|
||||
if (zvrf->other_table[AFI_IP][table_id])
|
||||
rib_close_table (zvrf->other_table[AFI_IP][table_id]);
|
||||
|
||||
if (zvrf->other_table[AFI_IP6][table_id])
|
||||
rib_close_table (zvrf->other_table[AFI_IP6][table_id]);
|
||||
}
|
||||
|
||||
zebra_mpls_close_tables(zvrf);
|
||||
|
||||
}
|
||||
|
||||
/* Routing information base initialize. */
|
||||
void
|
||||
rib_init (void)
|
||||
|
@ -163,6 +163,16 @@ zebra_lookup_rnh (struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
|
||||
return (rn->info);
|
||||
}
|
||||
|
||||
void
|
||||
zebra_free_rnh (struct rnh *rnh)
|
||||
{
|
||||
rnh->flags |= ZEBRA_NHT_DELETED;
|
||||
list_free (rnh->client_list);
|
||||
list_free (rnh->zebra_static_route_list);
|
||||
free_state (rnh->vrf_id, rnh->state, rnh->node);
|
||||
XFREE (MTYPE_RNH, rnh);
|
||||
}
|
||||
|
||||
void
|
||||
zebra_delete_rnh (struct rnh *rnh, rnh_type_t type)
|
||||
{
|
||||
@ -178,14 +188,9 @@ zebra_delete_rnh (struct rnh *rnh, rnh_type_t type)
|
||||
rnh->vrf_id, rnh_str(rnh, buf, sizeof (buf)), type);
|
||||
}
|
||||
|
||||
rnh->flags |= ZEBRA_NHT_DELETED;
|
||||
list_free(rnh->client_list);
|
||||
list_free(rnh->zebra_static_route_list);
|
||||
free_state(rnh->vrf_id, rnh->state, rn);
|
||||
XFREE(MTYPE_RNH, rn->info);
|
||||
zebra_free_rnh (rnh);
|
||||
rn->info = NULL;
|
||||
route_unlock_node (rn);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -59,6 +59,7 @@ extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid,
|
||||
rnh_type_t type);
|
||||
extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,
|
||||
rnh_type_t type);
|
||||
extern void zebra_free_rnh (struct rnh *rnh);
|
||||
extern void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type);
|
||||
extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
|
||||
vrf_id_t vrfid);
|
||||
|
@ -26,6 +26,10 @@
|
||||
int zebra_rnh_ip_default_route = 0;
|
||||
int zebra_rnh_ipv6_default_route = 0;
|
||||
|
||||
void
|
||||
zebra_free_rnh (struct rnh *rnh)
|
||||
{}
|
||||
|
||||
void zebra_evaluate_rnh (vrf_id_t vrfid, int family, int force, rnh_type_t type,
|
||||
struct prefix *p)
|
||||
{}
|
||||
|
@ -30,9 +30,11 @@
|
||||
#include "zebra/zserv.h"
|
||||
#include "zebra/rib.h"
|
||||
#include "zebra/zebra_vrf.h"
|
||||
#include "zebra/zebra_rnh.h"
|
||||
#include "zebra/router-id.h"
|
||||
#include "zebra/zebra_memory.h"
|
||||
#include "zebra/zebra_static.h"
|
||||
#include "zebra/interface.h"
|
||||
#include "zebra/zebra_mpls.h"
|
||||
|
||||
extern struct zebra_t zebrad;
|
||||
@ -214,18 +216,84 @@ static int
|
||||
zebra_vrf_delete (struct vrf *vrf)
|
||||
{
|
||||
struct zebra_vrf *zvrf = vrf->info;
|
||||
struct route_table *table;
|
||||
u_int32_t table_id;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
unsigned i;
|
||||
|
||||
assert (zvrf);
|
||||
|
||||
zebra_vrf_delete_update (zvrf);
|
||||
|
||||
rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||
rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||
/* uninstall everything */
|
||||
if (! CHECK_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN))
|
||||
{
|
||||
struct listnode *node;
|
||||
struct interface *ifp;
|
||||
|
||||
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
|
||||
{
|
||||
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
|
||||
rib_close_table (zvrf->table[afi][safi]);
|
||||
|
||||
if (vrf->vrf_id == VRF_DEFAULT)
|
||||
for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
|
||||
if (zvrf->other_table[afi][table_id])
|
||||
rib_close_table (zvrf->other_table[afi][table_id]);
|
||||
}
|
||||
|
||||
zebra_mpls_close_tables (zvrf);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
|
||||
}
|
||||
|
||||
/* clean-up work queues */
|
||||
for (i = 0; i < MQ_SIZE; i++)
|
||||
{
|
||||
struct listnode *lnode, *nnode;
|
||||
struct route_node *rnode;
|
||||
rib_dest_t *dest;
|
||||
|
||||
for (ALL_LIST_ELEMENTS (zebrad.mq->subq[i], lnode, nnode, rnode))
|
||||
{
|
||||
dest = rib_dest_from_rnode (rnode);
|
||||
if (dest && rib_dest_vrf (dest) == zvrf)
|
||||
{
|
||||
route_unlock_node (rnode);
|
||||
list_delete_node (zebrad.mq->subq[i], lnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* release allocated memory */
|
||||
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
|
||||
{
|
||||
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
|
||||
{
|
||||
table = zvrf->table[afi][safi];
|
||||
XFREE (MTYPE_RIB_TABLE_INFO, table->info);
|
||||
route_table_finish (table);
|
||||
|
||||
table = zvrf->stable[afi][safi];
|
||||
route_table_finish (table);
|
||||
}
|
||||
|
||||
for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
|
||||
if (zvrf->other_table[afi][table_id])
|
||||
{
|
||||
table = zvrf->other_table[afi][table_id];
|
||||
XFREE (MTYPE_RIB_TABLE_INFO, table->info);
|
||||
route_table_finish (table);
|
||||
}
|
||||
|
||||
route_table_finish (zvrf->rnh_table[afi]);
|
||||
route_table_finish (zvrf->import_check_table[afi]);
|
||||
}
|
||||
list_delete_all_node (zvrf->rid_all_sorted_list);
|
||||
list_delete_all_node (zvrf->rid_lo_sorted_list);
|
||||
|
||||
vrf->vrf_id = VRF_UNKNOWN;
|
||||
XFREE (MTYPE_ZEBRA_VRF, zvrf);
|
||||
vrf->info = NULL;
|
||||
|
||||
return 0;
|
||||
@ -257,6 +325,62 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
|
||||
return table;
|
||||
}
|
||||
|
||||
static void
|
||||
zebra_rtable_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
{
|
||||
struct rib *rib, *next;
|
||||
|
||||
RNODE_FOREACH_RIB_SAFE (node, rib, next)
|
||||
rib_unlink (node, rib);
|
||||
|
||||
if (node->info)
|
||||
XFREE (MTYPE_RIB_DEST, node->info);
|
||||
|
||||
route_node_destroy (delegate, table, node);
|
||||
}
|
||||
|
||||
static void
|
||||
zebra_stable_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
{
|
||||
struct static_route *si, *next;
|
||||
|
||||
if (node->info)
|
||||
for (si = node->info; si; si = next)
|
||||
{
|
||||
next = si->next;
|
||||
XFREE (MTYPE_STATIC_ROUTE, si);
|
||||
}
|
||||
|
||||
route_node_destroy (delegate, table, node);
|
||||
}
|
||||
|
||||
static void
|
||||
zebra_rnhtable_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
{
|
||||
if (node->info)
|
||||
zebra_free_rnh (node->info);
|
||||
|
||||
route_node_destroy (delegate, table, node);
|
||||
}
|
||||
|
||||
route_table_delegate_t zebra_rtable_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = zebra_rtable_node_destroy
|
||||
};
|
||||
|
||||
route_table_delegate_t zebra_stable_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = zebra_stable_node_destroy
|
||||
};
|
||||
|
||||
route_table_delegate_t zebra_rnhtable_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = zebra_rnhtable_node_destroy
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a routing table for the specific AFI/SAFI in the given VRF.
|
||||
*/
|
||||
@ -268,7 +392,7 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
|
||||
|
||||
assert (!zvrf->table[afi][safi]);
|
||||
|
||||
table = route_table_init ();
|
||||
table = route_table_init_with_delegate (&zebra_rtable_delegate);
|
||||
zvrf->table[afi][safi] = table;
|
||||
|
||||
info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
|
||||
@ -283,24 +407,25 @@ struct zebra_vrf *
|
||||
zebra_vrf_alloc (void)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
|
||||
zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
|
||||
|
||||
/* Allocate routing table and static table. */
|
||||
zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
|
||||
zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
|
||||
zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
|
||||
zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
|
||||
zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
|
||||
zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
|
||||
zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
|
||||
zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
|
||||
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
|
||||
{
|
||||
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
|
||||
{
|
||||
zebra_vrf_table_create (zvrf, afi, safi);
|
||||
zvrf->stable[afi][safi] =
|
||||
route_table_init_with_delegate (&zebra_stable_delegate);
|
||||
}
|
||||
|
||||
zvrf->rnh_table[AFI_IP] = route_table_init();
|
||||
zvrf->rnh_table[AFI_IP6] = route_table_init();
|
||||
|
||||
zvrf->import_check_table[AFI_IP] = route_table_init();
|
||||
zvrf->import_check_table[AFI_IP6] = route_table_init();
|
||||
zvrf->rnh_table[afi] =
|
||||
route_table_init_with_delegate (&zebra_rnhtable_delegate);
|
||||
zvrf->import_check_table[afi] =
|
||||
route_table_init_with_delegate (&zebra_rnhtable_delegate);
|
||||
}
|
||||
|
||||
zebra_mpls_init_tables (zvrf);
|
||||
|
||||
|
@ -40,6 +40,7 @@ struct zebra_vrf
|
||||
/* Flags. */
|
||||
u_int16_t flags;
|
||||
#define ZEBRA_VRF_RIB_SCHEDULED (1 << 0)
|
||||
#define ZEBRA_VRF_RETAIN (2 << 0)
|
||||
|
||||
u_int32_t table_id;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user