diff options
-rw-r--r-- | proto/ospf/config.Y | 4 | ||||
-rw-r--r-- | proto/ospf/lsalib.c | 7 | ||||
-rw-r--r-- | proto/ospf/lsupd.c | 2 | ||||
-rw-r--r-- | proto/ospf/ospf.c | 55 | ||||
-rw-r--r-- | proto/ospf/ospf.h | 16 | ||||
-rw-r--r-- | proto/ospf/rt.c | 36 | ||||
-rw-r--r-- | proto/ospf/rt.h | 9 | ||||
-rw-r--r-- | proto/ospf/topology.c | 4 |
8 files changed, 81 insertions, 52 deletions
diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 5b4f1ac..f92109e 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -38,6 +38,7 @@ ospf_proto_start: proto_start OSPF { this_proto->preference = DEF_PREF_OSPF; init_list(&OSPF_CFG->area_list); OSPF_CFG->rfc1583 = DEFAULT_RFC1583; + OSPF_CFG->tick = DEFAULT_OSPFTICK; } ; @@ -49,6 +50,7 @@ ospf_proto: ospf_proto_item: proto_item | RFC1583COMPAT bool ';' { OSPF_CFG->rfc1583 = $2; } + | TICK expr { OSPF_CFG->tick = $2 ; if($2<=0) cf_error("Tick must be greater than zero"); } | ospf_area '}' ; @@ -56,7 +58,7 @@ ospf_area_start: AREA idval '{' { this_area = cfg_allocz(sizeof(struct ospf_area_config)); add_tail(&OSPF_CFG->area_list, NODE this_area); this_area->areaid = $2; - this_area->tick = DEFAULT_DISPTICK; + this_area->tick = DEFAULT_AREATICK; this_area->stub = 0; init_list(&this_area->patt_list); init_list(&this_area->net_list); diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c index d78e30a..80649f5 100644 --- a/proto/ospf/lsalib.c +++ b/proto/ospf/lsalib.c @@ -49,7 +49,7 @@ ospf_age(struct ospf_area *oa) WALK_SLIST_DELSAFE(en, nxt, oa->lsal) { - if (oa->calcrt) + if (po->calcrt) { en->color = OUTSPF; en->dist = LSINFINITY; @@ -82,7 +82,7 @@ ospf_age(struct ospf_area *oa) if (flush) { flush_lsa(en, oa); - schedule_rtcalc(oa); + schedule_rtcalc(po); } else en->lsa.age = LSA_MAXAGE; @@ -438,6 +438,7 @@ lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa) int change = 0; unsigned i; struct top_hash_entry *en; + struct proto_ospf *po = oa->po; if ((en = ospf_hash_find_header(oa->gr, lsa)) == NULL) { @@ -477,7 +478,7 @@ lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa) if (change) { - schedule_rtcalc(oa); + schedule_rtcalc(po); } return en; diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c index 2cc0654..d906567 100644 --- a/proto/ospf/lsupd.c +++ b/proto/ospf/lsupd.c @@ -485,7 +485,7 @@ ospf_lsupd_receive(struct ospf_lsupd_packet *ps, && lsadb && can_flush_lsa(oa)) { flush_lsa(lsadb, oa); - schedule_rtcalc(oa); + schedule_rtcalc(po); continue; } /* FIXME lsack? */ diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 78e4644..302f56d 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -72,6 +72,9 @@ static int ospf_rte_better(struct rte *new, struct rte *old); static int ospf_rte_same(struct rte *new, struct rte *old); +static void area_disp(timer *timer); +static void ospf_disp(timer *timer); + static int ospf_start(struct proto *p) @@ -82,13 +85,24 @@ ospf_start(struct proto *p) struct ospf_area *oa; struct area_net *anet, *antmp; + po->rfc1583 = c->rfc1583; + po->ebit = 0; + + po->tick = c->tick; + po->disp_timer = tm_new(po->proto.pool); + po->disp_timer->data = po; + po->disp_timer->randomize = 0; + po->disp_timer->hook = ospf_disp; + po->disp_timer->recurrent = po->tick; + tm_start(po->disp_timer, 1); + fib_init(&po->efib, p->pool, sizeof(struct extfib), 16, init_efib); init_list(&(po->iface_list)); init_list(&(po->area_list)); po->areano = 0; if (EMPTY_LIST(c->area_list)) { - log("%s: Cannot start, no OSPF areas configured", p->name); + log(L_ERR "Cannot start, no OSPF areas configured!"); return PS_DOWN; } @@ -109,9 +123,7 @@ ospf_start(struct proto *p) oa->disp_timer->randomize = 0; oa->disp_timer->hook = area_disp; oa->disp_timer->recurrent = oa->tick; - tm_start(oa->disp_timer, 1); - oa->calcrt = 0; - oa->origrt = 0; + tm_start(oa->disp_timer, 2); init_list(&oa->net_list); WALK_LIST(anet, ac->net_list) { @@ -174,8 +186,6 @@ ospf_init(struct proto_config *c) p->rte_better = ospf_rte_better; p->rte_same = ospf_rte_same; - po->rfc1583 = oc->rfc1583; - po->ebit = 0; return p; } @@ -265,8 +275,7 @@ schedule_net_lsa(struct ospf_iface *ifa) void schedule_rt_lsa(struct ospf_area *oa) { - struct proto_ospf *po = oa->po; - struct proto *p = &po->proto; + struct proto *p = &oa->po->proto; OSPF_TRACE(D_EVENTS, "Scheduling RT lsa origination for area %I.", oa->areaid); @@ -274,16 +283,15 @@ schedule_rt_lsa(struct ospf_area *oa) } void -schedule_rtcalc(struct ospf_area *oa) +schedule_rtcalc(struct proto_ospf *po) { - struct proto_ospf *po = oa->po; struct proto *p = &po->proto; - if (oa->calcrt) + if (po->calcrt) return; - OSPF_TRACE(D_EVENTS, "Scheduling RT calculation for area %I.", oa->areaid); - oa->calcrt = 1; + OSPF_TRACE(D_EVENTS, "Scheduling RT calculation."); + po->calcrt = 1; } /** @@ -293,8 +301,6 @@ schedule_rtcalc(struct ospf_area *oa) * * It invokes aging and when @ospf_area->origrt is set to 1, start * function for origination of router LSA and network LSAs. - * It also starts routing - * table calculation when @ospf_area->calcrt is set. */ void area_disp(timer * timer) @@ -316,13 +322,21 @@ area_disp(timer * timer) /* Age LSA DB */ ospf_age(oa); +} + +void +ospf_disp(timer * timer) +{ + struct proto_ospf *po = timer->data; /* Calculate routing table */ - if (oa->calcrt) - ospf_rt_spfa(oa); - oa->calcrt = 0; + if (po->calcrt) + ospf_rt_spf (po); + po->calcrt = 0; } + + /** * ospf_import_control - accept or reject new route from nest's routing table * @p: current instance of protocol @@ -533,10 +547,7 @@ ospf_reconfigure(struct proto *p, struct proto_config *c) int found; po->rfc1583 = new->rfc1583; - WALK_LIST(oa, po->area_list) /* Routing table must be recalculated */ - { - schedule_rtcalc(oa); - } + schedule_rtcalc(po); ac1 = HEAD(old->area_list); ac2 = HEAD(new->area_list); diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 29e1af5..ea34ac8 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -52,14 +52,15 @@ #define MINLSARRIVAL 1 #define LSINFINITY 0xffff /* RFC says 0xffffff ??? */ -#define DEFAULT_DISPTICK 4 #define DEFAULT_OSPFTICK 5 -#define DEFAULT_RFC1583 1 /* compatibility with rfc1583 */ +#define DEFAULT_AREATICK 4 +#define DEFAULT_RFC1583 1 /* compatibility with rfc1583 */ struct ospf_config { struct proto_config c; + unsigned tick; int rfc1583; list area_list; }; @@ -422,7 +423,6 @@ struct ospf_area node n; u32 areaid; timer *disp_timer; /* Area's dispatcher hear beat */ - int calcrt; /* Routing table calculation scheduled? */ int origrt; /* Rt lsa origination scheduled? */ struct top_graph *gr; /* LSA graph */ slist lsal; /* List of all LSA's */ @@ -439,6 +439,9 @@ struct ospf_area struct proto_ospf { struct proto proto; + timer *disp_timer; /* OSPF proto dispatcher */ + unsigned tick; + int calcrt; /* Routing table calculation scheduled? */ list iface_list; /* Interfaces we really use */ list area_list; int areano; /* Number of area I belong to */ @@ -470,15 +473,14 @@ struct ospf_iface_patt list nbma_list; }; -int ospf_import_control(struct proto *p, rte ** new, ea_list ** attrs, +int ospf_import_control(struct proto *p, rte **new, ea_list **attrs, struct linpool *pool); struct ea_list *ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool); void ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs); -void ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old, +void ospf_rt_notify(struct proto *p, net *n, rte *new, rte *old, ea_list * attrs); -void area_disp(timer * timer); void schedule_rt_lsa(struct ospf_area *oa); -void schedule_rtcalc(struct ospf_area *oa); +void schedule_rtcalc(struct proto_ospf *po); void schedule_net_lsa(struct ospf_iface *ifa); void ospf_sh_neigh(struct proto *p, char *iff); void ospf_sh(struct proto *p); diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index f7453bd..cbd53f6 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -1,12 +1,18 @@ /* * BIRD -- OSPF * - * (c) 2000 Ondrej Filip <feela@network.cz> + * (c) 2000--2004 Ondrej Filip <feela@network.cz> * * Can be freely distributed and used under the terms of the GNU GPL. */ #include "ospf.h" +static void add_cand(list * l, struct top_hash_entry *en, + struct top_hash_entry *par, u16 dist, + struct ospf_area *oa); +static void calc_next_hop(struct top_hash_entry *en, + struct top_hash_entry *par, struct ospf_area *oa); +static void ospf_ext_spfa(struct proto_ospf *po); void init_infib(struct fib_node *fn) @@ -34,14 +40,14 @@ init_efib(struct fib_node *fn) } /** - * ospf_rt_spfa - calculate internal routes - * @oa: OSPF area + * ospf_rt_spf - calculate internal routes + * @po: OSPF protocol * * Calculation of internal paths in an area is described in 16.1 of RFC 2328. * It's based on Dijkstra's shortest path tree algorithms. * RFC recommends to add ASBR routers into routing table. I don't do this * and latter parts of routing table calculation look directly into LSA - * Database. This function is invoked from area_disp(). + * Database. This function is invoked from ospf_disp(). */ void ospf_rt_spfa(struct ospf_area *oa) @@ -270,6 +276,18 @@ skip: ospf_ext_spfa(po); } + +void +ospf_rt_spf(struct proto_ospf *po) +{ + struct ospf_area *oa; + WALK_LIST(oa, po->area_list) + { + ospf_rt_spfa(oa); + } +} + + /** * ospf_ext_spfa - calculate external paths * @po: protocol @@ -278,7 +296,7 @@ skip: * path is invoked. This process is described in 16.6 of RFC 2328. * Inter- and Intra-area paths are always prefered over externals. */ -void +static void ospf_ext_spfa(struct proto_ospf *po) /* FIXME looking into inter-area */ { struct top_hash_entry *en, *etmp, *absr; @@ -552,7 +570,7 @@ noch: } /* Add LSA into list of candidates in Dijkstra's algorithm */ -void +static void add_cand(list * l, struct top_hash_entry *en, struct top_hash_entry *par, u16 dist, struct ospf_area *oa) { @@ -625,7 +643,7 @@ add_cand(list * l, struct top_hash_entry *en, struct top_hash_entry *par, /* FIXME Some VLINK stuff should be here */ } -void +static void calc_next_hop(struct top_hash_entry *en, struct top_hash_entry *par, struct ospf_area *oa) { @@ -649,8 +667,8 @@ calc_next_hop(struct top_hash_entry *en, struct top_hash_entry *par, if (en->lsa.rt == myrid) { WALK_LIST(ifa, po->iface_list) - if (ipa_compare(ifa->iface->addr->ip, ipa_from_u32(en->lsa.id)) == - 0) + if (ipa_compare + (ifa->iface->addr->ip, ipa_from_u32(en->lsa.id)) == 0) { en->nhi = ifa->iface; return; diff --git a/proto/ospf/rt.h b/proto/ospf/rt.h index c236fce..73fe878 100644 --- a/proto/ospf/rt.h +++ b/proto/ospf/rt.h @@ -1,7 +1,7 @@ /* * BIRD -- OSPF * - * (c) 2000 Ondrej Filip <feela@network.cz> + * (c) 2000--2004 Ondrej Filip <feela@network.cz> * * Can be freely distributed and used under the terms of the GNU GPL. * @@ -33,12 +33,7 @@ struct extfib u32 oldtag; }; -void ospf_rt_spfa(struct ospf_area *oa); -void ospf_ext_spfa(struct proto_ospf *po); -void add_cand(list * l, struct top_hash_entry *en, struct top_hash_entry *par, - u16 dist, struct ospf_area *oa); -void calc_next_hop(struct top_hash_entry *par, struct top_hash_entry *en, - struct ospf_area *oa); +void ospf_rt_spf(struct proto_ospf *po); void init_infib(struct fib_node *fn); void init_efib(struct fib_node *fn); diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index a80ca3d..295b6ca 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -202,7 +202,7 @@ originate_rt_lsa(struct ospf_area *oa) en = lsa_install_new(&lsa, body, oa); oa->rt = en; ospf_lsupd_flood(NULL, NULL, &oa->rt->lsa, NULL, oa, 1); - schedule_rtcalc(oa); + schedule_rtcalc(po); oa->origrt = 0; } @@ -275,7 +275,7 @@ originate_net_lsa(struct ospf_iface *ifa) mb_free(ifa->nlsa->lsa_body); ifa->nlsa->lsa_body = NULL; ospf_hash_delete(ifa->oa->gr, ifa->nlsa); - schedule_rtcalc(ifa->oa); + schedule_rtcalc(po); ifa->nlsa = NULL; return; } |