* [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group
@ 2006-09-13 14:13 Jeff Layton
2006-09-13 14:32 ` David Stevens
0 siblings, 1 reply; 10+ messages in thread
From: Jeff Layton @ 2006-09-13 14:13 UTC (permalink / raw)
To: netdev; +Cc: linux-kernel
The situation is this:
Two programs have opened IPv4 UDP sockets, set SO_REUSEADDR on them, and
are bound to INADDR_ANY on the same port. One program joins a multicast
group address, the other program joins a different one. When a multicast
packet is sent to this port on one of the group addresses to which these
sockets are bound, both sockets get delivered a copy of the packet. Only
the socket that is bound to the group address to which the packet was
sent should get it.
The issue seems to be that there is no actual check to see if the socket
is joined to the multicast group. This patch adds such a check, and
corrected the problem on my test rig.
I looked briefly at the ipv6 equivalent code, and it appears to already
handle this correctly with a check near the top of inet6_mc_check(). I
have not actually verified this, however.
This patch should apply cleanly to Linus' git tree as of last night.
Signed-off-by: Jeff Layton <jlayton@poochiereds.net>
--- linux-2.6/net/ipv4/udp.c.mcast-filter
+++ linux-2.6/net/ipv4/udp.c
@@ -286,6 +286,8 @@ static inline struct sock *udp_v4_mcast_
struct hlist_node *node;
struct sock *s = sk;
unsigned short hnum = ntohs(loc_port);
+ struct ip_mc_socklist *mc_list;
+ int matched;
sk_for_each_from(s, node) {
struct inet_sock *inet = inet_sk(s);
@@ -299,6 +301,23 @@ static inline struct sock *udp_v4_mcast_
continue;
if (!ip_mc_sf_allow(s, loc_addr, rmt_addr, dif))
continue;
+
+ /* only deliver multicast packets to sockets that are
+ * explicitly joined to the multicast group */
+ if (MULTICAST(loc_addr)) {
+ matched = 0;
+ for (mc_list=inet->mc_list ; mc_list;
+ mc_list=mc_list->next) {
+ if (mc_list->multi.imr_multiaddr.s_addr ==
+ loc_addr) {
+ matched = 1;
+ break;
+ }
+ }
+ if (!matched)
+ continue;
+ }
+
goto found;
}
s = NULL;
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group
2006-09-13 14:13 [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group Jeff Layton
@ 2006-09-13 14:32 ` David Stevens
2006-09-13 16:12 ` Jeff Layton
2006-09-13 20:20 ` Alexey Kuznetsov
0 siblings, 2 replies; 10+ messages in thread
From: David Stevens @ 2006-09-13 14:32 UTC (permalink / raw)
To: Jeff Layton; +Cc: linux-kernel, netdev, netdev-owner
netdev-owner@vger.kernel.org wrote on 09/13/2006 07:13:55 AM:
> Only
> the socket that is bound to the group address to which the packet was
> sent should get it.
This is not true on any OS I'm aware of, including the
original sockets multicast implementation on early BSD.
Multicast group membership is per-interface, not per-socket.
Joining a group on any socket on the machine allows packets for that
group to be delivered on the interface where it was joined.
Delivery of packets to a socket is determined by the binding, and
INADDR_ANY means "any".
IPv6 behaves the same way.
+-DLS
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group
2006-09-13 14:32 ` David Stevens
@ 2006-09-13 16:12 ` Jeff Layton
2006-09-13 16:42 ` David Stevens
2006-09-14 1:09 ` David Miller
2006-09-13 20:20 ` Alexey Kuznetsov
1 sibling, 2 replies; 10+ messages in thread
From: Jeff Layton @ 2006-09-13 16:12 UTC (permalink / raw)
To: David Stevens; +Cc: linux-kernel, netdev
On Wed, 2006-09-13 at 07:32 -0700, David Stevens wrote:
> netdev-owner@vger.kernel.org wrote on 09/13/2006 07:13:55 AM:
>
> This is not true on any OS I'm aware of, including the
> original sockets multicast implementation on early BSD.
>
The current Linux behavior does seem to be consistent with the way
recent BSD and OSX seem to work. Solaris 8 seems to behave consistent
with the patch I posted.
Most of the RFC's I've looked at don't seem to have much to say about
how multicasting works at the socket level. Is there an RFC or
specification that spells this out, or is this one of those situations
where things are somewhat open to interpretation?
Thanks,
Jeff
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group
2006-09-13 16:12 ` Jeff Layton
@ 2006-09-13 16:42 ` David Stevens
2006-09-14 1:09 ` David Miller
1 sibling, 0 replies; 10+ messages in thread
From: David Stevens @ 2006-09-13 16:42 UTC (permalink / raw)
To: Jeff Layton; +Cc: linux-kernel, netdev
Jeff Layton <jlayton@poochiereds.net> wrote on 09/13/2006 09:12:23 AM:
> Most of the RFC's I've looked at don't seem to have much to say about
> how multicasting works at the socket level. Is there an RFC or
> specification that spells this out, or is this one of those situations
> where things are somewhat open to interpretation?
RFC's are standards for protocols and are concerned with
interoperability among multiple implementations. They, in general,
do not define API's (and those that do are "informational").
There are after-the-fact standards for sockets, including
POSIX, but older features are effectively defined by industry
practice; in this case, Deering's BSD implementation from nearly
20 years ago.
Sections 7.1 & 7.2 of RFC 988 [Deering, 1986] hint at this
interpretation (separation of membership from socket delivery),
esp. when it says "Incoming multicast IP datagrams are
delivered to upper-layer protocol modules using the
same 'Receive IP' operation as normal, unicast
datagrams."
But Deering's own implementation, which
does not distinguish which socket joined the group,
is the source of the standard practice.
+-DLS
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group
2006-09-13 16:12 ` Jeff Layton
2006-09-13 16:42 ` David Stevens
@ 2006-09-14 1:09 ` David Miller
1 sibling, 0 replies; 10+ messages in thread
From: David Miller @ 2006-09-14 1:09 UTC (permalink / raw)
To: jlayton; +Cc: dlstevens, linux-kernel, netdev
From: Jeff Layton <jlayton@poochiereds.net>
Date: Wed, 13 Sep 2006 12:12:23 -0400
> Most of the RFC's I've looked at don't seem to have much to say about
> how multicasting works at the socket level. Is there an RFC or
> specification that spells this out, or is this one of those situations
> where things are somewhat open to interpretation?
In these cases, whatever BSD does is effectively the definition of
what should happen since it is the "BSD socket API".
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group
2006-09-13 14:32 ` David Stevens
2006-09-13 16:12 ` Jeff Layton
@ 2006-09-13 20:20 ` Alexey Kuznetsov
2006-09-13 20:42 ` David Stevens
1 sibling, 1 reply; 10+ messages in thread
From: Alexey Kuznetsov @ 2006-09-13 20:20 UTC (permalink / raw)
To: David Stevens; +Cc: Jeff Layton, linux-kernel, netdev, netdev-owner
Hello!
> IPv6 behaves the same way.
Actually, Linux IPv6 filters received multicasts, inet6_mc_check() does
this.
IPv4 does not. I remember that attempts to do this were made in the past
and failed, because some applications, related to multicast routing,
did expect to receive all the multicasts even though they did not join
any multicast addresses. So, it was left intact.
Alexey
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group
2006-09-13 20:20 ` Alexey Kuznetsov
@ 2006-09-13 20:42 ` David Stevens
2006-09-14 10:30 ` Alexey Kuznetsov
0 siblings, 1 reply; 10+ messages in thread
From: David Stevens @ 2006-09-13 20:42 UTC (permalink / raw)
To: Alexey Kuznetsov; +Cc: Jeff Layton, linux-kernel, netdev, netdev-owner
Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> wrote on 09/13/2006 01:20:29 PM:
> Hello!
>
> > IPv6 behaves the same way.
>
> Actually, Linux IPv6 filters received multicasts, inet6_mc_check() does
> this.
No, it returns 1 (allow) if there are no filters to explicitly
filter it. I wrote that code. :-)
+-DLS
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group
2006-09-13 20:42 ` David Stevens
@ 2006-09-14 10:30 ` Alexey Kuznetsov
2006-09-14 15:39 ` David Stevens
0 siblings, 1 reply; 10+ messages in thread
From: Alexey Kuznetsov @ 2006-09-14 10:30 UTC (permalink / raw)
To: David Stevens; +Cc: Jeff Layton, linux-kernel, netdev, netdev-owner
Hello!
> No, it returns 1 (allow) if there are no filters to explicitly
> filter it. I wrote that code. :-)
I see. It did not behave this way old times.
>From your mails I understood that current behaviour matches another
implementations (BSD whatever), is it true?
Alexey
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group
2006-09-14 10:30 ` Alexey Kuznetsov
@ 2006-09-14 15:39 ` David Stevens
2006-09-14 17:12 ` Vlad Yasevich
0 siblings, 1 reply; 10+ messages in thread
From: David Stevens @ 2006-09-14 15:39 UTC (permalink / raw)
To: Alexey Kuznetsov; +Cc: Jeff Layton, linux-kernel, netdev, netdev-owner
Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> wrote on 09/14/2006 03:30:37 AM:
> Hello!
>
> > No, it returns 1 (allow) if there are no filters to explicitly
> > filter it. I wrote that code. :-)
>
> I see. It did not behave this way old times.
>
> From your mails I understood that current behaviour matches another
> implementations (BSD whatever), is it true?
Hi, Alexey,
If you mean IPv6 code in current BSD derivatives, I don't know.
The IPv6 behaviour was different from IPv4 on Linux and was changed for
compatibility with IPv4 (discussion on netdev agreed that binding
should determine socket delivery, not group membership, or simply
that there was no reason to be different from long-standing IPv4
practice).
The IPv4 code is that way for compatibility with everything else since
about ~4.3BSD (with the possible exception of Solaris 8, apparently).
FWIW, I think Deering's original interpretation is correct. Adding
a multicast address to an interface by joining a group is little
different from adding a unicast address via SIOCSIFADDR, which
certainly does affect packets delivered to the machine and to any
INADDR_ANY-bound socket. Binding to the multicast address and not
INADDR_ANY will give you only packets for that group, if that's
what you want, just as in the unicast address-specific bind.
+-DLS
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group
2006-09-14 15:39 ` David Stevens
@ 2006-09-14 17:12 ` Vlad Yasevich
0 siblings, 0 replies; 10+ messages in thread
From: Vlad Yasevich @ 2006-09-14 17:12 UTC (permalink / raw)
To: David Stevens; +Cc: netdev
On Thu, 2006-09-14 at 08:39 -0700, David Stevens wrote:
> Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> wrote on 09/14/2006 03:30:37 AM:
>
> > Hello!
> >
> > > No, it returns 1 (allow) if there are no filters to explicitly
> > > filter it. I wrote that code. :-)
> >
> > I see. It did not behave this way old times.
> >
> > From your mails I understood that current behaviour matches another
> > implementations (BSD whatever), is it true?
>
> Hi, Alexey,
>
> If you mean IPv6 code in current BSD derivatives, I don't know.
>
> The IPv6 behaviour was different from IPv4 on Linux and was changed for
> compatibility with IPv4 (discussion on netdev agreed that binding
> should determine socket delivery, not group membership, or simply
> that there was no reason to be different from long-standing IPv4
> practice).
>
> The IPv4 code is that way for compatibility with everything else since
> about ~4.3BSD (with the possible exception of Solaris 8, apparently).
>
> FWIW, I think Deering's original interpretation is correct. Adding
> a multicast address to an interface by joining a group is little
> different from adding a unicast address via SIOCSIFADDR, which
> certainly does affect packets delivered to the machine and to any
> INADDR_ANY-bound socket. Binding to the multicast address and not
> INADDR_ANY will give you only packets for that group, if that's
> what you want, just as in the unicast address-specific bind.
>
> +-DLS
There was an IETF daft quite a while ago that proposed something similar
to the patch that originated this thread. In case anyone is curious,
here is the link:
http://tools.ietf.org/wg/ipv6/draft-arunt-ipv6-multicast-filtering-rules-01.txt
That work got a few positive comments, but didn't really go anywhere.
-vlad
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2006-09-14 17:12 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-09-13 14:13 [PATCH] make ipv4 multicast packets only get delivered to sockets that are joined to group Jeff Layton
2006-09-13 14:32 ` David Stevens
2006-09-13 16:12 ` Jeff Layton
2006-09-13 16:42 ` David Stevens
2006-09-14 1:09 ` David Miller
2006-09-13 20:20 ` Alexey Kuznetsov
2006-09-13 20:42 ` David Stevens
2006-09-14 10:30 ` Alexey Kuznetsov
2006-09-14 15:39 ` David Stevens
2006-09-14 17:12 ` Vlad Yasevich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox