[ospf6d] GNU Zebra #3562: ABR Crash fix, memory fixes, route table debugs

2006-02-22  Yasuhiro Ohara  <yasu@sfc.wide.ad.jp>

	* valgrind check and memory fix
	* route table identification string added
	* ospf6d.h: version 0.9.7q
This commit is contained in:
Paul Jakma 2006-05-15 10:46:07 +00:00
parent 932bf1976a
commit cf1ce250d2
11 changed files with 340 additions and 54 deletions

View file

@ -1,3 +1,9 @@
2006-02-22 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
* valgrind check and memory fix
* route table identification string added
* ospf6d.h: version 0.9.7q
2005-10-20 Yasuhiro Ohara <yasu@sfc.wide.ad.jp> 2005-10-20 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
* ospf6_neighbor.c: add the calling of ospf6_maxage_remove () * ospf6_neighbor.c: add the calling of ospf6_maxage_remove ()

View file

@ -538,6 +538,8 @@ ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa)
char buf[64]; char buf[64];
int is_debug = 0; int is_debug = 0;
memset (&prefix, 0, sizeof (prefix));
if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX)) if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
{ {
struct ospf6_inter_prefix_lsa *prefix_lsa; 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 && if (route->path.area_id == oa->area_id &&
route->path.origin.type == lsa->header->type && route->path.origin.type == lsa->header->type &&
route->path.origin.id == lsa->header->id && 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; old = route;
route = ospf6_route_next (route); route = ospf6_route_next (route);
} }

View file

@ -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->hook_remove = ospf6_area_lsdb_hook_remove;
oa->lsdb_self = ospf6_lsdb_create (oa); oa->lsdb_self = ospf6_lsdb_create (oa);
oa->spf_table = ospf6_route_table_create (); oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS);
oa->route_table = ospf6_route_table_create (); 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_add = ospf6_area_route_hook_add;
oa->route_table->hook_remove = ospf6_area_route_hook_remove; oa->route_table->hook_remove = ospf6_area_route_hook_remove;
oa->range_table = ospf6_route_table_create (); oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
oa->summary_prefix = ospf6_route_table_create (); oa->range_table->scope = oa;
oa->summary_router = ospf6_route_table_create (); 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 */ /* set default options */
OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6); 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; tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
conf_debug_ospf6_spf = 0; 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); ospf6_spf_calculation (router_id, spf_table, oa);
conf_debug_ospf6_spf = tmp_debug_ospf6_spf; conf_debug_ospf6_spf = tmp_debug_ospf6_spf;

View file

@ -139,7 +139,8 @@ ospf6_interface_create (struct interface *ifp)
oi->lsdb->hook_remove = ospf6_interface_lsdb_hook; oi->lsdb->hook_remove = ospf6_interface_lsdb_hook;
oi->lsdb_self = ospf6_lsdb_create (oi); 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 */ /* link both */
oi->interface = ifp; oi->interface = ifp;

View file

@ -721,7 +721,7 @@ ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
intra_prefix_lsa->ref_id = htonl (0); intra_prefix_lsa->ref_id = htonl (0);
intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id; 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)) 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 */ /* connected prefix to advertise */
route_advertise = ospf6_route_table_create (); route_advertise = ospf6_route_table_create (0, 0);
type = ntohs (OSPF6_LSTYPE_LINK); type = ntohs (OSPF6_LSTYPE_LINK);
for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa; 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); 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 void
ospf6_intra_brouter_calculation (struct ospf6_area *oa) 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; for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
brouter = ospf6_route_next (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) if (brouter->path.area_id != oa->area_id)
continue; continue;
brouter->flag = OSPF6_ROUTE_REMOVE; 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; for (brouter = ospf6_route_head (oa->spf_table); brouter;
brouter = ospf6_route_next (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) if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
continue; continue;
if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0)) 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->type = OSPF6_DEST_TYPE_ROUTER;
copy->path.area_id = oa->area_id; copy->path.area_id = oa->area_id;
ospf6_route_add (copy, oa->ospf6->brouter_table); 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; 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)) IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
zlog_info ("brouter %s appears via area %s", zlog_info ("brouter %s appears via area %s",
brouter_name, oa->name); brouter_name, oa->name);
/* newly added */ /* newly added */
if (hook_add) if (hook_add)
(*hook_add) (brouter); (*hook_add) (brouter);

View file

@ -1120,10 +1120,9 @@ ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst,
on->name); on->name);
ospf6_decrement_retrans_count (mine); ospf6_decrement_retrans_count (mine);
ospf6_lsdb_remove (mine, on->retrans_list);
if (OSPF6_LSA_IS_MAXAGE (mine)) if (OSPF6_LSA_IS_MAXAGE (mine))
ospf6_maxage_remove (on->ospf6_if->area->ospf6); ospf6_maxage_remove (on->ospf6_if->area->ospf6);
ospf6_lsdb_remove (mine, on->retrans_list);
ospf6_lsa_delete (his); ospf6_lsa_delete (his);
} }
@ -1186,6 +1185,9 @@ ospf6_receive (struct thread *thread)
thread_add_read (master, ospf6_receive, NULL, sockfd); thread_add_read (master, ospf6_receive, NULL, sockfd);
/* initialize */ /* initialize */
memset (&src, 0, sizeof (src));
memset (&dst, 0, sizeof (dst));
ifindex = 0;
memset (recvbuf, 0, iobuflen); memset (recvbuf, 0, iobuflen);
iovector[0].iov_base = recvbuf; iovector[0].iov_base = recvbuf;
iovector[0].iov_len = iobuflen; iovector[0].iov_len = iobuflen;

View file

@ -254,6 +254,7 @@ ospf6_sendmsg (struct in6_addr *src, struct in6_addr *dst,
/* scmsgp = CMSG_NXTHDR (&smsghdr, scmsgp); */ /* scmsgp = CMSG_NXTHDR (&smsghdr, scmsgp); */
/* send msg hdr */ /* send msg hdr */
memset (&smsghdr, 0, sizeof (smsghdr));
smsghdr.msg_iov = message; smsghdr.msg_iov = message;
smsghdr.msg_iovlen = iov_count (message); smsghdr.msg_iovlen = iov_count (message);
smsghdr.msg_name = (caddr_t) &dst_sin6; 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); */ /* rcmsgp = CMSG_NXTHDR (&rmsghdr, rcmsgp); */
/* receive msg hdr */ /* receive msg hdr */
memset (&rmsghdr, 0, sizeof (rmsghdr));
rmsghdr.msg_iov = message; rmsghdr.msg_iov = message;
rmsghdr.msg_iovlen = iov_count (message); rmsghdr.msg_iovlen = iov_count (message);
rmsghdr.msg_name = (caddr_t) &src_sin6; rmsghdr.msg_name = (caddr_t) &src_sin6;

View file

@ -27,15 +27,112 @@
#include "table.h" #include "table.h"
#include "vty.h" #include "vty.h"
#include "command.h" #include "command.h"
#include "linklist.h"
#include "ospf6_proto.h" #include "ospf6_proto.h"
#include "ospf6_lsa.h" #include "ospf6_lsa.h"
#include "ospf6_lsdb.h" #include "ospf6_lsdb.h"
#include "ospf6_route.h" #include "ospf6_route.h"
#include "ospf6_top.h"
#include "ospf6_area.h"
#include "ospf6_interface.h"
#include "ospf6d.h" #include "ospf6d.h"
unsigned char conf_debug_ospf6_route = 0; 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 void
ospf6_linkstate_prefix (u_int32_t adv_router, u_int32_t id, ospf6_linkstate_prefix (u_int32_t adv_router, u_int32_t id,
struct prefix *prefix) struct prefix *prefix)
@ -100,6 +197,7 @@ ospf6_route_copy (struct ospf6_route *route)
new->rnode = NULL; new->rnode = NULL;
new->prev = NULL; new->prev = NULL;
new->next = NULL; new->next = NULL;
new->table = NULL;
new->lock = 0; new->lock = 0;
return new; return new;
} }
@ -116,8 +214,14 @@ ospf6_route_unlock (struct ospf6_route *route)
assert (route->lock > 0); assert (route->lock > 0);
route->lock--; route->lock--;
if (route->lock == 0) if (route->lock == 0)
{
/* 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); ospf6_route_delete (route);
} }
}
/* Route compare function. If ra is more preferred, it returns /* Route compare function. If ra is more preferred, it returns
less than 0. If rb is more preferred returns greater than 0. less than 0. If rb is more preferred returns greater than 0.
@ -202,33 +306,50 @@ ospf6_route_lookup_bestmatch (struct prefix *prefix,
#ifndef NDEBUG #ifndef NDEBUG
static void 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]; char buf[64];
unsigned int num = 0; unsigned int link_error = 0, num = 0;
for (debug = ospf6_route_head (table); debug;
debug = ospf6_route_next (debug)) 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++; num++;
if (num == table->count) if (link_error == 0 && num == table->count)
return; return;
zlog_debug ("PANIC !! table[%p]->count = %d, real = %d", zlog_err ("PANIC !!");
table, table->count, num); zlog_err ("Something has gone wrong with ospf6_route_table[%p]", table);
for (debug = ospf6_route_head (table); debug; zlog_debug ("table count = %d, real number = %d", table->count, num);
debug = ospf6_route_next (debug)) zlog_debug ("DUMP START");
for (r = ospf6_route_head (table); r; r = ospf6_route_next (r))
{ {
prefix2str (&debug->prefix, buf, sizeof (buf)); prefix2str (&r->prefix, buf, sizeof (buf));
zlog_debug ("%p %p %s", debug->prev, debug->next, buf); zlog_info ("%p<-[%p]->%p : %s", r->prev, r, r->next, buf);
} }
zlog_debug ("DUMP END"); 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 #else
#define ospf6_route_count_assert(t) ((void) 0) #define ospf6_route_table_assert(t) ((void) 0)
#endif /*NDEBUG*/ #endif /*NDEBUG*/
struct ospf6_route * struct ospf6_route *
@ -251,8 +372,11 @@ ospf6_route_add (struct ospf6_route *route,
else else
prefix2str (&route->prefix, buf, sizeof (buf)); prefix2str (&route->prefix, buf, sizeof (buf));
if (IS_OSPF6_DEBUG_ROUTE (TABLE)) if (IS_OSPF6_DEBUG_ROUTE (MEMORY))
zlog_debug ("route add %s", buf); 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); gettimeofday (&now, NULL);
@ -282,18 +406,26 @@ ospf6_route_add (struct ospf6_route *route,
/* if route does not actually change, return unchanged */ /* if route does not actually change, return unchanged */
if (ospf6_route_is_identical (old, route)) if (ospf6_route_is_identical (old, route))
{ {
if (IS_OSPF6_DEBUG_ROUTE (TABLE)) if (IS_OSPF6_DEBUG_ROUTE (MEMORY))
zlog_debug (" identical route found, ignore"); 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); ospf6_route_delete (route);
SET_FLAG (old->flag, OSPF6_ROUTE_ADD); SET_FLAG (old->flag, OSPF6_ROUTE_ADD);
ospf6_route_count_assert (table); ospf6_route_table_assert (table);
return old; return old;
} }
if (IS_OSPF6_DEBUG_ROUTE (TABLE)) if (IS_OSPF6_DEBUG_ROUTE (MEMORY))
zlog_debug (" old route found, replace"); 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 */ /* replace old one if exists */
if (node->info == old) if (node->info == old)
@ -311,12 +443,14 @@ ospf6_route_add (struct ospf6_route *route,
route->installed = old->installed; route->installed = old->installed;
route->changed = now; route->changed = now;
assert (route->table == NULL);
route->table = table;
ospf6_route_unlock (old); /* will be deleted later */ ospf6_route_unlock (old); /* will be deleted later */
ospf6_route_lock (route); ospf6_route_lock (route);
SET_FLAG (route->flag, OSPF6_ROUTE_CHANGE); SET_FLAG (route->flag, OSPF6_ROUTE_CHANGE);
ospf6_route_count_assert (table); ospf6_route_table_assert (table);
if (table->hook_add) if (table->hook_add)
(*table->hook_add) (route); (*table->hook_add) (route);
@ -327,8 +461,12 @@ ospf6_route_add (struct ospf6_route *route,
/* insert if previous or next node found */ /* insert if previous or next node found */
if (prev || next) if (prev || next)
{ {
if (IS_OSPF6_DEBUG_ROUTE (TABLE)) if (IS_OSPF6_DEBUG_ROUTE (MEMORY))
zlog_debug (" another path found, insert"); 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) if (prev == NULL)
prev = next->prev; prev = next->prev;
@ -348,14 +486,19 @@ ospf6_route_add (struct ospf6_route *route,
node->info = route; node->info = route;
UNSET_FLAG (next->flag, OSPF6_ROUTE_BEST); UNSET_FLAG (next->flag, OSPF6_ROUTE_BEST);
SET_FLAG (route->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->installed = now;
route->changed = now; route->changed = now;
assert (route->table == NULL);
route->table = table;
ospf6_route_lock (route); ospf6_route_lock (route);
table->count++; table->count++;
ospf6_route_count_assert (table); ospf6_route_table_assert (table);
SET_FLAG (route->flag, OSPF6_ROUTE_ADD); SET_FLAG (route->flag, OSPF6_ROUTE_ADD);
if (table->hook_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 */ /* Else, this is the brand new route regarding to the prefix */
if (IS_OSPF6_DEBUG_ROUTE (TABLE)) if (IS_OSPF6_DEBUG_ROUTE (MEMORY))
zlog_debug (" brand new route, add"); 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); assert (node->info == NULL);
node->info = route; node->info = route;
@ -374,6 +521,8 @@ ospf6_route_add (struct ospf6_route *route,
ospf6_route_lock (route); ospf6_route_lock (route);
route->installed = now; route->installed = now;
route->changed = now; route->changed = now;
assert (route->table == NULL);
route->table = table;
/* lookup real existing next route */ /* lookup real existing next route */
nextnode = node; nextnode = node;
@ -416,7 +565,7 @@ ospf6_route_add (struct ospf6_route *route,
} }
table->count++; table->count++;
ospf6_route_count_assert (table); ospf6_route_table_assert (table);
SET_FLAG (route->flag, OSPF6_ROUTE_ADD); SET_FLAG (route->flag, OSPF6_ROUTE_ADD);
if (table->hook_add) if (table->hook_add)
@ -438,8 +587,11 @@ ospf6_route_remove (struct ospf6_route *route,
else else
prefix2str (&route->prefix, buf, sizeof (buf)); prefix2str (&route->prefix, buf, sizeof (buf));
if (IS_OSPF6_DEBUG_ROUTE (TABLE)) if (IS_OSPF6_DEBUG_ROUTE (MEMORY))
zlog_debug ("route remove: %s", buf); 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); node = route_node_lookup (table->table, &route->prefix);
assert (node); assert (node);
@ -473,7 +625,7 @@ ospf6_route_remove (struct ospf6_route *route,
} }
table->count--; table->count--;
ospf6_route_count_assert (table); ospf6_route_table_assert (table);
SET_FLAG (route->flag, OSPF6_ROUTE_WAS_REMOVED); 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; route = (struct ospf6_route *) node->info;
assert (route->prev == NULL); assert (route->prev == NULL);
assert (route->table == table);
ospf6_route_lock (route); 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; return route;
} }
@ -513,6 +672,11 @@ ospf6_route_next (struct ospf6_route *route)
{ {
struct ospf6_route *next = route->next; 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); ospf6_route_unlock (route);
if (next) if (next)
ospf6_route_lock (next); ospf6_route_lock (next);
@ -600,11 +764,13 @@ ospf6_route_remove_all (struct ospf6_route_table *table)
} }
struct ospf6_route_table * struct ospf6_route_table *
ospf6_route_table_create () ospf6_route_table_create (int s, int t)
{ {
struct ospf6_route_table *new; struct ospf6_route_table *new;
new = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_route_table)); new = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_route_table));
new->table = route_table_init (); new->table = route_table_init ();
new->scope_type = s;
new->table_type = t;
return new; return new;
} }
@ -616,7 +782,6 @@ ospf6_route_table_delete (struct ospf6_route_table *table)
XFREE (MTYPE_OSPF6_ROUTE, table); XFREE (MTYPE_OSPF6_ROUTE, table);
} }
/* VTY commands */ /* VTY commands */
void void

View file

@ -29,6 +29,7 @@ extern unsigned char conf_debug_ospf6_route;
#define OSPF6_DEBUG_ROUTE_TABLE 0x01 #define OSPF6_DEBUG_ROUTE_TABLE 0x01
#define OSPF6_DEBUG_ROUTE_INTRA 0x02 #define OSPF6_DEBUG_ROUTE_INTRA 0x02
#define OSPF6_DEBUG_ROUTE_INTER 0x04 #define OSPF6_DEBUG_ROUTE_INTER 0x04
#define OSPF6_DEBUG_ROUTE_MEMORY 0x80
#define OSPF6_DEBUG_ROUTE_ON(level) \ #define OSPF6_DEBUG_ROUTE_ON(level) \
(conf_debug_ospf6_route |= (level)) (conf_debug_ospf6_route |= (level))
#define OSPF6_DEBUG_ROUTE_OFF(level) \ #define OSPF6_DEBUG_ROUTE_OFF(level) \
@ -112,7 +113,7 @@ struct ospf6_path
struct ospf6_route struct ospf6_route
{ {
struct route_node *rnode; struct route_node *rnode;
struct ospf6_route_table *table;
struct ospf6_route *prev; struct ospf6_route *prev;
struct ospf6_route *next; struct ospf6_route *next;
@ -162,6 +163,10 @@ struct ospf6_route
struct ospf6_route_table struct ospf6_route_table
{ {
int scope_type;
int table_type;
void *scope;
/* patricia tree */ /* patricia tree */
struct route_table *table; struct route_table *table;
@ -173,6 +178,25 @@ struct ospf6_route_table
void (*hook_remove) (struct ospf6_route *); 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_str[OSPF6_DEST_TYPE_MAX];
extern const char *ospf6_dest_type_substr[OSPF6_DEST_TYPE_MAX]; extern const char *ospf6_dest_type_substr[OSPF6_DEST_TYPE_MAX];
#define OSPF6_DEST_TYPE_NAME(x) \ #define OSPF6_DEST_TYPE_NAME(x) \
@ -258,7 +282,7 @@ struct ospf6_route *ospf6_route_match_next (struct prefix *prefix,
struct ospf6_route *route); struct ospf6_route *route);
void ospf6_route_remove_all (struct ospf6_route_table *); 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_table_delete (struct ospf6_route_table *);
void ospf6_route_dump (struct ospf6_route_table *table); void ospf6_route_dump (struct ospf6_route_table *table);

View file

@ -126,15 +126,19 @@ ospf6_create ()
o->lsdb->hook_add = ospf6_top_lsdb_hook_add; o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove; 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_add = ospf6_top_route_hook_add;
o->route_table->hook_remove = ospf6_top_route_hook_remove; 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_add = ospf6_top_brouter_hook_add;
o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove; 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 (); o->external_id_table = route_table_init ();
return o; return o;

View file

@ -22,7 +22,7 @@
#ifndef OSPF6D_H #ifndef OSPF6D_H
#define OSPF6D_H #define OSPF6D_H
#define OSPF6_DAEMON_VERSION "0.9.7p" #define OSPF6_DAEMON_VERSION "0.9.7q"
/* global variables */ /* global variables */
extern int errno; extern int errno;