Skip to content

Commit

Permalink
Merge pull request FRRouting#9813 from opensourcerouting/ospf-gr-fixes
Browse files Browse the repository at this point in the history
ospfd: more GR fixes
  • Loading branch information
donaldsharp authored Oct 15, 2021
2 parents 9eefec4 + 3ebf9d3 commit 1afa7d5
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 74 deletions.
2 changes: 1 addition & 1 deletion ospf6d/ospf6_gr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
60 changes: 18 additions & 42 deletions ospfd/ospf_gr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)
Expand All @@ -183,45 +186,13 @@ 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)
{
struct ospf_area *area;
struct listnode *anode;

for (ALL_LIST_ELEMENTS_RO(ospf->areas, anode, area)) {
struct ospf_lsa *lsa;
struct ospf_interface *oi;
struct listnode *inode;

Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
64 changes: 33 additions & 31 deletions ospfd/ospf_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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__);

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

/* 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->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);
/* 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);

/* 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;
Expand Down

0 comments on commit 1afa7d5

Please sign in to comment.