[quagga-dev 9639] Re: [PATCH 1/4] ospfd: Optimize and improve SPF nexthop calculation

Joakim Tjernlund joakim.tjernlund at transmode.se
Mon Aug 6 13:15:44 BST 2012


Paul Jakma <paul at jakma.org> wrote on 2012/08/06 13:10:31:
>
> Hi Joakim,
>
> Can I ask why you went for this approach? We already have a unique handle
> for an interface, the ifindex - why not use that?

Ifindex from where? The router LSA were one would put ifindex instead of IP address?
That does not work for the 2 cases I listed in the commit msg:

> > - Multiple PtP interfaces with the same IP address between two routers.

You don't have to set the unnumbered flag, for example current quagga does not.

> > - Use Unnumbered PtP on just one end of the link.

Unumbered on just one side shoukd also work, at least according to
Acee L. on the ietf list( if not memory fails ).

>
> On Sat, 7 Jul 2012, Joakim Tjernlund wrote:
>
> > Maintain router LSA positions in OSPF interface.
> > Find the OSPF interface in nexthop_calculation using
> > the position in the router LSA. This is possible because
> > the only time nexthop_calculation needs to look up interfaces
> > is when dealing with its own Router LSA.
> >
> > This has the following advantages:
> > - Multiple PtP interfaces with the same IP address between two routers.
> > - Use Unnumbered PtP on just one end of the link.
> > - Faster OI lookup for the OSPF interface and only
> >   done once for PtoP links.
> >
> > *ospf_interface.h: (struct ospf_interface) Add storage for
> >          storing router LSA position.
> >
> > *ospf_interface.c: (ospf_if_lookup_by_lsa_pos)
> >          lookup OSPF I/F in an area using LSA position.
> >
> > *ospf_lsa.c: (router_lsa_link_set) record Router LSA position.
> >
> > *ospf_spf.c: (ospf_spf_next) Count and pass along lsa position.
> >         (ospf_nexthop_calculation) Add lsa position argument.
> >         call ospf_if_lookup_by_lsa_pos() for OSFP interface handle.
> >         Clean up and remove all calls ospf_if_is_configured() the
> >         rest. Adjust a few debug logs.
> >
>
>
> > diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
> > index d5959eb..493209a 100644
> > --- a/ospfd/ospf_lsa.c
> > +++ b/ospfd/ospf_lsa.c
> > @@ -670,6 +670,7 @@ router_lsa_link_set (struct stream *s, struct ospf_area *area)
> >    {
> >      if (oi->state != ISM_Down)
> >        {
> > +         oi->lsa_pos_beg = links;
> >          /* Describe each link. */
> >          switch (oi->type)
> >       {
> > @@ -691,6 +692,7 @@ router_lsa_link_set (struct stream *s, struct ospf_area *area)
> >       case OSPF_IFTYPE_LOOPBACK:
> >         links += lsa_link_loopback_set (s, oi);
> >       }
> > +         oi->lsa_pos_end = links;
> >        }
> >    }
> >     }
>
> > diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
> > index d7f9ba2..e866d0c 100644
> > --- a/ospfd/ospf_spf.c
> > +++ b/ospfd/ospf_spf.c
> > @@ -477,13 +477,15 @@ ospf_spf_add_parent (struct vertex *v, struct vertex *w,
> > static unsigned int
> > ospf_nexthop_calculation (struct ospf_area *area, struct vertex *v,
> >                           struct vertex *w, struct router_lsa_link *l,
> > -                          unsigned int distance)
> > +                          unsigned int distance, int lsa_pos)
> > {
> >   struct listnode *node, *nnode;
> >   struct vertex_nexthop *nh;
> >   struct vertex_parent *vp;
> >   struct ospf_interface *oi = NULL;
> >   unsigned int added = 0;
> > +  char buf1[BUFSIZ];
> > +  char buf2[BUFSIZ];
> >
> >   if (IS_DEBUG_OSPF_EVENT)
> >     {
> > @@ -502,30 +504,38 @@ ospf_nexthop_calculation (struct ospf_area *area, struct vertex *v,
> >          the OSPF interface connecting to the destination network/router.
> >       */
> >
> > +      /* we *must* be supplied with the link data */
> > +      assert (l != NULL);
> > +      oi = ospf_if_lookup_by_lsa_pos (area, lsa_pos);
> > +      if (!oi)
> > +   {
> > +     zlog_debug("%s: OI not found in LSA: lsa_pos:%d link_id:%s link_data:%s",
> > +           __func__, lsa_pos,
> > +           inet_ntop (AF_INET, &l->link_id, buf1, BUFSIZ),
> > +           inet_ntop (AF_INET, &l->link_data, buf2, BUFSIZ));
> > +     return 0;
> > +   }
>
> I don't quite understand how this. How can the position of the link in the
> router-LSA in some far-off, off-link router have any correspondence with
> the ospf_interfaces of the local router?

It does not, but the trick here is that you only do the oi lookup for
you own router LSA:
if (v == area->spf)
    {
      /* 16.1.1 para 4.  In the first case, the parent vertex (V) is the
	 root (the calculating router itself).  This means that the
	 destination is either a directly connected network or directly
	 connected router.  The outgoing interface in this case is simply
         the OSPF interface connecting to the destination network/router.
      */

      /* we *must* be supplied with the link data */
      assert (l != NULL);
      oi = ospf_if_lookup_by_lsa_pos (area, lsa_pos);




More information about the Quagga-dev mailing list