[quagga-dev 10584] [RFC] ospfd: run DR election prior to LSA regeneration

Christian Franke chris at opensourcerouting.org
Mon Jul 8 21:50:58 BST 2013


The results from DR election are used when constructing router-LSAs.
E.g. they are used to determine whether a broadcast interface should
be added with a link type of stub interface or transit interface.

Therefore, we should run DR election before regenerating LSAs.

Before commit c363d3861b5384a31465a72ddc3b0f6ff007a95a the DR election
was called synchronously prior to router-LSA regeneration which was run
asynchronously.

This fixes bug #761 on the Quagga bugzilla.

Signed-off-by: Christian Franke <chris at opensourcerouting.org>
---

A few details on what exactly happens in bug #761:

                   10.0.1.0/24
       ----------------------------------
       |                 |              |
 +-------------+ +--------------+ +----------+
 | router 1 DR | | router 2 BDR | | router 3 |
 +-------------+ +--------------+ +----------+
       |                 |              |
      stub              stub           stub

All links are up and the routers have become fully adjacent.
Now suppose that router 1's connection to the network 10.0.1.0/24
fails. Eventually, router 3 will have an InactivityTimer event for
the neighbor that is router 1. This will cause the following events
on router 3:

  1. Neighbor router 1's state is changed from NSM_Full to NSM_Deleted
  2. A new router-LSA is generated.
     The link from router 3 to 10.0.1.0/24 is inserted as a stub network
     into that router-LSA because router 1 is still selected as DR, but not
     in state NSM_Full anymore.
  3. DR election is rerun, and as router 1 is no longer elegible, router 2
     becomes DR.
  4. The router-LSA isn't refreshed in a timely manner, until it expires,
     or it's updated by another event, it will contain the link from router 3
     to 10.0.1.0/24 as a stub-network, thereby breaking connectivity.

By having the DR election run before regenerating the router-LSA, this
problem can be fixed.

However I am wondering if it wouldn't be a good idea to additionally
regenerate the own router-LSA whenever the results from the DR election
for a local interface change, which is currently not done.
Any comments on that?

 ospfd/ospf_nsm.c |   33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c
index fe4ddf5..bcabd5f 100644
--- a/ospfd/ospf_nsm.c
+++ b/ospfd/ospf_nsm.c
@@ -661,6 +661,25 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)
   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
     vl_area = ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id);
 
+  /* Generate NeighborChange ISM event.
+   *
+   * In response to NeighborChange, DR election is rerun. The information
+   * from the election process is required by the router-lsa construction.
+   *
+   * Therefore, trigger the event prior to refreshing the LSAs. */
+  switch (oi->state) {
+  case ISM_DROther:
+  case ISM_Backup:
+  case ISM_DR:
+    if ((old_state < NSM_TwoWay && state >= NSM_TwoWay) ||
+        (old_state >= NSM_TwoWay && state < NSM_TwoWay))
+      OSPF_ISM_EVENT_EXECUTE (oi, ISM_NeighborChange);
+    break;
+  default:
+    /* ISM_PointToPoint -> ISM_Down, ISM_Loopback -> ISM_Down, etc. */
+    break;
+  }
+
   /* One of the neighboring routers changes to/from the FULL state. */
   if ((old_state != NSM_Full && state == NSM_Full) ||
       (old_state == NSM_Full && state != NSM_Full))
@@ -760,20 +779,6 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)
   if (state == NSM_Down)
     nbr->crypt_seqnum = 0;
   
-  /* Generete NeighborChange ISM event. */
-  switch (oi->state) {
-  case ISM_DROther:
-  case ISM_Backup:
-  case ISM_DR:
-    if ((old_state < NSM_TwoWay && state >= NSM_TwoWay) ||
-        (old_state >= NSM_TwoWay && state < NSM_TwoWay))
-      OSPF_ISM_EVENT_EXECUTE (oi, ISM_NeighborChange);
-    break;
-  default:
-    /* ISM_PointToPoint -> ISM_Down, ISM_Loopback -> ISM_Down, etc. */
-    break;
-  }
-
   /* Preserve old status? */
 }
 
-- 
1.7.10.4





More information about the Quagga-dev mailing list