From d107621dbcd2d0061bb2159ad0a7bdea6516ce3e Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Thu, 13 Jul 2017 11:39:22 -0700 Subject: [PATCH 1/3] ospf6d: Fix memory leaks Free route node upon asbr redistribute route cleanup from external_id_table route tale. Free route node when route_remove is called and node->info is set to null. Decrement route node lock in route_lookup api as it is incremented as part of node_lookup api. use local variable for nexthop vs. malloc in zebra parse routine. two of the memory leaks related to nexthops per route were not freed. two of the memory leak detected per frr service restart Signed-off-by: Chirag Shah --- ospf6d/ospf6_asbr.c | 3 ++- ospf6d/ospf6_lsa.c | 7 +++--- ospf6d/ospf6_lsdb.c | 2 ++ ospf6d/ospf6_memory.c | 1 + ospf6d/ospf6_memory.h | 1 + ospf6d/ospf6_route.c | 53 ++++++++++++++++++++++++------------------- ospf6d/ospf6_route.h | 1 - ospf6d/ospf6_spf.c | 1 + ospf6d/ospf6_zebra.c | 19 ++++++---------- 9 files changed, 48 insertions(+), 40 deletions(-) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 7f8341d0e4..dd3630af16 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -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); diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 329060a16f..7993916807 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -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); } diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c index 7e08d58791..8764a549d2 100644 --- a/ospf6d/ospf6_lsdb.c +++ b/ospf6d/ospf6_lsdb.c @@ -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); } diff --git a/ospf6d/ospf6_memory.c b/ospf6d/ospf6_memory.c index 133dc2cb3c..56c232d6da 100644 --- a/ospf6d/ospf6_memory.c +++ b/ospf6d/ospf6_memory.c @@ -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") diff --git a/ospf6d/ospf6_memory.h b/ospf6d/ospf6_memory.h index 324065c3a1..fe72ee3669 100644 --- a/ospf6d/ospf6_memory.h +++ b/ospf6d/ospf6_memory.h @@ -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) diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 5e8fd0e15d..a4e7af1d8b 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -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_free(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 lock %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 lock %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)) { diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h index 69d275f8b1..166074fb70 100644 --- a/ospf6d/ospf6_route.h +++ b/ospf6d/ospf6_route.h @@ -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); diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 86f893bc61..6d589aff8f 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -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(); diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index d33f41730e..e7481ba723 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -214,14 +214,14 @@ static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, struct zapi_ipv6 api; unsigned long ifindex; struct prefix p, src_p; - struct in6_addr *nexthop; + struct in6_addr nexthop; if (ospf6 == NULL) return 0; s = zclient->ibuf; ifindex = 0; - nexthop = NULL; + memset(&nexthop, 0, sizeof(struct in6_addr)); memset(&api, 0, sizeof(api)); /* Type, flags, message. */ @@ -250,10 +250,7 @@ static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { api.nexthop_num = stream_getc(s); - nexthop = (struct in6_addr *)malloc(api.nexthop_num - * sizeof(struct in6_addr)); - stream_get(nexthop, s, - api.nexthop_num * sizeof(struct in6_addr)); + stream_get(&nexthop, s, IPV6_MAX_BYTELEN); } if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc(s); @@ -276,9 +273,9 @@ static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, if (IS_OSPF6_DEBUG_ZEBRA(RECV)) { char prefixstr[PREFIX2STR_BUFFER], nexthopstr[128]; prefix2str((struct prefix *)&p, prefixstr, sizeof(prefixstr)); - if (nexthop) - inet_ntop(AF_INET6, nexthop, nexthopstr, - sizeof(nexthopstr)); + if (api.nexthop_num) + inet_ntop(AF_INET6, &nexthop, nexthopstr, + sizeof(nexthopstr)); else snprintf(nexthopstr, sizeof(nexthopstr), "::"); @@ -292,12 +289,10 @@ static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) ospf6_asbr_redistribute_add(api.type, ifindex, &p, - api.nexthop_num, nexthop, api.tag); + api.nexthop_num, &nexthop, api.tag); else ospf6_asbr_redistribute_remove(api.type, ifindex, &p); - if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) - free(nexthop); return 0; } From 7f586094bfd6d9e846d67f6ab95cbd652997ad40 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Thu, 13 Jul 2017 13:33:29 -0700 Subject: [PATCH 2/3] ospfd: Fix memory leaks Verified ospfd configuraiton with valgrind, Signed-off-by: Chirag Shah --- ospfd/ospf_memory.c | 3 +++ ospfd/ospf_memory.h | 2 ++ ospfd/ospf_zebra.c | 8 ++++++-- ospfd/ospfd.c | 4 ++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ospfd/ospf_memory.c b/ospfd/ospf_memory.c index cdc9b929fa..988991e35c 100644 --- a/ospfd/ospf_memory.c +++ b/ospfd/ospf_memory.c @@ -53,3 +53,6 @@ DEFINE_MTYPE(OSPFD, OSPF_IF_PARAMS, "OSPF if params") DEFINE_MTYPE(OSPFD, OSPF_MESSAGE, "OSPF message") DEFINE_MTYPE(OSPFD, OSPF_MPLS_TE, "OSPF MPLS parameters") DEFINE_MTYPE(OSPFD, OSPF_PCE_PARAMS, "OSPF PCE parameters") +DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL, "OSPF External route table") +DEFINE_MTYPE(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute") + diff --git a/ospfd/ospf_memory.h b/ospfd/ospf_memory.h index 5f5960eec7..d91cbd4111 100644 --- a/ospfd/ospf_memory.h +++ b/ospfd/ospf_memory.h @@ -52,5 +52,7 @@ DECLARE_MTYPE(OSPF_IF_PARAMS) DECLARE_MTYPE(OSPF_MESSAGE) DECLARE_MTYPE(OSPF_MPLS_TE) DECLARE_MTYPE(OSPF_PCE_PARAMS) +DECLARE_MTYPE(OSPF_EXTERNAL) +DECLARE_MTYPE(OSPF_REDISTRIBUTE) #endif /* _QUAGGA_OSPF_MEMORY_H */ diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index c6b0955dab..5839eb40ec 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -628,7 +628,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 +653,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 +689,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 +712,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); } } diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index cee2244dd9..77378512e5 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -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); From dfac5d3960c7c3941d135cf6417f2c37ab5a9605 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Mon, 31 Jul 2017 13:12:33 -0700 Subject: [PATCH 3/3] ospf6d: adjust changes per PR 870 review called list_delete instead of list_free Moved MTYPE_STATIC in ospfd/zebra.c Revert changes in ospf6_zebra.c where malloc is called for multiple nexthops. Signed-off-by: Chirag Shah --- ospf6d/ospf6_route.c | 6 +++--- ospf6d/ospf6_zebra.c | 19 ++++++++++++------- ospfd/ospf_memory.c | 3 --- ospfd/ospf_memory.h | 2 -- ospfd/ospf_zebra.c | 3 +++ 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index a4e7af1d8b..c2722a256d 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -351,7 +351,7 @@ void ospf6_route_delete(struct ospf6_route *route) { if (route) { if (route->nh_list) - list_free(route->nh_list); + list_delete(route->nh_list); XFREE(MTYPE_OSPF6_ROUTE, route); } } @@ -630,7 +630,7 @@ 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 node lock %u", + "%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, node->lock); @@ -758,7 +758,7 @@ 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 rnode lock %u", + zlog_debug("%s %p: route remove %p: %s rnode refcount %u", ospf6_route_table_name(table), (void *)table, (void *)route, buf, route->rnode->lock); else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index e7481ba723..d33f41730e 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -214,14 +214,14 @@ static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, struct zapi_ipv6 api; unsigned long ifindex; struct prefix p, src_p; - struct in6_addr nexthop; + struct in6_addr *nexthop; if (ospf6 == NULL) return 0; s = zclient->ibuf; ifindex = 0; - memset(&nexthop, 0, sizeof(struct in6_addr)); + nexthop = NULL; memset(&api, 0, sizeof(api)); /* Type, flags, message. */ @@ -250,7 +250,10 @@ static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { api.nexthop_num = stream_getc(s); - stream_get(&nexthop, s, IPV6_MAX_BYTELEN); + nexthop = (struct in6_addr *)malloc(api.nexthop_num + * sizeof(struct in6_addr)); + stream_get(nexthop, s, + api.nexthop_num * sizeof(struct in6_addr)); } if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc(s); @@ -273,9 +276,9 @@ static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, if (IS_OSPF6_DEBUG_ZEBRA(RECV)) { char prefixstr[PREFIX2STR_BUFFER], nexthopstr[128]; prefix2str((struct prefix *)&p, prefixstr, sizeof(prefixstr)); - if (api.nexthop_num) - inet_ntop(AF_INET6, &nexthop, nexthopstr, - sizeof(nexthopstr)); + if (nexthop) + inet_ntop(AF_INET6, nexthop, nexthopstr, + sizeof(nexthopstr)); else snprintf(nexthopstr, sizeof(nexthopstr), "::"); @@ -289,10 +292,12 @@ static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) ospf6_asbr_redistribute_add(api.type, ifindex, &p, - api.nexthop_num, &nexthop, api.tag); + api.nexthop_num, nexthop, api.tag); else ospf6_asbr_redistribute_remove(api.type, ifindex, &p); + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) + free(nexthop); return 0; } diff --git a/ospfd/ospf_memory.c b/ospfd/ospf_memory.c index 988991e35c..cdc9b929fa 100644 --- a/ospfd/ospf_memory.c +++ b/ospfd/ospf_memory.c @@ -53,6 +53,3 @@ DEFINE_MTYPE(OSPFD, OSPF_IF_PARAMS, "OSPF if params") DEFINE_MTYPE(OSPFD, OSPF_MESSAGE, "OSPF message") DEFINE_MTYPE(OSPFD, OSPF_MPLS_TE, "OSPF MPLS parameters") DEFINE_MTYPE(OSPFD, OSPF_PCE_PARAMS, "OSPF PCE parameters") -DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL, "OSPF External route table") -DEFINE_MTYPE(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute") - diff --git a/ospfd/ospf_memory.h b/ospfd/ospf_memory.h index d91cbd4111..5f5960eec7 100644 --- a/ospfd/ospf_memory.h +++ b/ospfd/ospf_memory.h @@ -52,7 +52,5 @@ DECLARE_MTYPE(OSPF_IF_PARAMS) DECLARE_MTYPE(OSPF_MESSAGE) DECLARE_MTYPE(OSPF_MPLS_TE) DECLARE_MTYPE(OSPF_PCE_PARAMS) -DECLARE_MTYPE(OSPF_EXTERNAL) -DECLARE_MTYPE(OSPF_REDISTRIBUTE) #endif /* _QUAGGA_OSPF_MEMORY_H */ diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 5839eb40ec..ec8f1ee852 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -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))