]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Fix WG/SGRpt & WG J/P processing 475/head
authorChirag Shah <chirag@cumulusnetworks.com>
Fri, 21 Apr 2017 22:08:03 +0000 (15:08 -0700)
committerChirag Shah <chirag@cumulusnetworks.com>
Sun, 7 May 2017 00:38:18 +0000 (17:38 -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.

From, downstream router received *,G Prune along with SGRpt
prune. Avoid sending *,G and SGRpt Prune together.
Reset upstream_del reset ifchannel to NULL.

Testing Done:
Run failed smoke test of sending data packets, 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_join.c
pimd/pim_jp_agg.c
pimd/pim_msg.c
pimd/pim_rp.c
pimd/pim_rpf.c
pimd/pim_upstream.c

index f3c3e282c60c289c7b70c5330daa193decca5b5c..f4fe609605bcd2dbedfe2baf0e1ab2bc7804054d 100644 (file)
@@ -145,6 +145,9 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
       if (ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
         mask = PIM_OIF_FLAG_PROTO_IGMP;
 
+      /* SGRpt entry could have empty oil */
+      if (ch->upstream->channel_oil)
+        pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask);
       pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask);
       /*
        * Do we have any S,G's that are inheriting?
@@ -610,6 +613,7 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
       pim_ifp = ifp->info;
       send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
 
+      //ch->ifjoin_state transition to NOINFO
       ifjoin_to_noinfo(ch);
       /* from here ch may have been deleted */
 
@@ -1093,8 +1097,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
          if (!chchannel && c_oil && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
             pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
 
-          if (c_oil->oil_size == 0)
-            pim_upstream_del (child, __PRETTY_FUNCTION__);
+          /* Child node removal/ref count-- will happen as part of parent' delete_no_info */
         }
     }
   delete_on_noinfo(orig);
@@ -1288,7 +1291,7 @@ pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t
               if (up)
                 {
                   if (PIM_DEBUG_TRACE)
-                    zlog_debug ("%s: add inherit oif to up %s ", __PRETTY_FUNCTION__, up->sg_str);
+                    zlog_debug ("%s: clearing SGRpt flag, 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);
                 }
             }
index a9ca349102297bd2e7859e7bb00284a861c02b05..828781a4670b511376491009154f30db7b00680d 100644 (file)
@@ -374,7 +374,7 @@ int pim_joinprune_send(struct pim_rpf *rpf,
                        struct list *groups)
 {
   struct pim_jp_agg_group *group;
-  struct pim_interface *pim_ifp;
+  struct pim_interface *pim_ifp = NULL;
   struct pim_jp_groups *grp = NULL;
   struct pim_jp *msg;
   struct listnode *node, *nnode;
@@ -395,12 +395,13 @@ int pim_joinprune_send(struct pim_rpf *rpf,
       return -1;
     }
 
-  if (!pim_ifp) {
-    zlog_warn("%s: multicast not enabled on interface %s",
+  if (!pim_ifp)
+    {
+      zlog_warn ("%s: multicast not enabled on interface %s",
               __PRETTY_FUNCTION__,
               rpf->source_nexthop.interface->name);
-    return -1;
-  }
+      return -1;
+    }
 
   if (PIM_INADDR_IS_ANY(rpf->rpf_addr.u.prefix4))
     {
index bbc51bd91c7fad8027638abc3a6bc9e5989332cb..46c6cbc6905ab4e966bb72b9e660b7a94b1ac8e4 100644 (file)
@@ -348,7 +348,7 @@ pim_jp_agg_single_upstream_send (struct pim_rpf *rpf,
   static bool first = true;
 
   /* skip JP upstream messages if source is directly connected */
-  if (!rpf->source_nexthop.interface ||
+  if (!up || !rpf->source_nexthop.interface ||
       pim_if_connected_to_source (rpf->source_nexthop.interface, up->sg.src))
     return;
 
index e19893f5dab4253f7de1970b64b4b77bbb270b98..a9e0130905859acbeae47fd4efe370acc42c4e06 100644 (file)
@@ -195,7 +195,9 @@ pim_msg_build_jp_groups (struct pim_jp_groups *grp, struct pim_jp_agg_group *sgs
           struct pim_rpf *rpf = pim_rp_g (source->up->sg.grp);
           bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT | PIM_ENCODE_RPT_BIT;
           stosend = rpf->rpf_addr.u.prefix4;
-          up = source->up;
+          /* Only Send SGRpt in case of *,G Join */
+          if (source->is_join)
+            up = source->up;
         }
       else
         {
index 062ae6e808eae6603b9cf28c6ee7c2a85000e8c8..6c4504d9b0be236b2a3ed2cbbf0da8eb4e6e35a0 100644 (file)
@@ -741,7 +741,7 @@ pim_rp_g (struct in_addr group)
           char buf1[PREFIX2STR_BUFFER];
           prefix2str (&nht_p, buf, sizeof (buf));
           prefix2str (&rp_info->group, buf1, sizeof (buf1));
-          zlog_debug ("%s: NHT Register RP addr %s grp %s with Zebra ",
+          zlog_debug ("%s: NHT Register RP addr %s grp %s with Zebra",
                       __PRETTY_FUNCTION__, buf, buf1);
         }
       memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
@@ -759,7 +759,7 @@ pim_rp_g (struct in_addr group)
               char buf1[PREFIX2STR_BUFFER];
               prefix2str (&nht_p, buf, sizeof (buf));
               prefix2str (&g, buf1, sizeof (buf1));
-              zlog_debug ("%s: Nexthop cache not found for RP %s grp %s register with Zebra NHT",
+              zlog_debug ("%s: Nexthop cache not found for RP %s grp %s register with Zebra",
                           __PRETTY_FUNCTION__, buf, buf1);
             }
           pim_rpf_set_refresh_time ();
index f454ac59c1ac476b55f5c1c201923b5894d56131..f46ebfb979b4712360c78f2a85abc80d6c00e40e 100644 (file)
@@ -240,8 +240,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
       if (pim_ecmp_nexthop_lookup (&rpf->source_nexthop,
                                    up->upstream_addr, &src, &grp,
                                    !PIM_UPSTREAM_FLAG_TEST_FHR (up->flags) &&
-                                   !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->
-                                                                     flags)))
+                                   !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags)))
         {
           return PIM_RPF_FAILURE;
         }
index 2afcd6aeea210236a30b219a5cdc826e5f9bb92e..dd6eab9cfe8766bce4ce75d7ae4b8ae203d760f4 100644 (file)
@@ -216,6 +216,7 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
   up->sources = NULL;
 
   list_delete (up->ifchannels);
+  up->ifchannels = NULL;
 
   /*
     notice that listnode_delete() can't be moved
@@ -243,7 +244,7 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
     {
       char buf[PREFIX2STR_BUFFER];
       prefix2str (&nht_p, buf, sizeof (buf));
-      zlog_debug ("%s: Deregister upstream %s addr %s with Zebra",
+      zlog_debug ("%s: Deregister upstream %s addr %s with Zebra NHT",
                   __PRETTY_FUNCTION__, up->sg_str, buf);
     }
   pim_delete_tracked_nexthop (&nht_p, up, NULL);
@@ -1017,14 +1018,17 @@ static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up)
   struct pim_ifchannel *ch;
 
   /* scan per-interface (S,G) state */
-  for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
-    pim_ifp = ch->interface->info;
-    if (!pim_ifp)
-      continue;
+  for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch))
+    {
+      if (!ch->interface)
+        continue;
+      pim_ifp = ch->interface->info;
+      if (!pim_ifp)
+        continue;
 
-    pim_ifchannel_update_assert_tracking_desired(ch);
+      pim_ifchannel_update_assert_tracking_desired(ch);
 
-  } /* scan iface channel list */
+    } /* scan iface channel list */
 }
 
 /* When kat is stopped CouldRegister goes to false so we need to