Fixing a couple of issues with ospf6_route_remove () routine.

When a route_node has multiple ospf6_routes under it (common subnet case),
then the current implementation has an issue in adjusting the route_node->info
on a ospf6_route_remove() call.

The main reason is that it ends up using exact match to determine if the next
ospf6_route belongs to the same route_node or not. Fixing that part to use
rnode (the existing back-pointer to the route_node) from the ospf6_route to
determine that.

Also fixing some of the walks to turn them safe so that the route deletion is
fine.

Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2015-05-19 18:03:53 -07:00
parent d973c4f045
commit 0f23bb679b
5 changed files with 21 additions and 16 deletions

View File

@ -110,14 +110,14 @@ void
ospf6_abr_disable_area (struct ospf6_area *area) ospf6_abr_disable_area (struct ospf6_area *area)
{ {
struct ospf6_area *oa; struct ospf6_area *oa;
struct ospf6_route *ro; struct ospf6_route *ro, *nro;
struct ospf6_lsa *old; struct ospf6_lsa *old;
struct listnode *node, *nnode; struct listnode *node, *nnode;
/* Withdraw all summary prefixes previously originated */ /* Withdraw all summary prefixes previously originated */
for (ro = ospf6_route_head (area->summary_prefix); ro; for (ro = ospf6_route_head (area->summary_prefix); ro; ro = nro)
ro = ospf6_route_next (ro))
{ {
nro = ospf6_route_next (ro);
old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id, old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,
area->ospf6->router_id, area->lsdb); area->ospf6->router_id, area->lsdb);
if (old) if (old)
@ -126,9 +126,9 @@ ospf6_abr_disable_area (struct ospf6_area *area)
} }
/* Withdraw all summary router-routes previously originated */ /* Withdraw all summary router-routes previously originated */
for (ro = ospf6_route_head (area->summary_router); ro; for (ro = ospf6_route_head (area->summary_router); ro; ro = nro)
ro = ospf6_route_next (ro))
{ {
nro = ospf6_route_next (ro);
old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id, old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,
area->ospf6->router_id, area->lsdb); area->ospf6->router_id, area->lsdb);
if (old) if (old)

View File

@ -243,7 +243,7 @@ ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
{ {
struct ospf6_as_external_lsa *external; struct ospf6_as_external_lsa *external;
struct prefix prefix; struct prefix prefix;
struct ospf6_route *route; struct ospf6_route *route, *nroute;
char buf[64]; char buf[64];
external = (struct ospf6_as_external_lsa *) external = (struct ospf6_as_external_lsa *)
@ -277,8 +277,9 @@ ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
for (ospf6_route_lock (route); for (ospf6_route_lock (route);
route && ospf6_route_is_prefix (&prefix, route); route && ospf6_route_is_prefix (&prefix, route);
route = ospf6_route_next (route)) route = nroute)
{ {
nroute = ospf6_route_next (route);
if (route->type != OSPF6_DEST_TYPE_NETWORK) if (route->type != OSPF6_DEST_TYPE_NETWORK)
continue; continue;
if (route->path.origin.type != lsa->header->type) if (route->path.origin.type != lsa->header->type)

View File

@ -1364,7 +1364,7 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
struct ospf6_area *oa; struct ospf6_area *oa;
struct ospf6_intra_prefix_lsa *intra_prefix_lsa; struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
struct prefix prefix; struct prefix prefix;
struct ospf6_route *route; struct ospf6_route *route, *nroute;
int prefix_num; int prefix_num;
struct ospf6_prefix *op; struct ospf6_prefix *op;
char *start, *current, *end; char *start, *current, *end;
@ -1402,8 +1402,9 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
for (ospf6_route_lock (route); for (ospf6_route_lock (route);
route && ospf6_route_is_prefix (&prefix, route); route && ospf6_route_is_prefix (&prefix, route);
route = ospf6_route_next (route)) route = nroute)
{ {
nroute = ospf6_route_next (route);
if (route->type != OSPF6_DEST_TYPE_NETWORK) if (route->type != OSPF6_DEST_TYPE_NETWORK)
continue; continue;
if (route->path.area_id != oa->area_id) if (route->path.area_id != oa->area_id)
@ -1433,7 +1434,7 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
void void
ospf6_intra_route_calculation (struct ospf6_area *oa) ospf6_intra_route_calculation (struct ospf6_area *oa)
{ {
struct ospf6_route *route; struct ospf6_route *route, *nroute;
u_int16_t type; u_int16_t type;
struct ospf6_lsa *lsa; struct ospf6_lsa *lsa;
void (*hook_add) (struct ospf6_route *) = NULL; void (*hook_add) (struct ospf6_route *) = NULL;
@ -1460,8 +1461,9 @@ ospf6_intra_route_calculation (struct ospf6_area *oa)
oa->route_table->hook_remove = hook_remove; oa->route_table->hook_remove = hook_remove;
for (route = ospf6_route_head (oa->route_table); route; for (route = ospf6_route_head (oa->route_table); route;
route = ospf6_route_next (route)) route = nroute)
{ {
nroute = ospf6_route_next (route);
if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) && if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD)) CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
{ {
@ -1544,7 +1546,7 @@ ospf6_brouter_debug_print (struct ospf6_route *brouter)
void void
ospf6_intra_brouter_calculation (struct ospf6_area *oa) ospf6_intra_brouter_calculation (struct ospf6_area *oa)
{ {
struct ospf6_route *brouter, *copy; struct ospf6_route *brouter, *nbrouter, *copy;
void (*hook_add) (struct ospf6_route *) = NULL; void (*hook_add) (struct ospf6_route *) = NULL;
void (*hook_remove) (struct ospf6_route *) = NULL; void (*hook_remove) (struct ospf6_route *) = NULL;
u_int32_t brouter_id; u_int32_t brouter_id;
@ -1613,8 +1615,9 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa)
oa->ospf6->brouter_table->hook_remove = hook_remove; oa->ospf6->brouter_table->hook_remove = hook_remove;
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 = nbrouter)
{ {
nbrouter = ospf6_route_next (brouter);
brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));

View File

@ -838,7 +838,7 @@ ospf6_route_remove (struct ospf6_route *route,
if (node->info == route) if (node->info == route)
{ {
if (route->next && ospf6_route_is_same (route->next, route)) if (route->next && route->next->rnode == node)
{ {
node->info = route->next; node->info = route->next;
SET_FLAG (route->next->flag, OSPF6_ROUTE_BEST); SET_FLAG (route->next->flag, OSPF6_ROUTE_BEST);

View File

@ -410,11 +410,12 @@ ospf6_spf_install (struct ospf6_vertex *v,
void void
ospf6_spf_table_finish (struct ospf6_route_table *result_table) ospf6_spf_table_finish (struct ospf6_route_table *result_table)
{ {
struct ospf6_route *route; struct ospf6_route *route, *nroute;
struct ospf6_vertex *v; struct ospf6_vertex *v;
for (route = ospf6_route_head (result_table); route; for (route = ospf6_route_head (result_table); route;
route = ospf6_route_next (route)) route = nroute)
{ {
nroute = ospf6_route_next (route);
v = (struct ospf6_vertex *) route->route_option; v = (struct ospf6_vertex *) route->route_option;
ospf6_vertex_delete (v); ospf6_vertex_delete (v);
ospf6_route_remove (route, result_table); ospf6_route_remove (route, result_table);