pimd: fix pimd crashes around pim rpf

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>
This commit is contained in:
Chirag Shah 2017-04-24 22:32:23 -07:00
parent 1f58d560da
commit 1131c2eb3b
7 changed files with 55 additions and 24 deletions

View 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); 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) { if (!pim_ifp) {
zlog_warn("%s: multicast not enabled on interface %s", zlog_warn("%s: multicast not enabled on interface %s",

View File

@ -343,8 +343,9 @@ pim_jp_agg_single_upstream_send (struct pim_rpf *rpf,
static bool first = true; static bool first = true;
/* skip JP upstream messages if source is directly connected */ /* skip JP upstream messages if source is directly connected */
if (pim_if_connected_to_source (rpf->source_nexthop.interface, up->sg.src)) if (!rpf->source_nexthop.interface ||
return; pim_if_connected_to_source (rpf->source_nexthop.interface, up->sg.src))
return;
if (first) if (first)
{ {

View File

@ -430,6 +430,9 @@ struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
struct listnode *node; struct listnode *node;
struct pim_neighbor *neigh; struct pim_neighbor *neigh;
if (!ifp)
return NULL;
pim_ifp = ifp->info; pim_ifp = ifp->info;
if (!pim_ifp) if (!pim_ifp)
return NULL; return NULL;

View 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 */ /* This API is used to parse Registered address nexthop update coming from Zebra */

View File

@ -281,7 +281,7 @@ pim_rp_check_interfaces (struct rp_info *rp_info)
int int
pim_rp_new (const char *rp, const char *group_range, const char *plist) 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_info;
struct rp_info *rp_all; struct rp_info *rp_all;
struct prefix group_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); __PRETTY_FUNCTION__, buf, buf1);
} }
memset (&pnc, 0, sizeof (struct pim_nexthop_cache)); memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
if ((ret = if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_all, &pnc)) == 1)
pim_find_or_track_nexthop (&nht_p, NULL, rp_all, &pnc)) == 1)
{ {
//Compute PIM RPF using Cached nexthop //Compute PIM RPF using Cached nexthop
pim_ecmp_nexthop_search (&pnc, &rp_all->rp.source_nexthop, if ((pim_ecmp_nexthop_search (&pnc, &rp_all->rp.source_nexthop,
&nht_p, &rp_all->group, 1); &nht_p, &rp_all->group, 1)) != 0)
return PIM_RP_NO_PATH;
} }
else 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)); 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 //Compute PIM RPF using Cached nexthop
pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop, if (pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,
&nht_p, &rp_info->group, 1); &nht_p, &rp_info->group, 1) != 0)
return PIM_RP_NO_PATH;
} }
else else
{ {
@ -575,8 +576,9 @@ pim_rp_setup (void)
if ((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 //Compute PIM RPF using Cached nexthop
pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop, if ((pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,
&nht_p, &rp_info->group, 1); &nht_p, &rp_info->group, 1)) != 0)
ret++;
} }
else else
{ {
@ -727,7 +729,6 @@ pim_rp_g (struct in_addr group)
if (rp_info) if (rp_info)
{ {
int ret = 0;
struct prefix nht_p; struct prefix nht_p;
struct pim_nexthop_cache pnc; struct pim_nexthop_cache pnc;
/* Register addr with Zebra NHT */ /* Register addr with Zebra NHT */
@ -744,7 +745,7 @@ pim_rp_g (struct in_addr group)
__PRETTY_FUNCTION__, buf, buf1); __PRETTY_FUNCTION__, buf, buf1);
} }
memset (&pnc, 0, sizeof (struct pim_nexthop_cache)); 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 //Compute PIM RPF using Cached nexthop
pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop, pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,

View File

@ -225,11 +225,14 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
if (pnc.nexthop_num) if (pnc.nexthop_num)
{ {
//Compute PIM RPF using Cached nexthop //Compute PIM RPF using Cached nexthop
pim_ecmp_nexthop_search (&pnc, &up->rpf.source_nexthop, if (pim_ecmp_nexthop_search (&pnc, &up->rpf.source_nexthop,
&src, &grp, &src, &grp,
!PIM_UPSTREAM_FLAG_TEST_FHR (up->flags) && !PIM_UPSTREAM_FLAG_TEST_FHR (up->flags) &&
!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up-> !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags)))
flags));
{
return PIM_RPF_FAILURE;
}
} }
} }
else else

View File

@ -481,7 +481,15 @@ static void forward_off(struct pim_upstream *up)
static int static int
pim_upstream_could_register (struct pim_upstream *up) 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) && if (pim_ifp && PIM_I_am_DR (pim_ifp) &&
pim_if_connected_to_source (up->rpf.source_nexthop.interface, up->sg.src)) 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 int
pim_upstream_inherited_olist_decide (struct pim_upstream *up) pim_upstream_inherited_olist_decide (struct pim_upstream *up)
{ {
struct pim_interface *pim_ifp; struct pim_interface *pim_ifp = NULL;
struct listnode *chnextnode; struct listnode *chnextnode;
struct pim_ifchannel *ch; struct pim_ifchannel *ch;
struct listnode *chnode; struct listnode *chnode;
int output_intf = 0; 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) if (pim_ifp && !up->channel_oil)
up->channel_oil = pim_channel_oil_add (&up->sg, pim_ifp->mroute_vif_index); up->channel_oil = pim_channel_oil_add (&up->sg, pim_ifp->mroute_vif_index);