]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Add Handler for Receive (*,G) join for (S,G,rpt)
authorDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 8 Nov 2016 20:26:48 +0000 (15:26 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Dec 2016 01:26:14 +0000 (20:26 -0500)
According to Figure 5( Downstream per-interface (S,G,rpt)
state when we receive a (*,G) we need to move (S,G,rpt)
children of the (*,G) into different states.  This
implements that.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_ifchannel.c
pimd/pim_ifchannel.h
pimd/pim_join.c

index 5838bfa63edf57e1081727ee6915d01158981821..3be88553d0e91a2814e3d51e739791e2a1813a0e 100644 (file)
@@ -725,19 +725,21 @@ void pim_ifchannel_join_add(struct interface *ifp,
     THREAD_OFF(ch->t_ifjoin_expiry_timer);
     break;
   case PIM_IFJOIN_PRUNE:
-    zlog_debug ("PIM_IFJOIN_PRUNE: NOT PROGRAMMED YET");
+    if (source_flags & PIM_ENCODE_RPT_BIT)
+      pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
     break;
   case PIM_IFJOIN_PRUNE_PENDING:
-    zassert(!ch->t_ifjoin_expiry_timer);
-    zassert(ch->t_ifjoin_prune_pending_timer);
-    THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
-    pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
+    if (source_flags & PIM_ENCODE_RPT_BIT)
+      pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
+    else
+      {
+        THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+        pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
+      }
     break;
   case PIM_IFJOIN_PRUNE_TMP:
-    zlog_debug ("PIM_IFJOIN_PRUNE_TMP: Not Programmed yet");
     break;
   case PIM_IFJOIN_PRUNE_PENDING_TMP:
-    zlog_debug ("PIM_IFJOIN_PRUNE_PENDING_TMP: Not Programmed yet");
     break;
   }
 
@@ -1072,3 +1074,51 @@ pim_ifchannel_scan_forward_start (struct interface *new_ifp)
         }
     }
 }
+
+/*
+ * Downstream per-interface (S,G,rpt) state machine
+ * states that we need to move (S,G,rpt) items
+ * into different states at the start of the
+ * reception of a *,G join as well, when
+ * we get End of Message
+ */
+void
+pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom)
+{
+  struct pim_ifchannel *child;
+  struct listnode *ch_node;
+
+  if (PIM_DEBUG_PIM_TRACE)
+    zlog_debug ("%s: %s %s eom: %d", __PRETTY_FUNCTION__,
+                pim_ifchannel_ifjoin_name(ch->ifjoin_state),
+                pim_str_sg_dump(&ch->sg), eom);
+  if (!ch->sources)
+    return;
+
+  for (ALL_LIST_ELEMENTS_RO (ch->sources, ch_node, child))
+    {
+      if (!PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
+        continue;
+
+      switch (child->ifjoin_state)
+      {
+      case PIM_IFJOIN_NOINFO:
+      case PIM_IFJOIN_JOIN:
+        break;
+      case PIM_IFJOIN_PRUNE:
+        if (!eom)
+          child->ifjoin_state = PIM_IFJOIN_PRUNE_TMP;
+        break;
+      case PIM_IFJOIN_PRUNE_PENDING:
+        if (!eom)
+          child->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING_TMP;
+        break;
+      case PIM_IFJOIN_PRUNE_TMP:
+      case PIM_IFJOIN_PRUNE_PENDING_TMP:
+        if (eom)
+          child->ifjoin_state = PIM_IFJOIN_NOINFO;
+        break;
+
+      }
+    }
+}
index 908d27fd68e8be106ea0c92c1f813a6500825bd9..b640cfd4df41b3809a562144f9fb6d08823c00da 100644 (file)
@@ -150,6 +150,7 @@ void pim_ifchannel_update_my_assert_metric(struct pim_ifchannel *ch);
 void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch);
 
 void pim_ifchannel_scan_forward_start (struct interface *new_ifp);
+void pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom);
 
 int pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2);
 #endif /* PIM_IFCHANNEL_H */
index 53c91ab4afbdc50245d107892e5ab41b800ef2cb..7f5c46004a5696c470d06434fca84be25f7b1d22 100644 (file)
@@ -292,6 +292,7 @@ int pim_joinprune_recv(struct interface *ifp,
     uint16_t      msg_num_joined_sources;
     uint16_t      msg_num_pruned_sources;
     int           source;
+    struct        pim_ifchannel *ch = NULL;
 
     memset (&sg, 0, sizeof (struct prefix_sg));
     addr_offset = pim_parse_addr_group (&sg,
@@ -347,6 +348,13 @@ int pim_joinprune_recv(struct interface *ifp,
                msg_upstream_addr.u.prefix4,
                &sg,
                msg_source_flags);
+
+      if (sg.src.s_addr == INADDR_ANY)
+        {
+          ch = pim_ifchannel_find (ifp, &sg);
+         if (ch)
+           pim_ifchannel_set_star_g_join_state (ch, 0);
+        }
     }
 
     /* Scan pruned sources */
@@ -365,7 +373,9 @@ int pim_joinprune_recv(struct interface *ifp,
                 &sg,
                 msg_source_flags);
     }
-
+    if (ch)
+      pim_ifchannel_set_star_g_join_state (ch, 1);
+    ch = NULL;
   } /* scan groups */
 
   return 0;