mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 16:54:30 +00:00
Merge pull request #9813 from opensourcerouting/ospf-gr-fixes
ospfd: more GR fixes
This commit is contained in:
commit
1afa7d5326
@ -58,7 +58,7 @@ static int ospf6_gr_lsa_originate(struct ospf6_interface *oi)
|
|||||||
char buffer[OSPF6_MAX_LSASIZE];
|
char buffer[OSPF6_MAX_LSASIZE];
|
||||||
|
|
||||||
if (IS_OSPF6_DEBUG_ORIGINATE(LINK))
|
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);
|
oi->interface->name);
|
||||||
|
|
||||||
/* prepare buffer */
|
/* prepare buffer */
|
||||||
|
@ -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. */
|
/* 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;
|
struct ospf_lsa *lsa, *old;
|
||||||
|
|
||||||
@ -164,6 +164,9 @@ static void ospf_gr_lsa_originate(struct ospf_interface *oi)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (maxage)
|
||||||
|
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
|
||||||
|
|
||||||
/* Find the old LSA and increase the seqno. */
|
/* Find the old LSA and increase the seqno. */
|
||||||
old = ospf_gr_lsa_lookup(oi->ospf, oi->area);
|
old = ospf_gr_lsa_lookup(oi->ospf, oi->area);
|
||||||
if (old)
|
if (old)
|
||||||
@ -183,37 +186,6 @@ static void ospf_gr_lsa_originate(struct ospf_interface *oi)
|
|||||||
ospf_flood_through_interface(oi, NULL, lsa);
|
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. */
|
/* Flush all self-originated Grace-LSAs. */
|
||||||
static void ospf_gr_flush_grace_lsas(struct ospf *ospf)
|
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;
|
struct listnode *anode;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(ospf->areas, anode, area)) {
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, anode, area)) {
|
||||||
struct ospf_lsa *lsa;
|
|
||||||
struct ospf_interface *oi;
|
struct ospf_interface *oi;
|
||||||
struct listnode *inode;
|
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]",
|
"GR: flushing self-originated Grace-LSAs [area %pI4]",
|
||||||
&area->area_id);
|
&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))
|
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. */
|
/* Send a Grace-LSA to all neighbors. */
|
||||||
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi))
|
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. */
|
/* Record end of the grace period in non-volatile memory. */
|
||||||
ospf_gr_nvm_update(ospf);
|
ospf_gr_nvm_update(ospf);
|
||||||
@ -770,6 +734,18 @@ DEFPY(graceful_restart_prepare, graceful_restart_prepare_cmd,
|
|||||||
IP_STR
|
IP_STR
|
||||||
"Prepare to restart the OSPF process")
|
"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();
|
ospf_gr_prepare();
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -1096,39 +1096,41 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Neighbor is under GR Restart, hence ignoring the ISM Events",
|
"%s, Neighbor is under GR Restart, hence ignoring the ISM Events",
|
||||||
__PRETTY_FUNCTION__);
|
__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;
|
/* neighbor itself declares BDR. */
|
||||||
}
|
if (oi->state == ISM_Waiting
|
||||||
|
&& IPV4_ADDR_SAME(&nbr->address.u.prefix4,
|
||||||
/* If neighbor itself declares DR and no BDR exists,
|
&hello->bd_router))
|
||||||
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);
|
OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen);
|
||||||
|
|
||||||
/* neighbor itself declares BDR. */
|
/* had not previously. */
|
||||||
if (oi->state == ISM_Waiting
|
if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router)
|
||||||
&& IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router))
|
&& IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->d_router))
|
||||||
OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen);
|
|| (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. */
|
/* had not previously. */
|
||||||
if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router)
|
if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router)
|
||||||
&& IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->d_router))
|
&& IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->bd_router))
|
||||||
|| (IPV4_ADDR_CMP(&nbr->address.u.prefix4, &hello->d_router)
|
|| (IPV4_ADDR_CMP(&nbr->address.u.prefix4,
|
||||||
&& IPV4_ADDR_SAME(&nbr->address.u.prefix4, &nbr->d_router)))
|
&hello->bd_router)
|
||||||
OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
|
&& IPV4_ADDR_SAME(&nbr->address.u.prefix4,
|
||||||
|
&nbr->bd_router)))
|
||||||
|
OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
|
||||||
|
|
||||||
/* had not previously. */
|
/* Neighbor priority check. */
|
||||||
if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router)
|
if (nbr->priority >= 0 && nbr->priority != hello->priority)
|
||||||
&& IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->bd_router))
|
OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
|
||||||
|| (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. */
|
/* Set neighbor information. */
|
||||||
nbr->priority = hello->priority;
|
nbr->priority = hello->priority;
|
||||||
|
Loading…
Reference in New Issue
Block a user