diff options
-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 | ||||
-rw-r--r-- | tests/ospfd/test_ospf_spf.c | 6 |
7 files changed, 76 insertions, 19 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. */ diff --git a/tests/ospfd/test_ospf_spf.c b/tests/ospfd/test_ospf_spf.c index 3562b5f2f..73f2e2983 100644 --- a/tests/ospfd/test_ospf_spf.c +++ b/tests/ospfd/test_ospf_spf.c @@ -52,6 +52,7 @@ static void test_run_spf(struct vty *vty, struct ospf *ospf, enum protection_type protection_type, bool verbose) { struct route_table *new_table, *new_rtrs; + struct route_table *all_rtrs = NULL; struct ospf_area *area; struct p_space *p_space; struct q_space *q_space; @@ -63,10 +64,11 @@ static void test_run_spf(struct vty *vty, struct ospf *ospf, new_table = route_table_init(); new_rtrs = route_table_init(); + all_rtrs = route_table_init(); /* dryrun true, root_node false */ - ospf_spf_calculate(area, area->router_lsa_self, new_table, new_rtrs, - true, false); + ospf_spf_calculate(area, area->router_lsa_self, new_table, all_rtrs, + new_rtrs, true, false); if (verbose) { vty_out(vty, "SPF Tree without TI-LFA backup paths:\n\n"); |