linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Kernel Multicast
@ 2001-08-28 17:19 Jean Tourrilhes
  0 siblings, 0 replies; 5+ messages in thread
From: Jean Tourrilhes @ 2001-08-28 17:19 UTC (permalink / raw)
  To: Linux kernel mailing list

	Hi,

	Could someone point me out who is the maintainer of the IP
multicast code in the kernel ? I've got a few questions regarding
multiple UDP multicast socket...
	And : please also reply to me personally, I'm not on the
mailing list...

	Thanks in advance...

	Jean

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Kernel Multicast
       [not found] <87009604743AD411B1F600508BA0F95994CA6A@XOVER.dedham.mindspeed.com>
@ 2001-08-28 21:28 ` Jean Tourrilhes
  0 siblings, 0 replies; 5+ messages in thread
From: Jean Tourrilhes @ 2001-08-28 21:28 UTC (permalink / raw)
  To: Linux kernel mailing list

On Tue, Aug 28, 2001 at 04:12:23PM -0400, Clayton, Mark wrote:
> 
> I think this is what I recall doing: 	
> 
> socket(AF_INET, SOCK_DGRAM, 0);
> 
> setsockopt(SO_REUSEADDR)
> 
> if ((remote_addr & 0xF0000000) == 0xE0000000) then saddr.sin_addr.s_addr 
> is INADDR_ANY otherwise use local_addr.  Port is local_port
> bind(saddr);
> 
> ipMreq.imr_multiaddr.s_addr = htonl(multicast_addr);
> ipMreq.imr_address.s_addr   = htonl(local_addr);
> ipMreq.imr_ifindex          = if_index (from /sbin/ipmaddr)
> setsockopt(IP_ADD_MEMBERSHIP, ipMreq
> 
> /* mcast sends */
> ifAddr.s_addr = htonl(local_addr) 
> setsockopt(IP_MULTICAST_IF, ifAddr);
> 
> setsockopt(SIOCGIFNAME, if_index);
> 
> setsockopt(SO_BINDTODEVICE)
> 
> Also, I think that for SOCK_RAW there needs to be a second
> socket just for reading.  But I don't recall the details.
> 
> If this helps, feel free to post the details to the list
> in a summary.  Please remove references to me though.
> 
> Thanks,
> Mark


	I did my little investigation and looked int he kernel for
answers.

	I was already looking at SO_BINDTODEVICE. This is very
powerful, unfortunately, it's reserved for ROOT. Maybe running my
program as root is not the brightest idea.
	Also, one might wonder why IP_MULTICAST_IF doesn't set
sk->bound_dev_if itself, which would be logical (it only checks that
the interface is the same as sk->bound_dev_if but seem to forget to
set it in .../net/ipv4/sockglue.c).

	Anyway, doing this definitely fix the problem :
------------------------------------------
socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(SO_BINDTODEVICE, ONE_INTERFACE);
bind(sock, INADDR_ANY, MY_PORT);
setsockopt(IP_ADD_MEMBERSHIP, INADDR_ALLHOSTS_GROUP, ONE_INTERFACE);
setsockopt(IP_MULTICAST_IF, ONE_INTERFACE);
------------------------------------------
	Works as advertised : you can have one and only one socket per
interface.

	Now, let's have a bit of fun... If you do :
------------------------------------------
socket(AF_INET, SOCK_DGRAM, 0);
bind(sock, INADDR_ANY, MY_PORT);
setsockopt(SO_BINDTODEVICE, ONE_INTERFACE);
setsockopt(IP_ADD_MEMBERSHIP, INADDR_ALLHOSTS_GROUP, ONE_INTERFACE);
setsockopt(IP_MULTICAST_IF, ONE_INTERFACE);
------------------------------------------
	In that case, the kernel let you open more than one socket per
interface (two, there...). I don't know if its intended, but it works
fine ;-)

	And you can also do this :
------------------------------------------
socket(AF_INET, SOCK_DGRAM, 0);
bind(sock, INADDR_ANY, MY_PORT);
setsockopt(IP_ADD_MEMBERSHIP, INADDR_ALLHOSTS_GROUP, ONE_INTERFACE);
setsockopt(IP_MULTICAST_IF, ONE_INTERFACE);
setsockopt(SO_BINDTODEVICE, ANOTHER_INTERFACE);
------------------------------------------
	This will send packet on ANOTHER_INTERFACE, but the source
address of those packet will be the one of ONE_INTERFACE.

	And if you look in .../net/core/sock.c, you will realise that
these two calls are handled very differently :
------------------------------------------
setsockopt(SO_BINDTODEVICE, "", 0);
setsockopt(SO_BINDTODEVICE, "", IFNAMSIZ);
------------------------------------------
	Which mean the man page need to be fixed ;-)

	Anyway, I don't really want to rely on SO_BINDTODEVICE,
because it needs ROOT capability.


	Now, you suggestions to use SO_REUSEADDR is spot on. It works
as any user. I get a little bit more than I bargained for (I want only
one socket per interface), but that's ok...
	In other words, this works :
------------------------------------------
socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(SO_REUSEADDR, 1);
bind(sock, INADDR_ANY, MY_PORT);
setsockopt(IP_ADD_MEMBERSHIP, INADDR_ALLHOSTS_GROUP, ONE_INTERFACE);
setsockopt(IP_MULTICAST_IF, ONE_INTERFACE);
------------------------------------------
	With one little caveat : such socket seems to receive
multicast comming from all interfaces. In other words, it seem that
IP_MULTICAST_IF only act on the outgoing path.
	In other words, IP_MULTICAST_IF doesn't do much... At least,
much less that what you would believe it to do...

	Also, using both SO_BINDTODEVICE and SO_REUSEADDR may be
overkill...

	That's it...

	Jean

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Kernel Multicast
  2001-08-28 18:30   ` Ion Badulescu
@ 2001-08-28 18:34     ` Jean Tourrilhes
  0 siblings, 0 replies; 5+ messages in thread
From: Jean Tourrilhes @ 2001-08-28 18:34 UTC (permalink / raw)
  To: Ion Badulescu; +Cc: linux-kernel

On Tue, Aug 28, 2001 at 02:30:56PM -0400, Ion Badulescu wrote:
> On Tue, 28 Aug 2001 11:13:21 -0700, Jean Tourrilhes <jt@bougret.hpl.hp.com> wrote:
> 
> >        And finally, I tried :
> > ------------------------------------------
> > bind(sock, ONE_INTERFACE, MY_PORT);
> > ------------------------------------------
> >        First instance : Tx ok, doesn't Rx anything at all. I can
> > understand why, the Rx packet don't have a dest IP address matching
> > ONE_INTERFACE.
> 
> This is the correct approach, I think. Have you tried adding the two
> setsockopt() calls after the bind, or at the very least the
> IP_ADD_MEMBERSHIP one, to see if you can Rx?

	Hum, I thought it was obvious. I did mention only this call
because that's the only difference, but what I did was :
------------------------------------------
socket(AF_INET, SOCK_DGRAM, 0);
bind(sock, ONE_INTERFACE, MY_PORT);
setsockopt(IP_ADD_MEMBERSHIP, INADDR_ALLHOSTS_GROUP, ONE_INTERFACE);
setsockopt(IP_MULTICAST_IF, ONE_INTERFACE);
------------------------------------------
	And in this case, no Rx at all !

> Otherwise quite obviously
> your physical interface will not have the multicast MAC address added to
> its filters and no packets will reach the IP stack.
> 
> 'ip maddr ls' is a useful tool for inspecting what your NIC is letting
> through.

	I'll try that...

> Ion

	Jean

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Kernel Multicast
  2001-08-28 18:13 ` Jean Tourrilhes
@ 2001-08-28 18:30   ` Ion Badulescu
  2001-08-28 18:34     ` Jean Tourrilhes
  0 siblings, 1 reply; 5+ messages in thread
From: Ion Badulescu @ 2001-08-28 18:30 UTC (permalink / raw)
  To: jt; +Cc: linux-kernel

On Tue, 28 Aug 2001 11:13:21 -0700, Jean Tourrilhes <jt@bougret.hpl.hp.com> wrote:

>        And finally, I tried :
> ------------------------------------------
> bind(sock, ONE_INTERFACE, MY_PORT);
> ------------------------------------------
>        First instance : Tx ok, doesn't Rx anything at all. I can
> understand why, the Rx packet don't have a dest IP address matching
> ONE_INTERFACE.

This is the correct approach, I think. Have you tried adding the two
setsockopt() calls after the bind, or at the very least the
IP_ADD_MEMBERSHIP one, to see if you can Rx? Otherwise quite obviously
your physical interface will not have the multicast MAC address added to
its filters and no packets will reach the IP stack.

'ip maddr ls' is a useful tool for inspecting what your NIC is letting
through.

Ion

-- 
  It is better to keep your mouth shut and be thought a fool,
            than to open it and remove all doubt.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Kernel Multicast
       [not found] <87009604743AD411B1F600508BA0F95994CA68@XOVER.dedham.mindspeed.com>
@ 2001-08-28 18:13 ` Jean Tourrilhes
  2001-08-28 18:30   ` Ion Badulescu
  0 siblings, 1 reply; 5+ messages in thread
From: Jean Tourrilhes @ 2001-08-28 18:13 UTC (permalink / raw)
  To: Clayton, Mark, Linux kernel mailing list

On Tue, Aug 28, 2001 at 01:45:35PM -0400, Clayton, Mark wrote:
> 
> Do you mind sharing your questions/thoughts?  This topic 
> interests me.  I'd be interested in hearing the dialog.
> 
> Thanks,
> Mark
> --
> [root@hjinc mclayton] /sbin/insmod stddisclaimer.o

	Ok, I'll try to be brief... I'm still not on the LKML...

	Linux 2.4.8, multiple network interfaces. I want to Rx/Tx
multicast junk on all interfaces or subset of them, on the same UDP
port.
	First, a bit of background : with multicast, packets are not
automatically sent on all interfaces. If you set a multicast route in
the routing table to an interface, they will be sent to this
interface, and only this one.
	The only way to bypass the routing table is to use the
IP_MULTICAST_IF option, but that select one specific outgoing
interface.
	Therefore, I'm trying to open a separate UDP multicast socket
on each interface active on the system (SIOCGIFCONF).


	I have a program that do (simplified) :
------------------------------------------
socket(AF_INET, SOCK_DGRAM, 0);
bind(sock, INADDR_ANY, MY_PORT);
setsockopt(IP_ADD_MEMBERSHIP, INADDR_ALLHOSTS_GROUP, ONE_INTERFACE);
setsockopt(IP_MULTICAST_IF, ONE_INTERFACE);
------------------------------------------
	First instance : work like a charm : multicast packet are
Tx/Rx on the selected interface without the need of explicit multicast
route.
        Second instance : "bind failed: Address already in use". In
other word, every time I try to bind a second socket on this port, it
fails...

	As "bind" is problematic, I tried as well :
------------------------------------------
bind(sock, INADDR_ALLHOSTS_GROUP, MY_PORT);
------------------------------------------
	This acts exactly as above, second bind fails.

	And finally, I tried :
------------------------------------------
bind(sock, ONE_INTERFACE, MY_PORT);
------------------------------------------
	First instance : Tx ok, doesn't Rx anything at all. I can
understand why, the Rx packet don't have a dest IP address matching
ONE_INTERFACE.


	That's it... As it's my first experiment with Multicast, I'm
probably missing something obvious...
	Thanks in advance...

	Jean

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2001-08-28 21:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-28 17:19 Kernel Multicast Jean Tourrilhes
     [not found] <87009604743AD411B1F600508BA0F95994CA68@XOVER.dedham.mindspeed.com>
2001-08-28 18:13 ` Jean Tourrilhes
2001-08-28 18:30   ` Ion Badulescu
2001-08-28 18:34     ` Jean Tourrilhes
     [not found] <87009604743AD411B1F600508BA0F95994CA6A@XOVER.dedham.mindspeed.com>
2001-08-28 21:28 ` Jean Tourrilhes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).