From 4c4c5359a79a417fad7050043a241592fe2c2932 Mon Sep 17 00:00:00 2001 From: Claudio Jeker Date: Sun, 16 Sep 2007 15:00:12 +0000 Subject: Change the way nexthops are calculated on the root level. Instead of looking from the target back and trying to figure the nexthop out, the link is searched in the interface list and the info from the matiching interface is used. This should solve the nexthop issues with setups having multiple point-to-point links between two routers as reported on misc@ some time ago. tested and OK norby@ --- usr.sbin/ospfd/rde_spf.c | 70 +++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/usr.sbin/ospfd/rde_spf.c b/usr.sbin/ospfd/rde_spf.c index 8209b7e32bc..f6b25f73fe5 100644 --- a/usr.sbin/ospfd/rde_spf.c +++ b/usr.sbin/ospfd/rde_spf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_spf.c,v 1.63 2007/08/06 11:32:34 claudio Exp $ */ +/* $OpenBSD: rde_spf.c,v 1.64 2007/09/16 15:00:11 claudio Exp $ */ /* * Copyright (c) 2005 Esben Norby @@ -37,7 +37,8 @@ struct vertex *spf_root = NULL; void calc_nexthop_clear(struct vertex *); void calc_nexthop_add(struct vertex *, struct vertex *, u_int32_t); -void calc_nexthop(struct vertex *, struct vertex *); +void calc_nexthop(struct vertex *, struct vertex *, + struct area *, struct lsa_rtr_link *); void rt_nexthop_clear(struct rt_node *); void rt_nexthop_add(struct rt_node *, struct v_nexthead *, struct in_addr); @@ -134,7 +135,7 @@ spf_calc(struct area *area) if (d < w->cost) { w->cost = d; calc_nexthop_clear(w); - calc_nexthop(w, v); + calc_nexthop(w, v, area, rtr_link); /* * need to readd to candidate list * because the list is sorted @@ -143,12 +144,12 @@ spf_calc(struct area *area) cand_list_add(w); } else /* equal cost path */ - calc_nexthop(w, v); + calc_nexthop(w, v, area, rtr_link); } else if (w->cost == LS_INFINITY && d < LS_INFINITY) { w->cost = d; calc_nexthop_clear(w); - calc_nexthop(w, v); + calc_nexthop(w, v, area, rtr_link); cand_list_add(w); } } @@ -384,54 +385,51 @@ calc_nexthop_add(struct vertex *dst, struct vertex *parent, u_int32_t nexthop) } void -calc_nexthop(struct vertex *dst, struct vertex *parent) +calc_nexthop(struct vertex *dst, struct vertex *parent, + struct area *area, struct lsa_rtr_link *rtr_link) { - struct lsa_rtr_link *rtr_link = NULL; struct v_nexthop *vn; + struct iface *iface; int i; /* case 1 */ if (parent == spf_root) { switch (dst->type) { case LSA_TYPE_ROUTER: - for (i = 0; i < lsa_num_links(dst); i++) { - rtr_link = get_rtr_link(dst, i); - if (rtr_link->type == LINK_TYPE_POINTTOPOINT && - ntohl(rtr_link->id) == parent->ls_id) { + if (rtr_link->type != LINK_TYPE_POINTTOPOINT) + fatalx("inconsistent SPF tree"); + LIST_FOREACH(iface, &area->iface_list, entry) { + if (rtr_link->data == iface->addr.s_addr) { calc_nexthop_add(dst, parent, - rtr_link->data); - break; + iface->dst.s_addr); + return; } } - return; + fatalx("no interface found for interface"); case LSA_TYPE_NETWORK: - for (i = 0; i < lsa_num_links(parent); i++) { - rtr_link = get_rtr_link(parent, i); - switch (rtr_link->type) { - case LINK_TYPE_POINTTOPOINT: - /* ignore */ - break; - case LINK_TYPE_TRANSIT_NET: - if ((htonl(dst->ls_id) & - dst->lsa->data.net.mask) == - (rtr_link->data & - dst->lsa->data.net.mask)) { - calc_nexthop_add(dst, parent, - rtr_link->data); - } - break; - case LINK_TYPE_STUB_NET: - break; - - default: - fatalx("calc_nexthop: invalid link " - "type"); + switch (rtr_link->type) { + case LINK_TYPE_POINTTOPOINT: + case LINK_TYPE_STUB_NET: + /* ignore */ + break; + case LINK_TYPE_TRANSIT_NET: + if ((htonl(dst->ls_id) & + dst->lsa->data.net.mask) == + (rtr_link->data & + dst->lsa->data.net.mask)) { + calc_nexthop_add(dst, parent, + rtr_link->data); } + break; + default: + fatalx("calc_nexthop: invalid link " + "type"); } return; default: fatalx("calc_nexthop: invalid dst type"); } + return; } /* case 2 */ @@ -459,7 +457,7 @@ calc_nexthop(struct vertex *dst, struct vertex *parent) /* case 3 */ TAILQ_FOREACH(vn, &parent->nexthop, entry) - calc_nexthop_add(dst, parent, vn->nexthop.s_addr); + calc_nexthop_add(dst, parent, vn->nexthop.s_addr); } /* candidate list */ -- cgit v1.2.3