]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: fix pimd crashes around pim rpf
authorChirag Shah <chirag@cumulusnetworks.com>
Tue, 25 Apr 2017 05:32:23 +0000 (22:32 -0700)
committerChirag Shah <chirag@cumulusnetworks.com>
Tue, 25 Apr 2017 19:52:04 +0000 (12:52 -0700)
During neighbor down event, all upstream entries rpf lookup may result
into nhop address with 0.0.0.0 and rpf interface info being NULL.
Put preventin check where rpf interface info is accessed.

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
pimd/pim_join.c
pimd/pim_jp_agg.c
pimd/pim_neighbor.c
pimd/pim_nht.c
pimd/pim_rp.c
pimd/pim_rpf.c
pimd/pim_upstream.c

index dc3a3cff8a88a1b135e74b153d2a3258f56a8875..a9ca349102297bd2e7859e7bb00284a861c02b05 100644 (file)
@@ -387,7 +387,13 @@ int pim_joinprune_send(struct pim_rpf *rpf,
 
   on_trace (__PRETTY_FUNCTION__, rpf->source_nexthop.interface, rpf->rpf_addr.u.prefix4);
 
-  pim_ifp = rpf->source_nexthop.interface->info;
+  if (rpf->source_nexthop.interface)
+    pim_ifp = rpf->source_nexthop.interface->info;
+  else
+    {
+      zlog_warn ("%s: RPF interface is not present", __PRETTY_FUNCTION__);
+      return -1;
+    }
 
   if (!pim_ifp) {
     zlog_warn("%s: multicast not enabled on interface %s",
index 251e67a35195e3d33b6b9a1d2fc697c9d64b6d7a..ce4ddfd4a4a20baa4ba904982ad1fac49bd40ab8 100644 (file)
@@ -343,8 +343,9 @@ pim_jp_agg_single_upstream_send (struct pim_rpf *rpf,
   static bool first = true;
 
   /* skip JP upstream messages if source is directly connected */
-  if (pim_if_connected_to_source (rpf->source_nexthop.interface, up->sg.src))
-      return;
+  if (!rpf->source_nexthop.interface ||
+      pim_if_connected_to_source (rpf->source_nexthop.interface, up->sg.src))
+    return;
 
   if (first)
     {
index 71d7ac414800d40d76ac7132a6d07301083f9135..181a71210c676f2de6281cf9d29ff7983f1a5ff2 100644 (file)
@@ -430,6 +430,9 @@ struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
   struct listnode      *node;
   struct pim_neighbor  *neigh;
 
+  if (!ifp)
+    return NULL;
+
   pim_ifp = ifp->info;
   if (!pim_ifp)
     return NULL;
index de3ea2daadf19ad4ce48329e7ba23ffa90bbd152..98c98cdf24da1eb391d6d42f62e839da6a268a0a 100644 (file)
@@ -665,7 +665,10 @@ pim_ecmp_nexthop_search (struct pim_nexthop_cache *pnc,
 
     }
 
-  return 0;
+  if (found)
+    return 0;
+  else
+    return -1;
 }
 
 /* This API is used to parse Registered address nexthop update coming from Zebra */
index ec31069eb5aad118eb5e3e47d88d01f65c45ba4a..776687d011f808a29f19496e31cfd39925373dc0 100644 (file)
@@ -281,7 +281,7 @@ pim_rp_check_interfaces (struct rp_info *rp_info)
 int
 pim_rp_new (const char *rp, const char *group_range, const char *plist)
 {
-  int result, ret = 0;
+  int result;
   struct rp_info *rp_info;
   struct rp_info *rp_all;
   struct prefix group_all;
@@ -400,12 +400,12 @@ pim_rp_new (const char *rp, const char *group_range, const char *plist)
                           __PRETTY_FUNCTION__, buf, buf1);
             }
           memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
-          if ((ret =
-               pim_find_or_track_nexthop (&nht_p, NULL, rp_all, &pnc)) == 1)
+          if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_all, &pnc)) == 1)
             {
               //Compute PIM RPF using Cached nexthop
-              pim_ecmp_nexthop_search (&pnc, &rp_all->rp.source_nexthop,
-                                       &nht_p, &rp_all->group, 1);
+              if ((pim_ecmp_nexthop_search (&pnc, &rp_all->rp.source_nexthop,
+                                       &nht_p, &rp_all->group, 1)) != 0)
+                return PIM_RP_NO_PATH;
             }
           else
             {
@@ -471,11 +471,12 @@ pim_rp_new (const char *rp, const char *group_range, const char *plist)
     }
 
   memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
-  if ((ret = pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1)
+  if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1)
     {
       //Compute PIM RPF using Cached nexthop
-      pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,
-                               &nht_p, &rp_info->group, 1);
+      if (pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,
+                               &nht_p, &rp_info->group, 1) != 0)
+        return PIM_RP_NO_PATH;
     }
   else
     {
@@ -575,8 +576,9 @@ pim_rp_setup (void)
       if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1)
         {
           //Compute PIM RPF using Cached nexthop
-          pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,
-                                   &nht_p, &rp_info->group, 1);
+          if ((pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,
+                                   &nht_p, &rp_info->group, 1)) != 0)
+            ret++;
         }
       else
         {
@@ -727,7 +729,6 @@ pim_rp_g (struct in_addr group)
 
   if (rp_info)
     {
-      int ret = 0;
       struct prefix nht_p;
       struct pim_nexthop_cache pnc;
       /* Register addr with Zebra NHT */
@@ -744,7 +745,7 @@ pim_rp_g (struct in_addr group)
                       __PRETTY_FUNCTION__, buf, buf1);
         }
       memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
-      if ((ret = pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1)
+      if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1)
         {
           //Compute PIM RPF using Cached nexthop
           pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,
index 0f5fab0d93596fa81721638322e02ba5aa14578e..f454ac59c1ac476b55f5c1c201923b5894d56131 100644 (file)
@@ -225,11 +225,14 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
       if (pnc.nexthop_num)
         {
           //Compute PIM RPF using Cached nexthop
-          pim_ecmp_nexthop_search (&pnc, &up->rpf.source_nexthop,
-                                   &src, &grp,
-                                   !PIM_UPSTREAM_FLAG_TEST_FHR (up->flags) &&
-                                   !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->
-                                                                     flags));
+          if (pim_ecmp_nexthop_search (&pnc, &up->rpf.source_nexthop,
+                                       &src, &grp,
+                                       !PIM_UPSTREAM_FLAG_TEST_FHR (up->flags) &&
+                                       !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags)))
+
+            {
+              return PIM_RPF_FAILURE;
+            }
         }
     }
   else
index 71634ebfe546211bef2dc6ccd1d3e1b28b8bf6a7..1c92a87a161238f6e74544b92cebbb280ad03df2 100644 (file)
@@ -481,7 +481,15 @@ static void forward_off(struct pim_upstream *up)
 static int
 pim_upstream_could_register (struct pim_upstream *up)
 {
-  struct pim_interface *pim_ifp = up->rpf.source_nexthop.interface->info;
+  struct pim_interface *pim_ifp = NULL;
+
+  if (up->rpf.source_nexthop.interface)
+    pim_ifp = up->rpf.source_nexthop.interface->info;
+  else
+    {
+      if (PIM_DEBUG_TRACE)
+        zlog_debug ("%s: up %s RPF is not present", __PRETTY_FUNCTION__, up->sg_str);
+    }
 
   if (pim_ifp && PIM_I_am_DR (pim_ifp) &&
       pim_if_connected_to_source (up->rpf.source_nexthop.interface, up->sg.src))
@@ -1439,13 +1447,19 @@ 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 pim_interface *pim_ifp = NULL;
   struct listnode *chnextnode;
   struct pim_ifchannel *ch;
   struct listnode *chnode;
   int output_intf = 0;
 
-  pim_ifp = up->rpf.source_nexthop.interface->info;
+  if (up->rpf.source_nexthop.interface)
+    pim_ifp = up->rpf.source_nexthop.interface->info;
+  else
+    {
+      if (PIM_DEBUG_TRACE)
+        zlog_debug ("%s: up %s RPF is not present", __PRETTY_FUNCTION__, up->sg_str);
+    }
   if (pim_ifp && !up->channel_oil)
     up->channel_oil = pim_channel_oil_add (&up->sg, pim_ifp->mroute_vif_index);