From: James Li <[email protected]>

Allow ospf to use unnumbered links by utilizing the loopback interface IP
address.

Example Config:

interface lo:1
  address 10.2.1.3/32

int swp1
  ip ospf network point-to-point

int swp2
  ip ospf network point-to-point

router ospf
  ospf router-id 10.2.1.3
  network 10.2.1.3/32 area 0.0.0.0

Signed-off-by: James Li <[email protected]>
Signed-off-by: Dinesh Dutt <[email protected]>
Reviewed-by: JR Rivers <[email protected]>
Signed-off-by: Donald Sharp <[email protected]>
---
 ospfd/ospf_interface.c | 13 +++++++++---
 ospfd/ospf_lsa.c       | 39 ++++++++++++++++++++++++-----------
 ospfd/ospf_route.c     |  2 +-
 ospfd/ospf_vty.c       | 55 ++++++++++++++++++++++++++++----------------------
 ospfd/ospf_zebra.c     | 25 +++++++++++++++++++++--
 5 files changed, 92 insertions(+), 42 deletions(-)

diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index f41c4f1..85494f4 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -351,7 +351,12 @@ ospf_if_is_configured (struct ospf *ospf, struct in_addr 
*address)
   for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
     if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
       {
-        if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+        if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
+          {
+            if (htonl(oi->ifp->ifindex) == address->s_addr)
+              return oi;
+          }
+        else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
          {
            /* special leniency: match if addr is anywhere on peer subnet */
            if (prefix_match(CONNECTED_PREFIX(oi->connected),
@@ -475,8 +480,10 @@ ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr 
src,
       if (if_is_loopback (oi->ifp))
         continue;
 
-      if (prefix_match (CONNECTED_PREFIX(oi->connected),
-                       (struct prefix *) &addr))
+      if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
+        match = oi;
+      else if (prefix_match (CONNECTED_PREFIX(oi->connected),
+                             (struct prefix *) &addr))
        {
          if ( (match == NULL) || 
               (match->address->prefixlen < oi->address->prefixlen)
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 05587e8..8d18120 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -543,7 +543,7 @@ lsa_link_ptop_set (struct stream *s, struct ospf_interface 
*oi)
 {
   int links = 0;
   struct ospf_neighbor *nbr;
-  struct in_addr id, mask;
+  struct in_addr id, mask, data;
   u_int16_t cost = ospf_link_cost (oi);
 
   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
@@ -552,19 +552,34 @@ lsa_link_ptop_set (struct stream *s, struct 
ospf_interface *oi)
   if ((nbr = ospf_nbr_lookup_ptop (oi)))
     if (nbr->state == NSM_Full)
       {
-       /* For unnumbered point-to-point networks, the Link Data field
-          should specify the interface's MIB-II ifIndex value. */
-       links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
-                               LSA_LINK_TYPE_POINTOPOINT, 0, cost);
+        if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
+          {
+            /* For unnumbered point-to-point networks, the Link Data field
+               should specify the interface's MIB-II ifIndex value. */
+            data.s_addr = htonl(oi->ifp->ifindex);
+            links += link_info_set (s, nbr->router_id, data,
+                                    LSA_LINK_TYPE_POINTOPOINT, 0, cost);
+          }
+        else
+          {
+            links += link_info_set (s, nbr->router_id,
+                                    oi->address->u.prefix4,
+                                    LSA_LINK_TYPE_POINTOPOINT, 0, cost);
+          }
       }
 
-  /* Regardless of the state of the neighboring router, we must
-     add a Type 3 link (stub network).
-     N.B. Options 1 & 2 share basically the same logic. */
-  masklen2ip (oi->address->prefixlen, &mask);
-  id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
-  links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
-                         oi->output_cost);
+  /* no need for a stub link for unnumbered interfaces */
+  if (!CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
+    {
+      /* Regardless of the state of the neighboring router, we must
+         add a Type 3 link (stub network).
+         N.B. Options 1 & 2 share basically the same logic. */
+      masklen2ip (oi->address->prefixlen, &mask);
+      id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & 
mask.s_addr;
+      links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
+                              oi->output_cost);
+    }
+
   return links;
 }
 
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index eb7829a..51e6eba 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -783,7 +783,7 @@ ospf_route_copy_nexthops_from_vertex (struct ospf_route *to,
              path = ospf_path_new ();
              path->nexthop = nexthop->router;
              path->ifindex = nexthop->oi->ifp->ifindex;
-             listnode_add (to->paths, path);
+             listnode_add (to->paths, path);
            }
        }
     }
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index d9038c8..7f8ff0e 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -3011,30 +3011,37 @@ show_ip_ospf_interface_sub (struct vty *vty, struct 
ospf *ospf,
       if (oi == NULL)
        continue;
       
-      /* Show OSPF interface information. */
-      vty_out (vty, "  Internet Address %s/%d,",
-              inet_ntoa (oi->address->u.prefix4), oi->address->prefixlen);
-
-      if (oi->connected->destination || oi->type == OSPF_IFTYPE_VIRTUALLINK)
+      if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
         {
-          struct in_addr *dest;
-          const char *dstr;
-          
-         if (CONNECTED_PEER(oi->connected)
-             || oi->type == OSPF_IFTYPE_VIRTUALLINK)
-            dstr = "Peer";
-          else
-            dstr = "Broadcast";
-          
-          /* For Vlinks, showing the peer address is probably more
-           * informative than the local interface that is being used
-           */
-          if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
-            dest = &oi->vl_data->peer_addr;
-          else
-            dest = &oi->connected->destination->u.prefix4;
-          
-         vty_out (vty, " %s %s,", dstr, inet_ntoa (*dest));
+          vty_out (vty, "  This interface is UNNUMBERED,");
+        }
+      else
+        {
+          /* Show OSPF interface information. */
+          vty_out (vty, "  Internet Address %s/%d,",
+                   inet_ntoa (oi->address->u.prefix4), oi->address->prefixlen);
+
+          if (oi->connected->destination || oi->type == 
OSPF_IFTYPE_VIRTUALLINK)
+            {
+              struct in_addr *dest;
+              const char *dstr;
+
+              if (CONNECTED_PEER(oi->connected)
+                  || oi->type == OSPF_IFTYPE_VIRTUALLINK)
+                dstr = "Peer";
+              else
+                dstr = "Broadcast";
+
+              /* For Vlinks, showing the peer address is probably more
+               * informative than the local interface that is being used
+               */
+              if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+                dest = &oi->vl_data->peer_addr;
+              else
+                dest = &oi->connected->destination->u.prefix4;
+
+              vty_out (vty, " %s %s,", dstr, inet_ntoa (*dest));
+            }
         }
 
       vty_out (vty, " Area %s%s", ospf_area_desc_string (oi->area),
@@ -3086,7 +3093,7 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf 
*ospf,
                       inet_ntoa (nbr->address.u.prefix4), VTY_NEWLINE);
            }
        }
-      
+
       /* Next network-LSA sequence number we'll use, if we're elected DR */
       if (oi->params && ntohl (oi->params->network_lsa_seqnum)
                           != OSPF_INITIAL_SEQUENCE_NUMBER)
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 83a0ba2..790a4c1 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -379,6 +379,26 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route 
*or)
       /* Nexthop, ifindex, distance and metric information. */
       for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
         {
+         if ((path->nexthop.s_addr != INADDR_ANY &&
+              path->ifindex != 0))
+           {
+             stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX);
+             stream_put_in_addr (s, &path->nexthop);
+             stream_putl (s, path->ifindex);
+           }
+         else if (path->nexthop.s_addr != INADDR_ANY)
+           {
+             stream_putc (s, ZEBRA_NEXTHOP_IPV4);
+             stream_put_in_addr (s, &path->nexthop);
+           }
+         else
+           {
+             stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
+             if (path->ifindex)
+               stream_putl (s, path->ifindex);
+             else
+               stream_putl (s, 0);
+           }
           if (path->nexthop.s_addr != INADDR_ANY &&
              path->ifindex != 0)
             {
@@ -403,12 +423,13 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route 
*or)
           if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
             {
              char buf[2][INET_ADDRSTRLEN];
-             zlog_debug("Zebra: Route add %s/%d nexthop %s",
+             zlog_debug("Zebra: Route add %s/%d nexthop %s, ifindex=%d",
                         inet_ntop(AF_INET, &p->prefix,
                                   buf[0], sizeof(buf[0])),
                         p->prefixlen,
                         inet_ntop(AF_INET, &path->nexthop,
-                                  buf[1], sizeof(buf[1])));
+                                  buf[1], sizeof(buf[1])),
+                        path->ifindex);
             }
         }
 
-- 
1.9.1


_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to