2004-04-08 Paul Jakma <paul@dishone.st>

* ospf_spf.h: Add backlink field to struct vertex
        * ospf_spf.h: (ospf_vertex_new) initialise backlink
          (ospf_lsa_has_link) return index of link back to
          vertex V from candidate vertex W, or -1 if no link exists.
          (ospf_spf_next) save backlink index for candidate vertex
        * ospf_interface.c: (ospf_vl_set_params) Use the backlink index
          to determine correct address for virtual-link peers. Fall back
          to older "pick first link" method if no backlink index exists.
This commit is contained in:
paul 2004-04-08 07:43:45 +00:00
parent 81b81822da
commit d355bfa780
4 changed files with 66 additions and 22 deletions

View File

@ -1,3 +1,14 @@
2004-04-08 Paul Jakma <paul@dishone.st>
* ospf_spf.h: Add backlink field to struct vertex
* ospf_spf.h: (ospf_vertex_new) initialise backlink
(ospf_lsa_has_link) return index of link back to
vertex V from candidate vertex W, or -1 if no link exists.
(ospf_spf_next) save backlink index for candidate vertex
* ospf_interface.c: (ospf_vl_set_params) Use the backlink index
to determine correct address for virtual-link peers. Fall back
to older "pick first link" method if no backlink index exists.
2004-04-06 Hasso Tepper <hasso@estpak.ee> 2004-04-06 Hasso Tepper <hasso@estpak.ee>
* zebra/ipforward_proc.c: Fixed lowering privileges. * zebra/ipforward_proc.c: Fixed lowering privileges.

View File

@ -933,24 +933,49 @@ ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v)
} }
rl = (struct router_lsa *)v->lsa; rl = (struct router_lsa *)v->lsa;
for (i = 0; i < ntohs (rl->links); i++) /* use SPF determined backlink index in struct vertex
* for virtual link destination address
*/
if (v->backlink >= 0)
{ {
switch (rl->link[i].type) if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
&rl->link[v->backlink].link_data))
changed = 1;
vl_data->peer_addr = rl->link[v->backlink].link_data;
}
else
{
/* This is highly odd, there is no backlink index
* there should be due to the ospf_spf_has_link() check
* in SPF. Lets warn and try pick a link anyway.
*/
zlog_warn ("ospf_vl_set_params: No backlink for %s!",
vl_data->vl_oi->ifp->name);
for (i = 0; i < ntohs (rl->links); i++)
{ {
case LSA_LINK_TYPE_VIRTUALLINK: switch (rl->link[i].type)
if (IS_DEBUG_OSPF_EVENT) {
zlog_info ("found back link through VL"); case LSA_LINK_TYPE_VIRTUALLINK:
case LSA_LINK_TYPE_TRANSIT: if (IS_DEBUG_OSPF_EVENT)
case LSA_LINK_TYPE_POINTOPOINT: zlog_info ("found back link through VL");
vl_data->peer_addr = rl->link[i].link_data; case LSA_LINK_TYPE_TRANSIT:
if (IS_DEBUG_OSPF_EVENT) case LSA_LINK_TYPE_POINTOPOINT:
zlog_info ("%s peer address is %s\n", vl_data->peer_addr = rl->link[i].link_data;
vl_data->vl_oi->ifp->name, if (IS_DEBUG_OSPF_EVENT)
inet_ntoa(vl_data->peer_addr)); zlog_info ("%s peer address is %s\n",
return changed; vl_data->vl_oi->ifp->name,
inet_ntoa(vl_data->peer_addr));
return changed;
}
} }
} }
if (IS_DEBUG_OSPF_EVENT)
zlog_info ("ospf_vl_set_params: %s peer address is %s\n",
vl_data->vl_oi->ifp->name,
inet_ntoa(vl_data->peer_addr));
return changed; return changed;
} }

View File

@ -93,6 +93,7 @@ ospf_vertex_new (struct ospf_lsa *lsa)
new->distance = 0; new->distance = 0;
new->child = list_new (); new->child = list_new ();
new->nexthop = list_new (); new->nexthop = list_new ();
new->backlink = -1;
return new; return new;
} }
@ -184,6 +185,7 @@ ospf_vertex_lookup (list vlist, struct in_addr id, int type)
return NULL; return NULL;
} }
/* return index of link back to V from W, or -1 if no link found */
int int
ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v) 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 (w->type == OSPF_NETWORK_LSA)
{ {
if (v->type == OSPF_NETWORK_LSA) if (v->type == OSPF_NETWORK_LSA)
return 0; return -1;
nl = (struct network_lsa *) w; nl = (struct network_lsa *) w;
length = (ntohs (w->length) - OSPF_LSA_HEADER_SIZE - 4) / 4; length = (ntohs (w->length) - OSPF_LSA_HEADER_SIZE - 4) / 4;
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
if (IPV4_ADDR_SAME (&nl->routers[i], &v->id)) if (IPV4_ADDR_SAME (&nl->routers[i], &v->id))
return 1; return i;
return 0; return -1;
} }
/* In case of W is Router LSA. */ /* 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 && if (v->type == OSPF_ROUTER_LSA &&
IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id)) IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
{ {
return 1; return i;
} }
break; break;
case LSA_LINK_TYPE_TRANSIT: 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 && if (v->type == OSPF_NETWORK_LSA &&
IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id)) IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
{ {
return 1; return i;
} }
break; break;
case LSA_LINK_TYPE_STUB: 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. /* 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) while (p < lim)
{ {
int link = -1; /* link index for w's back link */
/* In case of V is Router-LSA. */ /* In case of V is Router-LSA. */
if (v->lsa->type == OSPF_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)) if (IS_LSA_MAXAGE (w_lsa))
continue; 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) if (IS_DEBUG_OSPF_EVENT)
zlog_info ("The LSA doesn't have a link back"); 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. */ /* prepare vertex W. */
w = ospf_vertex_new (w_lsa); 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. */ /* calculate link cost D. */
if (v->lsa->type == OSPF_ROUTER_LSA) if (v->lsa->type == OSPF_ROUTER_LSA)
w->distance = v->distance + ntohs (l->m[0].metric); w->distance = v->distance + ntohs (l->m[0].metric);

View File

@ -33,6 +33,7 @@ struct vertex
struct in_addr id; struct in_addr id;
struct lsa_header *lsa; struct lsa_header *lsa;
u_int32_t distance; u_int32_t distance;
int backlink; /* link index of back-link */
list child; list child;
list nexthop; list nexthop;
}; };
@ -44,7 +45,7 @@ struct vertex_nexthop
struct vertex *parent; struct vertex *parent;
}; };
void ospf_spf_calculate_schedule (); void ospf_spf_calculate_schedule (struct ospf *);
void ospf_rtrs_free (struct route_table *); void ospf_rtrs_free (struct route_table *);
/* void ospf_spf_calculate_timer_add (); */ /* void ospf_spf_calculate_timer_add (); */