summaryrefslogtreecommitdiff
path: root/ospfd/ospf_orr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_orr.c')
-rw-r--r--ospfd/ospf_orr.c123
1 files changed, 89 insertions, 34 deletions
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);
}