Merge pull request #9813 from opensourcerouting/ospf-gr-fixes

ospfd: more GR fixes
This commit is contained in:
Donald Sharp 2021-10-15 09:21:40 -04:00 committed by GitHub
commit 1afa7d5326
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 71 deletions

View File

@ -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 */

View File

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

View File

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