From: Vipin Kumar <[email protected]> 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 <[email protected]> Reviewed-by: Vivek Venkatraman <[email protected]> --- ospf6d/ospf6_abr.c | 10 +++++----- ospf6d/ospf6_asbr.c | 5 +++-- ospf6d/ospf6_intra.c | 15 +++++++++------ ospf6d/ospf6_route.c | 2 +- ospf6d/ospf6_spf.c | 5 +++-- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index bb79900..7e94cef 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -106,14 +106,14 @@ void ospf6_abr_disable_area (struct ospf6_area *area) { struct ospf6_area *oa; - struct ospf6_route *ro; + struct ospf6_route *ro, *nro; struct ospf6_lsa *old; struct listnode *node, *nnode; /* Withdraw all summary prefixes previously originated */ - for (ro = ospf6_route_head (area->summary_prefix); ro; - ro = ospf6_route_next (ro)) + for (ro = ospf6_route_head (area->summary_prefix); ro; ro = nro) { + nro = ospf6_route_next (ro); old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id, area->ospf6->router_id, area->lsdb); if (old) @@ -122,9 +122,9 @@ ospf6_abr_disable_area (struct ospf6_area *area) } /* Withdraw all summary router-routes previously originated */ - for (ro = ospf6_route_head (area->summary_router); ro; - ro = ospf6_route_next (ro)) + for (ro = ospf6_route_head (area->summary_router); ro; ro = nro) { + nro = ospf6_route_next (ro); old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id, area->ospf6->router_id, area->lsdb); if (old) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index ec08ded..f99ccab 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -240,7 +240,7 @@ ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa) { struct ospf6_as_external_lsa *external; struct prefix prefix; - struct ospf6_route *route; + struct ospf6_route *route, *nroute; char buf[64]; external = (struct ospf6_as_external_lsa *) @@ -274,8 +274,9 @@ ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa) for (ospf6_route_lock (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) continue; if (route->path.origin.type != lsa->header->type) diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index c13865c..dbd6ad9 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -1338,7 +1338,7 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa) struct ospf6_area *oa; struct ospf6_intra_prefix_lsa *intra_prefix_lsa; struct prefix prefix; - struct ospf6_route *route; + struct ospf6_route *route, *nroute; int prefix_num; struct ospf6_prefix *op; char *start, *current, *end; @@ -1376,8 +1376,9 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa) for (ospf6_route_lock (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) continue; if (route->path.area_id != oa->area_id) @@ -1407,7 +1408,7 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa) void ospf6_intra_route_calculation (struct ospf6_area *oa) { - struct ospf6_route *route; + struct ospf6_route *route, *nroute; u_int16_t type; struct ospf6_lsa *lsa; void (*hook_add) (struct ospf6_route *) = NULL; @@ -1434,8 +1435,9 @@ ospf6_intra_route_calculation (struct ospf6_area *oa) oa->route_table->hook_remove = hook_remove; 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) && CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD)) { @@ -1515,7 +1517,7 @@ ospf6_brouter_debug_print (struct ospf6_route *brouter) void 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_remove) (struct ospf6_route *) = NULL; u_int32_t brouter_id; @@ -1584,8 +1586,9 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa) oa->ospf6->brouter_table->hook_remove = hook_remove; 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); inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 5057556..1c6495b 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -620,7 +620,7 @@ ospf6_route_remove (struct ospf6_route *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; SET_FLAG (route->next->flag, OSPF6_ROUTE_BEST); diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 88e1285..b4a920f 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -367,11 +367,12 @@ ospf6_spf_install (struct ospf6_vertex *v, void ospf6_spf_table_finish (struct ospf6_route_table *result_table) { - struct ospf6_route *route; + struct ospf6_route *route, *nroute; struct ospf6_vertex *v; 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; ospf6_vertex_delete (v); ospf6_route_remove (route, result_table); -- 1.9.1 _______________________________________________ Quagga-dev mailing list [email protected] https://lists.quagga.net/mailman/listinfo/quagga-dev
