ospfd: few fixes in rSPF calc when LSA received from non root node

Signed-off-by: Madhuri Kuruganti <maduri111@gmail.com>
This commit is contained in:
Madhuri Kuruganti 2022-09-12 19:57:20 +05:30
parent d6b2761134
commit 9f2984d97c
11 changed files with 286 additions and 113 deletions

View File

@ -831,6 +831,12 @@ Showing Information
Show the OSPF routing table, as determined by the most recent SPF Show the OSPF routing table, as determined by the most recent SPF
calculation. calculation.
.. clicmd:: show ip ospf (1-65535) route orr [NAME]
.. clicmd:: show ip ospf [vrf <NAME|all>] 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] .. clicmd:: show ip ospf graceful-restart helper [detail] [json]
Displays the Grcaeful Restart Helper details including helper Displays the Grcaeful Restart Helper details including helper

View File

@ -26,7 +26,8 @@ extern "C" {
#endif #endif
/* REVISIT: Need to check if we can use zero length array */ /* 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 orr_prefix_metric {
struct prefix prefix; struct prefix prefix;
@ -39,6 +40,7 @@ struct orr_igp_metric_reg {
uint8_t proto; uint8_t proto;
safi_t safi; safi_t safi;
struct prefix prefix; struct prefix prefix;
char group_name[ORR_GROUP_NAME_SIZE];
}; };
/* IGP-BGP message structures */ /* IGP-BGP message structures */
@ -60,6 +62,8 @@ struct orr_root {
afi_t afi; afi_t afi;
safi_t safi; safi_t safi;
char group_name[ORR_GROUP_NAME_SIZE];
/* MPLS_TE prefix and router ID */ /* MPLS_TE prefix and router ID */
struct prefix prefix; struct prefix prefix;
struct in_addr router_id; struct in_addr router_id;

View File

@ -1605,17 +1605,21 @@ DEFPY (debug_ospf_client_api,
DEFPY (debug_ospf_orr, DEFPY (debug_ospf_orr,
debug_ospf_orr_cmd, debug_ospf_orr_cmd,
"[no$no] debug ospf orr", "[no$no] debug ospf [(1-65535)$instance] orr",
NO_STR NO_STR
DEBUG_STR DEBUG_STR
OSPF_STR OSPF_STR
"Instance ID\n"
"OSPF ORR information\n") "OSPF ORR information\n")
{ {
if (instance && instance != ospf_instance)
return CMD_NOT_MY_INSTANCE;
if (vty->node == CONFIG_NODE) { if (vty->node == CONFIG_NODE) {
if (no) if (no)
CONF_DEBUG_OFF(orr, ORR); DEBUG_OFF(orr, ORR);
else else
CONF_DEBUG_ON(orr, ORR); DEBUG_ON(orr, ORR);
} else { } else {
if (no) if (no)
TERM_DEBUG_OFF(orr, ORR); TERM_DEBUG_OFF(orr, ORR);

View File

@ -2646,8 +2646,6 @@ ospf_router_lsa_install(struct ospf *ospf, struct ospf_lsa *new, int rt_recalc)
else if (ospf->orr_spf_request) { else if (ospf->orr_spf_request) {
ospf_lsa_unlock(&area->router_lsa_rcvd); ospf_lsa_unlock(&area->router_lsa_rcvd);
area->router_lsa_rcvd = ospf_lsa_lock(new); 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); 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, struct ospf_lsa *new,
int rt_recalc) int rt_recalc)
{ {
/* RFC 2328 Section 13.2 Router-LSAs and network-LSAs /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
The entire routing table must be recalculated, starting with The entire routing table must be recalculated, starting with
the shortest path calculations for each area (not just the the shortest path calculations for each area (not just the

View File

@ -47,7 +47,8 @@
static void ospf_show_orr_root(struct orr_root *root); 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 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, 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 list *orr_root_list = NULL;
struct orr_root *root = 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; root->safi = safi;
prefix_copy(&root->prefix, p); prefix_copy(&root->prefix, p);
IPV4_ADDR_COPY(&root->router_id, &p->u.prefix4); 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_rtrs = NULL;
root->new_table = NULL; root->new_table = NULL;
ospf_orr_debug("%s: For %s %s, created ORR Root entry %pFX.", __func__, ospf_orr_debug(
afi2str(afi), safi2str(safi), p); "%s: For %s %s, ORR Group %s, created ORR Root entry %pFX.",
__func__, afi2str(afi), safi2str(safi), root->group_name, p);
return root; return root;
} }
@ -195,8 +198,9 @@ int ospf_orr_igp_metric_register(struct orr_igp_metric_reg msg)
safi = msg.safi; safi = msg.safi;
ospf_orr_debug( ospf_orr_debug(
"%s: Received IGP metric %s message from BGP for location %pFX", "%s: Received IGP metric %s message from BGP for ORR Group %s from location %pFX",
__func__, msg.reg ? "Register" : "Unregister", &msg.prefix); __func__, msg.reg ? "Register" : "Unregister", msg.group_name,
&msg.prefix);
/* Get ORR Root entry for the given address-family */ /* Get ORR Root entry for the given address-family */
root = ospf_orr_root_lookup(ospf, afi, safi, &msg.prefix.u.prefix4); 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 */ /* Create ORR Root entry and calculate SPF from root */
if (!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) { if (!root) {
ospf_orr_debug( ospf_orr_debug(
"%s: For %s %s, Failed to create ORR Root entry %pFX.", "%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 */ /* 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. */ /* Delete ORR Root entry. SPF calculation not required. */
else { else {
@ -278,6 +283,10 @@ void ospf_orr_igp_metric_send_update(struct orr_root *root,
if (or->type != OSPF_DESTINATION_NETWORK) if (or->type != OSPF_DESTINATION_NETWORK)
continue; continue;
if (ospf_route_match_same(root->old_table,
(struct prefix_ipv4 *)&rn->p, or))
continue;
if (count < ORR_MAX_PREFIX) { if (count < ORR_MAX_PREFIX) {
prefix_copy(&msg.nexthop[count].prefix, prefix_copy(&msg.nexthop[count].prefix,
(struct prefix_ipv4 *)&rn->p); (struct prefix_ipv4 *)&rn->p);
@ -299,7 +308,7 @@ void ospf_orr_igp_metric_send_update(struct orr_root *root,
count++; count++;
} }
} }
if (count <= ORR_MAX_PREFIX) { if (count > 0 && count <= ORR_MAX_PREFIX) {
msg.num_entries = count; msg.num_entries = count;
ret = zclient_send_opaque(zclient, ORR_IGP_METRIC_UPDATE, ret = zclient_send_opaque(zclient, ORR_IGP_METRIC_UPDATE,
(uint8_t *)&msg, sizeof(msg)); (uint8_t *)&msg, sizeof(msg));
@ -314,6 +323,9 @@ static void ospf_show_orr_root(struct orr_root *root)
if (!root) if (!root)
return; 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: Router-Address: %pI4:", __func__, &root->router_id);
ospf_orr_debug("%s: Advertising Router: %pI4:", __func__, ospf_orr_debug("%s: Advertising Router: %pI4:", __func__,
&root->adv_router); &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) if (!orr_root_list)
return; 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)) for (ALL_LIST_ELEMENTS_RO(orr_root_list, node, orr_root))
ospf_show_orr_root(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) { FOREACH_AFI_SAFI (afi, safi) {
root = ospf_orr_root_lookup_by_adv_rid( root = ospf_orr_root_lookup_by_adv_rid(
lsa->area->ospf, afi, safi, &lsa->data->adv_router); lsa->area->ospf, afi, safi, &lsa->data->adv_router);
if (!root) if (root) {
continue; 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__, ospf_orr_debug("%s: Received LSA[Type%d:%pI4]", __func__,
lsa->data->type, &lsa->data->adv_router); lsa->data->type, &lsa->data->adv_router);
root->router_lsa_rcvd = lsa;
/* Compute SPF for all root nodes */ /* Compute SPF for all root nodes */
ospf_spf_calculate_schedule(lsa->area->ospf, ospf_orr_spf_calculate_schedule(lsa->area->ospf);
SPF_FLAG_ORR_ROOT_CHANGE);
return; 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) 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. * rt contains new routing table, new_table contains an old one.
* updating pointers * 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->old_table = root->new_table;
root->new_table = rt; root->new_table = rt;
}
/* Install new routes. */
for (rn = route_top(rt); rn; rn = route_next(rn)) { void ospf_orr_spf_calculate_schedule(struct ospf *ospf)
or = rn->info; {
if (or) { /* OSPF instance does not exist. */
if (or->type == OSPF_DESTINATION_NETWORK) { if (ospf == NULL)
if (!ospf_route_match_same( return;
root->old_table,
(struct prefix_ipv4 *)&rn->p, or)) { /* No roots nodes rgistered for rSPF */
} if (!ospf->orr_spf_request)
} else if (or->type == OSPF_DESTINATION_DISCARD) return;
if (!ospf_route_match_same(
root->old_table, /* ORR SPF calculation timer is already scheduled. */
(struct prefix_ipv4 *)&rn->p, or)) { 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);
} }

View File

@ -22,6 +22,7 @@
#define _ZEBRA_OSPF_ORR_H #define _ZEBRA_OSPF_ORR_H
#define BGP_OSPF_LSINFINITY 65535 #define BGP_OSPF_LSINFINITY 65535
#define OSPF_ORR_CALC_INTERVAL 1
/* Macro to log debug message */ /* Macro to log debug message */
#define ospf_orr_debug(...) \ #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, extern void ospf_orr_igp_metric_send_update(struct orr_root *root,
unsigned short instance); unsigned short instance);
extern void ospf_orr_root_table_update(struct ospf_lsa *lsa, bool add); 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_root_update_rcvd_lsa(struct ospf_lsa *lsa);
extern void ospf_orr_route_install(struct orr_root *root, extern void ospf_orr_route_install(struct orr_root *root,
struct route_table *rt); 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 */ #endif /* _ZEBRA_OSPF_ORR_H */

View File

@ -1911,6 +1911,8 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread)
ospf_ase_calculate_schedule(ospf); ospf_ase_calculate_schedule(ospf);
ospf_ase_calculate_timer_add(ospf); ospf_ase_calculate_timer_add(ospf);
ospf_orr_spf_calculate_schedule(ospf);
if (IS_DEBUG_OSPF_EVENT) if (IS_DEBUG_OSPF_EVENT)
zlog_debug( zlog_debug(
"%s: ospf install new route, vrf %s id %u new_table count %lu", "%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 #ifdef SUPPORT_OSPF_API
ospf_apiserver_notify_reachable(ospf->oall_rtrs, ospf->all_rtrs); ospf_apiserver_notify_reachable(ospf->oall_rtrs, ospf->all_rtrs);
#endif #endif
/* Free old ABR/ASBR routing table */ /* Free old ABR/ASBR routing table */
if (ospf->old_rtrs) if (ospf->old_rtrs)
/* ospf_route_delete (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. */ /* 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; afi_t afi;
safi_t safi; safi_t safi;
struct ospf_area *area;
struct ospf *ospf = THREAD_ARG(thread); struct ospf *ospf = THREAD_ARG(thread);
struct route_table *new_table, *new_rtrs; struct route_table *new_table, *new_rtrs;
struct route_table *all_rtrs = NULL; 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 ia_time, rt_time;
unsigned long abr_time, total_spf_time, spf_time; unsigned long abr_time, total_spf_time, spf_time;
struct listnode *rnode; struct listnode *rnode;
struct listnode *anode, *annode;
struct list *orr_root_list; struct list *orr_root_list;
struct orr_root *root; struct orr_root *root;
char rbuf[32]; /* reason_buf */ 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 */ /* Execute SPF for each ORR Root node */
FOREACH_AFI_SAFI (afi, safi) { FOREACH_AFI_SAFI (afi, safi) {
@ -2019,28 +2020,16 @@ static void ospf_orr_spf_calculate_schedule_worker(struct thread *thread)
new_rtrs = new_rtrs =
route_table_init(); /* ABR/ASBR routing table */ route_table_init(); /* ABR/ASBR routing table */
/* Calculate SPF for each area. */ /*
for (ALL_LIST_ELEMENTS(ospf->areas, anode, annode, * If we have opaque enabled then track all router
area)) { * reachability
/* */
* Do backbone last, so as to first discover if (CHECK_FLAG(ospf->opaque,
* intra-area paths for any back-bone OPAQUE_OPERATION_READY_BIT))
* virtual-links all_rtrs = route_table_init();
*/ ospf_orr_spf_calculate_areas(ospf, new_table, all_rtrs,
if (ospf->backbone && ospf->backbone == area) new_rtrs,
continue; root->router_lsa_rcvd);
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);
spf_time = monotime_since(&spf_start_time, NULL); 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); ia_time = monotime_since(&start_time, NULL);
/* /*
* REVISIT : Pruning of unreachable networks,routers and * REVISIT :
* ase routes calculation skipped * 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( ospf_orr_debug(
"%s: ospf install new route, vrf %s id %u new_table count %lu", "%s: ospf install new route, vrf %s id %u new_table count %lu",
__func__, ospf_vrf_id_to_name(ospf->vrf_id), __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); ospf_orr_route_install(root, new_table);
rt_time = monotime_since(&start_time, NULL); rt_time = monotime_since(&start_time, NULL);
/*
* REVISIT :
* Freeing up and Updating old all routers routing table
* skipped.
*/
/* Free old ABR/ASBR routing table */ /* Free old ABR/ASBR routing table */
if (root->old_rtrs) if (root->old_rtrs)
/* ospf_route_delete (ospf->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() */ } /* ALL_LIST_ELEMENTS_RO() */
} /* FOREACH_AFI_SAFI() */ } /* 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; ospf->t_spf_calc = NULL;
if (spf_reason_flags & (1 << SPF_FLAG_ORR_ROOT_CHANGE)) thread_add_timer_msec(master, ospf_spf_calculate_schedule_worker, ospf,
thread_add_timer_msec(master, delay, &ospf->t_spf_calc);
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);
} }
/* Restart OSPF SPF algorithm*/ /* Restart OSPF SPF algorithm*/

View File

@ -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_spf_print(struct vty *vty, struct vertex *v, int i);
extern void ospf_restart_spf(struct ospf *ospf); 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 (); */ /* void ospf_spf_calculate_timer_add (); */
#endif /* _QUAGGA_OSPF_SPF_H */ #endif /* _QUAGGA_OSPF_SPF_H */

View File

@ -10983,6 +10983,131 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
vty_out(vty, "\n"); 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 <NAME$vrf_name|all$all_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, static int show_ip_ospf_reachable_routers_common(struct vty *vty,
struct ospf *ospf, struct ospf *ospf,
uint8_t use_vrf) 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) if (ospf->all_rtrs)
show_ip_ospf_route_router(vty, ospf, ospf->all_rtrs, json_vrf); 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 AS External routes. */
show_ip_ospf_route_external(vty, ospf, ospf->old_external_route, show_ip_ospf_route_external(vty, ospf, ospf->old_external_route,
json_vrf); 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_route_cmd);
install_element(VIEW_NODE, &show_ip_ospf_border_routers_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_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_route_cmd);
install_element(VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd); install_element(VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd);
install_element(VIEW_NODE, install_element(VIEW_NODE,
&show_ip_ospf_instance_reachable_routers_cmd); &show_ip_ospf_instance_reachable_routers_cmd);
install_element(VIEW_NODE, &show_ip_ospf_instance_route_orr_cmd);
/* "show ip ospf vrfs" commands. */ /* "show ip ospf vrfs" commands. */
install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd); install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd);

View File

@ -795,6 +795,7 @@ static void ospf_finish_final(struct ospf *ospf)
THREAD_OFF(ospf->t_write); THREAD_OFF(ospf->t_write);
THREAD_OFF(ospf->t_spf_calc); THREAD_OFF(ospf->t_spf_calc);
THREAD_OFF(ospf->t_ase_calc); THREAD_OFF(ospf->t_ase_calc);
THREAD_OFF(ospf->t_orr_calc);
THREAD_OFF(ospf->t_maxage); THREAD_OFF(ospf->t_maxage);
THREAD_OFF(ospf->t_maxage_walker); THREAD_OFF(ospf->t_maxage_walker);
THREAD_OFF(ospf->t_abr_task); THREAD_OFF(ospf->t_abr_task);

View File

@ -263,6 +263,7 @@ struct ospf {
struct thread *t_distribute_update; /* Distirbute list update timer. */ struct thread *t_distribute_update; /* Distirbute list update timer. */
struct thread *t_spf_calc; /* SPF calculation timer. */ struct thread *t_spf_calc; /* SPF calculation timer. */
struct thread *t_ase_calc; /* ASE calculation timer. */ struct thread *t_ase_calc; /* ASE calculation timer. */
struct thread *t_orr_calc; /* ORR calculation timer. */
struct thread struct thread
*t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */ *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */
struct thread *t_sr_update; /* Segment Routing update timer */ struct thread *t_sr_update; /* Segment Routing update timer */