forked from Mirror/frr
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:
parent
d6b2761134
commit
9f2984d97c
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
127
ospfd/ospf_orr.c
127
ospfd/ospf_orr.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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*/
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
156
ospfd/ospf_vty.c
156
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");
|
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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue