From 8873ebd3d44f87e4a31c9a7292513880a5ec7ce8 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Thu, 19 Apr 2018 12:26:20 -0700 Subject: [PATCH] ospf6d: fix ospf6 asbr crash Durig ospf6 instance cleanup all border routers are removed from the db then external LSAs removal from DB is triggered. During the time, external route path would not be valid as brouters along with its rechability have vanished. For a given external route removal check if no more paths available simple remove the route from route db. Ticket:CM-20669 Testing Done: Bring up ASBR configuration with ECMP paths to a route. Bring down the ospf6 instance and validate route is removed from the DB. Signed-off-by: Chirag Shah --- ospf6d/ospf6_asbr.c | 46 +++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 1b46b9c68d..0fe0cada39 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -685,8 +685,9 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) { prefix2str(&prefix, buf, sizeof(buf)); zlog_debug( - "%s: route %s path found with nh %u to remove.", + "%s: route %s path found with cost %u nh %u to remove.", __PRETTY_FUNCTION__, buf, + route->path.cost, listcount(o_path->nh_list)); } @@ -738,28 +739,37 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, listcount(route->nh_list)); } - /* Update RIB/FIB with effective nh_list */ - if (ospf6->route_table->hook_add) - (*ospf6->route_table->hook_add)(route); + if (listcount(route->paths)) { + /* Update RIB/FIB with effective + * nh_list + */ + if (ospf6->route_table->hook_add) + (*ospf6->route_table->hook_add) + (route); - /* route's primary path is similar to LSA, - * replace route's primary path with - * route's paths list head. - */ - if (route->path.origin.id == lsa->header->id - && route->path.origin.adv_router - == lsa->header->adv_router) { - struct ospf6_path *h_path; + /* route's primary path is similar + * to LSA, replace route's primary + * path with route's paths list head. + */ + if ((route->path.origin.id == + lsa->header->id) && + (route->path.origin.adv_router + == lsa->header->adv_router)) { + struct ospf6_path *h_path; - h_path = (struct ospf6_path *) + h_path = (struct ospf6_path *) listgetdata( listhead(route->paths)); - route->path.origin.type = - h_path->origin.type; - route->path.origin.id = - h_path->origin.id; - route->path.origin.adv_router = + route->path.origin.type = + h_path->origin.type; + route->path.origin.id = + h_path->origin.id; + route->path.origin.adv_router = h_path->origin.adv_router; + } + } else { + ospf6_route_remove(route, + ospf6->route_table); } } continue;