summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorbms <bms@FreeBSD.org>2009-11-15 11:07:22 +0000
committerbms <bms@FreeBSD.org>2009-11-15 11:07:22 +0000
commitd1297db1aeb036a628e2f6fc5bd24e6f91cdb7b0 (patch)
tree9e77f95991160d95cbdeea880b8b2975f6743384 /sys/netinet
parent98727c096ee4c1bf290d899539be2dab614f1c4a (diff)
downloadFreeBSD-src-d1297db1aeb036a628e2f6fc5bd24e6f91cdb7b0.zip
FreeBSD-src-d1297db1aeb036a628e2f6fc5bd24e6f91cdb7b0.tar.gz
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
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/raw_ip.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index d612c2c..f87cdd0 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -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 = 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);
+ }
- blocked = imo_multi_filter(inp->inp_moptions, ifp,
- (struct sockaddr *)&group,
- (struct sockaddr *)&ripsrc);
if (blocked != MCAST_PASS) {
IPSTAT_INC(ips_notmember);
continue;
OpenPOWER on IntegriCloud