diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2007-09-16 15:00:12 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2007-09-16 15:00:12 +0000 |
commit | 4c4c5359a79a417fad7050043a241592fe2c2932 (patch) | |
tree | 24f78547332f2c72dd40e0f6ffc860650e3b4fa1 | |
parent | c647470a814faecb9c0902d151c305ab233373d4 (diff) |
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@
-rw-r--r-- | usr.sbin/ospfd/rde_spf.c | 70 |
1 files 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 <norby@openbsd.org> @@ -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 */ |