mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 10:09:25 +00:00
Merge pull request #12922 from opensourcerouting/ospf-gr-fixes
OSPF Graceful Restart fixes
This commit is contained in:
commit
4c88ac57d7
@ -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 {
|
||||
|
@ -1105,9 +1105,12 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
|
||||
&new->refresh);
|
||||
}
|
||||
|
||||
/* GR: check for network topology change. */
|
||||
struct ospf6 *ospf6 = from->ospf6_if->area->ospf6;
|
||||
struct ospf6_area *area = from->ospf6_if->area;
|
||||
if (ospf6->gr_info.restart_in_progress)
|
||||
if (ospf6->gr_info.restart_in_progress &&
|
||||
(new->header->type == ntohs(OSPF6_LSTYPE_ROUTER) ||
|
||||
new->header->type == ntohs(OSPF6_LSTYPE_NETWORK)))
|
||||
ospf6_gr_check_lsdb_consistency(ospf6, area);
|
||||
|
||||
return;
|
||||
|
@ -127,6 +127,7 @@ static void ospf6_gr_restart_exit(struct ospf6 *ospf6, const char *reason)
|
||||
{
|
||||
struct ospf6_area *area;
|
||||
struct listnode *onode, *anode;
|
||||
struct ospf6_route *route;
|
||||
|
||||
if (IS_DEBUG_OSPF6_GR)
|
||||
zlog_debug("GR: exiting graceful restart: %s", reason);
|
||||
@ -148,8 +149,16 @@ static void ospf6_gr_restart_exit(struct ospf6 *ospf6, const char *reason)
|
||||
*/
|
||||
OSPF6_ROUTER_LSA_EXECUTE(area);
|
||||
|
||||
/*
|
||||
* Force reorigination of intra-area-prefix-LSAs to handle
|
||||
* areas without any full adjacency.
|
||||
*/
|
||||
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(area);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(area->if_list, anode, oi)) {
|
||||
OSPF6_LINK_LSA_EXECUTE(oi);
|
||||
/* Reoriginate Link-LSA. */
|
||||
if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
|
||||
OSPF6_LINK_LSA_EXECUTE(oi);
|
||||
|
||||
/*
|
||||
* 2) The router should reoriginate network-LSAs on all
|
||||
@ -160,6 +169,16 @@ static void ospf6_gr_restart_exit(struct ospf6 *ospf6, const char *reason)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* While all self-originated NSSA and AS-external LSAs were already
|
||||
* learned from the helping neighbors, we need to reoriginate them in
|
||||
* order to ensure they will be refreshed periodically.
|
||||
*/
|
||||
for (route = ospf6_route_head(ospf6->external_table); route;
|
||||
route = ospf6_route_next(route))
|
||||
ospf6_handle_external_lsa_origination(ospf6, route,
|
||||
&route->prefix);
|
||||
|
||||
/*
|
||||
* 3) The router reruns its OSPF routing calculations, this time
|
||||
* installing the results into the system forwarding table, and
|
||||
|
@ -592,6 +592,7 @@ static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a,
|
||||
|
||||
uint8_t dr_election(struct ospf6_interface *oi)
|
||||
{
|
||||
struct ospf6 *ospf6 = oi->area->ospf6;
|
||||
struct listnode *node, *nnode;
|
||||
struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
|
||||
struct ospf6_neighbor *best_drouter, *best_bdrouter;
|
||||
@ -602,13 +603,12 @@ uint8_t dr_election(struct ospf6_interface *oi)
|
||||
|
||||
/* pseudo neighbor myself, including noting current DR/BDR (1) */
|
||||
memset(&myself, 0, sizeof(myself));
|
||||
inet_ntop(AF_INET, &oi->area->ospf6->router_id, myself.name,
|
||||
sizeof(myself.name));
|
||||
inet_ntop(AF_INET, &ospf6->router_id, myself.name, sizeof(myself.name));
|
||||
myself.state = OSPF6_NEIGHBOR_TWOWAY;
|
||||
myself.drouter = oi->drouter;
|
||||
myself.bdrouter = oi->bdrouter;
|
||||
myself.priority = oi->priority;
|
||||
myself.router_id = oi->area->ospf6->router_id;
|
||||
myself.router_id = ospf6->router_id;
|
||||
|
||||
/* Electing BDR (2) */
|
||||
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
|
||||
@ -657,8 +657,10 @@ uint8_t dr_election(struct ospf6_interface *oi)
|
||||
/* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
|
||||
/* RFC 2328 section 12.4. Originating LSAs (3) will be handled
|
||||
accordingly after AdjOK */
|
||||
if (oi->drouter != (drouter ? drouter->router_id : htonl(0))
|
||||
|| oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl(0))) {
|
||||
|
||||
if (oi->drouter != (drouter ? drouter->router_id : htonl(0)) ||
|
||||
oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl(0)) ||
|
||||
ospf6->gr_info.restart_in_progress) {
|
||||
if (IS_OSPF6_DEBUG_INTERFACE)
|
||||
zlog_debug("DR Election on %s: DR: %s BDR: %s",
|
||||
oi->interface->name,
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -2102,6 +2102,14 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
|
||||
if (ospf_flood(oi->ospf, nbr, current, lsa)
|
||||
< 0) /* Trap NSSA later. */
|
||||
DISCARD_LSA(lsa, 5);
|
||||
|
||||
/* GR: check for network topology change. */
|
||||
if (ospf->gr_info.restart_in_progress &&
|
||||
((lsa->data->type == OSPF_ROUTER_LSA ||
|
||||
lsa->data->type == OSPF_NETWORK_LSA)))
|
||||
ospf_gr_check_lsdb_consistency(oi->ospf,
|
||||
oi->area);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2214,9 +2222,6 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
|
||||
|
||||
assert(listcount(lsas) == 0);
|
||||
list_delete(&lsas);
|
||||
|
||||
if (ospf->gr_info.restart_in_progress)
|
||||
ospf_gr_check_lsdb_consistency(oi->ospf, oi->area);
|
||||
}
|
||||
|
||||
/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
|
||||
|
Loading…
Reference in New Issue
Block a user