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?

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

Reply via email to