summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ospfd/ospf_interface.c29
-rw-r--r--ospfd/ospf_route.c66
-rw-r--r--ospfd/ospf_route.h3
-rw-r--r--ospfd/ospf_spf.c206
-rw-r--r--ospfd/ospf_spf.h17
-rw-r--r--ospfd/ospfd.h2
6 files changed, 180 insertions, 143 deletions
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 7977a2a9f4..af801da8d7 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -995,7 +995,8 @@ void ospf_vl_delete(struct ospf *ospf, struct ospf_vl_data *vl_data)
ospf_vl_data_free(vl_data);
}
-static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v)
+static int ospf_vl_set_params(struct ospf_area *area,
+ struct ospf_vl_data *vl_data, struct vertex *v)
{
int changed = 0;
struct ospf_interface *voi;
@@ -1003,6 +1004,7 @@ static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v)
struct vertex_parent *vp = NULL;
unsigned int i;
struct router_lsa *rl;
+ struct ospf_interface *oi;
voi = vl_data->vl_oi;
@@ -1013,17 +1015,24 @@ static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v)
}
for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
- vl_data->nexthop.oi = vp->nexthop->oi;
+ vl_data->nexthop.lsa_pos = vp->nexthop->lsa_pos;
vl_data->nexthop.router = vp->nexthop->router;
- if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
- &vl_data->nexthop.oi->address->u.prefix4))
- changed = 1;
+ /*
+ * Only deal with interface data when the local
+ * (calculating) node is the SPF root node
+ */
+ if (!area->spf_dry_run) {
+ oi = ospf_if_lookup_by_lsa_pos(
+ area, vl_data->nexthop.lsa_pos);
- voi->address->u.prefix4 =
- vl_data->nexthop.oi->address->u.prefix4;
- voi->address->prefixlen =
- vl_data->nexthop.oi->address->prefixlen;
+ if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
+ &oi->address->u.prefix4))
+ changed = 1;
+
+ voi->address->u.prefix4 = oi->address->u.prefix4;
+ voi->address->prefixlen = oi->address->prefixlen;
+ }
break; /* We take the first interface. */
}
@@ -1114,7 +1123,7 @@ void ospf_vl_up_check(struct ospf_area *area, struct in_addr rid,
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
}
- if (ospf_vl_set_params(vl_data, v)) {
+ if (ospf_vl_set_params(area, vl_data, v)) {
if (IS_DEBUG_OSPF(ism, ISM_EVENTS))
zlog_debug(
"ospf_vl_up_check: VL cost change, scheduling router lsa refresh");
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index 776f50b33a..487275beec 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -375,7 +375,7 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
else
route_unlock_node(rn);
- ospf_route_copy_nexthops_from_vertex(or, v);
+ ospf_route_copy_nexthops_from_vertex(area, or, v);
listnode_add(rn->info, or);
@@ -438,7 +438,7 @@ void ospf_intra_add_transit(struct route_table *rt, struct vertex *v,
or->type = OSPF_DESTINATION_NETWORK;
or->u.std.origin = (struct lsa_header *)lsa;
- ospf_route_copy_nexthops_from_vertex(or, v);
+ ospf_route_copy_nexthops_from_vertex(area, or, v);
rn->info = or ;
}
@@ -453,7 +453,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
struct ospf_route * or ;
struct prefix_ipv4 p;
struct router_lsa *lsa;
- struct ospf_interface *oi;
+ struct ospf_interface *oi = NULL;
struct ospf_path *path;
if (IS_DEBUG_OSPF_EVENT)
@@ -538,7 +538,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
zlog_debug(
"ospf_intra_add_stub(): routes are equal, merge");
- ospf_route_copy_nexthops_from_vertex(cur_or, v);
+ ospf_route_copy_nexthops_from_vertex(area, cur_or, v);
if (IPV4_ADDR_CMP(&cur_or->u.std.origin->id,
&lsa->header.id)
@@ -563,7 +563,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
list_delete_all_node(cur_or->paths);
- ospf_route_copy_nexthops_from_vertex(cur_or, v);
+ ospf_route_copy_nexthops_from_vertex(area, cur_or, v);
cur_or->u.std.origin = (struct lsa_header *)lsa;
return;
@@ -588,24 +588,35 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_intra_add_stub(): this network is on remote router");
- ospf_route_copy_nexthops_from_vertex(or, v);
+ ospf_route_copy_nexthops_from_vertex(area, or, v);
} else {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_intra_add_stub(): this network is on this router");
- if ((oi = ospf_if_lookup_by_lsa_pos(area, lsa_pos))) {
+ /*
+ * Only deal with interface data when we
+ * don't do a dry run
+ */
+ if (!area->spf_dry_run)
+ oi = ospf_if_lookup_by_lsa_pos(area, lsa_pos);
+
+ if (oi || area->spf_dry_run) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
- "ospf_intra_add_stub(): the interface is %s",
- IF_NAME(oi));
+ "ospf_intra_add_stub(): the lsa pos is %d",
+ lsa_pos);
path = ospf_path_new();
path->nexthop.s_addr = INADDR_ANY;
- path->ifindex = oi->ifp->ifindex;
- if (CHECK_FLAG(oi->connected->flags,
- ZEBRA_IFA_UNNUMBERED))
- path->unnumbered = 1;
+
+ if (oi) {
+ path->ifindex = oi->ifp->ifindex;
+ if (CHECK_FLAG(oi->connected->flags,
+ ZEBRA_IFA_UNNUMBERED))
+ path->unnumbered = 1;
+ }
+
listnode_add(or->paths, path);
} else {
if (IS_DEBUG_OSPF_EVENT)
@@ -734,30 +745,41 @@ static int ospf_path_exist(struct list *plist, struct in_addr nexthop,
return 0;
}
-void ospf_route_copy_nexthops_from_vertex(struct ospf_route *to,
+void ospf_route_copy_nexthops_from_vertex(struct ospf_area *area,
+ struct ospf_route *to,
struct vertex *v)
{
struct listnode *node;
struct ospf_path *path;
struct vertex_nexthop *nexthop;
struct vertex_parent *vp;
+ struct ospf_interface *oi = NULL;
assert(to->paths);
for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
nexthop = vp->nexthop;
- if (nexthop->oi != NULL) {
- if (!ospf_path_exist(to->paths, nexthop->router,
- nexthop->oi)) {
- path = ospf_path_new();
- path->nexthop = nexthop->router;
- path->ifindex = nexthop->oi->ifp->ifindex;
- if (CHECK_FLAG(nexthop->oi->connected->flags,
+ /*
+ * Only deal with interface data when we
+ * don't do a dry run
+ */
+ if (!area->spf_dry_run)
+ oi = ospf_if_lookup_by_lsa_pos(area, nexthop->lsa_pos);
+
+ if ((oi && !ospf_path_exist(to->paths, nexthop->router, oi))
+ || area->spf_dry_run) {
+ path = ospf_path_new();
+ path->nexthop = nexthop->router;
+
+ if (oi) {
+ path->ifindex = oi->ifp->ifindex;
+ if (CHECK_FLAG(oi->connected->flags,
ZEBRA_IFA_UNNUMBERED))
path->unnumbered = 1;
- listnode_add(to->paths, path);
}
+
+ listnode_add(to->paths, path);
}
}
}
diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h
index 20cdc75fe8..a0aa7a0c6f 100644
--- a/ospfd/ospf_route.h
+++ b/ospfd/ospf_route.h
@@ -146,7 +146,8 @@ extern void ospf_intra_add_stub(struct route_table *, struct router_lsa_link *,
extern int ospf_route_cmp(struct ospf *, struct ospf_route *,
struct ospf_route *);
extern void ospf_route_copy_nexthops(struct ospf_route *, struct list *);
-extern void ospf_route_copy_nexthops_from_vertex(struct ospf_route *,
+extern void ospf_route_copy_nexthops_from_vertex(struct ospf_area *area,
+ struct ospf_route *,
struct vertex *);
extern void ospf_route_subst(struct route_node *, struct ospf_route *,
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 7e293d7edc..dfeb80bd17 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -252,14 +252,12 @@ static void ospf_vertex_dump(const char *msg, struct vertex *v,
if (vp) {
zlog_debug(
- "parent %s backlink %d nexthop %s interface %s",
+ "parent %s backlink %d nexthop %s lsa pos %d",
inet_ntoa(vp->parent->lsa->id),
vp->backlink,
inet_ntop(AF_INET, &vp->nexthop->router,
buf1, BUFSIZ),
- vp->nexthop->oi
- ? IF_NAME(vp->nexthop->oi)
- : "NULL");
+ vp->nexthop->lsa_pos);
}
}
}
@@ -291,7 +289,8 @@ static void ospf_vertex_add_parent(struct vertex *v)
}
}
-static void ospf_spf_init(struct ospf_area *area, struct ospf_lsa *root_lsa)
+static void ospf_spf_init(struct ospf_area *area, struct ospf_lsa *root_lsa,
+ bool is_dry_run)
{
struct vertex *v;
@@ -299,6 +298,7 @@ static void ospf_spf_init(struct ospf_area *area, struct ospf_lsa *root_lsa)
v = ospf_vertex_new(root_lsa);
area->spf = v;
+ area->spf_dry_run = is_dry_run;
/* Reset ABR and ASBR router counts. */
area->abr_count = 0;
@@ -486,6 +486,41 @@ static void ospf_spf_add_parent(struct vertex *v, struct vertex *w,
return;
}
+static int match_stub_prefix(struct lsa_header *lsa, struct in_addr v_link_addr,
+ struct in_addr w_link_addr)
+{
+ uint8_t *p, *lim;
+ struct router_lsa_link *l = NULL;
+ struct in_addr masked_lsa_addr;
+
+ if (lsa->type != OSPF_ROUTER_LSA)
+ return 0;
+
+ p = ((uint8_t *)lsa) + OSPF_LSA_HEADER_SIZE + 4;
+ lim = ((uint8_t *)lsa) + ntohs(lsa->length);
+
+ while (p < lim) {
+ l = (struct router_lsa_link *)p;
+ p += (OSPF_ROUTER_LSA_LINK_SIZE
+ + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE));
+
+ if (l->m[0].type != LSA_LINK_TYPE_STUB)
+ continue;
+
+ masked_lsa_addr.s_addr =
+ (l->link_id.s_addr & l->link_data.s_addr);
+
+ /* check that both links belong to the same stub subnet */
+ if ((masked_lsa_addr.s_addr
+ == (v_link_addr.s_addr & l->link_data.s_addr))
+ && (masked_lsa_addr.s_addr
+ == (w_link_addr.s_addr & l->link_data.s_addr)))
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* 16.1.1. Calculate nexthop from root through V (parent) to
* vertex W (destination), with given distance from root->W.
@@ -506,7 +541,6 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
struct listnode *node, *nnode;
struct vertex_nexthop *nh;
struct vertex_parent *vp;
- struct ospf_interface *oi = NULL;
unsigned int added = 0;
char buf1[BUFSIZ];
char buf2[BUFSIZ];
@@ -530,21 +564,11 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
/* we *must* be supplied with the link data */
assert(l != NULL);
- oi = ospf_if_lookup_by_lsa_pos(area, lsa_pos);
- if (!oi) {
- zlog_debug(
- "%s: OI not found in LSA: lsa_pos:%d link_id:%s link_data:%s",
- __func__, lsa_pos,
- inet_ntop(AF_INET, &l->link_id, buf1, BUFSIZ),
- inet_ntop(AF_INET, &l->link_data, buf2,
- BUFSIZ));
- return 0;
- }
if (IS_DEBUG_OSPF_EVENT) {
zlog_debug(
- "%s: considering link:%s type:%d link_id:%s link_data:%s",
- __func__, oi->ifp->name, l->m[0].type,
+ "%s: considering link type:%d link_id:%s link_data:%s",
+ __func__, l->m[0].type,
inet_ntop(AF_INET, &l->link_id, buf1, BUFSIZ),
inet_ntop(AF_INET, &l->link_data, buf2,
BUFSIZ));
@@ -557,8 +581,6 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
struct router_lsa_link *l2 = NULL;
if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT) {
- struct in_addr nexthop = {.s_addr = 0};
-
/*
* If the destination is a router which connects
* to the calculating router via a
@@ -580,55 +602,30 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
* then that link is a constituent of the PtMP
* link, and its address is a nexthop address
* for V.
+ *
+ * Note for point-to-point interfaces:
+ *
+ * Having nexthop = 0 (as proposed in the RFC)
+ * is tempting, but NOT acceptable. It breaks
+ * AS-External routes with a forwarding address,
+ * since ospf_ase_complete_direct_routes() will
+ * mistakenly assume we've reached the last hop
+ * and should place the forwarding address as
+ * nexthop. Also, users may configure multi-
+ * access links in p2p mode, so we need the IP
+ * to ARP the nexthop.
+ *
+ * Due to these reasons p2p and p2mp
+ * interfaces are handled the same way here,
+ * in the style of p2mp as described above.
*/
- if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
- /*
- * Having nexthop = 0 (as proposed in
- * the RFC) is tempting, but NOT
- * acceptable. It breaks AS-External
- * routes with a forwarding address,
- * since
- * ospf_ase_complete_direct_routes()
- * will mistakenly assume we've reached
- * the last hop and should place the
- * forwarding address as nexthop. Also,
- * users may configure multi-access
- * links in p2p mode, so we need the IP
- * to ARP the nexthop.
- */
- struct ospf_neighbor *nbr_w;
- nbr_w = ospf_nbr_lookup_by_routerid(
- oi->nbrs, &l->link_id);
- if (nbr_w != NULL) {
- added = 1;
- nexthop = nbr_w->src;
- }
- } else if (oi->type
- == OSPF_IFTYPE_POINTOMULTIPOINT) {
- struct prefix_ipv4 la;
-
- la.family = AF_INET;
- la.prefixlen = oi->address->prefixlen;
+ struct in_addr nexthop = {.s_addr = 0};
- /*
- * V links to W on PtMP interface;
- * find the interface address on W
- */
- while ((l2 = ospf_get_next_link(w, v,
- l2))) {
- la.prefix = l2->link_data;
-
- if (prefix_cmp((struct prefix
- *)&la,
- oi->address)
- != 0)
- continue;
-
- /*
- * link_data is on our PtMP
- * network
- */
+ while ((l2 = ospf_get_next_link(w, v, l2))) {
+ if (match_stub_prefix(v->lsa,
+ l->link_data,
+ l2->link_data)) {
added = 1;
nexthop = l2->link_data;
break;
@@ -636,23 +633,17 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
}
if (added) {
- /*
- * found all necessary info to build
- * nexthop
- */
nh = vertex_nexthop_new();
- nh->oi = oi;
nh->router = nexthop;
+ nh->lsa_pos = lsa_pos;
ospf_spf_add_parent(v, w, nh, distance);
return 1;
} else
zlog_info(
- "%s: could not determine nexthop for link %s",
- __func__, oi->ifp->name);
+ "%s: could not determine nexthop for link",
+ __func__);
} /* end point-to-point link from V to W */
else if (l->m[0].type == LSA_LINK_TYPE_VIRTUALLINK) {
- struct ospf_vl_data *vl_data;
-
/*
* VLink implementation limitations:
* a) vl_data can only reference one nexthop,
@@ -663,6 +654,9 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
* multiple ones exist this router through
* multiple transit-areas.
*/
+
+ struct ospf_vl_data *vl_data;
+
vl_data = ospf_vl_lookup(area->ospf, NULL,
l->link_id);
@@ -670,8 +664,8 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
&& CHECK_FLAG(vl_data->flags,
OSPF_VL_FLAG_APPROVED)) {
nh = vertex_nexthop_new();
- nh->oi = vl_data->nexthop.oi;
nh->router = vl_data->nexthop.router;
+ nh->lsa_pos = vl_data->nexthop.lsa_pos;
ospf_spf_add_parent(v, w, nh, distance);
return 1;
} else
@@ -684,8 +678,8 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
assert(w->type == OSPF_VERTEX_NETWORK);
nh = vertex_nexthop_new();
- nh->oi = oi;
nh->router.s_addr = 0; /* Nexthop not required */
+ nh->lsa_pos = lsa_pos;
ospf_spf_add_parent(v, w, nh, distance);
return 1;
}
@@ -717,8 +711,8 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
* inherited from the parent network).
*/
nh = vertex_nexthop_new();
- nh->oi = vp->nexthop->oi;
nh->router = l->link_data;
+ nh->lsa_pos = vp->nexthop->lsa_pos;
added = 1;
ospf_spf_add_parent(v, w, nh, distance);
}
@@ -817,6 +811,7 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
lsa_pos = lsa_pos_next; /* LSA link position */
lsa_pos_next++;
+
p += (OSPF_ROUTER_LSA_LINK_SIZE
+ (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE));
@@ -961,7 +956,7 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
*/
vertex_pqueue_del(candidate, w);
ospf_nexthop_calculation(area, v, w, l,
- distance, lsa_pos);
+ distance, lsa_pos);
vertex_pqueue_add(candidate, w);
}
} /* end W is already on the candidate list */
@@ -988,11 +983,9 @@ static void ospf_spf_dump(struct vertex *v, int i)
if (IS_DEBUG_OSPF_EVENT)
for (ALL_LIST_ELEMENTS_RO(v->parents, nnode, parent)) {
- zlog_debug(" nexthop %p %s %s", (void *)parent->nexthop,
+ zlog_debug(" nexthop %p %s %d", (void *)parent->nexthop,
inet_ntoa(parent->nexthop->router),
- parent->nexthop->oi
- ? IF_NAME(parent->nexthop->oi)
- : "NULL");
+ parent->nexthop->lsa_pos);
}
i++;
@@ -1158,10 +1151,9 @@ ospf_rtrs_print (struct route_table *rtrs)
#endif
/* Calculating the shortest-path tree for an area, see RFC2328 16.1. */
-static void ospf_spf_calculate(struct ospf_area *area,
- struct ospf_lsa *root_lsa,
- struct route_table *new_table,
- struct route_table *new_rtrs)
+void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa,
+ struct route_table *new_table,
+ struct route_table *new_rtrs, bool is_dry_run)
{
struct vertex_pqueue_head candidate;
struct vertex *v;
@@ -1200,7 +1192,7 @@ static void ospf_spf_calculate(struct ospf_area *area,
* Initialize the shortest-path tree to only the root (which is usually
* the router doing the calculation).
*/
- ospf_spf_init(area, root_lsa);
+ ospf_spf_init(area, root_lsa, is_dry_run);
/* Set Area A's TransitCapability to false. */
area->transit = OSPF_TRANSIT_FALSE;
@@ -1248,12 +1240,6 @@ static void ospf_spf_calculate(struct ospf_area *area,
ospf_spf_process_stubs(area, area->spf, new_table, 0);
ospf_vertex_dump(__func__, area->spf, 0, 1);
- /*
- * Free nexthop information, canonical versions of which are attached
- * the first level of router vertices attached to the root vertex, see
- * ospf_nexthop_calculation.
- */
- ospf_canonical_nexthops_free(area->spf);
/* Increment SPF Calculation Counter. */
area->spf_calculation++;
@@ -1265,16 +1251,25 @@ static void ospf_spf_calculate(struct ospf_area *area,
zlog_debug("ospf_spf_calculate: Stop. %zd vertices",
mtype_stats_alloc(MTYPE_OSPF_VERTEX));
- /*
- * Free SPF vertices, but not the list. List has ospf_vertex_free
- * as deconstructor.
- */
- list_delete_all_node(&vertex_list);
+ /* If this is a dry run then keep the SPF data in place */
+ if (!area->spf_dry_run) {
+ /*
+ * Free nexthop information, canonical versions of which are
+ * attached the first level of router vertices attached to the
+ * root vertex, see ospf_nexthop_calculation.
+ */
+ ospf_canonical_nexthops_free(area->spf);
+
+ /*
+ * Free SPF vertices, but not the list. List has
+ * ospf_vertex_free as deconstructor.
+ */
+ list_delete_all_node(&vertex_list);
+ }
}
-static int ospf_spf_calculate_areas(struct ospf *ospf,
- struct route_table *new_table,
- struct route_table *new_rtrs)
+int ospf_spf_calculate_areas(struct ospf *ospf, struct route_table *new_table,
+ struct route_table *new_rtrs, bool is_dry_run)
{
struct ospf_area *area;
struct listnode *node, *nnode;
@@ -1288,7 +1283,7 @@ static int ospf_spf_calculate_areas(struct ospf *ospf,
continue;
ospf_spf_calculate(area, area->router_lsa_self, new_table,
- new_rtrs);
+ new_rtrs, is_dry_run);
areas_processed++;
}
@@ -1296,7 +1291,7 @@ static int ospf_spf_calculate_areas(struct ospf *ospf,
if (ospf->backbone) {
area = ospf->backbone;
ospf_spf_calculate(area, area->router_lsa_self, new_table,
- new_rtrs);
+ new_rtrs, is_dry_run);
areas_processed++;
}
@@ -1325,7 +1320,8 @@ static int ospf_spf_calculate_schedule_worker(struct thread *thread)
monotime(&spf_start_time);
new_table = route_table_init(); /* routing table */
new_rtrs = route_table_init(); /* ABR/ASBR routing table */
- areas_processed = ospf_spf_calculate_areas(ospf, new_table, new_rtrs);
+ areas_processed =
+ ospf_spf_calculate_areas(ospf, new_table, new_rtrs, false);
spf_time = monotime_since(&spf_start_time, NULL);
ospf_vl_shut_unapproved(ospf);
diff --git a/ospfd/ospf_spf.h b/ospfd/ospf_spf.h
index 09a0b6f1b7..9bf3dc645e 100644
--- a/ospfd/ospf_spf.h
+++ b/ospfd/ospf_spf.h
@@ -49,15 +49,14 @@ struct vertex {
/* A nexthop taken on the root node to get to this (parent) vertex */
struct vertex_nexthop {
- struct ospf_interface *oi; /* output intf on root node */
struct in_addr router; /* router address to send to */
+ int lsa_pos; /* LSA position for resolving the interface */
};
struct vertex_parent {
- struct vertex_nexthop
- *nexthop; /* link to nexthop info for this parent */
- struct vertex *parent; /* parent vertex */
- int backlink; /* index back to parent for router-lsa's */
+ struct vertex_nexthop *nexthop; /* nexthop address for this parent */
+ struct vertex *parent; /* parent vertex */
+ int backlink; /* index back to parent for router-lsa's */
};
/* What triggered the SPF ? */
@@ -73,6 +72,14 @@ typedef enum {
} ospf_spf_reason_t;
extern void ospf_spf_calculate_schedule(struct ospf *, ospf_spf_reason_t);
+extern void ospf_spf_calculate(struct ospf_area *area,
+ struct ospf_lsa *root_lsa,
+ struct route_table *new_table,
+ struct route_table *new_rtrs, bool is_dry_run);
+extern int ospf_spf_calculate_areas(struct ospf *ospf,
+ struct route_table *new_table,
+ struct route_table *new_rtrs,
+ bool is_dry_run);
extern void ospf_rtrs_free(struct route_table *);
/* void ospf_spf_calculate_timer_add (); */
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index cdeaa38dc0..e3e63fea8f 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -410,6 +410,8 @@ struct ospf_area {
/* Shortest Path Tree. */
struct vertex *spf;
+ bool spf_dry_run; /* flag for checking if the SPF calculation is
+ intended for the local RIB */
/* Threads. */
struct thread *t_stub_router; /* Stub-router timer */