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