From b538baf352429ef238c7d6c8e23bb643d8e051cd Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Sat, 15 Jan 2022 06:13:43 -0500 Subject: ospfd: add all_rtrs route table when opaque enabled The reachable router table is used by OSPF opaque clients in order to determine if the router advertising the opaque LSA data is reachable (i.e., 2-way conectivity check). Signed-off-by: Christian Hopps --- ospfd/ospf_spf.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'ospfd/ospf_spf.c') diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index baf02365a2..1974a42f52 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -1669,6 +1669,7 @@ void ospf_spf_cleanup(struct vertex *spf, struct list *vertex_list) /* Calculating the shortest-path tree for an area, see RFC2328 16.1. */ void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa, struct route_table *new_table, + struct route_table *all_rtrs, struct route_table *new_rtrs, bool is_dry_run, bool is_root_node) { @@ -1737,10 +1738,13 @@ void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa, ospf_vertex_add_parent(v); /* RFC2328 16.1. (4). */ - if (v->type == OSPF_VERTEX_ROUTER) - ospf_intra_add_router(new_rtrs, v, area); - else + if (v->type != OSPF_VERTEX_ROUTER) ospf_intra_add_transit(new_table, v, area); + else { + ospf_intra_add_router(new_rtrs, v, area, false); + if (all_rtrs) + ospf_intra_add_router(all_rtrs, v, area, true); + } /* Iterate back to (2), see RFC2328 16.1. (5). */ } @@ -1748,6 +1752,8 @@ void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa, if (IS_DEBUG_OSPF_EVENT) { ospf_spf_dump(area->spf, 0); ospf_route_table_dump(new_table); + if (all_rtrs) + ospf_router_route_table_dump(all_rtrs); } /* @@ -1771,10 +1777,11 @@ void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa, void ospf_spf_calculate_area(struct ospf *ospf, struct ospf_area *area, struct route_table *new_table, + struct route_table *all_rtrs, struct route_table *new_rtrs) { - ospf_spf_calculate(area, area->router_lsa_self, new_table, new_rtrs, - false, true); + ospf_spf_calculate(area, area->router_lsa_self, new_table, all_rtrs, + new_rtrs, false, true); if (ospf->ti_lfa_enabled) ospf_ti_lfa_compute(area, new_table, @@ -1787,6 +1794,7 @@ void ospf_spf_calculate_area(struct ospf *ospf, struct ospf_area *area, } void ospf_spf_calculate_areas(struct ospf *ospf, struct route_table *new_table, + struct route_table *all_rtrs, struct route_table *new_rtrs) { struct ospf_area *area; @@ -1799,13 +1807,14 @@ void ospf_spf_calculate_areas(struct ospf *ospf, struct route_table *new_table, if (ospf->backbone && ospf->backbone == area) continue; - ospf_spf_calculate_area(ospf, area, new_table, new_rtrs); + ospf_spf_calculate_area(ospf, area, new_table, all_rtrs, + new_rtrs); } /* SPF for backbone, if required */ if (ospf->backbone) ospf_spf_calculate_area(ospf, ospf->backbone, new_table, - new_rtrs); + all_rtrs, new_rtrs); } /* Worker for SPF calculation scheduler. */ @@ -1813,6 +1822,7 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread) { struct ospf *ospf = THREAD_ARG(thread); struct route_table *new_table, *new_rtrs; + struct route_table *all_rtrs = NULL; struct timeval start_time, spf_start_time; unsigned long ia_time, prune_time, rt_time; unsigned long abr_time, total_spf_time, spf_time; @@ -1829,7 +1839,12 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread) monotime(&spf_start_time); new_table = route_table_init(); /* routing table */ new_rtrs = route_table_init(); /* ABR/ASBR routing table */ - ospf_spf_calculate_areas(ospf, new_table, new_rtrs); + + /* If we have opaque enabled then track all router reachability */ + if (CHECK_FLAG(ospf->opaque, OPAQUE_OPERATION_READY_BIT)) + all_rtrs = route_table_init(); + + ospf_spf_calculate_areas(ospf, new_table, all_rtrs, new_rtrs); spf_time = monotime_since(&spf_start_time, NULL); ospf_vl_shut_unapproved(ospf); @@ -1842,6 +1857,8 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread) /* Get rid of transit networks and routers we cannot reach anyway. */ monotime(&start_time); ospf_prune_unreachable_networks(new_table); + if (all_rtrs) + ospf_prune_unreachable_routers(all_rtrs); ospf_prune_unreachable_routers(new_rtrs); prune_time = monotime_since(&start_time, NULL); @@ -1866,6 +1883,15 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread) ospf_route_install(ospf, new_table); rt_time = monotime_since(&start_time, NULL); + /* Free old all routers routing table */ + if (ospf->oall_rtrs) + /* ospf_route_delete (ospf->old_rtrs); */ + ospf_rtrs_free(ospf->oall_rtrs); + + /* Update all routers routing table */ + ospf->oall_rtrs = ospf->all_rtrs; + ospf->all_rtrs = all_rtrs; + /* Free old ABR/ASBR routing table */ if (ospf->old_rtrs) /* ospf_route_delete (ospf->old_rtrs); */ -- cgit v1.2.3