summaryrefslogtreecommitdiff
path: root/proto/ospf/topology.c
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2019-07-10 11:27:08 +0200
committerMaria Matejka <mq@ucw.cz>2019-07-10 11:27:08 +0200
commitb2a4feeb4c877ff56d9b2ebd8119225c53ea40db (patch)
treedb22ae94ddf1208824e9ec70176dce63cb073174 /proto/ospf/topology.c
parenteac9250fd5b10809830361b94438339b3b31b270 (diff)
parent422a9334294dd9a5b13abd8563a3dc7233e64b13 (diff)
Merge branch 'master' into mq-filter-stack
Diffstat (limited to 'proto/ospf/topology.c')
-rw-r--r--proto/ospf/topology.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index efd03b54..2e9c3965 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",
@@ -280,11 +281,15 @@ ospf_do_originate_lsa(struct ospf_proto *p, struct top_hash_entry *en, void *lsa
struct top_hash_entry *
ospf_originate_lsa(struct ospf_proto *p, struct ospf_new_lsa *lsa)
{
- struct top_hash_entry *en;
+ struct top_hash_entry *en = NULL;
void *lsa_body = p->lsab;
u16 lsa_blen = p->lsab_used;
u16 lsa_length = sizeof(struct ospf_lsa_header) + lsa_blen;
+ /* RFC 3623 2 (1) - do not originate topology LSAs during graceful restart */
+ if (p->gr_recovery && (LSA_FUNCTION(lsa->type) <= LSA_FUNCTION(LSA_T_NSSA)))
+ goto drop;
+
/* For OSPFv2 Opaque LSAs, LS ID consists of Opaque Type and Opaque ID */
if (ospf_is_v2(p) && lsa_is_opaque(lsa->type))
lsa->id |= (u32) lsa_get_opaque_type(lsa->type) << 24;
@@ -329,7 +334,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 +427,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 +526,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 +543,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