]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospfd: add all_rtrs route table when opaque enabled
authorChristian Hopps <chopps@labn.net>
Sat, 15 Jan 2022 11:13:43 +0000 (06:13 -0500)
committerChristian Hopps <chopps@labn.net>
Thu, 2 Jun 2022 20:37:16 +0000 (16:37 -0400)
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>
ospfd/ospf_route.c
ospfd/ospf_route.h
ospfd/ospf_spf.c
ospfd/ospf_spf.h
ospfd/ospf_ti_lfa.c
ospfd/ospfd.h
tests/ospfd/test_ospf_spf.c

index ec0c5524c93678aa2114ee281fdd2cff6e0637b7..c5b26bbd76a01f646e78e840d7869bf5d6ccb1e4 100644 (file)
@@ -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,
index 5463e70ffba574897dc981387b4da91ecea5f655..fa9478fcedb2bd4136c7f06d244ffca31b7e6e08 100644 (file)
@@ -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 *);
index baf02365a227a9b4495db9bf2c072385c3e19dd3..1974a42f5232ce81511a4113e76f35a1e22fcf33 100644 (file)
@@ -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); */
index 20f38440aaef4ca1732ba551e075831ae92a7c5f..834bfd0bb02eccb01e14c4db603d04e719ffc4b7 100644 (file)
@@ -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);
index 347128a4f428b0275161e89d3d1fdbaf81df0ddf..28d24bcbe6b4b0af76dcc57d9f53af22205f57cf 100644 (file)
@@ -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;
index 268e4d6f8db895ff2d34d7e925e3c811e471cd4b..76501dd6bbce8ddcb8779d54630d767f07ea9d26 100644 (file)
@@ -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. */
 
index 3562b5f2f859991a44c15df7cf6998142b3e9c8d..73f2e29834e8f2f452eeb6c79e00ec5059f1bebc 100644 (file)
@@ -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");