summaryrefslogtreecommitdiffstats
path: root/ospfd/ospf_packet.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2021-10-12 21:08:23 +0200
committerRenato Westphal <renato@opensourcerouting.org>2021-10-12 22:33:32 +0200
commit3ebf9d34161833d5ab102d3d4f9107b1d8c01481 (patch)
tree163352f5eb89a7b79caac349560fffaa1bee4d52 /ospfd/ospf_packet.c
parentospfd: introduce additional opaque capability check in the GR code (diff)
downloadfrr-3ebf9d34161833d5ab102d3d4f9107b1d8c01481.tar.xz
frr-3ebf9d34161833d5ab102d3d4f9107b1d8c01481.zip
ospfd: fix another DR election issue during graceful restart
Commit 3551ee9e90304 introduced a regression that causes GR to fail under certain circumstances. In short, while ISM events should be ignored while acting as a helper for a restarting router, the DR/BDR fields of the neighbor structure should still be updated while processing a Hello packet. If that isn't done, it can cause the helper to elect the wrong DR while exiting from the helper mode, leading to a situation where there are two DRs for the same network segment (and a failed GR by consequence). Fix this. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'ospfd/ospf_packet.c')
-rw-r--r--ospfd/ospf_packet.c64
1 files changed, 33 insertions, 31 deletions
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index eacc30eba..ea356a2be 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__);
-
- 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;