]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Fix WG/SGRpt & WG J/P processing
authorChirag Shah <chirag@cumulusnetworks.com>
Fri, 21 Apr 2017 22:08:03 +0000 (15:08 -0700)
committerChirag Shah <chirag@cumulusnetworks.com>
Tue, 25 Apr 2017 19:51:58 +0000 (12:51 -0700)
During processing of Join/Prune,
for a S,G entry, current state is SGRpt, when only *,G is
received, need to clear SGRpt and add/inherit the *,G OIF to S,G so
it can forward traffic to downstream where *,G is received.
Upon receiving SGRpt prune remove the inherited *,G OIF.

Testing Done:
Trigger SPT switchover, *,G path received SGRpt later data
traffic stopped S,G ages out from LHR, sends only
*,G join to upstream, verified S,G entry inherit the OIF.
Upon receiving SGRpt deletes inherited oif and retains in SGRpt state.

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
pimd/pim_ifchannel.c
pimd/pim_ifchannel.h
pimd/pim_join.c

index ebd36f8782509c45fa47abaa3e4ab54156dd9afd..4f5054307a02fa25b72750b7936d76c725b913c4 100644 (file)
@@ -1223,20 +1223,55 @@ pim_ifchannel_scan_forward_start (struct interface *new_ifp)
  * we get End of Message
  */
 void
-pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom)
+pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t source_flags, uint8_t join)
 {
   struct pim_ifchannel *child;
   struct listnode *ch_node;
 
   if (PIM_DEBUG_PIM_TRACE)
-    zlog_debug ("%s: %s %s eom: %d", __PRETTY_FUNCTION__,
+    zlog_debug ("%s: %s %s eom: %d join %u", __PRETTY_FUNCTION__,
                 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
-                ch->sg_str, eom);
+                ch->sg_str, eom, join);
   if (!ch->sources)
     return;
 
   for (ALL_LIST_ELEMENTS_RO (ch->sources, ch_node, child))
     {
+      /* Only *,G Join received and no (SG-RPT) prune.
+         Scan all S,G associated to G and if any SG-RPT
+         remove the SG-RPT flag.
+      */
+      if (join && (source_flags & PIM_RPT_BIT_MASK) &&
+          (source_flags & PIM_WILDCARD_BIT_MASK))
+        {
+          if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
+            {
+              struct pim_upstream *up = child->upstream;
+
+              PIM_IF_FLAG_UNSET_S_G_RPT(child->flags);
+              if (up)
+                {
+                  if (PIM_DEBUG_TRACE)
+                    zlog_debug ("%s: add inherit oif to up %s ", __PRETTY_FUNCTION__, up->sg_str);
+                  pim_channel_add_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
+                }
+            }
+        }
+      /* Received SG-RPT Prune delete oif from S,G */
+      else if (join == 0 && (source_flags & PIM_RPT_BIT_MASK) &&
+               !(source_flags & PIM_WILDCARD_BIT_MASK))
+        {
+          struct pim_upstream *up = child->upstream;
+
+          PIM_IF_FLAG_SET_S_G_RPT(child->flags);
+          if (up)
+            {
+              if (PIM_DEBUG_TRACE)
+                zlog_debug ("%s: del inherit oif from up %s", __PRETTY_FUNCTION__, up->sg_str);
+              pim_channel_del_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
+            }
+        }
+
       if (!PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
         continue;
 
index fe9fb9a7f10d6a086cb9544ccb6e475c9fafa862..3ffb9190fb336eb50dbf20af9a11e9b76a6aa33f 100644 (file)
@@ -151,7 +151,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);
+void pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t source_flags, uint8_t join);
 
 int pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2);
 
index 884aa35bc563d3d6b21e1154f71e81a38597dd3f..dc3a3cff8a88a1b135e74b153d2a3258f56a8875 100644 (file)
@@ -276,7 +276,7 @@ int pim_joinprune_recv(struct interface *ifp,
         {
           ch = pim_ifchannel_find (ifp, &sg);
          if (ch)
-           pim_ifchannel_set_star_g_join_state (ch, 0);
+           pim_ifchannel_set_star_g_join_state (ch, 0, msg_source_flags, 1);
         }
     }
 
@@ -297,7 +297,7 @@ int pim_joinprune_recv(struct interface *ifp,
                 msg_source_flags);
     }
     if (ch)
-      pim_ifchannel_set_star_g_join_state (ch, 1);
+      pim_ifchannel_set_star_g_join_state (ch, 1, msg_source_flags, 0);
     ch = NULL;
   } /* scan groups */