]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: fix another DR election issue during graceful restart 9813/head
authorRenato Westphal <renato@opensourcerouting.org>
Tue, 12 Oct 2021 19:08:23 +0000 (16:08 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Tue, 12 Oct 2021 20:33:32 +0000 (17:33 -0300)
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>
ospfd/ospf_packet.c

index eacc30eba0a5f8175670fbbf3d2a467bdbf4b439..ea356a2bef29317191884500df421ab674408d52 100644 (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__);
-
-               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;