Author: bms
Date: Sun Nov 15 11:07:22 2009
New Revision: 199287
URL: http://svn.freebsd.org/changeset/base/199287

Log:
  Fix a functional regression in multicast.
  
  Userland daemons need to see IGMP traffic regardless of the group;
  omit the imo filter check if the proto is IGMP. The kernel part
  of IGMP will have already filtered appropriately at this point.
  
  MFC after:      ASAP
  Submitted by:   Franz Struwig
  Reported by:    Ivor Prebeg, Franz Struwig

Modified:
  head/sys/netinet/raw_ip.c

Modified: head/sys/netinet/raw_ip.c
==============================================================================
--- head/sys/netinet/raw_ip.c   Sun Nov 15 07:28:37 2009        (r199286)
+++ head/sys/netinet/raw_ip.c   Sun Nov 15 11:07:22 2009        (r199287)
@@ -343,17 +343,35 @@ rip_input(struct mbuf *m, int off)
                 */
                if (inp->inp_moptions != NULL &&
                    IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
-                       struct sockaddr_in group;
+                       /*
+                        * If the incoming datagram is for IGMP, allow it
+                        * through unconditionally to the raw socket.
+                        *
+                        * In the case of IGMPv2, we may not have explicitly
+                        * joined the group, and may have set IFF_ALLMULTI
+                        * on the interface. imo_multi_filter() may discard
+                        * control traffic we actually need to see.
+                        *
+                        * Userland multicast routing daemons should continue
+                        * filter the control traffic appropriately.
+                        */
                        int blocked;
 
-                       bzero(&group, sizeof(struct sockaddr_in));
-                       group.sin_len = sizeof(struct sockaddr_in);
-                       group.sin_family = AF_INET;
-                       group.sin_addr = ip->ip_dst;
-
-                       blocked = imo_multi_filter(inp->inp_moptions, ifp,
-                           (struct sockaddr *)&group,
-                           (struct sockaddr *)&ripsrc);
+                       blocked = MCAST_PASS;
+                       if (proto != IPPROTO_IGMP) {
+                               struct sockaddr_in group;
+
+                               bzero(&group, sizeof(struct sockaddr_in));
+                               group.sin_len = sizeof(struct sockaddr_in);
+                               group.sin_family = AF_INET;
+                               group.sin_addr = ip->ip_dst;
+
+                               blocked = imo_multi_filter(inp->inp_moptions,
+                                   ifp,
+                                   (struct sockaddr *)&group,
+                                   (struct sockaddr *)&ripsrc);
+                       }
+
                        if (blocked != MCAST_PASS) {
                                IPSTAT_INC(ips_notmember);
                                continue;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to