diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-08-08 12:22:49 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-08-08 12:22:49 +0000 |
commit | e883ceeb99d336da9a755250708941e6d84afe14 (patch) | |
tree | e6d9c3dee54721a7869646215ab9b8faa909b5a9 | |
parent | a22286a7f69eeaeb793ca17852f88268a6951733 (diff) |
Try to do an SPF recalculation only if the LS DB changed.
This is still not perfect as on ABRs it is only necessary to
recalculate the area that got changed and not all others too.
More to come but it is a good start. OK norby@
-rw-r--r-- | usr.sbin/ospfd/rde.c | 5 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde.h | 4 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde_lsdb.c | 40 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde_spf.c | 18 |
4 files changed, 45 insertions, 22 deletions
diff --git a/usr.sbin/ospfd/rde.c b/usr.sbin/ospfd/rde.c index 9d59129b7cc..65e9ab66bab 100644 --- a/usr.sbin/ospfd/rde.c +++ b/usr.sbin/ospfd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.27 2005/05/26 22:22:37 norby Exp $ */ +/* $OpenBSD: rde.c,v 1.28 2005/08/08 12:22:48 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org> @@ -371,7 +371,6 @@ rde_dispatch_imsg(int fd, short event, void *bula) if (nbr->self) { lsa_merge(nbr, lsa, v); - start_spf_timer(rdeconf); break; } @@ -395,8 +394,6 @@ rde_dispatch_imsg(int fd, short event, void *bula) imsg_compose(ibuf_ospfe, IMSG_LS_FLOOD, v->nbr->peerid, 0, -1, v->lsa, ntohs(v->lsa->hdr.len)); - - start_spf_timer(rdeconf); } else if (rde_req_list_exists(nbr, &lsa->hdr)) { imsg_compose(ibuf_ospfe, IMSG_LS_BADREQ, imsg.hdr.peerid, 0, -1, NULL, 0); diff --git a/usr.sbin/ospfd/rde.h b/usr.sbin/ospfd/rde.h index 9f1c0d46ba5..fb3023729fa 100644 --- a/usr.sbin/ospfd/rde.h +++ b/usr.sbin/ospfd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.19 2005/06/27 18:59:41 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.20 2005/08/08 12:22:48 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -135,7 +135,7 @@ void cand_list_clr(void); int cand_list_empty(void); void spf_timer(int, short, void *); -int start_spf_timer(struct ospfd_conf *); +int start_spf_timer(void); int stop_spf_timer(struct ospfd_conf *); int start_spf_holdtimer(struct ospfd_conf *); diff --git a/usr.sbin/ospfd/rde_lsdb.c b/usr.sbin/ospfd/rde_lsdb.c index 95de5c6b870..3e6bcd52914 100644 --- a/usr.sbin/ospfd/rde_lsdb.c +++ b/usr.sbin/ospfd/rde_lsdb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_lsdb.c,v 1.18 2005/05/25 15:21:39 norby Exp $ */ +/* $OpenBSD: rde_lsdb.c,v 1.19 2005/08/08 12:22:48 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org> @@ -32,6 +32,7 @@ struct vertex *vertex_get(struct lsa *, struct rde_nbr *); int lsa_router_check(struct lsa *, u_int16_t); void lsa_timeout(int, short, void *); void lsa_refresh(struct vertex *); +int lsa_equal(struct lsa *, struct lsa *); struct lsa_tree *global_lsa_tree; @@ -337,11 +338,16 @@ lsa_add(struct rde_nbr *nbr, struct lsa *lsa) new = vertex_get(lsa, nbr); old = RB_INSERT(lsa_tree, tree, new); + if (old != NULL) { + if (!lsa_equal(new->lsa, old->lsa)) + start_spf_timer(); RB_REMOVE(lsa_tree, tree, old); vertex_free(old); RB_INSERT(lsa_tree, tree, new); - } + } else + start_spf_timer(); + /* timeout handling either MAX_AGE or LS_REFRESH_TIME */ timerclear(&tv); @@ -582,11 +588,7 @@ lsa_merge(struct rde_nbr *nbr, struct lsa *lsa, struct vertex *v) lsa->hdr.seq_num = v->lsa->hdr.seq_num; /* compare LSA most header fields are equal so don't check them */ - if (lsa->hdr.len == v->lsa->hdr.len && - lsa->hdr.opts == v->lsa->hdr.opts && - lsa->hdr.age != htons(MAX_AGE) && - memcmp(&lsa->data, &v->lsa->data, ntohs(lsa->hdr.len) - - sizeof(struct lsa_hdr)) == 0) { + if (lsa_equal(lsa, v->lsa)) { free(lsa); return; } @@ -594,6 +596,7 @@ lsa_merge(struct rde_nbr *nbr, struct lsa *lsa, struct vertex *v) /* overwrite the lsa all other fields are unaffected */ free(v->lsa); v->lsa = lsa; + start_spf_timer(); /* set correct timeout for reflooding the LSA */ now = time(NULL); @@ -625,3 +628,26 @@ lsa_remove_invalid_sums(struct area *area) } } +int +lsa_equal(struct lsa *a, struct lsa *b) +{ + /* + * compare LSA that already have same type, adv_rtr and ls_id + * so not all header need to be compared + */ + if (a == NULL || b == NULL) + return (0); + if (a->hdr.len != b->hdr.len) + return (0); + if (a->hdr.opts != b->hdr.opts) + return (0); + /* LSA with age MAX_AGE are never equal */ + if (a->hdr.age == htons(MAX_AGE) || b->hdr.age == htons(MAX_AGE)) + return (0); + if (memcmp(&a->data, &b->data, ntohs(a->hdr.len) - + sizeof(struct lsa_hdr))) + return (0); + + return (1); +} + diff --git a/usr.sbin/ospfd/rde_spf.c b/usr.sbin/ospfd/rde_spf.c index fa783880f87..745350caaa2 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.30 2005/08/08 08:51:47 claudio Exp $ */ +/* $OpenBSD: rde_spf.c,v 1.31 2005/08/08 12:22:48 claudio Exp $ */ /* * Copyright (c) 2005 Esben Norby <norby@openbsd.org> @@ -353,7 +353,7 @@ spf_calc(struct area *area) inet_ntoa(area->id)); area->num_spf_calc++; - start_spf_timer(rdeconf); + start_spf_timer(); return; } @@ -558,7 +558,7 @@ spf_timer(int fd, short event, void *arg) LIST_FOREACH(area, &conf->area_list, entry) lsa_remove_invalid_sums(area); - start_spf_holdtimer(rdeconf); + start_spf_holdtimer(conf); break; case SPF_HOLD: log_debug("spf_timer: state HOLD -> IDLE"); @@ -570,23 +570,23 @@ spf_timer(int fd, short event, void *arg) } int -start_spf_timer(struct ospfd_conf *conf) +start_spf_timer(void) { struct timeval tv; - switch (conf->spf_state) { + switch (rdeconf->spf_state) { case SPF_IDLE: log_debug("start_spf_timer: IDLE -> DELAY"); timerclear(&tv); - tv.tv_sec = conf->spf_delay; - conf->spf_state = SPF_DELAY; - return (evtimer_add(&conf->spf_timer, &tv)); + tv.tv_sec = rdeconf->spf_delay; + rdeconf->spf_state = SPF_DELAY; + return (evtimer_add(&rdeconf->spf_timer, &tv)); case SPF_DELAY: /* ignore */ break; case SPF_HOLD: log_debug("start_spf_timer: HOLD -> HOLDQUEUE"); - conf->spf_state = SPF_HOLDQUEUE; + rdeconf->spf_state = SPF_HOLDQUEUE; break; case SPF_HOLDQUEUE: /* ignore */ |