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>
This commit is contained in:
Renato Westphal 2023-03-01 17:31:56 -03:00
parent 5cbcc459ae
commit 3a94ed5696
3 changed files with 43 additions and 3 deletions

View File

@ -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 {

View File

@ -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)

View File

@ -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);