]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Rework approach for needing nbrs
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 15 Sep 2016 14:18:28 +0000 (14:18 +0000)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Dec 2016 01:26:09 +0000 (20:26 -0500)
Pim sometimes needs the upstream rpf lookup to
only take into account if we have a nbr out
the selected interface or not.  Move
the code for this to a better spot so
we can make a more intelligent decision
here.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_cmd.c
pimd/pim_mroute.c
pimd/pim_register.c
pimd/pim_rp.c
pimd/pim_rpf.c
pimd/pim_rpf.h
pimd/pim_zlookup.c

index a3ff7c25edf202e9db5970505c7482efd451c6da..76d42f3614fb9925913cc9d00878803214a794e3 100644 (file)
@@ -2713,7 +2713,7 @@ DEFUN (show_ip_rib,
     return CMD_WARNING;
   }
 
-  if (pim_nexthop_lookup(&nexthop, addr)) {
+  if (pim_nexthop_lookup(&nexthop, addr, 0)) {
     vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
            addr_str, VTY_NEWLINE);
     return CMD_WARNING;
index 1f64a6e299bebd440b50d2948997077efa853a23..dd3ae3117d1154f60411ad9899e44cb3e7c1ac17 100644 (file)
@@ -345,7 +345,7 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
          pim_ifp = rpf->source_nexthop.interface->info;
 
          //No if channel, but upstream we are at the RP.
-         pim_nexthop_lookup (&source, up->upstream_register);
+         pim_nexthop_lookup (&source, up->upstream_register, 1);
          pim_register_stop_send(source.interface, &sg, pim_ifp->primary_address, up->upstream_register);
           if (!up->channel_oil)
             up->channel_oil = pim_channel_oil_add (&sg, pim_ifp->mroute_vif_index);
index ebc46f60ea866d2ec441b5c332b7f768095fcefe..f8144557c809feb40b2fa90817669b193a49f676 100644 (file)
@@ -162,9 +162,16 @@ pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct
     }
 
   ifp = rpg->source_nexthop.interface;
+  if (!ifp)
+    {
+      if (PIM_DEBUG_PIM_REG)
+        zlog_debug ("%s: No interface to transmit register on", __PRETTY_FUNCTION__);
+      return;
+    }
   pinfo = (struct pim_interface *)ifp->info;
   if (!pinfo) {
-    zlog_debug("%s: No pinfo!\n", __PRETTY_FUNCTION__);
+    if (PIM_DEBUG_PIM_REG)
+      zlog_debug("%s: Interface: %s not configured for pim to trasmit on!\n", __PRETTY_FUNCTION__, ifp->name);
     return;
   }
 
@@ -327,13 +334,13 @@ pim_register_recv (struct interface *ifp,
        upstream = pim_upstream_add (&sg, ifp);
         if (!upstream)
           {
-            zlog_warn ("Failure to crate upstream state");
+            zlog_warn ("Failure to create upstream state");
             return 1;
           }
         upstream->upstream_register = src_addr;
        pim_rp_set_upstream_addr (&upstream->upstream_addr, sg.src, sg.grp);
        pim_nexthop_lookup (&upstream->rpf.source_nexthop,
-                           upstream->upstream_addr);
+                           upstream->upstream_addr, 1);
        upstream->sg.src = sg.src;
        upstream->rpf.rpf_addr = upstream->rpf.source_nexthop.mrib_nexthop_addr;
 
index ae2ce6e4763a0ee2bfce971607756afbcf97d36f..b5c5ad55b9e02fafeb1c8c8cbe031bd56e83647d 100644 (file)
@@ -487,7 +487,7 @@ pim_rp_setup (void)
 
   for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
     {
-      if (pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4) != 0)
+      if (pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1) != 0)
         {
           zlog_err ("Unable to lookup nexthop for rp specified");
           ret++;
@@ -583,7 +583,7 @@ pim_rp_g (struct in_addr group)
 
   if (rp_info)
     {
-      pim_nexthop_lookup(&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4);
+      pim_nexthop_lookup(&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1);
       return (&rp_info->rp);
     }
 
index 2e93162694d1f5f15e91f683e6204b70eefb4cf0..44acde0c9ee539f9832ece1fcc2a6dc2f662bd73 100644 (file)
 
 static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up);
 
-int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr)
+int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed)
 {
   struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
   int num_ifindex;
   struct interface *ifp;
   int first_ifindex;
+  int found = 0;
+  int i = 0;
 
   memset (nexthop_tab, 0, sizeof (struct pim_zlookup_nexthop) * MULTIPATH_NUM);
-
   num_ifindex = zclient_lookup_nexthop(nexthop_tab,
                                       MULTIPATH_NUM,
                                       addr, PIM_NEXTHOP_LOOKUP_MAX);
@@ -58,56 +59,73 @@ int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr)
     return -1;
   }
 
-  first_ifindex = nexthop_tab[0].ifindex;
-
-  if (num_ifindex > 1 && PIM_DEBUG_ZEBRA) {
-    char addr_str[100];
-    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
-    zlog_debug("%s %s: Ignoring multiple nexthop ifindex'es num_ifindex=%d for address %s (using only ifindex=%d)",
-             __FILE__, __PRETTY_FUNCTION__,
-             num_ifindex, addr_str, first_ifindex);
-    /* debug warning only, do not return */
-  }
-
-  ifp = if_lookup_by_index(first_ifindex);
-  if (!ifp) {
-    char addr_str[100];
-    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
-    zlog_warn("%s %s: could not find interface for ifindex %d (address %s)",
-             __FILE__, __PRETTY_FUNCTION__,
-             first_ifindex, addr_str);
-    return -2;
-  }
-
-  if (!ifp->info) {
-    char addr_str[100];
-    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
-    zlog_warn("%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
-             __PRETTY_FUNCTION__,
-             ifp->name, first_ifindex, addr_str);
-    /* debug warning only, do not return */
-  }
-
-  if (PIM_DEBUG_ZEBRA) {
-    char nexthop_str[100];
-    char addr_str[100];
-    pim_addr_dump("<nexthop?>", &nexthop_tab[0].nexthop_addr, nexthop_str, sizeof(nexthop_str));
-    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
-    zlog_debug("%s %s: found nexthop %s for address %s: interface %s ifindex=%d metric=%d pref=%d",
-              __FILE__, __PRETTY_FUNCTION__,
-              nexthop_str, addr_str,
-              ifp->name, first_ifindex,
-              nexthop_tab[0].route_metric,
-              nexthop_tab[0].protocol_distance);
-  }
+  while (!found)
+    {
+      first_ifindex = nexthop_tab[i].ifindex;
+
+      ifp = if_lookup_by_index(first_ifindex);
+      if (!ifp)
+        {
+          if (PIM_DEBUG_ZEBRA)
+            {
+              char addr_str[100];
+              pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+              zlog_debug("%s %s: could not find interface for ifindex %d (address %s)",
+                         __FILE__, __PRETTY_FUNCTION__,
+                         first_ifindex, addr_str);
+            }
+          return -2;
+        }
+
+      if (!ifp->info && PIM_DEBUG_ZEBRA)
+        {
+          char addr_str[100];
+          pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+          zlog_debug("%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
+                    __PRETTY_FUNCTION__,
+                    ifp->name, first_ifindex, addr_str);
+        }
+
+      if (neighbor_needed)
+        {
+          struct pim_neighbor *nbr;
+
+          nbr = pim_neighbor_find (ifp, nexthop_tab[i].nexthop_addr.u.prefix4);
+          if (PIM_DEBUG_ZEBRA)
+            zlog_debug ("ifp name: %s, pim nbr: %p", ifp->name, nbr);
+          if (!nbr && !if_is_loopback (ifp))
+            i++;
+          else
+            found = 1;
+        }
+      else
+        found = 1;
+    }
 
-  /* update nextop data */
-  nexthop->interface                = ifp;
-  nexthop->mrib_nexthop_addr        = nexthop_tab[0].nexthop_addr;
-  nexthop->mrib_metric_preference   = nexthop_tab[0].protocol_distance;
-  nexthop->mrib_route_metric        = nexthop_tab[0].route_metric;
+  if (found)
+    {
+      if (PIM_DEBUG_ZEBRA) {
+        char nexthop_str[100];
+        char addr_str[100];
+        pim_addr_dump("<nexthop?>", &nexthop_tab[0].nexthop_addr, nexthop_str, sizeof(nexthop_str));
+        pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+        zlog_debug("%s %s: found nexthop %s for address %s: interface %s ifindex=%d metric=%d pref=%d",
+                  __FILE__, __PRETTY_FUNCTION__,
+                  nexthop_str, addr_str,
+                  ifp->name, first_ifindex,
+                  nexthop_tab[0].route_metric,
+                  nexthop_tab[0].protocol_distance);
+      }
+      /* update nextop data */
+      nexthop->interface                = ifp;
+      nexthop->mrib_nexthop_addr        = nexthop_tab[0].nexthop_addr;
+      nexthop->mrib_metric_preference   = nexthop_tab[0].protocol_distance;
+      nexthop->mrib_route_metric        = nexthop_tab[0].route_metric;
 
-  return 0;
+      return 0;
+    }
+  else
+    return -1;
 }
 
 static int nexthop_mismatch(const struct pim_nexthop *nh1,
@@ -128,7 +146,8 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct in_addr *old_
   save_nexthop  = rpf->source_nexthop; /* detect change in pim_nexthop */
   save_rpf_addr = rpf->rpf_addr;       /* detect change in RPF'(S,G) */
 
-  if (pim_nexthop_lookup(&rpf->source_nexthop, up->upstream_addr)) {
+  if (pim_nexthop_lookup(&rpf->source_nexthop,
+                         up->upstream_addr, !PIM_UPSTREAM_FLAG_TEST_FHR (up->flags))) {
     return PIM_RPF_FAILURE;
   }
 
index fddc74a725e6cc1d7c43645c425f7bcac1eacc5f..b93c934116c2c5e1400de7623e8cf4d20db7f1df 100644 (file)
@@ -59,7 +59,7 @@ enum pim_rpf_result {
 
 struct pim_upstream;
 
-int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr);
+int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed);
 enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct in_addr *old_rpf_addr);
 
 int pim_rpf_addr_is_inaddr_none (struct pim_rpf *rpf);
index 636552abd77297001c6ca9307b8db5022337ab48..bee9c63e963c2ff6d0fd82e8e43a8e6e56777f43 100644 (file)
@@ -332,7 +332,6 @@ zclient_lookup_nexthop (struct pim_zlookup_nexthop nexthop_tab[],
   int lookup;
   uint32_t route_metric = 0xFFFFFFFF;
   uint8_t  protocol_distance = 0xFF;
-  int i;
 
   qpim_nexthop_lookups++;
 
@@ -394,27 +393,6 @@ zclient_lookup_nexthop (struct pim_zlookup_nexthop nexthop_tab[],
        nexthop_tab[0].protocol_distance = protocol_distance;
       }
 
-      /*
-       * Let's see if any of the nexthops can actually be used.
-       * We need to check them against the neighbors that we
-       * have formed.  As that we shouldn't be sending
-       * j/p messages upstream towards non-neighbors
-       */
-      for (i = 0; i < num_ifindex ; i++)
-       {
-         struct interface *ifp;
-         struct pim_neighbor *nbr;
-
-         ifp = if_lookup_by_index_vrf (nexthop_tab[i].ifindex, VRF_DEFAULT);
-         nbr = pim_neighbor_find (ifp, nexthop_tab[i].nexthop_addr.u.prefix4);
-         if (ifp->info && !nbr && !if_is_loopback (ifp))
-           {
-             num_ifindex--;
-             if (i != num_ifindex)
-               memcpy (&nexthop_tab[i], &nexthop_tab[i+1], sizeof (nexthop_tab[i]));
-             i--;
-           }
-       }
       return num_ifindex;
     }