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

Joachim Nilsson troglobit at gmail.com
Thu Jul 11 15:14:18 BST 2013


Looks good.

Verified, also reproduced bug prior to this patch.

Signed-off-by: Joachim Nilsson <troglobit at gmail.com>

On 07/08/2013 10:50 PM, Christian Franke wrote:
> 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? */
>   }
>   





More information about the Quagga-dev mailing list