]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Allow ip address selection for BGP unnumbered
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 7 Sep 2016 13:06:47 +0000 (09:06 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Dec 2016 01:26:08 +0000 (20:26 -0500)
When a interface is configured as BGP unnumbered, it
has a v6 LL address as well as no v4 addresses.  In
this case let's look at the lo's ip address as the
primary address to use.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
rebase

pimd/pim_iface.c
pimd/pim_zebra.c

index 43c5f4b1427d20635e4052c1665524d9dcd4c1a5..e55ef30b31babf61b180a7868e1cf7571210f738 100644 (file)
@@ -498,6 +498,8 @@ void pim_if_addr_add_all(struct interface *ifp)
   struct connected *ifc;
   struct listnode *node;
   struct listnode *nextnode;
+  int v4_addrs = 0;
+  int v6_addrs = 0;
 
   /* PIM/IGMP enabled ? */
   if (!ifp->info)
@@ -507,10 +509,35 @@ void pim_if_addr_add_all(struct interface *ifp)
     struct prefix *p = ifc->address;
     
     if (p->family != AF_INET)
-      continue;
+      {
+        v6_addrs++;
+        continue;
+      }
 
+    v4_addrs++;
     pim_if_addr_add(ifc);
   }
+
+  if (!v4_addrs && v6_addrs && !if_is_loopback (ifp))
+    {
+      struct pim_interface *pim_ifp = ifp->info;
+
+      if (pim_ifp && PIM_IF_TEST_PIM(pim_ifp->options)) {
+
+       /* Interface has a valid primary address ? */
+       if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {
+
+         /* Interface has a valid socket ? */
+         if (pim_ifp->pim_sock_fd < 0) {
+           if (pim_sock_add(ifp)) {
+             zlog_warn("Failure creating PIM socket for interface %s",
+                       ifp->name);
+           }
+         }
+
+       }
+      } /* pim */
+    }
 }
 
 void pim_if_addr_del_all(struct interface *ifp)
@@ -579,12 +606,17 @@ pim_find_primary_addr (struct interface *ifp)
   struct connected *ifc;
   struct listnode *node;
   struct in_addr addr;
+  int v4_addrs = 0;
+  int v6_addrs = 0;
 
   for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
     struct prefix *p = ifc->address;
-    
+
     if (p->family != AF_INET)
-      continue;
+      {
+       v6_addrs++;
+       continue;
+      }
 
     if (PIM_INADDR_IS_ANY(p->u.prefix4)) {
       zlog_warn("%s: null IPv4 address connected to interface %s",
@@ -592,12 +624,28 @@ pim_find_primary_addr (struct interface *ifp)
       continue;
     }
 
+    v4_addrs++;
+
     if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
       continue;
 
     return p->u.prefix4;
   }
 
+  /*
+   * If we have no v4_addrs and v6 is configured
+   * We probably are using unnumbered
+   * So let's grab the loopbacks v4 address
+   * and use that as the primary address
+   */
+  if (!v4_addrs && v6_addrs && !if_is_loopback (ifp))
+    {
+      struct interface *lo_ifp;
+      lo_ifp = if_lookup_by_name_vrf ("lo", VRF_DEFAULT);
+      if (lo_ifp)
+       return pim_find_primary_addr (lo_ifp);
+    }
+
   addr.s_addr = PIM_NET_INADDR_ANY;
 
   return addr;
index 68df086a1bde901104dee592c7439e4402ee4ed7..f2789369bff0414bb2dfce31529eac7da3ead844 100644 (file)
@@ -236,9 +236,7 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
     return 0;
 
   p = c->address;
-  if (p->family != AF_INET)
-    return 0;
-  
+
   if (PIM_DEBUG_ZEBRA) {
     char buf[BUFSIZ];
     prefix2str(p, buf, BUFSIZ);
@@ -252,6 +250,27 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
 #endif
   }
 
+  if (p->family != AF_INET)
+    {
+      struct pim_interface *pim_ifp = c->ifp->info;
+      struct listnode *cnode;
+      struct connected *conn;
+      int v4addrs = 0;
+
+      for (ALL_LIST_ELEMENTS_RO (c->ifp->connected, cnode, conn))
+        {
+          if (conn->address->family == AF_INET)
+           v4addrs++;
+        }
+      if (!v4addrs && pim_ifp) 
+       {
+
+         pim_ifp->primary_address = pim_find_primary_addr (c->ifp);
+         pim_if_addr_add_all (c->ifp);
+       }
+      return 0;
+    }
+
   pim_rp_check_rp (old, p->u.prefix4);
 
   if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
@@ -278,6 +297,18 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
 
   pim_if_addr_add(c);
 
+  if (if_is_loopback (c->ifp))
+    {
+      struct listnode *ifnode;
+      struct interface *ifp;
+
+      for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
+        {
+         if (!if_is_loopback (ifp) && if_is_operative (ifp))
+           pim_if_addr_add_all (ifp);
+        }
+    }
+
   return 0;
 }