summaryrefslogtreecommitdiffstats
path: root/ospfd/ospf_lsa.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2021-05-31 15:27:51 +0200
committerRenato Westphal <renato@opensourcerouting.org>2021-07-05 16:43:02 +0200
commit1051417011b98dcebba527e0c9053db6fc7c6e30 (patch)
tree4e07b4e25d3de792d20c6a78eb095b45a77ae731 /ospfd/ospf_lsa.c
parentospfd: rename the graceful restart header (diff)
downloadfrr-1051417011b98dcebba527e0c9053db6fc7c6e30.tar.xz
frr-1051417011b98dcebba527e0c9053db6fc7c6e30.zip
ospfd: introduce support for Graceful Restart (restarting mode)
RFC 3623 specifies the Graceful Restart enhancement to the OSPF routing protocol. This PR implements support for the restarting mode, whereas the helper mode was implemented by #6811. This work is based on #6782, which implemented the pre-restart part and settled the foundations for the post-restart part (behavioral changes, GR exit conditions, and on-exit actions). Here's a quick summary of how the GR restarting mode works: * GR can be enabled on a per-instance basis using the `graceful-restart [grace-period (1-1800)]` command; * To perform a graceful shutdown, the `graceful-restart prepare ospf` EXEC-level command needs to be issued before restarting the ospfd daemon (there's no specific requirement on how the daemon should be restarted); * `graceful-restart prepare ospf` will initiate the graceful restart for all GR-enabled instances by taking the following actions: o Flooding Grace-LSAs over all interfaces o Freezing the OSPF routes in the RIB o Saving the end of the grace period in non-volatile memory (a JSON file stored in `$frr_statedir`) * Once ospfd is started again, it will follow the procedures described in RFC 3623 until it detects it's time to exit the graceful restart (either successfully or unsuccessfully). Testing done: * New topotest featuring a multi-area OSPF topology (including stub and NSSA areas); * Successful interop tests against IOS-XR routers acting as helpers. Co-authored-by: GalaxyGorilla <sascha@netdef.org> Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'ospfd/ospf_lsa.c')
-rw-r--r--ospfd/ospf_lsa.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index b098581ce..723a54a77 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -819,6 +819,14 @@ static struct ospf_lsa *ospf_router_lsa_originate(struct ospf_area *area)
{
struct ospf_lsa *new;
+ if (area->ospf->gr_info.restart_in_progress) {
+ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
+ zlog_debug(
+ "LSA[Type%d]: Graceful Restart in progress, don't originate",
+ OSPF_ROUTER_LSA);
+ return NULL;
+ }
+
/* Create new router-LSA instance. */
if ((new = ospf_router_lsa_new(area)) == NULL) {
zlog_err("%s: ospf_router_lsa_new returned NULL", __func__);
@@ -1045,6 +1053,14 @@ void ospf_network_lsa_update(struct ospf_interface *oi)
{
struct ospf_lsa *new;
+ if (oi->area->ospf->gr_info.restart_in_progress) {
+ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
+ zlog_debug(
+ "LSA[Type%d]: Graceful Restart in progress, don't originate",
+ OSPF_NETWORK_LSA);
+ return;
+ }
+
if (oi->network_lsa_self != NULL) {
ospf_lsa_refresh(oi->ospf, oi->network_lsa_self);
return;
@@ -1212,6 +1228,14 @@ struct ospf_lsa *ospf_summary_lsa_originate(struct prefix_ipv4 *p,
struct ospf_lsa *new;
struct in_addr id;
+ if (area->ospf->gr_info.restart_in_progress) {
+ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
+ zlog_debug(
+ "LSA[Type%d]: Graceful Restart in progress, don't originate",
+ OSPF_SUMMARY_LSA);
+ return NULL;
+ }
+
id = ospf_lsa_unique_id(area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
if (id.s_addr == 0xffffffff) {
@@ -1353,6 +1377,14 @@ struct ospf_lsa *ospf_summary_asbr_lsa_originate(struct prefix_ipv4 *p,
struct ospf_lsa *new;
struct in_addr id;
+ if (area->ospf->gr_info.restart_in_progress) {
+ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
+ zlog_debug(
+ "LSA[Type%d]: Graceful Restart in progress, don't originate",
+ OSPF_ASBR_SUMMARY_LSA);
+ return NULL;
+ }
+
id = ospf_lsa_unique_id(area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA,
p);
@@ -1799,6 +1831,13 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
struct ospf_lsa *new;
struct as_external_lsa *extnew;
+ if (ospf->gr_info.restart_in_progress) {
+ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
+ zlog_debug(
+ "LSA[Translated Type5]: Graceful Restart in progress, don't originate");
+ return NULL;
+ }
+
/* we cant use ospf_external_lsa_originate() as we need to set
* the OSPF_LSA_LOCAL_XLT flag, must originate by hand
*/
@@ -1964,6 +2003,13 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
{
struct ospf_lsa *new;
+ if (ospf->gr_info.restart_in_progress) {
+ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
+ zlog_debug(
+ "LSA[Type5]: Graceful Restart in progress, don't originate");
+ return NULL;
+ }
+
/* Added for NSSA project....
External LSAs are originated in ASBRs as usual, but for NSSA