* 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
[parent not found: <87009604743AD411B1F600508BA0F95994CA68@XOVER.dedham.mindspeed.com>]
* 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
* 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 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
[parent not found: <87009604743AD411B1F600508BA0F95994CA6A@XOVER.dedham.mindspeed.com>]
* 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
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).