summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ospfd/ospf_route.c23
-rw-r--r--ospfd/ospf_route.h5
-rw-r--r--ospfd/ospf_spf.c42
-rw-r--r--ospfd/ospf_spf.h3
-rw-r--r--ospfd/ospf_ti_lfa.c13
-rw-r--r--ospfd/ospfd.h3
-rw-r--r--tests/ospfd/test_ospf_spf.c6
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");