]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #870 from chiragshah6/mdev
authorDavid Lamparter <equinox@diac24.net>
Fri, 4 Aug 2017 06:46:38 +0000 (08:46 +0200)
committerGitHub <noreply@github.com>
Fri, 4 Aug 2017 06:46:38 +0000 (08:46 +0200)
Fix various memory leaks in OSPFd and OSPF6d

ospf6d/ospf6_asbr.c
ospf6d/ospf6_lsa.c
ospf6d/ospf6_lsdb.c
ospf6d/ospf6_memory.c
ospf6d/ospf6_memory.h
ospf6d/ospf6_route.c
ospf6d/ospf6_route.h
ospf6d/ospf6_spf.c
ospfd/ospf_zebra.c
ospfd/ospfd.c

index 7f8341d0e42c67ab91a8fad2eca5c28760fc4853..dd3630af160ce32278a95c2a0f82531313c08757 100644 (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);
        assert(node);
        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);
        XFREE(MTYPE_OSPF6_EXTERNAL_INFO, info);
index e1a431ea07245f57dd536897e2355077f65733b7..a0dad9344aa0a21cdb1901b4c0310659e5d0e2d0 100644 (file)
@@ -509,7 +509,8 @@ struct ospf6_lsa *ospf6_lsa_create(struct ospf6_lsa_header *header)
 
        /* allocate memory for this LSA */
        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 */
        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 */
        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 */
        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);
 
        /* do free */
-       XFREE(MTYPE_OSPF6_LSA, lsa->header);
+       XFREE(MTYPE_OSPF6_LSA_HEADER, lsa->header);
        XFREE(MTYPE_OSPF6_LSA, lsa);
 }
 
index 7e08d58791e13ee57d7f8a31d58e2cfdec36d7f4..8764a549d2572f084762198d007bdcb240e71f4e 100644 (file)
@@ -139,6 +139,8 @@ void ospf6_lsdb_add(struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
                                        (*lsdb->hook_add)(lsa);
                        }
                }
+               /* to free the lookup lock in node get*/
+               route_unlock_node(current);
                ospf6_lsa_unlock(old);
        }
 
index 133dc2cb3cbebe9e273d6e640bc5387308b1a833..56c232d6da98bbb90c07f2cef085e5fec8e56ca6 100644 (file)
@@ -34,6 +34,7 @@ DEFINE_MTYPE(OSPF6D, OSPF6_ROUTE, "OSPF6 route")
 DEFINE_MTYPE(OSPF6D, OSPF6_PREFIX, "OSPF6 prefix")
 DEFINE_MTYPE(OSPF6D, OSPF6_MESSAGE, "OSPF6 message")
 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_LSDB, "OSPF6 LSA database")
 DEFINE_MTYPE(OSPF6D, OSPF6_VERTEX, "OSPF6 vertex")
index 324065c3a10e50d50de5208c299a0449ecc99c86..fe72ee3669763e89cdd4fe490bdb446dc90864e8 100644 (file)
@@ -33,6 +33,7 @@ DECLARE_MTYPE(OSPF6_ROUTE)
 DECLARE_MTYPE(OSPF6_PREFIX)
 DECLARE_MTYPE(OSPF6_MESSAGE)
 DECLARE_MTYPE(OSPF6_LSA)
+DECLARE_MTYPE(OSPF6_LSA_HEADER)
 DECLARE_MTYPE(OSPF6_LSA_SUMMARY)
 DECLARE_MTYPE(OSPF6_LSDB)
 DECLARE_MTYPE(OSPF6_VERTEX)
index e0e9fc9449074f42b366f3deecf14c5d4deaa21d..bfe583a91149755bf16139c025659e5d9a06120e 100644 (file)
@@ -178,17 +178,6 @@ void ospf6_nexthop_delete(struct 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)
 {
        struct listnode *node;
@@ -340,19 +329,29 @@ int ospf6_route_get_first_nh_index(struct ospf6_route *route)
        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 *route;
        route = XCALLOC(MTYPE_OSPF6_ROUTE, sizeof(struct ospf6_route));
        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;
 }
 
 void ospf6_route_delete(struct ospf6_route *route)
 {
        if (route) {
-               ospf6_free_nexthops(route->nh_list);
-               list_free(route->nh_list);
+               if (route->nh_list)
+                       list_delete(route->nh_list);
                XFREE(MTYPE_OSPF6_ROUTE, route);
        }
 }
@@ -439,6 +438,7 @@ struct ospf6_route *ospf6_route_lookup(struct prefix *prefix,
                return NULL;
 
        route = (struct ospf6_route *)node->info;
+       route_unlock_node(node); /* to free the lookup lock */
        return route;
 }
 
@@ -583,6 +583,8 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
                        SET_FLAG(old->flag, OSPF6_ROUTE_ADD);
                        ospf6_route_table_assert(table);
 
+                       /* to free the lookup lock */
+                       route_unlock_node(node);
                        return old;
                }
 
@@ -628,9 +630,10 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
        if (prev || next) {
                if (IS_OSPF6_DEBUG_ROUTE(MEMORY))
                        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,
-                               (void *)route, (void *)prev, (void *)next);
+                               (void *)route, (void *)prev, (void *)next,
+                               node->lock);
                else if (IS_OSPF6_DEBUG_ROUTE(TABLE))
                        zlog_debug("%s: route add: another path found",
                                   ospf6_route_table_name(table));
@@ -755,9 +758,9 @@ void ospf6_route_remove(struct ospf6_route *route,
                prefix2str(&route->prefix, buf, sizeof(buf));
 
        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,
-                          (void *)route, buf);
+                          (void *)route, buf, route->rnode->lock);
        else if (IS_OSPF6_DEBUG_ROUTE(TABLE))
                zlog_debug("%s: route remove: %s",
                           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
           is from the route table. */
        current = node->info;
-       while (current && ospf6_route_is_same(current, route)) {
-               if (current == route)
-                       break;
+       while (current && current != route)
                current = current->next;
-       }
+
        assert(current == route);
 
        /* adjust doubly linked list */
@@ -785,10 +786,14 @@ void ospf6_route_remove(struct ospf6_route *route,
                if (route->next && route->next->rnode == node) {
                        node->info = route->next;
                        SET_FLAG(route->next->flag, OSPF6_ROUTE_BEST);
-               } else
-                       node->info = NULL; /* should unlock route_node here ? */
+               } else {
+                       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--;
        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)
 {
        ospf6_route_remove_all(table);
+       bf_free(table->idspace);
        route_table_finish(table->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,
                route->path.u.cost_e2);
 
+       vty_out(vty, "Nexthop count: %u\n", route->nh_list->count);
        /* Nexthops */
        vty_out(vty, "Nexthop:\n");
        for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) {
index 69d275f8b119d315da30edbbe61d425d638275a0..166074fb705c5c2d239dac829eb5a07cf8f6d2d8 100644 (file)
@@ -256,7 +256,6 @@ extern void ospf6_linkstate_prefix2str(struct prefix *prefix, char *buf,
 
 extern struct ospf6_nexthop *ospf6_nexthop_create(void);
 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 int ospf6_num_nexthops(struct list *nh_list);
 extern void ospf6_copy_nexthops(struct list *dst, struct list *src);
index 86f893bc61b925506a26ad0aab187a31b297b92a..6d589aff8f9b960f869442acdfbcc0eb1c4653d1 100644 (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->nh_list = list_new();
+       v->nh_list->del = (void (*) (void *))ospf6_nexthop_delete;
 
        v->parent = NULL;
        v->child_list = list_new();
index c6b0955dab0003c63a05f840b3e1346de848832f..ec8f1ee8524e6057511bf3c3e36c05daa77ecdac 100644 (file)
@@ -51,6 +51,9 @@
 #include "ospfd/ospf_zebra.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_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();
 
        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;
        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]);
                        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();
 
        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->dmetric.type = -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]);
                        ospf->redist[type] = NULL;
                }
+               XFREE(MTYPE_OSPF_REDISTRIBUTE, red);
        }
 }
 
index 381082fcda8dffcd2482888c32a2a1e754a1f4c3..b3553238efddda71881e56f2c333d06f6043de7a 100644 (file)
@@ -590,6 +590,7 @@ static void ospf_finish_final(struct ospf *ospf)
                        route_unlock_node(rn);
                }
        }
+       route_table_finish(ospf->networks);
 
        for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, 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->oi_write_q);
+       list_delete(ospf->oiflist);
 
        for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) {
                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)
        ospf_discard_from_db(area->ospf, area->lsdb, lsa);
 
+       ospf_opaque_type10_lsa_term(area);
        ospf_lsdb_delete_all(area->lsdb);
        ospf_lsdb_free(area->lsdb);