]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Add code to handle pim prune(S,G) with sptbit
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 10 Nov 2016 15:25:36 +0000 (10:25 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Dec 2016 01:26:14 +0000 (20:26 -0500)
Add some more code to handle the prune(S,G) with the
sptbit set.  Turns this ifchannel into a (S,G,rpt).

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

index b3b2748359f2e551bd2d050fc475e6afecfc40aa..0da3abe99e3840592722d356d09766ee8468424e 100644 (file)
@@ -493,8 +493,6 @@ static int on_ifjoin_expiry_timer(struct thread *t)
 
   ch->t_ifjoin_expiry_timer = NULL;
 
-  zassert(ch->ifjoin_state == PIM_IFJOIN_JOIN);
-
   ifjoin_to_noinfo(ch);
   /* ch may have been deleted */
 
@@ -753,6 +751,7 @@ void pim_ifchannel_prune(struct interface *ifp,
                         uint16_t holdtime)
 {
   struct pim_ifchannel *ch;
+  struct pim_interface *pim_ifp;
   int jp_override_interval_msec;
 
   if (nonlocal_upstream(0 /* prune */, ifp, upstream,
@@ -773,49 +772,82 @@ void pim_ifchannel_prune(struct interface *ifp,
   if (!ch)
     return;
 
+  pim_ifp = ifp->info;
+
   switch (ch->ifjoin_state) {
   case PIM_IFJOIN_NOINFO:
+    if (source_flags & PIM_ENCODE_RPT_BIT)
+      {
+       PIM_IF_FLAG_SET_S_G_RPT(ch->flags);
+       ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
+        if (listcount(pim_ifp->pim_neighbor_list) > 1)
+          jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
+        else
+          jp_override_interval_msec = 0; /* schedule to expire immediately */
+          /* If we called ifjoin_prune() directly instead, care should
+             be taken not to use "ch" afterwards since it would be
+             deleted. */
+
+       THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+       THREAD_OFF(ch->t_ifjoin_expiry_timer);
+       THREAD_TIMER_MSEC_ON(master, ch->t_ifjoin_prune_pending_timer,
+                            on_ifjoin_prune_pending_timer,
+                            ch, jp_override_interval_msec);
+       THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
+                       on_ifjoin_expiry_timer,
+                       ch, holdtime);
+      }
+    break;
   case PIM_IFJOIN_PRUNE_PENDING:
     /* nothing to do */
     break;
   case PIM_IFJOIN_JOIN:
-    {
-      struct pim_interface *pim_ifp;
-
-      pim_ifp = ifp->info;
+    THREAD_OFF(ch->t_ifjoin_expiry_timer);
 
-      zassert(ch->t_ifjoin_expiry_timer);
-      zassert(!ch->t_ifjoin_prune_pending_timer);
+    pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_PRUNE_PENDING);
 
-      THREAD_OFF(ch->t_ifjoin_expiry_timer);
-      
-      pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_PRUNE_PENDING);
-      
-      if (listcount(pim_ifp->pim_neighbor_list) > 1) {
-       jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
-      }
-      else {
-       jp_override_interval_msec = 0; /* schedule to expire immediately */
-       /* If we called ifjoin_prune() directly instead, care should
-          be taken not to use "ch" afterwards since it would be
-          deleted. */
-      }
-      
-      THREAD_TIMER_MSEC_ON(master, ch->t_ifjoin_prune_pending_timer,
-                          on_ifjoin_prune_pending_timer,
-                          ch, jp_override_interval_msec);
-      
-      zassert(!ch->t_ifjoin_expiry_timer);
-      zassert(ch->t_ifjoin_prune_pending_timer);
-    }
+    if (listcount(pim_ifp->pim_neighbor_list) > 1)
+      jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
+    else
+      jp_override_interval_msec = 0; /* schedule to expire immediately */
+      /* If we called ifjoin_prune() directly instead, care should
+        be taken not to use "ch" afterwards since it would be
+        deleted. */
+    THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+    THREAD_TIMER_MSEC_ON(master, ch->t_ifjoin_prune_pending_timer,
+                        on_ifjoin_prune_pending_timer,
+                        ch, jp_override_interval_msec);
     break;
   case PIM_IFJOIN_PRUNE:
+    if (source_flags & PIM_ENCODE_RPT_BIT)
+      {
+       THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+       THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
+                       on_ifjoin_expiry_timer,
+                       ch, holdtime);
+      }
+    break;
   case PIM_IFJOIN_PRUNE_TMP:
+    if (source_flags & PIM_ENCODE_RPT_BIT)
+      {
+       ch->ifjoin_state = PIM_IFJOIN_PRUNE;
+       THREAD_OFF(ch->t_ifjoin_expiry_timer);
+       THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
+                       on_ifjoin_expiry_timer,
+                       ch, holdtime);
+      }
+    break;
   case PIM_IFJOIN_PRUNE_PENDING_TMP:
-    zlog_debug ("CASE NOT HANDLED");
+    if (source_flags & PIM_ENCODE_RPT_BIT)
+      {
+       ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
+       THREAD_OFF(ch->t_ifjoin_expiry_timer);
+       THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
+                       on_ifjoin_expiry_timer,
+                       ch, holdtime);
+      }
     break;
   }
-
 }
 
 void pim_ifchannel_local_membership_add(struct interface *ifp,
@@ -1097,24 +1129,23 @@ pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom)
         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;
-
-      }
+       {
+       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 7f5c46004a5696c470d06434fca84be25f7b1d22..42d4a518744a26cfb57f0ad8ad0a85dab94bbeaa 100644 (file)
@@ -127,7 +127,6 @@ static void recv_join(struct interface *ifp,
            }
         }
     }
-
 }
 
 static void recv_prune(struct interface *ifp,
@@ -352,8 +351,8 @@ int pim_joinprune_recv(struct interface *ifp,
       if (sg.src.s_addr == INADDR_ANY)
         {
           ch = pim_ifchannel_find (ifp, &sg);
-         if (ch)
-           pim_ifchannel_set_star_g_join_state (ch, 0);
+         if (ch)
+           pim_ifchannel_set_star_g_join_state (ch, 0);
         }
     }