diff options
-rw-r--r-- | usr.sbin/ospfd/rde.h | 3 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde_spf.c | 175 |
2 files changed, 92 insertions, 86 deletions
diff --git a/usr.sbin/ospfd/rde.h b/usr.sbin/ospfd/rde.h index 405352aa6e5..8bc9b14ad1f 100644 --- a/usr.sbin/ospfd/rde.h +++ b/usr.sbin/ospfd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.22 2006/01/24 18:31:32 norby Exp $ */ +/* $OpenBSD: rde.h,v 1.23 2006/01/26 15:05:08 norby Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -119,6 +119,7 @@ void lsa_remove_invalid_sums(struct area *); /* rde_spf.c */ void spf_calc(struct area *); +void rt_calc(struct vertex *, struct area *); void asext_calc(struct vertex *); void spf_tree_clr(struct area *); diff --git a/usr.sbin/ospfd/rde_spf.c b/usr.sbin/ospfd/rde_spf.c index 2384e7e2d25..1a2b0e2d5f0 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.41 2006/01/24 20:27:04 norby Exp $ */ +/* $OpenBSD: rde_spf.c,v 1.42 2006/01/26 15:05:08 norby Exp $ */ /* * Copyright (c) 2005 Esben Norby <norby@openbsd.org> @@ -83,7 +83,7 @@ spf_calc(struct area *area) struct lsa_net_link *net_link; u_int32_t d; int i; - struct in_addr addr, adv_rtr, a; + struct in_addr a; log_debug("spf_calc: calculation started, area ID %s", inet_ntoa(area->id)); @@ -196,109 +196,114 @@ spf_calc(struct area *area) /* calculate route table */ RB_FOREACH(v, lsa_tree, tree) { - lsa_age(v); - if (ntohs(v->lsa->hdr.age) == MAX_AGE) - continue; + rt_calc(v, area); + } - switch (v->type) { - case LSA_TYPE_ROUTER: - /* stub networks */ - if (v->cost >= LS_INFINITY || v->nexthop.s_addr == 0) - continue; + /* calculate as-external routes */ + RB_FOREACH(v, lsa_tree, &rdeconf->lsa_tree) { + asext_calc(v); + } - for (i = 0; i < lsa_num_links(v); i++) { - rtr_link = get_rtr_link(v, i); - if (rtr_link->type != LINK_TYPE_STUB_NET) - continue; + /* spf_dump(area); */ + log_debug("spf_calc: calculation ended, area ID %s", + inet_ntoa(area->id)); - addr.s_addr = rtr_link->id; - adv_rtr.s_addr = htonl(v->adv_rtr); + area->num_spf_calc++; + start_spf_timer(); +} - rt_update(addr, mask2prefixlen(rtr_link->data), - v->nexthop, v->cost + - ntohs(rtr_link->metric), 0, area->id, - adv_rtr, PT_INTRA_AREA, DT_NET, - v->lsa->data.rtr.flags, - v->prev == spf_root); - } +void +rt_calc(struct vertex *v, struct area *area) +{ + struct vertex *w; + struct lsa_rtr_link *rtr_link = NULL; + int i; + struct in_addr addr, adv_rtr; - /* router, only add border and as-external routers */ - if ((v->lsa->data.rtr.flags & (OSPF_RTR_B | - OSPF_RTR_E)) == 0) - continue; + lsa_age(v); + if (ntohs(v->lsa->hdr.age) == MAX_AGE) + return; - addr.s_addr = htonl(v->ls_id); - adv_rtr.s_addr = htonl(v->adv_rtr); + switch (v->type) { + case LSA_TYPE_ROUTER: + /* stub networks */ + if (v->cost >= LS_INFINITY || v->nexthop.s_addr == 0) + return; - rt_update(addr, 32, v->nexthop, v->cost, 0, area->id, - adv_rtr, PT_INTRA_AREA, DT_RTR, - v->lsa->data.rtr.flags, 0); - break; - case LSA_TYPE_NETWORK: - if (v->cost >= LS_INFINITY || v->nexthop.s_addr == 0) + for (i = 0; i < lsa_num_links(v); i++) { + rtr_link = get_rtr_link(v, i); + if (rtr_link->type != LINK_TYPE_STUB_NET) continue; - addr.s_addr = htonl(v->ls_id) & v->lsa->data.net.mask; + addr.s_addr = rtr_link->id; adv_rtr.s_addr = htonl(v->adv_rtr); - rt_update(addr, mask2prefixlen(v->lsa->data.net.mask), - v->nexthop, v->cost, 0, area->id, adv_rtr, - PT_INTRA_AREA, DT_NET, 0, v->prev == spf_root); - break; - case LSA_TYPE_SUM_NETWORK: - case LSA_TYPE_SUM_ROUTER: - /* if ABR only look at area 0.0.0.0 LSA */ - /* ignore self-originated stuff */ - if (v->nbr->self) - continue; + rt_update(addr, mask2prefixlen(rtr_link->data), + v->nexthop, v->cost + ntohs(rtr_link->metric), 0, + area->id, adv_rtr, PT_INTRA_AREA, DT_NET, + v->lsa->data.rtr.flags, v->prev == spf_root); + } - /* TODO type 3 area address range check */ + /* router, only add border and as-external routers */ + if ((v->lsa->data.rtr.flags & (OSPF_RTR_B | OSPF_RTR_E)) == 0) + return; - if ((w = lsa_find(area, LSA_TYPE_ROUTER, - htonl(v->adv_rtr), - htonl(v->adv_rtr))) == NULL) - continue; + addr.s_addr = htonl(v->ls_id); + adv_rtr.s_addr = htonl(v->adv_rtr); - v->nexthop = w->nexthop; - v->cost = w->cost + - (ntohl(v->lsa->data.sum.metric) & LSA_METRIC_MASK); + rt_update(addr, 32, v->nexthop, v->cost, 0, area->id, + adv_rtr, PT_INTRA_AREA, DT_RTR, v->lsa->data.rtr.flags, 0); + break; + case LSA_TYPE_NETWORK: + if (v->cost >= LS_INFINITY || v->nexthop.s_addr == 0) + return; - if (v->cost >= LS_INFINITY || v->nexthop.s_addr == 0) - continue; + addr.s_addr = htonl(v->ls_id) & v->lsa->data.net.mask; + adv_rtr.s_addr = htonl(v->adv_rtr); + rt_update(addr, mask2prefixlen(v->lsa->data.net.mask), + v->nexthop, v->cost, 0, area->id, adv_rtr, PT_INTRA_AREA, + DT_NET, 0, v->prev == spf_root); + break; + case LSA_TYPE_SUM_NETWORK: + case LSA_TYPE_SUM_ROUTER: + /* if ABR only look at area 0.0.0.0 LSA */ - adv_rtr.s_addr = htonl(v->adv_rtr); - if (v->type == LSA_TYPE_SUM_NETWORK) { - addr.s_addr = htonl(v->ls_id) & - v->lsa->data.sum.mask; - rt_update(addr, - mask2prefixlen(v->lsa->data.sum.mask), - v->nexthop, v->cost, 0, area->id, adv_rtr, - PT_INTER_AREA, DT_NET, 0, 0); - } else { - addr.s_addr = htonl(v->ls_id); - rt_update(addr, 32, v->nexthop, v->cost, 0, - area->id, adv_rtr, PT_INTER_AREA, DT_RTR, - v->lsa->data.rtr.flags, 0); - } + /* ignore self-originated stuff */ + if (v->nbr->self) + return; - break; - default: - /* as-external LSA are stored in a different tree */ - fatalx("spf_calc: invalid LSA type"); - } - } + /* TODO type 3 area address range check */ - /* calculate as-external routes */ - RB_FOREACH(v, lsa_tree, &rdeconf->lsa_tree) { - asext_calc(v); - } + if ((w = lsa_find(area, LSA_TYPE_ROUTER, + htonl(v->adv_rtr), + htonl(v->adv_rtr))) == NULL) + return; - /* spf_dump(area); */ - log_debug("spf_calc: calculation ended, area ID %s", - inet_ntoa(area->id)); + v->nexthop = w->nexthop; + v->cost = w->cost + + (ntohl(v->lsa->data.sum.metric) & LSA_METRIC_MASK); - area->num_spf_calc++; - start_spf_timer(); + if (v->cost >= LS_INFINITY || v->nexthop.s_addr == 0) + return; + + adv_rtr.s_addr = htonl(v->adv_rtr); + if (v->type == LSA_TYPE_SUM_NETWORK) { + addr.s_addr = htonl(v->ls_id) & v->lsa->data.sum.mask; + rt_update(addr, mask2prefixlen(v->lsa->data.sum.mask), + v->nexthop, v->cost, 0, area->id, adv_rtr, + PT_INTER_AREA, DT_NET, 0, 0); + } else { + addr.s_addr = htonl(v->ls_id); + rt_update(addr, 32, v->nexthop, v->cost, 0, area->id, + adv_rtr, PT_INTER_AREA, DT_RTR, + v->lsa->data.rtr.flags, 0); + } + + break; + default: + /* as-external LSA are stored in a different tree */ + fatalx("rt_calc: invalid LSA type"); + } } void |