User can get that information as JSON format when ``json`` keyword
at the end of cli is presented.
-.. 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]
Displays the Grcaeful Restart Helper details including helper
#endif
/* REVISIT: Need to check if we can use zero length array */
-#define ORR_MAX_PREFIX 100
-#define ORR_GROUP_NAME_SIZE 32
+#define ORR_MAX_PREFIX 100
struct orr_prefix_metric {
struct prefix prefix;
uint8_t proto;
safi_t safi;
struct prefix prefix;
- char group_name[ORR_GROUP_NAME_SIZE];
};
/* IGP-BGP message structures */
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;
DEFPY (debug_ospf_orr,
debug_ospf_orr_cmd,
- "[no$no] debug ospf [(1-65535)$instance] orr",
+ "[no$no] debug ospf 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)
- DEBUG_OFF(orr, ORR);
+ CONF_DEBUG_OFF(orr, ORR);
else
- DEBUG_ON(orr, ORR);
+ CONF_DEBUG_ON(orr, ORR);
} else {
if (no)
TERM_DEBUG_OFF(orr, ORR);
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);
}
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
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,
- char *group_name)
+ safi_t safi, struct prefix *p)
{
struct list *orr_root_list = NULL;
struct orr_root *root = NULL;
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, ORR Group %s, created ORR Root entry %pFX.",
- __func__, afi2str(afi), safi2str(safi), root->group_name, p);
+ ospf_orr_debug("%s: For %s %s, created ORR Root entry %pFX.", __func__,
+ afi2str(afi), safi2str(safi), p);
return root;
}
safi = msg.safi;
ospf_orr_debug(
- "%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);
+ "%s: Received IGP metric %s message from BGP for location %pFX",
+ __func__, msg.reg ? "Register" : "Unregister", &msg.prefix);
/* Get ORR Root entry for the given address-family */
root = ospf_orr_root_lookup(ospf, afi, safi, &msg.prefix.u.prefix4);
/* Create ORR Root entry and calculate SPF from root */
if (!root) {
- root = ospf_orr_root_new(ospf, afi, safi, &msg.prefix,
- msg.group_name);
+ root = ospf_orr_root_new(ospf, afi, safi, &msg.prefix);
if (!root) {
ospf_orr_debug(
"%s: For %s %s, Failed to create ORR Root entry %pFX.",
}
/* Compute SPF for all root nodes */
- ospf_orr_spf_calculate_schedule(ospf);
+ ospf_spf_calculate_schedule(ospf, SPF_FLAG_ORR_ROOT_CHANGE);
}
/* Delete ORR Root entry. SPF calculation not required. */
else {
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);
count++;
}
}
- if (count > 0 && count <= ORR_MAX_PREFIX) {
+ if (count <= ORR_MAX_PREFIX) {
msg.num_entries = count;
ret = zclient_send_opaque(zclient, ORR_IGP_METRIC_UPDATE,
(uint8_t *)&msg, sizeof(msg));
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);
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);
}
FOREACH_AFI_SAFI (afi, safi) {
root = ospf_orr_root_lookup_by_adv_rid(
lsa->area->ospf, afi, safi, &lsa->data->adv_router);
- if (root) {
- SET_FLAG(lsa->flags, OSPF_LSA_ORR);
- ospf_refresher_register_lsa(lsa->area->ospf, lsa);
- root->router_lsa_rcvd = lsa;
- }
+ if (!root)
+ continue;
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_orr_spf_calculate_schedule(lsa->area->ospf);
+ ospf_spf_calculate_schedule(lsa->area->ospf,
+ SPF_FLAG_ORR_ROOT_CHANGE);
return;
}
}
-/* Do not Install routes to root table. Just update table ponters */
+/* Install routes to root table. */
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
root->old_table = root->new_table;
root->new_table = rt;
-}
-
-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);
+ /* 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)) {
+ }
+ }
}
-
- /* SPF for backbone, if required */
- if (ospf->backbone)
- ospf_orr_spf_calculate_area(ospf, ospf->backbone, new_table,
- all_rtrs, new_rtrs, lsa_rcvd);
}
#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(...) \
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 */
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",
#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_rtrs_free(ospf->old_rtrs);
}
/* Worker for ORR SPF calculation scheduler. */
-void ospf_orr_spf_calculate_schedule_worker(struct thread *thread)
+static 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;
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_orr_debug("%s: SPF: Timer (SPF calculation expire)", __func__);
-
- ospf->t_orr_calc = NULL;
+ ospf->t_spf_calc = NULL;
/* Execute SPF for each ORR Root node */
FOREACH_AFI_SAFI (afi, safi) {
new_rtrs =
route_table_init(); /* ABR/ASBR routing table */
- /*
- * 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);
+ /* 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);
spf_time = monotime_since(&spf_start_time, NULL);
ia_time = monotime_since(&start_time, NULL);
/*
- * REVISIT :
- * Pruning of unreachable networks, routers skipped.
+ * REVISIT : Pruning of unreachable networks,routers and
+ * ase routes calculation 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),
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); */
} /* ALL_LIST_ELEMENTS_RO() */
} /* FOREACH_AFI_SAFI() */
+
+ ospf_clear_spf_reason_flags();
}
/*
ospf->t_spf_calc = NULL;
- thread_add_timer_msec(master, ospf_spf_calculate_schedule_worker, ospf,
- delay, &ospf->t_spf_calc);
+ 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);
}
/* Restart OSPF SPF algorithm*/
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 */
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,
struct ospf *ospf,
uint8_t use_vrf)
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);
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);
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);
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 */