]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Limit search to relevant ifchannels in some cases
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 20 Apr 2017 13:03:47 +0000 (09:03 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 20 Apr 2017 19:59:01 +0000 (15:59 -0400)
When we are determining an inherited_olist, let's be allot
smarter about what we look at.  Before this code change
we are looping over the entirety of all ifchannels in
the system to find the relevant ones.  Convert the
code to *find*(hash table lookup) the specific ifchannels we
are interested in.

Ticket: CM-15629
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_ifchannel.c
pimd/pim_upstream.c
pimd/pim_upstream.h

index b19118f3ac18c10c205abe8cdcc00433ac22deb8..5afb8e7737acad6093ce81d7bd9aedc64bea9902 100644 (file)
@@ -959,7 +959,7 @@ int
 pim_ifchannel_local_membership_add(struct interface *ifp,
                                   struct prefix_sg *sg)
 {
-  struct pim_ifchannel *ch;
+  struct pim_ifchannel *ch, *starch;
   struct pim_interface *pim_ifp;
 
   /* PIM enabled on interface? */
@@ -994,18 +994,21 @@ pim_ifchannel_local_membership_add(struct interface *ifp,
       struct pim_upstream *child;
       struct listnode *up_node;
 
+      starch = ch;
+
       for (ALL_LIST_ELEMENTS_RO (up->sources, up_node, child))
         {
-         if (PIM_DEBUG_EVENTS)
-           zlog_debug("%s %s: IGMP (S,G)=%s(%s) from %s",
-                      __FILE__, __PRETTY_FUNCTION__,
-                      child->sg_str, ifp->name, up->sg_str);
+          if (PIM_DEBUG_EVENTS)
+            zlog_debug("%s %s: IGMP (S,G)=%s(%s) from %s",
+                       __FILE__, __PRETTY_FUNCTION__,
+                       child->sg_str, ifp->name, up->sg_str);
 
-         if (pim_upstream_evaluate_join_desired_interface (child, ch))
-           {
-             pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
-             pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
-           }
+          ch = pim_ifchannel_find (ifp, &child->sg);
+          if (pim_upstream_evaluate_join_desired_interface (child, ch, starch))
+            {
+              pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
+              pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
+            }
         }
 
       if (pimg->spt.switchover == PIM_SPT_INFINITY)
@@ -1034,7 +1037,7 @@ pim_ifchannel_local_membership_add(struct interface *ifp,
 void pim_ifchannel_local_membership_del(struct interface *ifp,
                                        struct prefix_sg *sg)
 {
-  struct pim_ifchannel *ch;
+  struct pim_ifchannel *starch, *ch, *orig;
   struct pim_interface *pim_ifp;
 
   /* PIM enabled on interface? */
@@ -1044,7 +1047,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
   if (!PIM_IF_TEST_PIM(pim_ifp->options))
     return;
 
-  ch = pim_ifchannel_find(ifp, sg);
+  orig = ch = pim_ifchannel_find(ifp, sg);
   if (!ch)
     return;
 
@@ -1056,6 +1059,8 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
       struct pim_upstream *child;
       struct listnode *up_node, *up_nnode;
 
+      starch = ch;
+
       for (ALL_LIST_ELEMENTS (up->sources, up_node, up_nnode, child))
         {
          struct channel_oil *c_oil = child->channel_oil;
@@ -1067,7 +1072,8 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
                       __FILE__, __PRETTY_FUNCTION__,
                       up->sg_str, ifp->name, child->sg_str);
 
-         if (c_oil && !pim_upstream_evaluate_join_desired_interface (child, ch))
+          ch = pim_ifchannel_find (ifp, &child->sg);
+         if (c_oil && !pim_upstream_evaluate_join_desired_interface (child, ch, starch))
             pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
 
          /*
@@ -1082,7 +1088,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
             pim_upstream_del (child, __PRETTY_FUNCTION__);
         }
     }
-  delete_on_noinfo(ch);
+  delete_on_noinfo(orig);
 }
 
 void pim_ifchannel_update_could_assert(struct pim_ifchannel *ch)
index 167588daef61d21d5a41700e1a2dd9b175409408..b9db75f14847e3057a6466a6f0f4a935b3aba057 100644 (file)
@@ -794,38 +794,34 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
   return up;
 }
 
+/*
+ * Passed in up must be the upstream for ch.  starch is NULL if no
+ * information
+ */
 int
 pim_upstream_evaluate_join_desired_interface (struct pim_upstream *up,
-                                             struct pim_ifchannel *ch)
+                                              struct pim_ifchannel *ch,
+                                              struct pim_ifchannel *starch)
 {
-  struct pim_upstream *parent = up->parent;
-
-  if (ch->upstream == up)
+  if (ch)
     {
       if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
-       return 0;
+        return 0;
 
       if (!pim_macro_ch_lost_assert(ch) && pim_macro_chisin_joins_or_include(ch))
-       return 1;
+        return 1;
     }
 
   /*
    * joins (*,G)
    */
-  if (parent && ch->upstream == parent)
+  if (starch)
     {
-      struct listnode *ch_node;
-      struct pim_ifchannel *child;
-      for (ALL_LIST_ELEMENTS_RO (ch->sources, ch_node, child))
-        {
-          if (child->upstream == up)
-            {
-               if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
-                 return 0;
-             }
-        }
-      if (!pim_macro_ch_lost_assert (ch) && pim_macro_chisin_joins_or_include (ch))
-       return 1;
+      if (PIM_IF_FLAG_TEST_S_G_RPT (starch->upstream->flags))
+        return 0;
+
+      if (!pim_macro_ch_lost_assert (starch) && pim_macro_chisin_joins_or_include (starch))
+        return 1;
     }
 
   return 0;
@@ -856,20 +852,28 @@ pim_upstream_evaluate_join_desired_interface (struct pim_upstream *up,
  */
 int pim_upstream_evaluate_join_desired(struct pim_upstream *up)
 {
-  struct listnode      *chnode;
-  struct listnode      *chnextnode;
-  struct pim_interface *pim_ifp;
-  struct pim_ifchannel *ch;
+  struct interface     *ifp;
+  struct listnode      *node;
+  struct pim_ifchannel *ch, *starch;
+  struct pim_upstream  *starup = up->parent;
   int                  ret = 0;
 
-  /* scan per-interface (S,G) state */
-  for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch))
+  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
     {
-      pim_ifp = ch->interface->info;
-      if (!pim_ifp)
-       continue;
+      if (!ifp->info)
+        continue;
+
+      ch = pim_ifchannel_find (ifp, &up->sg);
+
+      if (starup)
+        starch = pim_ifchannel_find (ifp, &starup->sg);
+      else
+        starch = NULL;
 
-      ret += pim_upstream_evaluate_join_desired_interface (up, ch);
+      if (!ch && !starch)
+        continue;
+
+      ret += pim_upstream_evaluate_join_desired_interface (up, ch, starch);
     } /* scan iface channel list */
 
   return ret; /* false */
@@ -1433,31 +1437,42 @@ pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_regist
 int
 pim_upstream_inherited_olist_decide (struct pim_upstream *up)
 {
-  struct pim_interface *pim_ifp;
-  struct listnode *chnextnode;
-  struct pim_ifchannel *ch;
-  struct listnode *chnode;
+  struct interface *ifp;
+  struct pim_interface *pim_ifp = NULL;
+  struct pim_ifchannel *ch, *starch;
+  struct listnode *node;
+  struct pim_upstream *starup = up->parent;
   int output_intf = 0;
 
   pim_ifp = up->rpf.source_nexthop.interface->info;
   if (pim_ifp && !up->channel_oil)
     up->channel_oil = pim_channel_oil_add (&up->sg, pim_ifp->mroute_vif_index);
 
-  for (ALL_LIST_ELEMENTS (pim_ifchannel_list, chnode, chnextnode, ch))
+  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
     {
-      pim_ifp = ch->interface->info;
-      if (!pim_ifp)
-       continue;
+      if (!ifp->info)
+        continue;
 
-      if (pim_upstream_evaluate_join_desired_interface (up, ch))
-       {
+      ch = pim_ifchannel_find (ifp, &up->sg);
+
+      if (starup)
+        starch = pim_ifchannel_find (ifp, &starup->sg);
+      else
+        starch = NULL;
+
+      if (!ch && !starch)
+        continue;
+
+      if (pim_upstream_evaluate_join_desired_interface (up, ch, starch))
+        {
           int flag = PIM_OIF_FLAG_PROTO_PIM;
 
-          if (ch->sg.src.s_addr == INADDR_ANY && ch->upstream != up)
+          if (!ch)
             flag = PIM_OIF_FLAG_PROTO_STAR;
-          pim_channel_add_oif (up->channel_oil, ch->interface, flag);
-         output_intf++;
-       }
+
+          pim_channel_add_oif (up->channel_oil, ifp, flag);
+          output_intf++;
+        }
     }
 
   return output_intf;
index ec40f3c243fa9883befde50e779c114f24697d80..e74ee37a128939a0860383448e150f54f5272108 100644 (file)
@@ -149,7 +149,8 @@ struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name)
 
 int pim_upstream_evaluate_join_desired(struct pim_upstream *up);
 int pim_upstream_evaluate_join_desired_interface(struct pim_upstream *up,
-                                                 struct pim_ifchannel *ch);
+                                                 struct pim_ifchannel *ch,
+                                                 struct pim_ifchannel *starch);
 void pim_upstream_update_join_desired(struct pim_upstream *up);
 
 void pim_upstream_join_suppress(struct pim_upstream *up,