summaryrefslogtreecommitdiff
path: root/ospfd/ospf_spf.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_spf.c')
-rw-r--r--ospfd/ospf_spf.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index c8cbe3f6..51e33832 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -172,7 +172,6 @@ ospf_vertex_new (struct ospf_lsa *lsa)
new->type = lsa->data->type;
new->id = lsa->data->id;
new->lsa = lsa->data;
- new->distance = OSPF_OUTPUT_COST_INFINITE;
new->children = list_new ();
new->parents = list_new ();
new->parents->del = vertex_parent_free;
@@ -285,7 +284,6 @@ ospf_spf_init (struct ospf_area *area)
/* Create root node. */
v = ospf_vertex_new (area->router_lsa_self);
- v->distance = 0;
area->spf = v;
@@ -431,13 +429,18 @@ ospf_spf_add_parent (struct vertex *v, struct vertex *w,
{
struct vertex_parent *vp;
- /* we must have a newhop.. */
+ /* we must have a newhop, and a distance */
assert (v && w && newhop);
+ assert (distance);
- /* We shouldn't get here unless callers have determined V(l)->W is
- * shortest / equal-shortest path.
+ /* IFF w has already been assigned a distance, then we shouldn't get here
+ * unless callers have determined V(l)->W is shortest / equal-shortest
+ * path (0 is a special case distance (no distance yet assigned)).
*/
- assert (distance <= w->distance);
+ if (w->distance)
+ assert (distance <= w->distance);
+ else
+ w->distance = distance;
if (IS_DEBUG_OSPF_EVENT)
{
@@ -750,6 +753,13 @@ ospf_spf_next (struct vertex *v, struct ospf_area *area,
calculation. */
if ((type = l->m[0].type) == LSA_LINK_TYPE_STUB)
continue;
+
+ /* Infinite distance links shouldn't be followed, except
+ * for local links (a stub-routed router still wants to
+ * calculate tree, so must follow its own links).
+ */
+ if ((v != area->spf) && l->m[0].metric >= OSPF_OUTPUT_COST_INFINITE)
+ continue;
/* (b) Otherwise, W is a transit vertex (router or transit
network). Look up the vertex W's LSA (router-LSA or