diff --git a/ospf6d/ospf6_gr.c b/ospf6d/ospf6_gr.c index 40893ed998..c3e6f62f06 100644 --- a/ospf6d/ospf6_gr.c +++ b/ospf6d/ospf6_gr.c @@ -58,7 +58,7 @@ static int ospf6_gr_lsa_originate(struct ospf6_interface *oi) char buffer[OSPF6_MAX_LSASIZE]; if (IS_OSPF6_DEBUG_ORIGINATE(LINK)) - zlog_debug("Originate Link-LSA for Interface %s", + zlog_debug("Originate Grace-LSA for Interface %s", oi->interface->name); /* prepare buffer */ diff --git a/ospfd/ospf_gr.c b/ospfd/ospf_gr.c index 6a5c0bae98..8276ccb89c 100644 --- a/ospfd/ospf_gr.c +++ b/ospfd/ospf_gr.c @@ -150,7 +150,7 @@ static struct ospf_lsa *ospf_gr_lsa_new(struct ospf_interface *oi) } /* Originate and install Grace-LSA for a given interface. */ -static void ospf_gr_lsa_originate(struct ospf_interface *oi) +static void ospf_gr_lsa_originate(struct ospf_interface *oi, bool maxage) { struct ospf_lsa *lsa, *old; @@ -164,6 +164,9 @@ static void ospf_gr_lsa_originate(struct ospf_interface *oi) return; } + if (maxage) + lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); + /* Find the old LSA and increase the seqno. */ old = ospf_gr_lsa_lookup(oi->ospf, oi->area); if (old) @@ -183,37 +186,6 @@ static void ospf_gr_lsa_originate(struct ospf_interface *oi) ospf_flood_through_interface(oi, NULL, lsa); } -/* Flush a given self-originated Grace-LSA. */ -static struct ospf_lsa *ospf_gr_flush_grace_lsa(struct ospf_interface *oi, - struct ospf_lsa *old) -{ - struct ospf_lsa *lsa; - - if (ospf_interface_neighbor_count(oi) == 0) - return NULL; - - if (IS_DEBUG_OSPF_GR) - zlog_debug( - "GR: flushing self-originated Grace-LSAs [interface %s]", - oi->ifp->name); - - lsa = ospf_lsa_dup(old); - lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); - lsa->data->ls_seqnum = lsa_seqnum_increment(lsa); - - /* Install updated LSA into LSDB. */ - if (ospf_lsa_install(oi->ospf, oi, lsa) == NULL) { - zlog_warn("%s: ospf_lsa_install() failed", __func__); - ospf_lsa_unlock(&lsa); - return NULL; - } - - /* Flood the LSA through out the interface */ - ospf_flood_through_interface(oi, NULL, lsa); - - return lsa; -} - /* Flush all self-originated Grace-LSAs. */ static void ospf_gr_flush_grace_lsas(struct ospf *ospf) { @@ -221,7 +193,6 @@ static void ospf_gr_flush_grace_lsas(struct ospf *ospf) struct listnode *anode; for (ALL_LIST_ELEMENTS_RO(ospf->areas, anode, area)) { - struct ospf_lsa *lsa; struct ospf_interface *oi; struct listnode *inode; @@ -230,15 +201,8 @@ static void ospf_gr_flush_grace_lsas(struct ospf *ospf) "GR: flushing self-originated Grace-LSAs [area %pI4]", &area->area_id); - lsa = ospf_gr_lsa_lookup(ospf, area); - if (!lsa) { - zlog_warn("%s: Grace-LSA not found [area %pI4]", - __func__, &area->area_id); - continue; - } - for (ALL_LIST_ELEMENTS_RO(area->oiflist, inode, oi)) - ospf_gr_flush_grace_lsa(oi, lsa); + ospf_gr_lsa_originate(oi, true); } } @@ -750,7 +714,7 @@ static void ospf_gr_prepare(void) /* Send a Grace-LSA to all neighbors. */ for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) - ospf_gr_lsa_originate(oi); + ospf_gr_lsa_originate(oi, false); /* Record end of the grace period in non-volatile memory. */ ospf_gr_nvm_update(ospf); @@ -770,6 +734,18 @@ DEFPY(graceful_restart_prepare, graceful_restart_prepare_cmd, IP_STR "Prepare to restart the OSPF process") { + struct ospf *ospf; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)) { + vty_out(vty, + "%% Can't start graceful restart: opaque capability not enabled (VRF %s)\n\n", + ospf_get_name(ospf)); + return CMD_WARNING; + } + } + ospf_gr_prepare(); return CMD_SUCCESS; diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 4294c255af..ca4bb0a2b9 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -1096,39 +1096,41 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, zlog_debug( "%s, Neighbor is under GR Restart, hence ignoring the ISM Events", __PRETTY_FUNCTION__); + } else { + /* If neighbor itself declares DR and no BDR exists, + cause event BackupSeen */ + if (IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router)) + if (hello->bd_router.s_addr == INADDR_ANY + && oi->state == ISM_Waiting) + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen); - return; - } - - /* If neighbor itself declares DR and no BDR exists, - cause event BackupSeen */ - if (IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router)) - if (hello->bd_router.s_addr == INADDR_ANY - && oi->state == ISM_Waiting) + /* neighbor itself declares BDR. */ + if (oi->state == ISM_Waiting + && IPV4_ADDR_SAME(&nbr->address.u.prefix4, + &hello->bd_router)) OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen); - /* neighbor itself declares BDR. */ - if (oi->state == ISM_Waiting - && IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router)) - OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen); + /* had not previously. */ + if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router) + && IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->d_router)) + || (IPV4_ADDR_CMP(&nbr->address.u.prefix4, &hello->d_router) + && IPV4_ADDR_SAME(&nbr->address.u.prefix4, + &nbr->d_router))) + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); - /* had not previously. */ - if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router) - && IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->d_router)) - || (IPV4_ADDR_CMP(&nbr->address.u.prefix4, &hello->d_router) - && IPV4_ADDR_SAME(&nbr->address.u.prefix4, &nbr->d_router))) - OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); + /* had not previously. */ + if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router) + && IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->bd_router)) + || (IPV4_ADDR_CMP(&nbr->address.u.prefix4, + &hello->bd_router) + && IPV4_ADDR_SAME(&nbr->address.u.prefix4, + &nbr->bd_router))) + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); - /* had not previously. */ - if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router) - && IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->bd_router)) - || (IPV4_ADDR_CMP(&nbr->address.u.prefix4, &hello->bd_router) - && IPV4_ADDR_SAME(&nbr->address.u.prefix4, &nbr->bd_router))) - OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); - - /* Neighbor priority check. */ - if (nbr->priority >= 0 && nbr->priority != hello->priority) - OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); + /* Neighbor priority check. */ + if (nbr->priority >= 0 && nbr->priority != hello->priority) + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); + } /* Set neighbor information. */ nbr->priority = hello->priority;