[quagga-dev 7153] [PATCH 1/2] ospfd: Update SPF calculation for unnumbered links

Joakim Tjernlund Joakim.Tjernlund at transmode.se
Thu Aug 13 17:39:42 BST 2009


Add support for real unnumbered PtP interfaces in
ospf_nexthop_calculation().
Add ospf_if_lookup_by_ifindex() to support Unnumbered
PtP links. This version does not support:
 - Multiple numbered PtP interfaces with the same IP address
   between the same two routers.
 - Unnumbered PtP on just one end of the link.

* ospfd/ospf_interface.c: Add ospf_if_lookup_by_ifindex().
* ospfd/ospf_interface.h: ditto.
* ospfd/ospf_spf.c: ospf_nexthop_calculation (), call
  		    ospf_if_lookup_by_ifindex() for Unnumbered
		    PtP links.
---
 ospfd/ospf_interface.c |   14 ++++++
 ospfd/ospf_interface.h |    3 +-
 ospfd/ospf_spf.c       |  108 +++++++++++++++++++++++++++++-------------------
 3 files changed, 81 insertions(+), 44 deletions(-)

diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index afe3acf..775b121 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -479,6 +479,20 @@ ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src,
 
   return match;
 }
+
+struct ospf_interface *
+ospf_if_lookup_by_ifindex(struct ospf_area *area, unsigned int ifindex)
+{
+  struct listnode *node;
+  struct ospf_interface *oi;
+
+  for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
+    {
+      if (oi->ifp->ifindex == ifindex)
+	return oi;
+    }
+  return NULL;
+}
 
 void
 ospf_if_stream_set (struct ospf_interface *oi)
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index ab0b758..9cda3d8 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -256,7 +256,8 @@ extern struct ospf_interface *ospf_if_lookup_recv_if (struct ospf *,
 						      struct interface *);
 extern struct ospf_interface *ospf_if_is_configured (struct ospf *,
 						     struct in_addr *);
-
+extern struct ospf_interface *ospf_if_lookup_by_ifindex(struct ospf_area *,
+							unsigned int);
 extern struct ospf_if_params *ospf_lookup_if_params (struct interface *,
 						     struct in_addr);
 extern struct ospf_if_params *ospf_get_if_params (struct interface *,
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index ca20022..f9ec11b 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -529,6 +529,10 @@ ospf_nexthop_calculation (struct ospf_area *area, struct vertex *v,
 
           if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT)
             {
+	      int nh_found = 0;
+	      struct in_addr nexthop;
+	      unsigned long ifindex;
+
               /* If the destination is a router which connects to
                  the calculating router via a Point-to-MultiPoint
                  network, the destination's next hop IP address(es)
@@ -548,53 +552,71 @@ ospf_nexthop_calculation (struct ospf_area *area, struct vertex *v,
                  is a constituent of the PtMP link, and its address is 
                  a nexthop address for V.
               */
-              oi = ospf_if_is_configured (area->ospf, &l->link_data);
-              if (oi && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
-                {
-                  struct prefix_ipv4 la;
-
-                  la.family = AF_INET;
-                  la.prefixlen = oi->address->prefixlen;
-
-                  /* V links to W on PtMP interface
-                     - find the interface address on W */
-                  while ((l2 = ospf_get_next_link (w, v, l2)))
-                    {
-                      la.prefix = l2->link_data;
-
-                      if (prefix_cmp ((struct prefix *) &la,
-                                      oi->address) == 0)
-                        /* link_data is on our PtMP network */
-                        break;
-                    }
-                } /* end l is on point-to-multipoint link */
-              else
-                {
-                  /* l is a regular point-to-point link.
-                     Look for a link from W to V.
-                   */
-                  while ((l2 = ospf_get_next_link (w, v, l2)))
-                    {
-                      oi = ospf_if_is_configured (area->ospf,
-                                                  &(l2->link_data));
-
-                      if (oi == NULL)
-                        continue;
-
-                      if (!IPV4_ADDR_SAME (&oi->address->u.prefix4,
-                                           &l->link_data))
-                        continue;
-
-                      break;
-                    }
-                }
-
-              if (oi && l2)
+	      ifindex = ntohl(l->link_data.s_addr);
+	      if (ifindex <= 0x00ffffff) /* unnumbered ? */
+		{
+		  oi = ospf_if_lookup_by_ifindex(area, ifindex);
+		  if (oi && oi->type == OSPF_IFTYPE_POINTOPOINT)
+		    nh_found = 1;
+		  nexthop.s_addr = 0;
+		}
+	      else
+		{
+		  oi = ospf_if_is_configured (area->ospf, &l->link_data);
+		  if (oi && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
+		    {
+		      struct prefix_ipv4 la;
+
+		      la.family = AF_INET;
+		      la.prefixlen = oi->address->prefixlen;
+
+		      /* V links to W on PtMP interface
+			 - find the interface address on W */
+		      while ((l2 = ospf_get_next_link (w, v, l2)))
+			{
+			  la.prefix = l2->link_data;
+
+			  if (prefix_cmp ((struct prefix *) &la,
+					  oi->address) != 0)
+			    continue;
+			  /* link_data is on our PtMP network */
+			  nh_found = 1;
+			  nexthop = l2->link_data;
+			  break;
+			}
+		    } /* end l is on point-to-multipoint link */
+		  else
+		    {
+		      /* l is a regular point-to-point link.
+			 Look for a link from W to V.
+		      */
+		      while ((l2 = ospf_get_next_link (w, v, l2)))
+			{
+			  if (ntohl(l2->link_data.s_addr) <= 0x00ffffff)
+			    continue; /* skip unnumbered links */
+
+			  oi = ospf_if_is_configured (area->ospf,
+						      &l2->link_data);
+
+			  if (oi == NULL)
+			    continue;
+
+			  if (!IPV4_ADDR_SAME (&oi->address->u.prefix4,
+					       &l->link_data))
+			    continue;
+			  nexthop.s_addr = 0; /* zero better for equal-cost ? */
+			  nh_found = 1;
+			  break;
+			}
+		    }
+		}
+
+              if (nh_found)
                 {
                   /* found all necessary info to build nexthop */
                   nh = vertex_nexthop_new ();
                   nh->oi = oi;
-                  nh->router = l2->link_data;
+                  nh->router = nexthop;
                   ospf_spf_add_parent (v, w, nh, distance);
                   return 1;
                 }
-- 
1.6.4




More information about the Quagga-dev mailing list