diff options
author | Renato Westphal <renato@opensourcerouting.org> | 2021-10-12 21:08:23 +0200 |
---|---|---|
committer | Renato Westphal <renato@opensourcerouting.org> | 2021-10-12 22:33:32 +0200 |
commit | 3ebf9d34161833d5ab102d3d4f9107b1d8c01481 (patch) | |
tree | 163352f5eb89a7b79caac349560fffaa1bee4d52 /ospfd/ospf_packet.c | |
parent | ospfd: introduce additional opaque capability check in the GR code (diff) | |
download | frr-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.c | 64 |
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; |