Everton -

I was able to create an assert crash with my original proposed scenario.
No route to Source when receiving a igmp join for that Source.  My proposed
fix solved the problem with pim asserting:

2015/06/12 23:23:44.266191 PIM: nonlocal_upstream: recv join
(S,G)=(1.1.1.3,232.0.0.2) to local upstream=169.254.0.9 on swp3

2015/06/12 23:23:44.267673 PIM: zclient_read_nexthop: socket 10 bad
nexthop_num=0

2015/06/12 23:23:44.267946 PIM: pim_zlookup.c zclient_lookup_nexthop:
lookup=0/3: could not find nexthop ifindex for address 1.1.1.3

2015/06/12 23:23:44.269864 PIM: pim_rpf.c pim_nexthop_lookup: could not
find nexthop ifindex for address 1.1.1.3

2015/06/12 23:23:44.270161 PIM: pim_ifchannel_new: could not attach
upstream (S,G)=(1.1.1.3,232.0.0.2) on interface swp3

2015/06/12 23:23:44.270336 PIM: pim_ifchannel_add: pim_ifchannel_new()
failure for (S,G)=(1.1.1.3,232.0.0.2) on interface swp3

I'll be sending a patch for the problem here shortly.

I also agree with your assertion that there might be problems with the code
when we loose a route to the Source after we have already originally
established the multicast route.  I'll get it recreated in house and then I
can get started with your code sample.

donald



On Fri, Jun 12, 2015 at 6:25 PM, Everton Marques <[email protected]>
wrote:

> Donald,
>
> I propose a different fix, sketched below, yet untested.
> The reason is RPF information is refreshed upon unicast routing changes.
> Then when pimd fails to solve the RPF, it could yet set the interface to
> NULL.
> Though this does not happen on current code, it might be changed.
>
> Cheers,
> Everton
>
>
> diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
> index e253a0e..b1bea87 100644
> --- a/pimd/pim_ifchannel.c
> +++ b/pimd/pim_ifchannel.c
> @@ -392,6 +392,7 @@ static void prune_echo(struct interface *ifp,
>    struct pim_interface *pim_ifp;
>    struct in_addr neigh_dst_addr;
>
> +  zassert(ifp);
>    pim_ifp = ifp->info;
>    zassert(pim_ifp);
>
> @@ -431,6 +432,7 @@ static int on_ifjoin_prune_pending_timer(struct thread
> *t)
>
>    /* Send PruneEcho(S,G) ? */
>    ifp = ch->interface;
> +  zassert(ifp);
>    pim_ifp = ifp->info;
>    send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
>
> diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
> index d02f915..97a0ba1 100644
> --- a/pimd/pim_upstream.c
> +++ b/pimd/pim_upstream.c
> @@ -96,6 +96,21 @@ static void send_join(struct pim_upstream *up)
>        /* warning only */
>      }
>    }
> +
> +  if (!up->rpf.source_nexthop.interface) {
> +    if (PIM_DEBUG_PIM_TRACE) {
> +      char src_str[100];
> +      char grp_str[100];
> +      pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
> +      pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
> +      zlog_warn("%s: can't send join upstream: missing RPF_interface(S)
> for (S=G)=(%s,%s)",
> +               __PRETTY_FUNCTION__, src_str, grp_str);
> +    }
> +
> +    return;
> +  }
> +
> +  zassert(up->rpf.source_nexthop.interface);
>
>    /* send Join(S,G) to the current upstream neighbor */
>    pim_joinprune_send(up->rpf.source_nexthop.interface,
> @@ -334,6 +349,20 @@ static void pim_upstream_switch(struct pim_upstream
> *up,
>    }
>    else {
>      forward_off(up);
> +
> +    if (!up->rpf.source_nexthop.interface) {
> +      if (PIM_DEBUG_PIM_TRACE) {
> +       char src_str[100];
> +       char grp_str[100];
> +       pim_inet4_dump("<src?>", up->source_addr, src_str,
> sizeof(src_str));
> +       pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
> +       zlog_warn("%s: can't send prune upstream: missing RPF_interface(S)
> for (S=G)=(%s,%s)",
> +                 __PRETTY_FUNCTION__, src_str, grp_str);
> +      }
> +      return;
> +    }
> +    zassert(up->rpf.source_nexthop.interface);
> +
>      pim_joinprune_send(up->rpf.source_nexthop.interface,
>                        up->rpf.rpf_addr,
>                        up->source_addr,
> diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
> index dfc871b..822abdf 100644
> --- a/pimd/pim_zebra.c
> +++ b/pimd/pim_zebra.c
> @@ -354,6 +354,8 @@ static void scan_upstream_rpf_cache()
>      if (rpf_result == PIM_RPF_FAILURE)
>        continue;
>
> +    zassert(up->rpf.source_nexthop.interface);
> +
>      if (rpf_result == PIM_RPF_CHANGED) {
>
>        if (up->join_state == PIM_UPSTREAM_JOINED) {
>
>
_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to