On Mon, Mar 13, 2017 at 06:03:56PM +0100, Rafael Zalamena wrote:
> On Fri, Mar 10, 2017 at 04:14:44PM +0100, Paul de Weerd wrote:
> > Hi Rafael, others,
> >
> > It looks like your commit to ip_mroute.[ch] from January 11th broke
> > multicast forwarding. I found another thread that may suffer from the
> > same problem: http://marc.info/?l=openbsd-bugs&m=148605155027668&w=2 -
> > I'm CC:'ing the OP from that thread here (hope you don't mind :).
> >
> > On Wed, Jan 11, 2017 at 06:17:35AM -0700, Rafael Zalamena wrote:
> > | CVSROOT: /cvs
> > | Module name: src
> > | Changes by: [email protected] 2017/01/11 06:17:35
> > |
> > | Modified files:
> > | sys/netinet : ip_mroute.c ip_mroute.h
> > |
> > | Log message:
> > | Remove mfc hash tables and use the OpenBSD routing table for multicast
> > | routes. Beside the code simplification and removal, we also get to see
> > | the multicast routes now in the route(8) utility.
> > |
> > | ok mpi@
>
> After exchanging a few e-mails with Paul we identified and fixed the
> problem reported.
>
> The problem was that the mfc_find() function was matching default route
> as a multicast route, so it was never notifying the multicast routing
> daemon that we had a new IGMP message. Without sending the IGMP messages
> to the userland, igmpproxy never had a chance to install the needed
> routes for the rest to work.
>
> The diff below makes mfc_find() route search more strict.
>
> ok?
Reads fine by me. OK claudio@
I think you can move the RTF_HOST check outside of the while loop since
rtable_iterate will only return routes with the same addr/mask and therfor
RTF_HOST flag. Minor optimization, probably not worth the effort though.
> Index: sys/netinet/ip_mroute.c
> ===================================================================
> RCS file: /home/obsdcvs/src/sys/netinet/ip_mroute.c,v
> retrieving revision 1.110
> diff -u -p -r1.110 ip_mroute.c
> --- sys/netinet/ip_mroute.c 9 Feb 2017 15:36:46 -0000 1.110
> +++ sys/netinet/ip_mroute.c 13 Mar 2017 11:25:13 -0000
> @@ -157,11 +157,14 @@ mfc_find(struct ifnet *ifp, struct in_ad
> if (rt == NULL)
> return (NULL);
>
> - /* Return first ocurrence if interface is not specified. */
> - if (ifp == NULL)
> - return (rt);
> -
> do {
> + /* Don't consider non multicast routes. */
> + if (ISSET(rt->rt_flags, RTF_HOST | RTF_MULTICAST) !=
> + (RTF_HOST | RTF_MULTICAST))
> + continue;
> + /* Return first occurrence if interface is not specified. */
> + if (ifp == NULL)
> + return (rt);
> if (rt->rt_ifidx == ifp->if_index)
> return (rt);
> } while ((rt = rtable_iterate(rt)) != NULL);
>
--
:wq Claudio