From cf1ce250d20003ae94c835e73e95e7442d7a5b53 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Mon, 15 May 2006 10:46:07 +0000 Subject: [ospf6d] GNU Zebra #3562: ABR Crash fix, memory fixes, route table debugs 2006-02-22 Yasuhiro Ohara * valgrind check and memory fix * route table identification string added * ospf6d.h: version 0.9.7q --- ospf6d/ChangeLog | 6 ++ ospf6d/ospf6_abr.c | 5 +- ospf6d/ospf6_area.c | 17 ++-- ospf6d/ospf6_interface.c | 3 +- ospf6d/ospf6_intra.c | 78 +++++++++++++++- ospf6d/ospf6_message.c | 6 +- ospf6d/ospf6_network.c | 2 + ospf6d/ospf6_route.c | 237 ++++++++++++++++++++++++++++++++++++++++------- ospf6d/ospf6_route.h | 28 +++++- ospf6d/ospf6_top.c | 10 +- ospf6d/ospf6d.h | 2 +- 11 files changed, 340 insertions(+), 54 deletions(-) (limited to 'ospf6d') diff --git a/ospf6d/ChangeLog b/ospf6d/ChangeLog index 2676a3f5..01064aa5 100644 --- a/ospf6d/ChangeLog +++ b/ospf6d/ChangeLog @@ -1,3 +1,9 @@ +2006-02-22 Yasuhiro Ohara + + * valgrind check and memory fix + * route table identification string added + * ospf6d.h: version 0.9.7q + 2005-10-20 Yasuhiro Ohara * ospf6_neighbor.c: add the calling of ospf6_maxage_remove () diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index 833a1bc9..180a2048 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -538,6 +538,8 @@ ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa) char buf[64]; int is_debug = 0; + memset (&prefix, 0, sizeof (prefix)); + if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX)) { struct ospf6_inter_prefix_lsa *prefix_lsa; @@ -593,7 +595,8 @@ ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa) if (route->path.area_id == oa->area_id && route->path.origin.type == lsa->header->type && route->path.origin.id == lsa->header->id && - route->path.origin.adv_router == lsa->header->adv_router) + route->path.origin.adv_router == lsa->header->adv_router && + ! CHECK_FLAG (route->flag, OSPF6_ROUTE_WAS_REMOVED)) old = route; route = ospf6_route_next (route); } diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 9368defe..94283dba 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -149,14 +149,19 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o) oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove; oa->lsdb_self = ospf6_lsdb_create (oa); - oa->spf_table = ospf6_route_table_create (); - oa->route_table = ospf6_route_table_create (); + oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS); + oa->spf_table->scope = oa; + oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES); + oa->route_table->scope = oa; oa->route_table->hook_add = ospf6_area_route_hook_add; oa->route_table->hook_remove = ospf6_area_route_hook_remove; - oa->range_table = ospf6_route_table_create (); - oa->summary_prefix = ospf6_route_table_create (); - oa->summary_router = ospf6_route_table_create (); + oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES); + oa->range_table->scope = oa; + oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES); + oa->summary_prefix->scope = oa; + oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS); + oa->summary_router->scope = oa; /* set default options */ OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6); @@ -719,7 +724,7 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root, tmp_debug_ospf6_spf = conf_debug_ospf6_spf; conf_debug_ospf6_spf = 0; - spf_table = ospf6_route_table_create (); + spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS); ospf6_spf_calculation (router_id, spf_table, oa); conf_debug_ospf6_spf = tmp_debug_ospf6_spf; diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 3ca5e2d1..95464b63 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -139,7 +139,8 @@ ospf6_interface_create (struct interface *ifp) oi->lsdb->hook_remove = ospf6_interface_lsdb_hook; oi->lsdb_self = ospf6_lsdb_create (oi); - oi->route_connected = ospf6_route_table_create (); + oi->route_connected = OSPF6_ROUTE_TABLE_CREATE (INTERFACE, CONNECTED_ROUTES); + oi->route_connected->scope = oi; /* link both */ oi->interface = ifp; diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index 0be88f01..ffd9c725 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -721,7 +721,7 @@ ospf6_intra_prefix_lsa_originate_stub (struct thread *thread) intra_prefix_lsa->ref_id = htonl (0); intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id; - route_advertise = ospf6_route_table_create (); + route_advertise = ospf6_route_table_create (0, 0); for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi)) { @@ -900,7 +900,7 @@ ospf6_intra_prefix_lsa_originate_transit (struct thread *thread) } /* connected prefix to advertise */ - route_advertise = ospf6_route_table_create (); + route_advertise = ospf6_route_table_create (0, 0); type = ntohs (OSPF6_LSTYPE_LINK); for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa; @@ -1238,6 +1238,58 @@ ospf6_intra_route_calculation (struct ospf6_area *oa) zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name); } +void +ospf6_brouter_debug_print (struct ospf6_route *brouter) +{ + u_int32_t brouter_id; + char brouter_name[16]; + char area_name[16]; + char destination[64]; + char installed[16], changed[16]; + struct timeval now, res; + char id[16], adv_router[16]; + char capa[16], options[16]; + + brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); + inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); + inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name)); + ospf6_linkstate_prefix2str (&brouter->prefix, destination, + sizeof (destination)); + + gettimeofday (&now, (struct timezone *) NULL); + timersub (&now, &brouter->installed, &res); + timerstring (&res, installed, sizeof (installed)); + + gettimeofday (&now, (struct timezone *) NULL); + timersub (&now, &brouter->changed, &res); + timerstring (&res, changed, sizeof (changed)); + + inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id)); + inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router, + sizeof (adv_router)); + + ospf6_options_printbuf (brouter->path.options, options, sizeof (options)); + ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa)); + + zlog_info ("Brouter: %s via area %s", brouter_name, area_name); + zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p", + brouter->prev, brouter, brouter->next, brouter->rnode); + zlog_info (" type: %d prefix: %s installed: %s changed: %s", + brouter->type, destination, installed, changed); + zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock, + (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"), + (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"), + (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"), + (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-")); + zlog_info (" path type: %s ls-origin %s id: %s adv-router %s", + OSPF6_PATH_TYPE_NAME (brouter->path.type), + ospf6_lstype_name (brouter->path.origin.type), + id, adv_router); + zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d", + options, capa, brouter->path.metric_type, + brouter->path.cost, brouter->path.cost_e2); +} + void ospf6_intra_brouter_calculation (struct ospf6_area *oa) { @@ -1259,14 +1311,27 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa) for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter; brouter = ospf6_route_next (brouter)) { + brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); + inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); if (brouter->path.area_id != oa->area_id) continue; brouter->flag = OSPF6_ROUTE_REMOVE; + + if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || + IS_OSPF6_DEBUG_ROUTE (MEMORY)) + { + zlog_info ("%p: mark as removing: area %s brouter %s", + brouter, oa->name, brouter_name); + ospf6_brouter_debug_print (brouter); + } } for (brouter = ospf6_route_head (oa->spf_table); brouter; brouter = ospf6_route_next (brouter)) { + brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); + inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); + if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE) continue; if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0)) @@ -1279,6 +1344,14 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa) copy->type = OSPF6_DEST_TYPE_ROUTER; copy->path.area_id = oa->area_id; ospf6_route_add (copy, oa->ospf6->brouter_table); + + if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || + IS_OSPF6_DEBUG_ROUTE (MEMORY)) + { + zlog_info ("%p: transfer: area %s brouter %s", + brouter, oa->name, brouter_name); + ospf6_brouter_debug_print (brouter); + } } oa->ospf6->brouter_table->hook_add = hook_add; @@ -1320,6 +1393,7 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa) IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) zlog_info ("brouter %s appears via area %s", brouter_name, oa->name); + /* newly added */ if (hook_add) (*hook_add) (brouter); diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index fbda675e..6ece88b8 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -1120,10 +1120,9 @@ ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst, on->name); ospf6_decrement_retrans_count (mine); - ospf6_lsdb_remove (mine, on->retrans_list); if (OSPF6_LSA_IS_MAXAGE (mine)) ospf6_maxage_remove (on->ospf6_if->area->ospf6); - + ospf6_lsdb_remove (mine, on->retrans_list); ospf6_lsa_delete (his); } @@ -1186,6 +1185,9 @@ ospf6_receive (struct thread *thread) thread_add_read (master, ospf6_receive, NULL, sockfd); /* initialize */ + memset (&src, 0, sizeof (src)); + memset (&dst, 0, sizeof (dst)); + ifindex = 0; memset (recvbuf, 0, iobuflen); iovector[0].iov_base = recvbuf; iovector[0].iov_len = iobuflen; diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c index 4df7c9db..8c0cbf5e 100644 --- a/ospf6d/ospf6_network.c +++ b/ospf6d/ospf6_network.c @@ -254,6 +254,7 @@ ospf6_sendmsg (struct in6_addr *src, struct in6_addr *dst, /* scmsgp = CMSG_NXTHDR (&smsghdr, scmsgp); */ /* send msg hdr */ + memset (&smsghdr, 0, sizeof (smsghdr)); smsghdr.msg_iov = message; smsghdr.msg_iovlen = iov_count (message); smsghdr.msg_name = (caddr_t) &dst_sin6; @@ -291,6 +292,7 @@ ospf6_recvmsg (struct in6_addr *src, struct in6_addr *dst, /* rcmsgp = CMSG_NXTHDR (&rmsghdr, rcmsgp); */ /* receive msg hdr */ + memset (&rmsghdr, 0, sizeof (rmsghdr)); rmsghdr.msg_iov = message; rmsghdr.msg_iovlen = iov_count (message); rmsghdr.msg_name = (caddr_t) &src_sin6; diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 521d8ade..38fdd51a 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -27,15 +27,112 @@ #include "table.h" #include "vty.h" #include "command.h" +#include "linklist.h" #include "ospf6_proto.h" #include "ospf6_lsa.h" #include "ospf6_lsdb.h" #include "ospf6_route.h" +#include "ospf6_top.h" +#include "ospf6_area.h" +#include "ospf6_interface.h" #include "ospf6d.h" unsigned char conf_debug_ospf6_route = 0; +static char * +ospf6_route_table_name (struct ospf6_route_table *table) +{ + static char name[32]; + switch (table->scope_type) + { + case OSPF6_SCOPE_TYPE_GLOBAL: + { + switch (table->table_type) + { + case OSPF6_TABLE_TYPE_ROUTES: + snprintf (name, sizeof (name), "global route table"); + break; + case OSPF6_TABLE_TYPE_BORDER_ROUTERS: + snprintf (name, sizeof (name), "global brouter table"); + break; + case OSPF6_TABLE_TYPE_EXTERNAL_ROUTES: + snprintf (name, sizeof (name), "global external table"); + break; + default: + snprintf (name, sizeof (name), "global unknown table"); + break; + } + } + break; + + case OSPF6_SCOPE_TYPE_AREA: + { + struct ospf6_area *oa = (struct ospf6_area *) table->scope; + switch (table->table_type) + { + case OSPF6_TABLE_TYPE_SPF_RESULTS: + snprintf (name, sizeof (name), + "area %s spf table", oa->name); + break; + case OSPF6_TABLE_TYPE_ROUTES: + snprintf (name, sizeof (name), + "area %s route table", oa->name); + break; + case OSPF6_TABLE_TYPE_PREFIX_RANGES: + snprintf (name, sizeof (name), + "area %s range table", oa->name); + break; + case OSPF6_TABLE_TYPE_SUMMARY_PREFIXES: + snprintf (name, sizeof (name), + "area %s summary prefix table", oa->name); + break; + case OSPF6_TABLE_TYPE_SUMMARY_ROUTERS: + snprintf (name, sizeof (name), + "area %s summary router table", oa->name); + break; + default: + snprintf (name, sizeof (name), + "area %s unknown table", oa->name); + break; + } + } + break; + + case OSPF6_SCOPE_TYPE_INTERFACE: + { + struct ospf6_interface *oi = (struct ospf6_interface *) table->scope; + switch (table->table_type) + { + case OSPF6_TABLE_TYPE_CONNECTED_ROUTES: + snprintf (name, sizeof (name), "interface %s connected table", + oi->interface->name); + break; + default: + snprintf (name, sizeof (name), "interface %s unknown table", + oi->interface->name); + break; + } + } + break; + + default: + { + switch (table->table_type) + { + case OSPF6_TABLE_TYPE_SPF_RESULTS: + snprintf (name, sizeof (name), "temporary spf table"); + break; + default: + snprintf (name, sizeof (name), "temporary unknown table"); + break; + } + } + break; + } + return name; +} + void ospf6_linkstate_prefix (u_int32_t adv_router, u_int32_t id, struct prefix *prefix) @@ -100,6 +197,7 @@ ospf6_route_copy (struct ospf6_route *route) new->rnode = NULL; new->prev = NULL; new->next = NULL; + new->table = NULL; new->lock = 0; return new; } @@ -116,7 +214,13 @@ ospf6_route_unlock (struct ospf6_route *route) assert (route->lock > 0); route->lock--; if (route->lock == 0) - ospf6_route_delete (route); + { + /* Can't detach from the table until here + because ospf6_route_next () will use + the 'route->table' pointer for logging */ + route->table = NULL; + ospf6_route_delete (route); + } } /* Route compare function. If ra is more preferred, it returns @@ -202,33 +306,50 @@ ospf6_route_lookup_bestmatch (struct prefix *prefix, #ifndef NDEBUG static void -_route_count_assert (struct ospf6_route_table *table) +route_table_assert (struct ospf6_route_table *table) { - struct ospf6_route *debug; + struct ospf6_route *prev, *r, *next; char buf[64]; - unsigned int num = 0; - for (debug = ospf6_route_head (table); debug; - debug = ospf6_route_next (debug)) + unsigned int link_error = 0, num = 0; + + r = ospf6_route_head (table); + prev = NULL; + while (r) + { + if (r->prev != prev) + link_error++; + + next = ospf6_route_next (r); + + if (r->next != next) + link_error++; + + prev = r; + r = next; + } + + for (r = ospf6_route_head (table); r; r = ospf6_route_next (r)) num++; - - if (num == table->count) + + if (link_error == 0 && num == table->count) return; - zlog_debug ("PANIC !! table[%p]->count = %d, real = %d", - table, table->count, num); - for (debug = ospf6_route_head (table); debug; - debug = ospf6_route_next (debug)) + zlog_err ("PANIC !!"); + zlog_err ("Something has gone wrong with ospf6_route_table[%p]", table); + zlog_debug ("table count = %d, real number = %d", table->count, num); + zlog_debug ("DUMP START"); + for (r = ospf6_route_head (table); r; r = ospf6_route_next (r)) { - prefix2str (&debug->prefix, buf, sizeof (buf)); - zlog_debug ("%p %p %s", debug->prev, debug->next, buf); + prefix2str (&r->prefix, buf, sizeof (buf)); + zlog_info ("%p<-[%p]->%p : %s", r->prev, r, r->next, buf); } zlog_debug ("DUMP END"); - assert (num == table->count); + assert (link_error == 0 && num == table->count); } -#define ospf6_route_count_assert(t) (_route_count_assert (t)) +#define ospf6_route_table_assert(t) (route_table_assert (t)) #else -#define ospf6_route_count_assert(t) ((void) 0) +#define ospf6_route_table_assert(t) ((void) 0) #endif /*NDEBUG*/ struct ospf6_route * @@ -251,8 +372,11 @@ ospf6_route_add (struct ospf6_route *route, else prefix2str (&route->prefix, buf, sizeof (buf)); - if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug ("route add %s", buf); + if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) + zlog_debug ("%s %p: route add %p: %s", ospf6_route_table_name (table), + table, route, buf); + else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) + zlog_debug ("%s: route add: %s", ospf6_route_table_name (table), buf); gettimeofday (&now, NULL); @@ -282,18 +406,26 @@ ospf6_route_add (struct ospf6_route *route, /* if route does not actually change, return unchanged */ if (ospf6_route_is_identical (old, route)) { - if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug (" identical route found, ignore"); + if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) + zlog_debug ("%s %p: route add %p: needless update of %p", + ospf6_route_table_name (table), table, route, old); + else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) + zlog_debug ("%s: route add: needless update", + ospf6_route_table_name (table)); ospf6_route_delete (route); SET_FLAG (old->flag, OSPF6_ROUTE_ADD); - ospf6_route_count_assert (table); + ospf6_route_table_assert (table); return old; } - if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug (" old route found, replace"); + if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) + zlog_debug ("%s %p: route add %p: update of %p", + ospf6_route_table_name (table), table, route, old); + else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) + zlog_debug ("%s: route add: update", + ospf6_route_table_name (table)); /* replace old one if exists */ if (node->info == old) @@ -311,12 +443,14 @@ ospf6_route_add (struct ospf6_route *route, route->installed = old->installed; route->changed = now; + assert (route->table == NULL); + route->table = table; ospf6_route_unlock (old); /* will be deleted later */ ospf6_route_lock (route); SET_FLAG (route->flag, OSPF6_ROUTE_CHANGE); - ospf6_route_count_assert (table); + ospf6_route_table_assert (table); if (table->hook_add) (*table->hook_add) (route); @@ -327,8 +461,12 @@ ospf6_route_add (struct ospf6_route *route, /* insert if previous or next node found */ if (prev || next) { - if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug (" another path found, insert"); + if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) + zlog_debug ("%s %p: route add %p: another path: prev %p, next %p", + ospf6_route_table_name (table), table, route, prev, next); + else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) + zlog_debug ("%s: route add: another path found", + ospf6_route_table_name (table)); if (prev == NULL) prev = next->prev; @@ -348,14 +486,19 @@ ospf6_route_add (struct ospf6_route *route, node->info = route; UNSET_FLAG (next->flag, OSPF6_ROUTE_BEST); SET_FLAG (route->flag, OSPF6_ROUTE_BEST); + if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) + zlog_info ("%s %p: route add %p: replacing previous best: %p", + ospf6_route_table_name (table), table, route, next); } route->installed = now; route->changed = now; + assert (route->table == NULL); + route->table = table; ospf6_route_lock (route); table->count++; - ospf6_route_count_assert (table); + ospf6_route_table_assert (table); SET_FLAG (route->flag, OSPF6_ROUTE_ADD); if (table->hook_add) @@ -365,8 +508,12 @@ ospf6_route_add (struct ospf6_route *route, } /* Else, this is the brand new route regarding to the prefix */ - if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug (" brand new route, add"); + if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) + zlog_debug ("%s %p: route add %p: brand new route", + ospf6_route_table_name (table), table, route); + else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) + zlog_debug ("%s: route add: brand new route", + ospf6_route_table_name (table)); assert (node->info == NULL); node->info = route; @@ -374,6 +521,8 @@ ospf6_route_add (struct ospf6_route *route, ospf6_route_lock (route); route->installed = now; route->changed = now; + assert (route->table == NULL); + route->table = table; /* lookup real existing next route */ nextnode = node; @@ -416,7 +565,7 @@ ospf6_route_add (struct ospf6_route *route, } table->count++; - ospf6_route_count_assert (table); + ospf6_route_table_assert (table); SET_FLAG (route->flag, OSPF6_ROUTE_ADD); if (table->hook_add) @@ -438,8 +587,11 @@ ospf6_route_remove (struct ospf6_route *route, else prefix2str (&route->prefix, buf, sizeof (buf)); - if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug ("route remove: %s", buf); + if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) + zlog_debug ("%s %p: route remove %p: %s", + ospf6_route_table_name (table), table, route, buf); + else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) + zlog_debug ("%s: route remove: %s", ospf6_route_table_name (table), buf); node = route_node_lookup (table->table, &route->prefix); assert (node); @@ -473,7 +625,7 @@ ospf6_route_remove (struct ospf6_route *route, } table->count--; - ospf6_route_count_assert (table); + ospf6_route_table_assert (table); SET_FLAG (route->flag, OSPF6_ROUTE_WAS_REMOVED); @@ -504,7 +656,14 @@ ospf6_route_head (struct ospf6_route_table *table) route = (struct ospf6_route *) node->info; assert (route->prev == NULL); + assert (route->table == table); ospf6_route_lock (route); + + if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) + zlog_info ("%s %p: route head: %p<-[%p]->%p", + ospf6_route_table_name (table), table, + route->prev, route, route->next); + return route; } @@ -513,6 +672,11 @@ ospf6_route_next (struct ospf6_route *route) { struct ospf6_route *next = route->next; + if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) + zlog_info ("%s %p: route next: %p<-[%p]->%p", + ospf6_route_table_name (route->table), route->table, + route->prev, route, route->next); + ospf6_route_unlock (route); if (next) ospf6_route_lock (next); @@ -600,11 +764,13 @@ ospf6_route_remove_all (struct ospf6_route_table *table) } struct ospf6_route_table * -ospf6_route_table_create () +ospf6_route_table_create (int s, int t) { struct ospf6_route_table *new; new = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_route_table)); new->table = route_table_init (); + new->scope_type = s; + new->table_type = t; return new; } @@ -616,7 +782,6 @@ ospf6_route_table_delete (struct ospf6_route_table *table) XFREE (MTYPE_OSPF6_ROUTE, table); } - /* VTY commands */ void diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h index d91cd7b7..722fa158 100644 --- a/ospf6d/ospf6_route.h +++ b/ospf6d/ospf6_route.h @@ -29,6 +29,7 @@ extern unsigned char conf_debug_ospf6_route; #define OSPF6_DEBUG_ROUTE_TABLE 0x01 #define OSPF6_DEBUG_ROUTE_INTRA 0x02 #define OSPF6_DEBUG_ROUTE_INTER 0x04 +#define OSPF6_DEBUG_ROUTE_MEMORY 0x80 #define OSPF6_DEBUG_ROUTE_ON(level) \ (conf_debug_ospf6_route |= (level)) #define OSPF6_DEBUG_ROUTE_OFF(level) \ @@ -112,7 +113,7 @@ struct ospf6_path struct ospf6_route { struct route_node *rnode; - + struct ospf6_route_table *table; struct ospf6_route *prev; struct ospf6_route *next; @@ -162,6 +163,10 @@ struct ospf6_route struct ospf6_route_table { + int scope_type; + int table_type; + void *scope; + /* patricia tree */ struct route_table *table; @@ -173,6 +178,25 @@ struct ospf6_route_table void (*hook_remove) (struct ospf6_route *); }; +#define OSPF6_SCOPE_TYPE_NONE 0 +#define OSPF6_SCOPE_TYPE_GLOBAL 1 +#define OSPF6_SCOPE_TYPE_AREA 2 +#define OSPF6_SCOPE_TYPE_INTERFACE 3 + +#define OSPF6_TABLE_TYPE_NONE 0 +#define OSPF6_TABLE_TYPE_ROUTES 1 +#define OSPF6_TABLE_TYPE_BORDER_ROUTERS 2 +#define OSPF6_TABLE_TYPE_CONNECTED_ROUTES 3 +#define OSPF6_TABLE_TYPE_EXTERNAL_ROUTES 4 +#define OSPF6_TABLE_TYPE_SPF_RESULTS 5 +#define OSPF6_TABLE_TYPE_PREFIX_RANGES 6 +#define OSPF6_TABLE_TYPE_SUMMARY_PREFIXES 7 +#define OSPF6_TABLE_TYPE_SUMMARY_ROUTERS 8 + +#define OSPF6_ROUTE_TABLE_CREATE(s, t) \ + ospf6_route_table_create (OSPF6_SCOPE_TYPE_ ## s, \ + OSPF6_TABLE_TYPE_ ## t) + extern const char *ospf6_dest_type_str[OSPF6_DEST_TYPE_MAX]; extern const char *ospf6_dest_type_substr[OSPF6_DEST_TYPE_MAX]; #define OSPF6_DEST_TYPE_NAME(x) \ @@ -258,7 +282,7 @@ struct ospf6_route *ospf6_route_match_next (struct prefix *prefix, struct ospf6_route *route); void ospf6_route_remove_all (struct ospf6_route_table *); -struct ospf6_route_table *ospf6_route_table_create (); +struct ospf6_route_table *ospf6_route_table_create (int s, int t); void ospf6_route_table_delete (struct ospf6_route_table *); void ospf6_route_dump (struct ospf6_route_table *table); diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 66b1a121..a5efcb8d 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -126,15 +126,19 @@ ospf6_create () o->lsdb->hook_add = ospf6_top_lsdb_hook_add; o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove; - o->route_table = ospf6_route_table_create (); + o->route_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, ROUTES); + o->route_table->scope = o; o->route_table->hook_add = ospf6_top_route_hook_add; o->route_table->hook_remove = ospf6_top_route_hook_remove; - o->brouter_table = ospf6_route_table_create (); + o->brouter_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, BORDER_ROUTERS); + o->brouter_table->scope = o; o->brouter_table->hook_add = ospf6_top_brouter_hook_add; o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove; - o->external_table = ospf6_route_table_create (); + o->external_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, EXTERNAL_ROUTES); + o->external_table->scope = o; + o->external_id_table = route_table_init (); return o; diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h index 2346cc9a..1dfd96b5 100644 --- a/ospf6d/ospf6d.h +++ b/ospf6d/ospf6d.h @@ -22,7 +22,7 @@ #ifndef OSPF6D_H #define OSPF6D_H -#define OSPF6_DAEMON_VERSION "0.9.7p" +#define OSPF6_DAEMON_VERSION "0.9.7q" /* global variables */ extern int errno; -- cgit v1.2.1