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);
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",

View 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)
{

View 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;

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 */

View 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,

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)
{
//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

View 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);