diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index e8a2f93e76..3aa3d47f35 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -831,6 +831,12 @@ Showing Information Show the OSPF routing table, as determined by the most recent SPF calculation. +.. clicmd:: show ip ospf (1-65535) route orr [NAME] + +.. clicmd:: show ip ospf [vrf ] route orr [NAME] + + Show the OSPF routing table, calculated from the active root of all ORR groups or specified ORR group. + .. clicmd:: show ip ospf graceful-restart helper [detail] [json] Displays the Grcaeful Restart Helper details including helper diff --git a/lib/orr_msg.h b/lib/orr_msg.h index 03f92ef125..ec13df61bb 100644 --- a/lib/orr_msg.h +++ b/lib/orr_msg.h @@ -26,7 +26,8 @@ extern "C" { #endif /* REVISIT: Need to check if we can use zero length array */ -#define ORR_MAX_PREFIX 100 +#define ORR_MAX_PREFIX 100 +#define ORR_GROUP_NAME_SIZE 32 struct orr_prefix_metric { struct prefix prefix; @@ -39,6 +40,7 @@ struct orr_igp_metric_reg { uint8_t proto; safi_t safi; struct prefix prefix; + char group_name[ORR_GROUP_NAME_SIZE]; }; /* IGP-BGP message structures */ @@ -60,6 +62,8 @@ struct orr_root { afi_t afi; safi_t safi; + char group_name[ORR_GROUP_NAME_SIZE]; + /* MPLS_TE prefix and router ID */ struct prefix prefix; struct in_addr router_id; diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index 18cb9573f4..59f95c5da2 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -1605,17 +1605,21 @@ DEFPY (debug_ospf_client_api, DEFPY (debug_ospf_orr, debug_ospf_orr_cmd, - "[no$no] debug ospf orr", + "[no$no] debug ospf [(1-65535)$instance] orr", NO_STR DEBUG_STR OSPF_STR + "Instance ID\n" "OSPF ORR information\n") { + if (instance && instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; + if (vty->node == CONFIG_NODE) { if (no) - CONF_DEBUG_OFF(orr, ORR); + DEBUG_OFF(orr, ORR); else - CONF_DEBUG_ON(orr, ORR); + DEBUG_ON(orr, ORR); } else { if (no) TERM_DEBUG_OFF(orr, ORR); diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 6f42fa8d3a..c67181cba6 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2646,8 +2646,6 @@ ospf_router_lsa_install(struct ospf *ospf, struct ospf_lsa *new, int rt_recalc) else if (ospf->orr_spf_request) { ospf_lsa_unlock(&area->router_lsa_rcvd); area->router_lsa_rcvd = ospf_lsa_lock(new); - SET_FLAG(new->flags, OSPF_LSA_ORR); - ospf_refresher_register_lsa(ospf, new); ospf_orr_root_update_rcvd_lsa(area->router_lsa_rcvd); } @@ -2662,7 +2660,6 @@ static struct ospf_lsa *ospf_network_lsa_install(struct ospf *ospf, struct ospf_lsa *new, int rt_recalc) { - /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs The entire routing table must be recalculated, starting with the shortest path calculations for each area (not just the diff --git a/ospfd/ospf_orr.c b/ospfd/ospf_orr.c index 881dd14079..41e2c8e2df 100644 --- a/ospfd/ospf_orr.c +++ b/ospfd/ospf_orr.c @@ -47,7 +47,8 @@ static void ospf_show_orr_root(struct orr_root *root); static void ospf_show_orr(struct ospf *ospf, afi_t afi, safi_t safi); static struct orr_root *ospf_orr_root_new(struct ospf *ospf, afi_t afi, - safi_t safi, struct prefix *p) + safi_t safi, struct prefix *p, + char *group_name) { struct list *orr_root_list = NULL; struct orr_root *root = NULL; @@ -64,11 +65,13 @@ static struct orr_root *ospf_orr_root_new(struct ospf *ospf, afi_t afi, root->safi = safi; prefix_copy(&root->prefix, p); IPV4_ADDR_COPY(&root->router_id, &p->u.prefix4); + strlcpy(root->group_name, group_name, sizeof(root->group_name)); root->new_rtrs = NULL; root->new_table = NULL; - ospf_orr_debug("%s: For %s %s, created ORR Root entry %pFX.", __func__, - afi2str(afi), safi2str(safi), p); + ospf_orr_debug( + "%s: For %s %s, ORR Group %s, created ORR Root entry %pFX.", + __func__, afi2str(afi), safi2str(safi), root->group_name, p); return root; } @@ -195,8 +198,9 @@ int ospf_orr_igp_metric_register(struct orr_igp_metric_reg msg) safi = msg.safi; ospf_orr_debug( - "%s: Received IGP metric %s message from BGP for location %pFX", - __func__, msg.reg ? "Register" : "Unregister", &msg.prefix); + "%s: Received IGP metric %s message from BGP for ORR Group %s from location %pFX", + __func__, msg.reg ? "Register" : "Unregister", msg.group_name, + &msg.prefix); /* Get ORR Root entry for the given address-family */ root = ospf_orr_root_lookup(ospf, afi, safi, &msg.prefix.u.prefix4); @@ -207,7 +211,8 @@ int ospf_orr_igp_metric_register(struct orr_igp_metric_reg msg) /* Create ORR Root entry and calculate SPF from root */ if (!root) { - root = ospf_orr_root_new(ospf, afi, safi, &msg.prefix); + root = ospf_orr_root_new(ospf, afi, safi, &msg.prefix, + msg.group_name); if (!root) { ospf_orr_debug( "%s: For %s %s, Failed to create ORR Root entry %pFX.", @@ -233,7 +238,7 @@ int ospf_orr_igp_metric_register(struct orr_igp_metric_reg msg) } /* Compute SPF for all root nodes */ - ospf_spf_calculate_schedule(ospf, SPF_FLAG_ORR_ROOT_CHANGE); + ospf_orr_spf_calculate_schedule(ospf); } /* Delete ORR Root entry. SPF calculation not required. */ else { @@ -278,6 +283,10 @@ void ospf_orr_igp_metric_send_update(struct orr_root *root, if (or->type != OSPF_DESTINATION_NETWORK) continue; + if (ospf_route_match_same(root->old_table, + (struct prefix_ipv4 *)&rn->p, or)) + continue; + if (count < ORR_MAX_PREFIX) { prefix_copy(&msg.nexthop[count].prefix, (struct prefix_ipv4 *)&rn->p); @@ -299,7 +308,7 @@ void ospf_orr_igp_metric_send_update(struct orr_root *root, count++; } } - if (count <= ORR_MAX_PREFIX) { + if (count > 0 && count <= ORR_MAX_PREFIX) { msg.num_entries = count; ret = zclient_send_opaque(zclient, ORR_IGP_METRIC_UPDATE, (uint8_t *)&msg, sizeof(msg)); @@ -314,6 +323,9 @@ static void ospf_show_orr_root(struct orr_root *root) if (!root) return; + ospf_orr_debug("%s: Address Family: %s %s", __func__, + afi2str(root->afi), safi2str(root->safi)); + ospf_orr_debug("%s: ORR Group: %s", __func__, root->group_name); ospf_orr_debug("%s: Router-Address: %pI4:", __func__, &root->router_id); ospf_orr_debug("%s: Advertising Router: %pI4:", __func__, &root->adv_router); @@ -330,8 +342,6 @@ static void ospf_show_orr(struct ospf *ospf, afi_t afi, safi_t safi) if (!orr_root_list) return; - ospf_orr_debug("%s: For Address Family %s %s:", __func__, - afi2str(afi), safi2str(safi)); for (ALL_LIST_ELEMENTS_RO(orr_root_list, node, orr_root)) ospf_show_orr_root(orr_root); } @@ -412,26 +422,24 @@ void ospf_orr_root_update_rcvd_lsa(struct ospf_lsa *lsa) FOREACH_AFI_SAFI (afi, safi) { root = ospf_orr_root_lookup_by_adv_rid( lsa->area->ospf, afi, safi, &lsa->data->adv_router); - if (!root) - continue; + if (root) { + SET_FLAG(lsa->flags, OSPF_LSA_ORR); + ospf_refresher_register_lsa(lsa->area->ospf, lsa); + root->router_lsa_rcvd = lsa; + } ospf_orr_debug("%s: Received LSA[Type%d:%pI4]", __func__, lsa->data->type, &lsa->data->adv_router); - root->router_lsa_rcvd = lsa; /* Compute SPF for all root nodes */ - ospf_spf_calculate_schedule(lsa->area->ospf, - SPF_FLAG_ORR_ROOT_CHANGE); + ospf_orr_spf_calculate_schedule(lsa->area->ospf); return; } } -/* Install routes to root table. */ +/* Do not Install routes to root table. Just update table ponters */ void ospf_orr_route_install(struct orr_root *root, struct route_table *rt) { - struct route_node *rn; - struct ospf_route *or; - /* * rt contains new routing table, new_table contains an old one. * updating pointers @@ -441,21 +449,68 @@ void ospf_orr_route_install(struct orr_root *root, struct route_table *rt) root->old_table = root->new_table; root->new_table = rt; - - /* Install new routes. */ - for (rn = route_top(rt); rn; rn = route_next(rn)) { - or = rn->info; - if (or) { - if (or->type == OSPF_DESTINATION_NETWORK) { - if (!ospf_route_match_same( - root->old_table, - (struct prefix_ipv4 *)&rn->p, or)) { - } - } else if (or->type == OSPF_DESTINATION_DISCARD) - if (!ospf_route_match_same( - root->old_table, - (struct prefix_ipv4 *)&rn->p, or)) { - } - } - } +} + +void ospf_orr_spf_calculate_schedule(struct ospf *ospf) +{ + /* OSPF instance does not exist. */ + if (ospf == NULL) + return; + + /* No roots nodes rgistered for rSPF */ + if (!ospf->orr_spf_request) + return; + + /* ORR SPF calculation timer is already scheduled. */ + if (ospf->t_orr_calc) { + ospf_orr_debug( + "SPF: calculation timer is already scheduled: %p", + (void *)ospf->t_orr_calc); + return; + } + + ospf->t_orr_calc = NULL; + + ospf_orr_debug("%s: SPF: calculation timer scheduled", __func__); + + thread_add_timer(master, ospf_orr_spf_calculate_schedule_worker, ospf, + OSPF_ORR_CALC_INTERVAL, &ospf->t_orr_calc); +} + +void ospf_orr_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, + struct ospf_lsa *lsa_rcvd) +{ + ospf_spf_calculate(area, lsa_rcvd, new_table, all_rtrs, new_rtrs, false, + true); +} + +void ospf_orr_spf_calculate_areas(struct ospf *ospf, + struct route_table *new_table, + struct route_table *all_rtrs, + struct route_table *new_rtrs, + struct ospf_lsa *lsa_rcvd) +{ + struct ospf_area *area; + struct listnode *node, *nnode; + + /* Calculate SPF for each area. */ + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + /* + * Do backbone last, so as to first discover intra-area paths + * for any back-bone virtual-links + */ + if (ospf->backbone && ospf->backbone == area) + continue; + + ospf_orr_spf_calculate_area(ospf, area, new_table, all_rtrs, + new_rtrs, lsa_rcvd); + } + + /* SPF for backbone, if required */ + if (ospf->backbone) + ospf_orr_spf_calculate_area(ospf, ospf->backbone, new_table, + all_rtrs, new_rtrs, lsa_rcvd); } diff --git a/ospfd/ospf_orr.h b/ospfd/ospf_orr.h index 44e826d220..24b610c61c 100644 --- a/ospfd/ospf_orr.h +++ b/ospfd/ospf_orr.h @@ -22,6 +22,7 @@ #define _ZEBRA_OSPF_ORR_H #define BGP_OSPF_LSINFINITY 65535 +#define OSPF_ORR_CALC_INTERVAL 1 /* Macro to log debug message */ #define ospf_orr_debug(...) \ @@ -36,9 +37,19 @@ extern int ospf_orr_igp_metric_register(struct orr_igp_metric_reg orr_reg); extern void ospf_orr_igp_metric_send_update(struct orr_root *root, unsigned short instance); extern void ospf_orr_root_table_update(struct ospf_lsa *lsa, bool add); -extern struct orr_root *ospf_get_orr(struct ospf *ospf, afi_t afi, safi_t safi); extern void ospf_orr_root_update_rcvd_lsa(struct ospf_lsa *lsa); extern void ospf_orr_route_install(struct orr_root *root, struct route_table *rt); - +extern void ospf_orr_spf_calculate_schedule(struct ospf *ospf); +extern void ospf_orr_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, + struct ospf_lsa *lsa_rcvd); +extern void ospf_orr_spf_calculate_areas(struct ospf *ospf, + struct route_table *new_table, + struct route_table *all_rtrs, + struct route_table *new_rtrs, + struct ospf_lsa *lsa_rcvd); #endif /* _ZEBRA_OSPF_ORR_H */ diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index b20ac756e2..467ec76090 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -1911,6 +1911,8 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread) ospf_ase_calculate_schedule(ospf); ospf_ase_calculate_timer_add(ospf); + ospf_orr_spf_calculate_schedule(ospf); + if (IS_DEBUG_OSPF_EVENT) zlog_debug( "%s: ospf install new route, vrf %s id %u new_table count %lu", @@ -1933,7 +1935,6 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread) #ifdef SUPPORT_OSPF_API ospf_apiserver_notify_reachable(ospf->oall_rtrs, ospf->all_rtrs); #endif - /* Free old ABR/ASBR routing table */ if (ospf->old_rtrs) /* ospf_route_delete (ospf->old_rtrs); */ @@ -1976,11 +1977,10 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread) } /* Worker for ORR SPF calculation scheduler. */ -static void ospf_orr_spf_calculate_schedule_worker(struct thread *thread) +void ospf_orr_spf_calculate_schedule_worker(struct thread *thread) { afi_t afi; safi_t safi; - struct ospf_area *area; struct ospf *ospf = THREAD_ARG(thread); struct route_table *new_table, *new_rtrs; struct route_table *all_rtrs = NULL; @@ -1988,12 +1988,13 @@ static void ospf_orr_spf_calculate_schedule_worker(struct thread *thread) unsigned long ia_time, rt_time; unsigned long abr_time, total_spf_time, spf_time; struct listnode *rnode; - struct listnode *anode, *annode; struct list *orr_root_list; struct orr_root *root; char rbuf[32]; /* reason_buf */ - ospf->t_spf_calc = NULL; + ospf_orr_debug("%s: SPF: Timer (SPF calculation expire)", __func__); + + ospf->t_orr_calc = NULL; /* Execute SPF for each ORR Root node */ FOREACH_AFI_SAFI (afi, safi) { @@ -2019,28 +2020,16 @@ static void ospf_orr_spf_calculate_schedule_worker(struct thread *thread) new_rtrs = route_table_init(); /* ABR/ASBR routing table */ - /* Calculate SPF for each area. */ - for (ALL_LIST_ELEMENTS(ospf->areas, anode, annode, - area)) { - /* - * Do backbone last, so as to first discover - * intra-area paths for any back-bone - * virtual-links - */ - if (ospf->backbone && ospf->backbone == area) - continue; - - ospf_spf_calculate(area, root->router_lsa_rcvd, - new_table, all_rtrs, - new_rtrs, false, true); - } - - /* SPF for backbone, if required */ - if (ospf->backbone) - ospf_spf_calculate(ospf->backbone, - root->router_lsa_rcvd, - new_table, all_rtrs, - new_rtrs, false, true); + /* + * 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_orr_spf_calculate_areas(ospf, new_table, all_rtrs, + new_rtrs, + root->router_lsa_rcvd); spf_time = monotime_since(&spf_start_time, NULL); @@ -2052,10 +2041,18 @@ static void ospf_orr_spf_calculate_schedule_worker(struct thread *thread) ia_time = monotime_since(&start_time, NULL); /* - * REVISIT : Pruning of unreachable networks,routers and - * ase routes calculation skipped + * REVISIT : + * Pruning of unreachable networks, routers skipped. */ + /* Note: RFC 2328 16.3. is apparently missing. */ + /* Calculate AS external routes, see RFC 2328 16.4. + * There is a dedicated routing table for external + * routes which is not handled here directly + */ + ospf_ase_calculate_schedule(ospf); + ospf_ase_calculate_timer_add(ospf); + ospf_orr_debug( "%s: ospf install new route, vrf %s id %u new_table count %lu", __func__, ospf_vrf_id_to_name(ospf->vrf_id), @@ -2066,6 +2063,12 @@ static void ospf_orr_spf_calculate_schedule_worker(struct thread *thread) ospf_orr_route_install(root, new_table); rt_time = monotime_since(&start_time, NULL); + /* + * REVISIT : + * Freeing up and Updating old all routers routing table + * skipped. + */ + /* Free old ABR/ASBR routing table */ if (root->old_rtrs) /* ospf_route_delete (ospf->old_rtrs); */ @@ -2117,8 +2120,6 @@ static void ospf_orr_spf_calculate_schedule_worker(struct thread *thread) } /* ALL_LIST_ELEMENTS_RO() */ } /* FOREACH_AFI_SAFI() */ - - ospf_clear_spf_reason_flags(); } /* @@ -2180,14 +2181,8 @@ void ospf_spf_calculate_schedule(struct ospf *ospf, ospf_spf_reason_t reason) ospf->t_spf_calc = NULL; - if (spf_reason_flags & (1 << SPF_FLAG_ORR_ROOT_CHANGE)) - thread_add_timer_msec(master, - ospf_orr_spf_calculate_schedule_worker, - ospf, delay, &ospf->t_spf_calc); - else - thread_add_timer_msec(master, - ospf_spf_calculate_schedule_worker, ospf, - delay, &ospf->t_spf_calc); + thread_add_timer_msec(master, ospf_spf_calculate_schedule_worker, ospf, + delay, &ospf->t_spf_calc); } /* Restart OSPF SPF algorithm*/ diff --git a/ospfd/ospf_spf.h b/ospfd/ospf_spf.h index 88daf4c013..2578051c2c 100644 --- a/ospfd/ospf_spf.h +++ b/ospfd/ospf_spf.h @@ -105,5 +105,6 @@ extern int vertex_parent_cmp(void *aa, void *bb); extern void ospf_spf_print(struct vty *vty, struct vertex *v, int i); extern void ospf_restart_spf(struct ospf *ospf); +extern void ospf_orr_spf_calculate_schedule_worker(struct thread *thread); /* void ospf_spf_calculate_timer_add (); */ #endif /* _QUAGGA_OSPF_SPF_H */ diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 39e93bd613..4f0fa6194a 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -10983,6 +10983,131 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf, vty_out(vty, "\n"); } +static void show_ip_ospf_route_orr_root(struct vty *vty, struct ospf *ospf, + struct orr_root *root, bool use_vrf) +{ + if (ospf->instance) + vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance); + + ospf_show_vrf_name(ospf, vty, NULL, use_vrf); + + vty_out(vty, "ORR Group: %s\n", root->group_name); + vty_out(vty, "Active Root: %pI4\n\n", &root->router_id); + vty_out(vty, "SPF calculated from %pI4\n\n", &root->router_id); + + if (root->new_table) + show_ip_ospf_route_network(vty, ospf, root->new_table, NULL); + + if (root->new_rtrs) + show_ip_ospf_route_router(vty, ospf, root->new_rtrs, NULL); + + vty_out(vty, "\n"); +} + +static void show_ip_ospf_route_orr_common(struct vty *vty, struct ospf *ospf, + const char *orr_group, bool use_vrf) +{ + afi_t afi; + safi_t safi; + struct orr_root *root = NULL; + struct listnode *node = NULL; + struct list *orr_root_list = NULL; + + if (!ospf->orr_spf_request) + return; + + FOREACH_AFI_SAFI (afi, safi) { + orr_root_list = ospf->orr_root[afi][safi]; + if (!orr_root_list) + continue; + for (ALL_LIST_ELEMENTS_RO(orr_root_list, node, root)) { + if (orr_group) { + if (!strmatch(root->group_name, orr_group)) + continue; + show_ip_ospf_route_orr_root(vty, ospf, root, + use_vrf); + } else + show_ip_ospf_route_orr_root(vty, ospf, root, + use_vrf); + } + } +} + +DEFPY (show_ip_ospf_instance_route_orr, + show_ip_ospf_instance_route_orr_cmd, + "show ip ospf (1-65535)$instance route orr [WORD$orr_group]", + SHOW_STR + IP_STR + OSPF_STR + "Instance ID\n" + "OSPF routing table\n" + "Optimal Route Reflection\n" + "ORR Group name\n") +{ + struct ospf *ospf; + + if (instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; + + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) + return CMD_SUCCESS; + + show_ip_ospf_route_orr_common(vty, ospf, orr_group, false); + + return CMD_SUCCESS; +} + +DEFPY (show_ip_ospf_route_orr, + show_ip_ospf_route_orr_cmd, + "show ip ospf [vrf ] route orr [WORD$orr_group]", + SHOW_STR + IP_STR + OSPF_STR + VRF_CMD_HELP_STR + "All VRFs\n" + "OSPF routing table\n" + "Optimal Route Reflection\n" + "ORR Group name\n") +{ + struct ospf *ospf = NULL; + struct listnode *node = NULL; + int ret = CMD_SUCCESS; + int inst = 0; + bool use_vrf = vrf_name || all_vrf; + + if (all_vrf) { + bool ospf_output = false; + + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ospf_output = true; + + show_ip_ospf_route_orr_common(vty, ospf, orr_group, + use_vrf); + } + if (!ospf_output) + vty_out(vty, "%% OSPF is not enabled\n"); + return ret; + } + + if (vrf_name) + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + else + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + + if (!ospf || !ospf->oi_running) { + vty_out(vty, "%% OSPF is not enabled in vrf %s\n", + vrf_name ? vrf_name : "default"); + return CMD_SUCCESS; + } + + show_ip_ospf_route_orr_common(vty, ospf, orr_group, use_vrf); + + return ret; +} + static int show_ip_ospf_reachable_routers_common(struct vty *vty, struct ospf *ospf, uint8_t use_vrf) @@ -11237,35 +11362,6 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf, if (ospf->all_rtrs) show_ip_ospf_route_router(vty, ospf, ospf->all_rtrs, json_vrf); - /* Show ORR routes */ - if (ospf->orr_spf_request) { - afi_t afi; - safi_t safi; - struct orr_root *root = NULL; - struct listnode *node = NULL; - struct list *orr_root_list = NULL; - - FOREACH_AFI_SAFI (afi, safi) { - orr_root_list = ospf->orr_root[afi][safi]; - if (!orr_root_list) - continue; - for (ALL_LIST_ELEMENTS_RO(orr_root_list, node, root)) { - if (!root->new_table) - continue; - if (!json) - vty_out(vty, - "Calculated from location %pI4\n", - &root->router_id); - show_ip_ospf_route_network( - vty, ospf, root->new_table, json_vrf); - if (!root->new_rtrs) - continue; - show_ip_ospf_route_router( - vty, ospf, root->new_rtrs, json_vrf); - } - } - } - /* Show AS External routes. */ show_ip_ospf_route_external(vty, ospf, ospf->old_external_route, json_vrf); @@ -12724,11 +12820,13 @@ void ospf_vty_show_init(void) install_element(VIEW_NODE, &show_ip_ospf_route_cmd); install_element(VIEW_NODE, &show_ip_ospf_border_routers_cmd); install_element(VIEW_NODE, &show_ip_ospf_reachable_routers_cmd); + install_element(VIEW_NODE, &show_ip_ospf_route_orr_cmd); install_element(VIEW_NODE, &show_ip_ospf_instance_route_cmd); install_element(VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd); install_element(VIEW_NODE, &show_ip_ospf_instance_reachable_routers_cmd); + install_element(VIEW_NODE, &show_ip_ospf_instance_route_orr_cmd); /* "show ip ospf vrfs" commands. */ install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index e0c36d86fe..3f82d86921 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -795,6 +795,7 @@ static void ospf_finish_final(struct ospf *ospf) THREAD_OFF(ospf->t_write); THREAD_OFF(ospf->t_spf_calc); THREAD_OFF(ospf->t_ase_calc); + THREAD_OFF(ospf->t_orr_calc); THREAD_OFF(ospf->t_maxage); THREAD_OFF(ospf->t_maxage_walker); THREAD_OFF(ospf->t_abr_task); diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 2f3ad04c44..c7735136bc 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -263,6 +263,7 @@ struct ospf { struct thread *t_distribute_update; /* Distirbute list update timer. */ struct thread *t_spf_calc; /* SPF calculation timer. */ struct thread *t_ase_calc; /* ASE calculation timer. */ + struct thread *t_orr_calc; /* ORR calculation timer. */ struct thread *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */ struct thread *t_sr_update; /* Segment Routing update timer */