diff options
author | Christian Hopps <chopps@labn.net> | 2022-01-15 12:13:43 +0100 |
---|---|---|
committer | Christian Hopps <chopps@labn.net> | 2022-06-02 22:37:16 +0200 |
commit | b538baf352429ef238c7d6c8e23bb643d8e051cd (patch) | |
tree | 6e2acf05cc1b478a50e58c1ef4fcfc6cee3755cf /ospfd | |
parent | ospfd: cli: add client api debug option (diff) | |
download | frr-b538baf352429ef238c7d6c8e23bb643d8e051cd.tar.xz frr-b538baf352429ef238c7d6c8e23bb643d8e051cd.zip |
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 <chopps@labn.net>
Diffstat (limited to 'ospfd')
-rw-r--r-- | ospfd/ospf_route.c | 23 | ||||
-rw-r--r-- | ospfd/ospf_route.h | 5 | ||||
-rw-r--r-- | ospfd/ospf_spf.c | 42 | ||||
-rw-r--r-- | ospfd/ospf_spf.h | 3 | ||||
-rw-r--r-- | ospfd/ospf_ti_lfa.c | 13 | ||||
-rw-r--r-- | ospfd/ospfd.h | 3 |
6 files changed, 72 insertions, 17 deletions
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index ec0c5524c..c5b26bbd7 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -363,7 +363,7 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt) /* RFC2328 16.1. (4). For "router". */ void ospf_intra_add_router(struct route_table *rt, struct vertex *v, - struct ospf_area *area) + struct ospf_area *area, bool add_all) { struct route_node *rn; struct ospf_route * or ; @@ -388,7 +388,8 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v, /* If the newly added vertex is an area border router or AS boundary router, a routing table entry is added whose destination type is "router". */ - if (!IS_ROUTER_LSA_BORDER(lsa) && !IS_ROUTER_LSA_EXTERNAL(lsa)) { + if (!add_all && !IS_ROUTER_LSA_BORDER(lsa) && + !IS_ROUTER_LSA_EXTERNAL(lsa)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( "ospf_intra_add_router: this router is neither ASBR nor ABR, skipping it"); @@ -733,6 +734,24 @@ void ospf_route_table_dump(struct route_table *rt) zlog_debug("========================================"); } +void ospf_router_route_table_dump(struct route_table *rt) +{ + struct route_node *rn; + struct ospf_route *or; + struct listnode *node; + + zlog_debug("========== OSPF routing table =========="); + for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or)) { + assert(or->type == OSPF_DESTINATION_ROUTER); + zlog_debug("R %-18pI4 %-15pI4 %s %d", &rn->p.u.prefix4, + &or->u.std.area_id, + ospf_path_type_str[or->path_type], or->cost); + } + } + zlog_debug("========================================"); +} + /* This is 16.4.1 implementation. o Intra-area paths using non-backbone areas are always the most preferred. o The other paths, intra-area backbone paths and inter-area paths, diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h index 5463e70ff..fa9478fce 100644 --- a/ospfd/ospf_route.h +++ b/ospfd/ospf_route.h @@ -139,9 +139,10 @@ extern void ospf_route_table_free(struct route_table *); extern void ospf_route_install(struct ospf *, struct route_table *); extern void ospf_route_table_dump(struct route_table *); +extern void ospf_router_route_table_dump(struct route_table *rt); -extern void ospf_intra_add_router(struct route_table *, struct vertex *, - struct ospf_area *); +extern void ospf_intra_add_router(struct route_table *rt, struct vertex *v, + struct ospf_area *area, bool add_all); extern void ospf_intra_add_transit(struct route_table *, struct vertex *, struct ospf_area *); diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index baf02365a..1974a42f5 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); */ diff --git a/ospfd/ospf_spf.h b/ospfd/ospf_spf.h index 20f38440a..834bfd0bb 100644 --- a/ospfd/ospf_spf.h +++ b/ospfd/ospf_spf.h @@ -76,13 +76,16 @@ extern void ospf_spf_calculate_schedule(struct ospf *, ospf_spf_reason_t); extern 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); extern 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); extern void ospf_spf_calculate_areas(struct ospf *ospf, struct route_table *new_table, + struct route_table *all_rtrs, struct route_table *new_rtrs); extern void ospf_rtrs_free(struct route_table *); extern void ospf_spf_cleanup(struct vertex *spf, struct list *vertex_list); diff --git a/ospfd/ospf_ti_lfa.c b/ospfd/ospf_ti_lfa.c index 347128a4f..28d24bcbe 100644 --- a/ospfd/ospf_ti_lfa.c +++ b/ospfd/ospf_ti_lfa.c @@ -326,8 +326,8 @@ static void ospf_ti_lfa_generate_inner_label_stack( XCALLOC(MTYPE_OSPF_P_SPACE, sizeof(struct p_spaces_head)); /* dry run true, root node false */ - ospf_spf_calculate(area, start_vertex->lsa_p, new_table, new_rtrs, true, - false); + ospf_spf_calculate(area, start_vertex->lsa_p, new_table, NULL, new_rtrs, + true, false); q_node = ospf_spf_vertex_find(end_vertex->id, area->spf_vertex_list); @@ -676,6 +676,7 @@ static void ospf_ti_lfa_generate_q_spaces(struct ospf_area *area, sizeof(struct ospf_ti_lfa_node_info)); new_table = route_table_init(); + /* XXX do these get freed?? */ new_rtrs = route_table_init(); /* @@ -683,7 +684,8 @@ static void ospf_ti_lfa_generate_q_spaces(struct ospf_area *area, * dry run true, root node false */ area->spf_reversed = true; - ospf_spf_calculate(area, dest->lsa_p, new_table, new_rtrs, true, false); + ospf_spf_calculate(area, dest->lsa_p, new_table, NULL, new_rtrs, true, + false); /* Reset the flag for reverse SPF */ area->spf_reversed = false; @@ -750,6 +752,7 @@ static void ospf_ti_lfa_generate_post_convergence_spf(struct ospf_area *area, struct route_table *new_table, *new_rtrs; new_table = route_table_init(); + /* XXX do these get freed?? */ new_rtrs = route_table_init(); area->spf_protected_resource = p_space->protected_resource; @@ -769,8 +772,8 @@ static void ospf_ti_lfa_generate_post_convergence_spf(struct ospf_area *area, * endeavour (because LSAs are stored as a 'raw' stream), so we go with * this rather hacky way for now. */ - ospf_spf_calculate(area, area->router_lsa_self, new_table, new_rtrs, - true, false); + ospf_spf_calculate(area, area->router_lsa_self, new_table, NULL, + new_rtrs, true, false); p_space->pc_spf = area->spf; p_space->pc_vertex_list = area->spf_vertex_list; diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 268e4d6f8..76501dd6b 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -234,6 +234,9 @@ struct ospf { struct route_table *old_table; /* Old routing table. */ struct route_table *new_table; /* Current routing table. */ + struct route_table *oall_rtrs; /* Old router RT. */ + struct route_table *all_rtrs; /* New routers RT. */ + struct route_table *old_rtrs; /* Old ABR/ASBR RT. */ struct route_table *new_rtrs; /* New ABR/ASBR RT. */ |