Index: ospfd/ospf_interface.c =================================================================== RCS file: /var/cvsroot/quagga/ospfd/ospf_interface.c,v retrieving revision 1.21 diff -u -r1.21 ospf_interface.c --- ospfd/ospf_interface.c 17 Feb 2004 20:07:30 -0000 1.21 +++ ospfd/ospf_interface.c 11 Mar 2004 21:44:53 -0000 @@ -933,24 +933,49 @@ } 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: - if (IS_DEBUG_OSPF_EVENT) - zlog_info ("found back link through VL"); - case LSA_LINK_TYPE_TRANSIT: - case LSA_LINK_TYPE_POINTOPOINT: - vl_data->peer_addr = rl->link[i].link_data; - if (IS_DEBUG_OSPF_EVENT) - zlog_info ("%s peer address is %s\n", - vl_data->vl_oi->ifp->name, - inet_ntoa(vl_data->peer_addr)); - return changed; + switch (rl->link[i].type) + { + case LSA_LINK_TYPE_VIRTUALLINK: + if (IS_DEBUG_OSPF_EVENT) + zlog_info ("found back link through VL"); + case LSA_LINK_TYPE_TRANSIT: + case LSA_LINK_TYPE_POINTOPOINT: + vl_data->peer_addr = rl->link[i].link_data; + if (IS_DEBUG_OSPF_EVENT) + zlog_info ("%s peer address is %s\n", + 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; } Index: ospfd/ospf_spf.c =================================================================== RCS file: /var/cvsroot/quagga/ospfd/ospf_spf.c,v retrieving revision 1.8 diff -u -r1.8 ospf_spf.c --- ospfd/ospf_spf.c 4 Mar 2004 17:45:01 -0000 1.8 +++ ospfd/ospf_spf.c 11 Mar 2004 21:44:53 -0000 @@ -93,6 +93,7 @@ new->distance = 0; new->child = list_new (); new->nexthop = list_new (); + new->backlink = -1; return new; } @@ -184,6 +185,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ } } } - return 0; + return -1; } /* Add the nexthop to the list, only if it is unique. @@ -544,6 +546,8 @@ 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 @@ 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"); @@ -640,6 +644,9 @@ /* 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) Index: ospfd/ospf_spf.h =================================================================== RCS file: /var/cvsroot/quagga/ospfd/ospf_spf.h,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 ospf_spf.h --- ospfd/ospf_spf.h 25 Mar 2003 02:37:17 -0000 1.1.1.2 +++ ospfd/ospf_spf.h 11 Mar 2004 21:44:53 -0000 @@ -33,6 +33,7 @@ struct in_addr id; struct lsa_header *lsa; u_int32_t distance; + int backlink; /* link index of back-link */ list child; list nexthop; };