diff options
author | Chirag Shah <chirag@cumulusnetworks.com> | 2017-04-25 07:32:23 +0200 |
---|---|---|
committer | Chirag Shah <chirag@cumulusnetworks.com> | 2017-04-25 21:52:04 +0200 |
commit | 1131c2eb3b04fad3b86a5df8d551419d928dc669 (patch) | |
tree | c67cd999718e99b26f39a6d9ecef5bbd76675777 /pimd | |
parent | pimd: Fix WG/SGRpt & WG J/P processing (diff) | |
download | frr-1131c2eb3b04fad3b86a5df8d551419d928dc669.tar.xz frr-1131c2eb3b04fad3b86a5df8d551419d928dc669.zip |
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>
Diffstat (limited to 'pimd')
-rw-r--r-- | pimd/pim_join.c | 8 | ||||
-rw-r--r-- | pimd/pim_jp_agg.c | 5 | ||||
-rw-r--r-- | pimd/pim_neighbor.c | 3 | ||||
-rw-r--r-- | pimd/pim_nht.c | 5 | ||||
-rw-r--r-- | pimd/pim_rp.c | 25 | ||||
-rw-r--r-- | pimd/pim_rpf.c | 13 | ||||
-rw-r--r-- | pimd/pim_upstream.c | 20 |
7 files changed, 55 insertions, 24 deletions
diff --git a/pimd/pim_join.c b/pimd/pim_join.c index dc3a3cff8..a9ca34910 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -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", diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c index 251e67a35..ce4ddfd4a 100644 --- a/pimd/pim_jp_agg.c +++ b/pimd/pim_jp_agg.c @@ -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) { diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index 71d7ac414..181a71210 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -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; diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index de3ea2daa..98c98cdf2 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -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 */ diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index ec31069eb..776687d01 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -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, diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index 0f5fab0d9..f454ac59c 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -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 diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 71634ebfe..1c92a87a1 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -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); |