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);
/* 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);
/* 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));
THREAD_OFF(lsa->refresh);
/* do free */
- XFREE(MTYPE_OSPF6_LSA, lsa->header);
+ XFREE(MTYPE_OSPF6_LSA_HEADER, lsa->header);
XFREE(MTYPE_OSPF6_LSA, lsa);
}
(*lsdb->hook_add)(lsa);
}
}
+ /* to free the lookup lock in node get*/
+ route_unlock_node(current);
ospf6_lsa_unlock(old);
}
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")
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)
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;
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);
}
}
return NULL;
route = (struct ospf6_route *)node->info;
+ route_unlock_node(node); /* to free the lookup lock */
return route;
}
SET_FLAG(old->flag, OSPF6_ROUTE_ADD);
ospf6_route_table_assert(table);
+ /* to free the lookup lock */
+ route_unlock_node(node);
return old;
}
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));
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);
/* 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 */
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);
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);
}
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)) {
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);
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();
#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))
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();
list_free(om->external[type]);
om->external[type] = NULL;
}
+ XFREE(MTYPE_OSPF_EXTERNAL, ext);
}
}
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;
list_free(ospf->redist[type]);
ospf->redist[type] = NULL;
}
+ XFREE(MTYPE_OSPF_REDISTRIBUTE, red);
}
}
route_unlock_node(rn);
}
}
+ route_table_finish(ospf->networks);
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
listnode_delete(ospf->areas, area);
}
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;
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);