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.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 5ced71ca..916e9800 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -93,6 +93,7 @@ ospf_vertex_new (struct ospf_lsa *lsa)
new->distance = 0;
new->child = list_new ();
new->nexthop = list_new ();
+ new->backlink = -1;
return new;
}
@@ -184,6 +185,7 @@ ospf_vertex_lookup (list vlist, struct in_addr id, int type)
return NULL;
}
+/* return index of link back to V from W, or -1 if no link found */
int
ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v)
{
@@ -196,15 +198,15 @@ ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v)
if (w->type == OSPF_NETWORK_LSA)
{
if (v->type == OSPF_NETWORK_LSA)
- return 0;
+ return -1;
nl = (struct network_lsa *) w;
length = (ntohs (w->length) - OSPF_LSA_HEADER_SIZE - 4) / 4;
for (i = 0; i < length; i++)
if (IPV4_ADDR_SAME (&nl->routers[i], &v->id))
- return 1;
- return 0;
+ return i;
+ return -1;
}
/* In case of W is Router LSA. */
@@ -226,7 +228,7 @@ ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v)
if (v->type == OSPF_ROUTER_LSA &&
IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
{
- return 1;
+ return i;
}
break;
case LSA_LINK_TYPE_TRANSIT:
@@ -234,7 +236,7 @@ ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v)
if (v->type == OSPF_NETWORK_LSA &&
IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
{
- return 1;
+ return i;
}
break;
case LSA_LINK_TYPE_STUB:
@@ -245,7 +247,7 @@ ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v)
}
}
}
- return 0;
+ return -1;
}
/* Add the nexthop to the list, only if it is unique.
@@ -544,6 +546,8 @@ ospf_spf_next (struct vertex *v, struct ospf_area *area,
while (p < lim)
{
+ int link = -1; /* link index for w's back link */
+
/* In case of V is Router-LSA. */
if (v->lsa->type == OSPF_ROUTER_LSA)
{
@@ -616,7 +620,7 @@ ospf_spf_next (struct vertex *v, struct ospf_area *area,
if (IS_LSA_MAXAGE (w_lsa))
continue;
- if (!ospf_lsa_has_link (w_lsa->data, v->lsa))
+ if ( (link = ospf_lsa_has_link (w_lsa->data, v->lsa)) < 0 )
{
if (IS_DEBUG_OSPF_EVENT)
zlog_info ("The LSA doesn't have a link back");
@@ -641,6 +645,9 @@ ospf_spf_next (struct vertex *v, struct ospf_area *area,
/* prepare vertex W. */
w = ospf_vertex_new (w_lsa);
+ /* Save W's back link index number, for use by virtual links */
+ w->backlink = link;
+
/* calculate link cost D. */
if (v->lsa->type == OSPF_ROUTER_LSA)
w->distance = v->distance + ntohs (l->m[0].metric);