Merge pull request #870 from chiragshah6/mdev

Fix various memory leaks in OSPFd and OSPF6d
This commit is contained in:
David Lamparter 2017-08-04 08:46:38 +02:00 committed by GitHub
commit f28762d235
10 changed files with 54 additions and 30 deletions

View File

@ -622,7 +622,8 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
node = route_node_lookup(ospf6->external_id_table, &prefix_id); node = route_node_lookup(ospf6->external_id_table, &prefix_id);
assert(node); assert(node);
node->info = NULL; node->info = NULL;
route_unlock_node(node); route_unlock_node(node); /* to free the lookup lock */
route_unlock_node(node); /* to free the original lock */
ospf6_route_remove(match, ospf6->external_table); ospf6_route_remove(match, ospf6->external_table);
XFREE(MTYPE_OSPF6_EXTERNAL_INFO, info); XFREE(MTYPE_OSPF6_EXTERNAL_INFO, info);

View File

@ -509,7 +509,8 @@ struct ospf6_lsa *ospf6_lsa_create(struct ospf6_lsa_header *header)
/* allocate memory for this LSA */ /* allocate memory for this LSA */
new_header = new_header =
(struct ospf6_lsa_header *)XMALLOC(MTYPE_OSPF6_LSA, lsa_size); (struct ospf6_lsa_header *)XMALLOC(MTYPE_OSPF6_LSA_HEADER,
lsa_size);
/* copy LSA from original header */ /* copy LSA from original header */
memcpy(new_header, header, lsa_size); memcpy(new_header, header, lsa_size);
@ -537,7 +538,7 @@ struct ospf6_lsa *ospf6_lsa_create_headeronly(struct ospf6_lsa_header *header)
/* allocate memory for this LSA */ /* allocate memory for this LSA */
new_header = (struct ospf6_lsa_header *)XMALLOC( new_header = (struct ospf6_lsa_header *)XMALLOC(
MTYPE_OSPF6_LSA, sizeof(struct ospf6_lsa_header)); MTYPE_OSPF6_LSA_HEADER, sizeof(struct ospf6_lsa_header));
/* copy LSA from original header */ /* copy LSA from original header */
memcpy(new_header, header, sizeof(struct ospf6_lsa_header)); memcpy(new_header, header, sizeof(struct ospf6_lsa_header));
@ -568,7 +569,7 @@ void ospf6_lsa_delete(struct ospf6_lsa *lsa)
THREAD_OFF(lsa->refresh); THREAD_OFF(lsa->refresh);
/* do free */ /* do free */
XFREE(MTYPE_OSPF6_LSA, lsa->header); XFREE(MTYPE_OSPF6_LSA_HEADER, lsa->header);
XFREE(MTYPE_OSPF6_LSA, lsa); XFREE(MTYPE_OSPF6_LSA, lsa);
} }

View File

@ -139,6 +139,8 @@ void ospf6_lsdb_add(struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
(*lsdb->hook_add)(lsa); (*lsdb->hook_add)(lsa);
} }
} }
/* to free the lookup lock in node get*/
route_unlock_node(current);
ospf6_lsa_unlock(old); ospf6_lsa_unlock(old);
} }

View File

@ -34,6 +34,7 @@ DEFINE_MTYPE(OSPF6D, OSPF6_ROUTE, "OSPF6 route")
DEFINE_MTYPE(OSPF6D, OSPF6_PREFIX, "OSPF6 prefix") DEFINE_MTYPE(OSPF6D, OSPF6_PREFIX, "OSPF6 prefix")
DEFINE_MTYPE(OSPF6D, OSPF6_MESSAGE, "OSPF6 message") DEFINE_MTYPE(OSPF6D, OSPF6_MESSAGE, "OSPF6 message")
DEFINE_MTYPE(OSPF6D, OSPF6_LSA, "OSPF6 LSA") DEFINE_MTYPE(OSPF6D, OSPF6_LSA, "OSPF6 LSA")
DEFINE_MTYPE(OSPF6D, OSPF6_LSA_HEADER, "OSPF6 LSA header")
DEFINE_MTYPE(OSPF6D, OSPF6_LSA_SUMMARY, "OSPF6 LSA summary") DEFINE_MTYPE(OSPF6D, OSPF6_LSA_SUMMARY, "OSPF6 LSA summary")
DEFINE_MTYPE(OSPF6D, OSPF6_LSDB, "OSPF6 LSA database") DEFINE_MTYPE(OSPF6D, OSPF6_LSDB, "OSPF6 LSA database")
DEFINE_MTYPE(OSPF6D, OSPF6_VERTEX, "OSPF6 vertex") DEFINE_MTYPE(OSPF6D, OSPF6_VERTEX, "OSPF6 vertex")

View File

@ -33,6 +33,7 @@ DECLARE_MTYPE(OSPF6_ROUTE)
DECLARE_MTYPE(OSPF6_PREFIX) DECLARE_MTYPE(OSPF6_PREFIX)
DECLARE_MTYPE(OSPF6_MESSAGE) DECLARE_MTYPE(OSPF6_MESSAGE)
DECLARE_MTYPE(OSPF6_LSA) DECLARE_MTYPE(OSPF6_LSA)
DECLARE_MTYPE(OSPF6_LSA_HEADER)
DECLARE_MTYPE(OSPF6_LSA_SUMMARY) DECLARE_MTYPE(OSPF6_LSA_SUMMARY)
DECLARE_MTYPE(OSPF6_LSDB) DECLARE_MTYPE(OSPF6_LSDB)
DECLARE_MTYPE(OSPF6_VERTEX) DECLARE_MTYPE(OSPF6_VERTEX)

View File

@ -178,17 +178,6 @@ void ospf6_nexthop_delete(struct ospf6_nexthop *nh)
XFREE(MTYPE_OSPF6_NEXTHOP, nh); XFREE(MTYPE_OSPF6_NEXTHOP, nh);
} }
void ospf6_free_nexthops(struct list *nh_list)
{
struct ospf6_nexthop *nh;
struct listnode *node, *nnode;
if (nh_list) {
for (ALL_LIST_ELEMENTS(nh_list, node, nnode, nh))
ospf6_nexthop_delete(nh);
}
}
void ospf6_clear_nexthops(struct list *nh_list) void ospf6_clear_nexthops(struct list *nh_list)
{ {
struct listnode *node; struct listnode *node;
@ -340,19 +329,29 @@ int ospf6_route_get_first_nh_index(struct ospf6_route *route)
return (-1); return (-1);
} }
static int ospf6_nexthop_cmp(struct ospf6_nexthop *a, struct ospf6_nexthop *b)
{
if ((a)->ifindex == (b)->ifindex &&
IN6_ARE_ADDR_EQUAL(&(a)->address, &(b)->address))
return 1;
return 0;
}
struct ospf6_route *ospf6_route_create(void) struct ospf6_route *ospf6_route_create(void)
{ {
struct ospf6_route *route; struct ospf6_route *route;
route = XCALLOC(MTYPE_OSPF6_ROUTE, sizeof(struct ospf6_route)); route = XCALLOC(MTYPE_OSPF6_ROUTE, sizeof(struct ospf6_route));
route->nh_list = list_new(); route->nh_list = list_new();
route->nh_list->cmp = (int (*)(void *, void *))ospf6_nexthop_cmp;
route->nh_list->del = (void (*) (void *))ospf6_nexthop_delete;
return route; return route;
} }
void ospf6_route_delete(struct ospf6_route *route) void ospf6_route_delete(struct ospf6_route *route)
{ {
if (route) { if (route) {
ospf6_free_nexthops(route->nh_list); if (route->nh_list)
list_free(route->nh_list); list_delete(route->nh_list);
XFREE(MTYPE_OSPF6_ROUTE, route); XFREE(MTYPE_OSPF6_ROUTE, route);
} }
} }
@ -439,6 +438,7 @@ struct ospf6_route *ospf6_route_lookup(struct prefix *prefix,
return NULL; return NULL;
route = (struct ospf6_route *)node->info; route = (struct ospf6_route *)node->info;
route_unlock_node(node); /* to free the lookup lock */
return route; return route;
} }
@ -583,6 +583,8 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
SET_FLAG(old->flag, OSPF6_ROUTE_ADD); SET_FLAG(old->flag, OSPF6_ROUTE_ADD);
ospf6_route_table_assert(table); ospf6_route_table_assert(table);
/* to free the lookup lock */
route_unlock_node(node);
return old; return old;
} }
@ -628,9 +630,10 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
if (prev || next) { if (prev || next) {
if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) if (IS_OSPF6_DEBUG_ROUTE(MEMORY))
zlog_debug( zlog_debug(
"%s %p: route add %p: another path: prev %p, next %p", "%s %p: route add %p: another path: prev %p, next %p node refcount %u",
ospf6_route_table_name(table), (void *)table, ospf6_route_table_name(table), (void *)table,
(void *)route, (void *)prev, (void *)next); (void *)route, (void *)prev, (void *)next,
node->lock);
else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) else if (IS_OSPF6_DEBUG_ROUTE(TABLE))
zlog_debug("%s: route add: another path found", zlog_debug("%s: route add: another path found",
ospf6_route_table_name(table)); ospf6_route_table_name(table));
@ -755,9 +758,9 @@ void ospf6_route_remove(struct ospf6_route *route,
prefix2str(&route->prefix, buf, sizeof(buf)); prefix2str(&route->prefix, buf, sizeof(buf));
if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) if (IS_OSPF6_DEBUG_ROUTE(MEMORY))
zlog_debug("%s %p: route remove %p: %s", zlog_debug("%s %p: route remove %p: %s rnode refcount %u",
ospf6_route_table_name(table), (void *)table, ospf6_route_table_name(table), (void *)table,
(void *)route, buf); (void *)route, buf, route->rnode->lock);
else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) else if (IS_OSPF6_DEBUG_ROUTE(TABLE))
zlog_debug("%s: route remove: %s", zlog_debug("%s: route remove: %s",
ospf6_route_table_name(table), buf); ospf6_route_table_name(table), buf);
@ -768,11 +771,9 @@ void ospf6_route_remove(struct ospf6_route *route,
/* find the route to remove, making sure that the route pointer /* find the route to remove, making sure that the route pointer
is from the route table. */ is from the route table. */
current = node->info; current = node->info;
while (current && ospf6_route_is_same(current, route)) { while (current && current != route)
if (current == route)
break;
current = current->next; current = current->next;
}
assert(current == route); assert(current == route);
/* adjust doubly linked list */ /* adjust doubly linked list */
@ -785,10 +786,14 @@ void ospf6_route_remove(struct ospf6_route *route,
if (route->next && route->next->rnode == node) { if (route->next && route->next->rnode == node) {
node->info = route->next; node->info = route->next;
SET_FLAG(route->next->flag, OSPF6_ROUTE_BEST); SET_FLAG(route->next->flag, OSPF6_ROUTE_BEST);
} else } else {
node->info = NULL; /* should unlock route_node here ? */ node->info = NULL;
route->rnode = NULL;
route_unlock_node(node); /* to free the original lock */
}
} }
route_unlock_node(node); /* to free the lookup lock */
table->count--; table->count--;
ospf6_route_table_assert(table); ospf6_route_table_assert(table);
@ -935,6 +940,7 @@ struct ospf6_route_table *ospf6_route_table_create(int s, int t)
void ospf6_route_table_delete(struct ospf6_route_table *table) void ospf6_route_table_delete(struct ospf6_route_table *table)
{ {
ospf6_route_remove_all(table); ospf6_route_remove_all(table);
bf_free(table->idspace);
route_table_finish(table->table); route_table_finish(table->table);
XFREE(MTYPE_OSPF6_ROUTE, table); XFREE(MTYPE_OSPF6_ROUTE, table);
} }
@ -1062,6 +1068,7 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route)
vty_out(vty, "Metric: %d (%d)\n", route->path.cost, vty_out(vty, "Metric: %d (%d)\n", route->path.cost,
route->path.u.cost_e2); route->path.u.cost_e2);
vty_out(vty, "Nexthop count: %u\n", route->nh_list->count);
/* Nexthops */ /* Nexthops */
vty_out(vty, "Nexthop:\n"); vty_out(vty, "Nexthop:\n");
for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) { for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) {

View File

@ -256,7 +256,6 @@ extern void ospf6_linkstate_prefix2str(struct prefix *prefix, char *buf,
extern struct ospf6_nexthop *ospf6_nexthop_create(void); extern struct ospf6_nexthop *ospf6_nexthop_create(void);
extern void ospf6_nexthop_delete(struct ospf6_nexthop *nh); extern void ospf6_nexthop_delete(struct ospf6_nexthop *nh);
extern void ospf6_free_nexthops(struct list *nh_list);
extern void ospf6_clear_nexthops(struct list *nh_list); extern void ospf6_clear_nexthops(struct list *nh_list);
extern int ospf6_num_nexthops(struct list *nh_list); extern int ospf6_num_nexthops(struct list *nh_list);
extern void ospf6_copy_nexthops(struct list *dst, struct list *src); extern void ospf6_copy_nexthops(struct list *dst, struct list *src);

View File

@ -141,6 +141,7 @@ static struct ospf6_vertex *ospf6_vertex_create(struct ospf6_lsa *lsa)
v->options[2] = *(u_char *)(OSPF6_LSA_HEADER_END(lsa->header) + 3); v->options[2] = *(u_char *)(OSPF6_LSA_HEADER_END(lsa->header) + 3);
v->nh_list = list_new(); v->nh_list = list_new();
v->nh_list->del = (void (*) (void *))ospf6_nexthop_delete;
v->parent = NULL; v->parent = NULL;
v->child_list = list_new(); v->child_list = list_new();

View File

@ -51,6 +51,9 @@
#include "ospfd/ospf_zebra.h" #include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_te.h" #include "ospfd/ospf_te.h"
DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table")
DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute")
DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp)) DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp)) DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
@ -628,7 +631,8 @@ struct ospf_external *ospf_external_add(u_char type, u_short instance)
om->external[type] = list_new(); om->external[type] = list_new();
ext_list = om->external[type]; ext_list = om->external[type];
ext = (struct ospf_external *)calloc(1, sizeof(struct ospf_external)); ext = (struct ospf_external *)XCALLOC(MTYPE_OSPF_EXTERNAL,
sizeof(struct ospf_external));
ext->instance = instance; ext->instance = instance;
EXTERNAL_INFO(ext) = route_table_init(); EXTERNAL_INFO(ext) = route_table_init();
@ -652,6 +656,7 @@ void ospf_external_del(u_char type, u_short instance)
list_free(om->external[type]); list_free(om->external[type]);
om->external[type] = NULL; om->external[type] = NULL;
} }
XFREE(MTYPE_OSPF_EXTERNAL, ext);
} }
} }
@ -687,7 +692,8 @@ struct ospf_redist *ospf_redist_add(struct ospf *ospf, u_char type,
ospf->redist[type] = list_new(); ospf->redist[type] = list_new();
red_list = ospf->redist[type]; red_list = ospf->redist[type];
red = (struct ospf_redist *)calloc(1, sizeof(struct ospf_redist)); red = (struct ospf_redist *)XCALLOC(MTYPE_OSPF_REDISTRIBUTE,
sizeof(struct ospf_redist));
red->instance = instance; red->instance = instance;
red->dmetric.type = -1; red->dmetric.type = -1;
red->dmetric.value = -1; red->dmetric.value = -1;
@ -709,6 +715,7 @@ void ospf_redist_del(struct ospf *ospf, u_char type, u_short instance)
list_free(ospf->redist[type]); list_free(ospf->redist[type]);
ospf->redist[type] = NULL; ospf->redist[type] = NULL;
} }
XFREE(MTYPE_OSPF_REDISTRIBUTE, red);
} }
} }

View File

@ -590,6 +590,7 @@ static void ospf_finish_final(struct ospf *ospf)
route_unlock_node(rn); route_unlock_node(rn);
} }
} }
route_table_finish(ospf->networks);
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
listnode_delete(ospf->areas, area); listnode_delete(ospf->areas, area);
@ -655,6 +656,8 @@ static void ospf_finish_final(struct ospf *ospf)
} }
list_delete(ospf->areas); list_delete(ospf->areas);
list_delete(ospf->oi_write_q);
list_delete(ospf->oiflist);
for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) { for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) {
struct list *ext_list; struct list *ext_list;
@ -752,6 +755,7 @@ static void ospf_area_free(struct ospf_area *area)
LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa) LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa)
ospf_discard_from_db(area->ospf, area->lsdb, lsa); ospf_discard_from_db(area->ospf, area->lsdb, lsa);
ospf_opaque_type10_lsa_term(area);
ospf_lsdb_delete_all(area->lsdb); ospf_lsdb_delete_all(area->lsdb);
ospf_lsdb_free(area->lsdb); ospf_lsdb_free(area->lsdb);