diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2019-07-09 03:31:54 +0200 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2019-07-09 03:39:19 +0200 |
commit | 85840d4c03552a69927b666774fa39921e7b1047 (patch) | |
tree | 83602f31fd98940bd74713017e9b26deb8ac6e58 /proto/ospf/topology.c | |
parent | 05e3933c06b488e71c9c149c25aec9c733a8bd1f (diff) |
OSPF: Fix handling of external routes on graceful restart
We need to flush learned external LSAs a bit later than other LSAs (after
first feed after end of the graceful restart) to avoid flap of external
routes.
Diffstat (limited to 'proto/ospf/topology.c')
-rw-r--r-- | proto/ospf/topology.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index efd03b54..a5875770 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -71,6 +71,7 @@ ospf_install_lsa(struct ospf_proto *p, struct ospf_lsa_header *lsa, u32 type, u3 en->lsa = *lsa; en->init_age = en->lsa.age; en->inst_time = current_time(); + en->gr_dirty = p->gr_recovery && (lsa->rt == p->router_id); /* * We do not set en->mode. It is either default LSA_M_BASIC, or in a special @@ -246,7 +247,7 @@ ospf_do_originate_lsa(struct ospf_proto *p, struct top_hash_entry *en, void *lsa en->lsa.age = 0; en->init_age = 0; en->inst_time = current_time(); - en->dirty = 0; + en->gr_dirty = 0; lsa_generate_checksum(&en->lsa, en->lsa_body); OSPF_TRACE(D_EVENTS, "Originating LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x", @@ -329,7 +330,7 @@ ospf_originate_lsa(struct ospf_proto *p, struct ospf_new_lsa *lsa) (lsa_length == en->lsa.length) && !memcmp(lsa_body, en->lsa_body, lsa_blen) && (!ospf_is_v2(p) || (lsa->opts == lsa_get_options(&en->lsa))) && - !en->dirty) + !en->gr_dirty) goto drop; lsa_body = lsab_flush(p); @@ -422,6 +423,7 @@ void ospf_flush_lsa(struct ospf_proto *p, struct top_hash_entry *en) { en->nf = NULL; + en->gr_dirty = 0; if (en->next_lsa_body) { @@ -520,12 +522,6 @@ ospf_update_lsadb(struct ospf_proto *p) continue; } - if (en->dirty) - { - ospf_flush_lsa(p, en); - continue; - } - if ((en->lsa.rt == p->router_id) && (real_age >= LSREFRESHTIME)) { ospf_refresh_lsa(p, en); @@ -543,14 +539,27 @@ ospf_update_lsadb(struct ospf_proto *p) } void -ospf_mark_lsadb(struct ospf_proto *p) +ospf_feed_begin(struct channel *C, int initial UNUSED) { + struct ospf_proto *p = (struct ospf_proto *) C->proto; struct top_hash_entry *en; - /* Mark all local LSAs as dirty */ + /* Mark all external LSAs as stale */ WALK_SLIST(en, p->lsal) - if (en->lsa.rt == p->router_id) - en->dirty = 1; + if (en->mode == LSA_M_EXPORT) + en->mode = LSA_M_EXPORT_STALE; +} + +void +ospf_feed_end(struct channel *C) +{ + struct ospf_proto *p = (struct ospf_proto *) C->proto; + struct top_hash_entry *en; + + /* Flush stale LSAs */ + WALK_SLIST(en, p->lsal) + if (en->mode == LSA_M_EXPORT_STALE) + ospf_flush_lsa(p, en); } static u32 |