summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2023-03-01 17:31:56 -0300
committerRenato Westphal <renato@opensourcerouting.org>2023-03-02 19:38:03 -0300
commit3a94ed56964097e35c932bafce0c164b9323c12d (patch)
tree7c89e28fc1491d4b72e808857f81c2c002e57f94
parent5cbcc459aec36faa38d84a62cd57789bdf8f2882 (diff)
ospf6d: fix duplicate inter-area-prefix-LSAs after exiting from GR mode
An ABR that is originating inter-area-prefix-LSAs should take into account the fact that there might be self-originated LSAs for the same prefixes that were originated prior to a graceful restart. When that happens, the previous LSA-IDs should be reused to avoid having duplicate LSAs. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
-rw-r--r--ospf6d/ospf6_abr.c16
-rw-r--r--ospf6d/ospf6_lsdb.c27
-rw-r--r--ospf6d/ospf6_lsdb.h3
3 files changed, 43 insertions, 3 deletions
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c
index 4def3c7386..5b2b204dd8 100644
--- a/ospf6d/ospf6_abr.c
+++ b/ospf6d/ospf6_abr.c
@@ -515,11 +515,21 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
summary->path.origin.id =
ADV_ROUTER_IN_PREFIX(&route->prefix);
} else {
+ struct ospf6_lsa *old;
+
summary->path.origin.type =
htons(OSPF6_LSTYPE_INTER_PREFIX);
- summary->path.origin.id = ospf6_new_ls_id(
- summary->path.origin.type,
- summary->path.origin.adv_router, area->lsdb);
+
+ /* Try to reuse LS-ID from previous running instance. */
+ old = ospf6_find_inter_prefix_lsa(area->ospf6, area,
+ &route->prefix);
+ if (old)
+ summary->path.origin.id = old->header->id;
+ else
+ summary->path.origin.id = ospf6_new_ls_id(
+ summary->path.origin.type,
+ summary->path.origin.adv_router,
+ area->lsdb);
}
summary = ospf6_route_add(summary, summary_table);
} else {
diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c
index 0221102b59..586183731c 100644
--- a/ospf6d/ospf6_lsdb.c
+++ b/ospf6d/ospf6_lsdb.c
@@ -13,8 +13,10 @@
#include "vty.h"
#include "ospf6_proto.h"
+#include "ospf6_area.h"
#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
+#include "ospf6_abr.h"
#include "ospf6_asbr.h"
#include "ospf6_route.h"
#include "ospf6d.h"
@@ -216,6 +218,31 @@ struct ospf6_lsa *ospf6_find_external_lsa(struct ospf6 *ospf6, struct prefix *p)
return lsa;
}
+struct ospf6_lsa *ospf6_find_inter_prefix_lsa(struct ospf6 *ospf6,
+ struct ospf6_area *area,
+ struct prefix *p)
+{
+ struct ospf6_lsa *lsa;
+ uint16_t type = htons(OSPF6_LSTYPE_INTER_PREFIX);
+
+ for (ALL_LSDB_TYPED_ADVRTR(area->lsdb, type, ospf6->router_id, lsa)) {
+ struct ospf6_inter_prefix_lsa *prefix_lsa;
+ struct prefix prefix;
+
+ prefix_lsa =
+ (struct ospf6_inter_prefix_lsa *)OSPF6_LSA_HEADER_END(
+ lsa->header);
+ prefix.family = AF_INET6;
+ prefix.prefixlen = prefix_lsa->prefix.prefix_length;
+ ospf6_prefix_in6_addr(&prefix.u.prefix6, prefix_lsa,
+ &prefix_lsa->prefix);
+ if (prefix_same(p, &prefix))
+ return lsa;
+ }
+
+ return NULL;
+}
+
struct ospf6_lsa *ospf6_lsdb_lookup_next(uint16_t type, uint32_t id,
uint32_t adv_router,
struct ospf6_lsdb *lsdb)
diff --git a/ospf6d/ospf6_lsdb.h b/ospf6d/ospf6_lsdb.h
index 7e20b05447..a2444f1c14 100644
--- a/ospf6d/ospf6_lsdb.h
+++ b/ospf6d/ospf6_lsdb.h
@@ -29,6 +29,9 @@ extern struct ospf6_lsa *ospf6_lsdb_lookup(uint16_t type, uint32_t id,
extern struct ospf6_lsa *ospf6_lsdb_lookup_next(uint16_t type, uint32_t id,
uint32_t adv_router,
struct ospf6_lsdb *lsdb);
+extern struct ospf6_lsa *ospf6_find_inter_prefix_lsa(struct ospf6 *ospf6,
+ struct ospf6_area *area,
+ struct prefix *p);
extern void ospf6_lsdb_add(struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb);
extern void ospf6_lsdb_remove(struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb);